// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 NXP
 */

#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/devfreq.h>
#include <linux/pm_opp.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/arm-smccc.h>

#define IMX_SIP_DDR_DVFS			0xc2000004

/* Query available frequencies. */
#define IMX_SIP_DDR_DVFS_GET_FREQ_COUNT		0x10
#define IMX_SIP_DDR_DVFS_GET_FREQ_INFO		0x11

/*
 * This should be in a 1:1 mapping with devicetree OPPs but
 * firmware provides additional info.
 */
struct imx8m_ddrc_freq {
	unsigned long rate;
	unsigned long smcarg;
	int dram_core_parent_index;
	int dram_alt_parent_index;
	int dram_apb_parent_index;
};

/* Hardware limitation */
#define IMX8M_DDRC_MAX_FREQ_COUNT 4

/*
 * i.MX8M DRAM Controller clocks have the following structure (abridged):
 *
 * +----------+       |\            +------+
 * | dram_pll |-------|M| dram_core |      |
 * +----------+       |U|---------->| D    |
 *                 /--|X|           |  D   |
 *   dram_alt_root |  |/            |   R  |
 *                 |                |    C |
 *            +---------+           |      |
 *            |FIX DIV/4|           |      |
 *            +---------+           |      |
 *  composite:     |                |      |
 * +----------+    |                |      |
 * | dram_alt |----/                |      |
 * +----------+                     |      |
 * | dram_apb |-------------------->|      |
 * +----------+                     +------+
 *
 * The dram_pll is used for higher rates and dram_alt is used for lower rates.
 *
 * Frequency switching is implemented in TF-A (via SMC call) and can change the
 * configuration of the clocks, including mux parents. The dram_alt and
 * dram_apb clocks are "imx composite" and their parent can change too.
 *
 * We need to prepare/enable the new mux parents head of switching and update
 * their information afterwards.
 */
struct imx8m_ddrc {
	struct devfreq_dev_profile profile;
	struct devfreq *devfreq;

	/* For frequency switching: */
	struct clk *dram_core;
	struct clk *dram_pll;
	struct clk *dram_alt;
	struct clk *dram_apb;

	int freq_count;
	struct imx8m_ddrc_freq freq_table[IMX8M_DDRC_MAX_FREQ_COUNT];
};

static struct imx8m_ddrc_freq *imx8m_ddrc_find_freq(struct imx8m_ddrc *priv,
						    unsigned long rate)
{
	struct imx8m_ddrc_freq *freq;
	int i;

	/*
	 * Firmware reports values in MT/s, so we round-down from Hz
	 * Rounding is extra generous to ensure a match.
	 */
	rate = DIV_ROUND_CLOSEST(rate, 250000);
	for (i = 0; i < priv->freq_count; ++i) {
		freq = &priv->freq_table[i];
		if (freq->rate == rate ||
				freq->rate + 1 == rate ||
				freq->rate - 1 == rate)
			return freq;
	}

	return NULL;
}

static void imx8m_ddrc_smc_set_freq(int target_freq)
{
	struct arm_smccc_res res;
	u32 online_cpus = 0;
	int cpu;

	local_irq_disable();

	for_each_online_cpu(cpu)
		online_cpus |= (1 << (cpu * 8));

	/* change the ddr freqency */
	arm_smccc_smc(IMX_SIP_DDR_DVFS, target_freq, online_cpus,
			0, 0, 0, 0, 0, &res);

	local_irq_enable();
}

static struct clk *clk_get_parent_by_index(struct clk *clk, int index)
{
	struct clk_hw *hw;

	hw = clk_hw_get_parent_by_index(__clk_get_hw(clk), index);

	return hw ? hw->clk : NULL;
}

