// SPDX-License-Identifier: GPL-2.0
/*
 * Qualcomm A53 PLL driver
 *
 * Copyright (c) 2017, Linaro Limited
 * Author: Georgi Djakov <georgi.djakov@linaro.org>
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/regmap.h>
#include <linux/module.h>

#include "clk-pll.h"
#include "clk-regmap.h"

static const struct pll_freq_tbl a53pll_freq[] = {
	{  998400000, 52, 0x0, 0x1, 0 },
	{ 1094400000, 57, 0x0, 0x1, 0 },
	{ 1152000000, 62, 0x0, 0x1, 0 },
	{ 1209600000, 63, 0x0, 0x1, 0 },
	{ 1248000000, 65, 0x0, 0x1, 0 },
	{ 1363200000, 71, 0x0, 0x1, 0 },
	{ 1401600000, 73, 0x0, 0x1, 0 },
	{ }
};

static const struct regmap_config a53pll_regmap_config = {
	.reg_bits		= 32,
	.reg_stride		= 4,
	.val_bits		= 32,
	.max_register		= 0x40,
};

static struct pll_freq_tbl *qcom_a53pll_get_freq_tbl(struct device *dev)
{
	struct pll_freq_tbl *freq_tbl;
	unsigned long xo_freq;
	unsigned long freq;
	struct clk *xo_clk;
	int count;
	int ret;
	int i;

	xo_clk = devm_clk_get(dev, "xo");
	if (IS_ERR(xo_clk))
		return NULL;

	xo_freq = clk_get_rate(xo_clk);

	ret = devm_pm_opp_of_add_table(dev);
	if (ret)
		return NULL;

	count = dev_pm_opp_get_opp_count(dev);
	if (count <= 0)
		return NULL;

	freq_tbl = devm_kcalloc(dev, count + 1, sizeof(*freq_tbl), GFP_KERNEL);
	if (!freq_tbl)
		return NULL;

	for (i = 0, freq = 0; i < count; i++, freq++) {
		struct dev_pm_opp *opp;

		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
		if (IS_ERR(opp))
			return NULL;

		/* Skip the freq that is not divisible */
		if (freq % xo_freq)
			continue;

		freq_tbl[i].freq = freq;
		freq_tbl[i].l = freq / xo_freq;
		freq_tbl[i].n = 1;

		dev_pm_opp_put(opp);
	}

	return freq_tbl;
}

static int qcom_a53pll_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct regmap *regmap;
	struct clk_pll *pll;
	void __iomem *base;
	struct clk_init_data init = { };
	int ret;

	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
	if (!pll)
		return -ENOMEM;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	regmap = devm_regmap_init_mmio(dev, base, &a53pll_regmap_config);
	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	pll->l_reg = 0x04;
	pll->m_reg = 0x08;
	pll->n_reg = 0x0c;
	pll->config_reg = 0x14;
	pll->mode_reg = 0x00;
	pll->status_reg = 0x1c;
	pll->status_bit = 16;

	pll->freq_tbl = qcom_a53pll_get_freq_tbl(dev);
	if (!pll->freq_tbl) {
		/* Fall on a53pll_freq if no freq_tbl is found from OPP */
		pll->freq_tbl = a53pll_freq;
	}

	/* Use an unique name by appending @unit-address */
	init.name = devm_kasprintf(dev, GFP_KERNEL, "a53pll%s",
				   strchrnul(np->full_name, '@'));
	if (!init.name)
		return -ENOMEM;

	init.parent_data = &(const struct clk_parent_data){
		.fw_name = "xo", .name = "xo_board",
	};
	init.num_parents = 1;
	init.ops = &clk_pll_sr2_ops;
	pll->clkr.hw.init = &init;

	ret = devm_clk_register_regmap(dev, &pll->clkr);
	if (ret) {
		dev_err(dev, "failed to register regmap clock: %d\n", ret);
		return ret;
	}

	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
					  &pll->clkr.hw);
	if (ret) {
		dev_err(dev, "failed to add clock provider: %d\n", ret);
		return ret;
	}

	return 0;
}

static const struct of_device_id qcom_a53pll_match_table[] = {
	{ .compatible = "qcom,msm8226-a7pll" },
	{ .compatible = "qcom,msm8916-a53pll" },
	{ .compatible = "qcom,msm8939-a53pll" },
	{ }
};
MODULE_DEVICE_TABLE(of, qcom_a53pll_match_table);

static struct platform_driver qcom_a53pll_driver = {
	.probe = qcom_a53pll_probe,
	.driver = {
		.name = "qcom-a53pll",
		.of_match_table = qcom_a53pll_match_table,
	},
};
module_platform_driver(qcom_a53pll_driver);

MODULE_DESCRIPTION("Qualcomm A53 PLL Driver");
MODULE_LICENSE("GPL v2");