static int imx8m_ddrc_set_freq(struct device *dev, struct imx8m_ddrc_freq *freq)
{
	struct imx8m_ddrc *priv = dev_get_drvdata(dev);
	struct clk *new_dram_core_parent;
	struct clk *new_dram_alt_parent;
	struct clk *new_dram_apb_parent;
	int ret;

	/*
	 * Fetch new parents
	 *
	 * new_dram_alt_parent and new_dram_apb_parent are optional but
	 * new_dram_core_parent is not.
	 */
	new_dram_core_parent = clk_get_parent_by_index(
			priv->dram_core, freq->dram_core_parent_index - 1);
	if (!new_dram_core_parent) {
		dev_err(dev, "failed to fetch new dram_core parent\n");
		return -EINVAL;
	}
	if (freq->dram_alt_parent_index) {
		new_dram_alt_parent = clk_get_parent_by_index(
				priv->dram_alt,
				freq->dram_alt_parent_index - 1);
		if (!new_dram_alt_parent) {
			dev_err(dev, "failed to fetch new dram_alt parent\n");
			return -EINVAL;
		}
	} else
		new_dram_alt_parent = NULL;

	if (freq->dram_apb_parent_index) {
		new_dram_apb_parent = clk_get_parent_by_index(
				priv->dram_apb,
				freq->dram_apb_parent_index - 1);
		if (!new_dram_apb_parent) {
			dev_err(dev, "failed to fetch new dram_apb parent\n");
			return -EINVAL;
		}
	} else
		new_dram_apb_parent = NULL;

	/* increase reference counts and ensure clks are ON before switch */
	ret = clk_prepare_enable(new_dram_core_parent);
	if (ret) {
		dev_err(dev, "failed to enable new dram_core parent: %d\n",
			ret);
		goto out;
	}
	ret = clk_prepare_enable(new_dram_alt_parent);
	if (ret) {
		dev_err(dev, "failed to enable new dram_alt parent: %d\n",
			ret);
		goto out_disable_core_parent;
	}
	ret = clk_prepare_enable(new_dram_apb_parent);
	if (ret) {
		dev_err(dev, "failed to enable new dram_apb parent: %d\n",
			ret);
		goto out_disable_alt_parent;
	}

	imx8m_ddrc_smc_set_freq(freq->smcarg);

	/* update parents in clk tree after switch. */
	ret = clk_set_parent(priv->dram_core, new_dram_core_parent);
	if (ret)
		dev_warn(dev, "failed to set dram_core parent: %d\n", ret);
	if (new_dram_alt_parent) {
		ret = clk_set_parent(priv->dram_alt, new_dram_alt_parent);
		if (ret)
			dev_warn(dev, "failed to set dram_alt parent: %d\n",
				 ret);
	}
	if (new_dram_apb_parent) {
		ret = clk_set_parent(priv->dram_apb, new_dram_apb_parent);
		if (ret)
			dev_warn(dev, "failed to set dram_apb parent: %d\n",
				 ret);
	}

	/*
	 * Explicitly refresh dram PLL rate.
	 *
	 * Even if it's marked with CLK_GET_RATE_NOCACHE the rate will not be
	 * automatically refreshed when clk_get_rate is called on children.
	 */
	clk_get_rate(priv->dram_pll);

	/*
	 * clk_set_parent transfer the reference count from old parent.
	 * now we drop extra reference counts used during the switch
	 */
	clk_disable_unprepare(new_dram_apb_parent);
out_disable_alt_parent:
	clk_disable_unprepare(new_dram_alt_parent);
out_disable_core_parent:
	clk_disable_unprepare(new_dram_core_parent);
out:
	return ret;
}

static int imx8m_ddrc_target(struct device *dev, unsigned long *freq, u32 flags)
{
	struct imx8m_ddrc *priv = dev_get_drvdata(dev);
	struct imx8m_ddrc_freq *freq_info;
	struct dev_pm_opp *new_opp;
	unsigned long old_freq, new_freq;
	int ret;

	new_opp = devfreq_recommended_opp(dev, freq, flags);
	if (IS_ERR(new_opp)) {
		ret = PTR_ERR(new_opp);
		dev_err(dev, "failed to get recommended opp: %d\n", ret);
		return ret;
	}
	dev_pm_opp_put(new_opp);

	old_freq = clk_get_rate(priv->dram_core);
	if (*freq == old_freq)
		return 0;

	freq_info = imx8m_ddrc_find_freq(priv, *freq);
	if (!freq_info)
		return -EINVAL;

	/*
	 * Read back the clk rate to verify switch was correct and so that
	 * we can report it on all error paths.
	 */
	ret = imx8m_ddrc_set_freq(dev, freq_info);

	new_freq = clk_get_rate(priv->dram_core);
	if (ret)
		dev_err(dev, "ddrc failed freq switch to %lu from %lu: error %d. now at %lu\n",
			*freq, old_freq, ret, new_freq);
	else if (*freq != new_freq)
		dev_err(dev, "ddrc failed freq update to %lu from %lu, now at %lu\n",
			*freq, old_freq, new_freq);
	else
		dev_dbg(dev, "ddrc freq set to %lu (was %lu)\n",
			*freq, old_freq);

	return ret;
}

static int imx8m_ddrc_get_cur_freq(struct device *dev, unsigned long *freq)
{
	struct imx8m_ddrc *priv = dev_get_drvdata(dev);

	*freq = clk_get_rate(priv->dram_core);

	return 0;
}

static int imx8m_ddrc_init_freq_info(struct device *dev)
{
	struct imx8m_ddrc *priv = dev_get_drvdata(dev);
	struct arm_smccc_res res;
	int index;

	/* An error here means DDR DVFS API not supported by firmware */
	arm_smccc_smc(IMX_SIP_DDR_DVFS, IMX_SIP_DDR_DVFS_GET_FREQ_COUNT,
			0, 0, 0, 0, 0, 0, &res);
	priv->freq_count = res.a0;
	if (priv->freq_count <= 0 ||
			priv->freq_count > IMX8M_DDRC_MAX_FREQ_COUNT)
		return -ENODEV;

	for (index = 0; index < priv->freq_count; ++index) {
		struct imx8m_ddrc_freq *freq = &priv->freq_table[index];

		arm_smccc_smc(IMX_SIP_DDR_DVFS, IMX_SIP_DDR_DVFS_GET_FREQ_INFO,
			      index, 0, 0, 0, 0, 0, &res);
		/* Result should be strictly positive */
		if ((long)res.a0 <= 0)
			return -ENODEV;

		freq->rate = res.a0;
		freq->smcarg = index;
		freq->dram_core_parent_index = res.a1;
		freq->dram_alt_parent_index = res.a2;
		freq->dram_apb_parent_index = res.a3;

		/* dram_core has 2 options: dram_pll or dram_alt_root */
		if (freq->dram_core_parent_index != 1 &&
				freq->dram_core_parent_index != 2)
			return -ENODEV;
		/* dram_apb and dram_alt have exactly 8 possible parents */
		if (freq->dram_alt_parent_index > 8 ||
				freq->dram_apb_parent_index > 8)
			return -ENODEV;
		/* dram_core from alt requires explicit dram_alt parent */
		if (freq->dram_core_parent_index == 2 &&
				freq->dram_alt_parent_index == 0)
			return -ENODEV;
	}

	return 0;
}

static int imx8m_ddrc_check_opps(struct device *dev)
{
	struct imx8m_ddrc *priv = dev_get_drvdata(dev);
	struct imx8m_ddrc_freq *freq_info;
	struct dev_pm_opp *opp;
	unsigned long freq;
	int i, opp_count;

	/* Enumerate DT OPPs and disable those not supported by firmware */
	opp_count = dev_pm_opp_get_opp_count(dev);
	if (opp_count < 0)
		return opp_count;
	for (i = 0, freq = 0; i < opp_count; ++i, ++freq) {
		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
		if (IS_ERR(opp)) {
			dev_err(dev, "Failed enumerating OPPs: %ld\n",
				PTR_ERR(opp));
			return PTR_ERR(opp);
		}
		dev_pm_opp_put(opp);

		freq_info = imx8m_ddrc_find_freq(priv, freq);
		if (!freq_info) {
			dev_info(dev, "Disable unsupported OPP %luHz %luMT/s\n",
					freq, DIV_ROUND_CLOSEST(freq, 250000));
			dev_pm_opp_disable(dev, freq);
		}
	}

	return 0;
}

static void imx8m_ddrc_exit(struct device *dev)
{
	dev_pm_opp_of_remove_table(dev);
}

static int imx8m_ddrc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct imx8m_ddrc *priv;
	const char *gov = DEVFREQ_GOV_USERSPACE;
	int ret;

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

	platform_set_drvdata(pdev, priv);

	ret = imx8m_ddrc_init_freq_info(dev);
	if (ret) {
		dev_err(dev, "failed to init firmware freq info: %d\n", ret);
		return ret;
	}

	priv->dram_core = devm_clk_get(dev, "core");
	if (IS_ERR(priv->dram_core)) {
		ret = PTR_ERR(priv->dram_core);
		dev_err(dev, "failed to fetch core clock: %d\n", ret);
		return ret;
	}
	priv->dram_pll = devm_clk_get(dev, "pll");
	if (IS_ERR(priv->dram_pll)) {
		ret = PTR_ERR(priv->dram_pll);
		dev_err(dev, "failed to fetch pll clock: %d\n", ret);
		return ret;
	}
	priv->dram_alt = devm_clk_get(dev, "alt");
	if (IS_ERR(priv->dram_alt)) {
		ret = PTR_ERR(priv->dram_alt);
		dev_err(dev, "failed to fetch alt clock: %d\n", ret);
		return ret;
	}
	priv->dram_apb = devm_clk_get(dev, "apb");
	if (IS_ERR(priv->dram_apb)) {
		ret = PTR_ERR(priv->dram_apb);
		dev_err(dev, "failed to fetch apb clock: %d\n", ret);
		return ret;
	}

	ret = dev_pm_opp_of_add_table(dev);
	if (ret < 0) {
		dev_err(dev, "failed to get OPP table\n");
		return ret;
	}

	ret = imx8m_ddrc_check_opps(dev);
	if (ret < 0)
		goto err;

	priv->profile.target = imx8m_ddrc_target;
	priv->profile.exit = imx8m_ddrc_exit;
	priv->profile.get_cur_freq = imx8m_ddrc_get_cur_freq;
	priv->profile.initial_freq = clk_get_rate(priv->dram_core);

	priv->devfreq = devm_devfreq_add_device(dev, &priv->profile,
						gov, NULL);
	if (IS_ERR(priv->devfreq)) {
		ret = PTR_ERR(priv->devfreq);
		dev_err(dev, "failed to add devfreq device: %d\n", ret);
		goto err;
	}

	return 0;

err:
	dev_pm_opp_of_remove_table(dev);
	return ret;
}

static const struct of_device_id imx8m_ddrc_of_match[] = {
	{ .compatible = "fsl,imx8m-ddrc", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx8m_ddrc_of_match);

static struct platform_driver imx8m_ddrc_platdrv = {
	.probe		= imx8m_ddrc_probe,
	.driver = {
		.name	= "imx8m-ddrc-devfreq",
		.of_match_table = imx8m_ddrc_of_match,
	},
};
module_platform_driver(imx8m_ddrc_platdrv);

MODULE_DESCRIPTION("i.MX8M DDR Controller frequency driver");
MODULE_AUTHOR("Leonard Crestez <leonard.crestez@nxp.com>");
MODULE_LICENSE("GPL v2");
