 /*
 * Copyright 2017 NXP.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>

#define MAX_RUN_FREQ	528000

static struct clk *arm_clk;
static struct clk *core_div;
static struct clk *sys_sel;
static struct clk *hsrun_sys_sel;
static struct clk *hsrun_core;
static struct clk *spll_pfd0;
static struct clk *spll_sel;
static struct clk *firc_clk;
static struct clk *spll;

static struct pm_qos_request pm_qos_hsrun;
static struct regulator *arm_reg;
static struct device *cpu_dev;
static struct cpufreq_frequency_table *freq_table;
static unsigned int transition_latency;

static int imx7ulp_set_target(struct cpufreq_policy *policy, unsigned int index)
{
	struct dev_pm_opp *opp;
	unsigned long freq_hz, volt, volt_old;
	unsigned int old_freq, new_freq;
	int ret;

	new_freq = freq_table[index].frequency;
	freq_hz = new_freq * 1000;
	old_freq = clk_get_rate(arm_clk) / 1000;
	if (new_freq == 0 || old_freq == 0)
		return -EINVAL;

	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
	if (IS_ERR(opp)) {
		dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
		return PTR_ERR(opp);
	}
	volt = dev_pm_opp_get_voltage(opp);
	dev_pm_opp_put(opp);

	volt_old = regulator_get_voltage(arm_reg);

	dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
		old_freq / 1000, volt_old / 1000,
		new_freq / 1000, volt / 1000);

	/* Scaling up? scale voltage before frequency */
	if (new_freq > old_freq) {
		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
		if (ret) {
			dev_err(cpu_dev, "failed to scale vddarm up: %d\n", ret);
			return ret;
		}
	}

	/* before changing pll_arm rate, change the arm_src's soure
	 * to firc clk first.
	 */
	if (new_freq > MAX_RUN_FREQ) {
		pm_qos_add_request(&pm_qos_hsrun, PM_QOS_CPU_DMA_LATENCY, 0);
		/* change the RUN clock to firc */
		clk_set_parent(sys_sel, firc_clk);
		/* change the clock rate in HSRUN */
		clk_set_rate(spll, 480000000);
		clk_set_rate(spll_pfd0, new_freq * 1000);
		clk_set_parent(hsrun_sys_sel, spll_sel);
		clk_set_parent(arm_clk, hsrun_core);
	} else {
		/* change the HSRUN clock to firc */
		clk_set_parent(hsrun_sys_sel, firc_clk);
		/* change the clock rate in RUN */
		clk_set_rate(spll, 528000000);
		clk_set_rate(spll_pfd0, new_freq * 1000);
		clk_set_parent(sys_sel, spll_sel);
		clk_set_parent(arm_clk, core_div);
		if (old_freq > MAX_RUN_FREQ)
			pm_qos_remove_request(&pm_qos_hsrun);
	}

	/* scaling down? scaling voltage after frequency */
	if (new_freq < old_freq) {
		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
		if (ret) {
			dev_warn(cpu_dev, "failed to scale vddarm down: %d\n", ret);
			ret = 0;
		}
	}

	return 0;
}

static int imx7ulp_cpufreq_init(struct cpufreq_policy *policy)
{
	int ret;
	policy->clk = arm_clk;
	policy->cur = clk_get_rate(arm_clk) / 1000;
	policy->suspend_freq = freq_table[0].frequency;

	ret = cpufreq_generic_init(policy, freq_table, transition_latency);

	if (ret) {
		dev_err(cpu_dev, "imx7ulp cpufreq init failed\n");
		return ret;
	}

	return 0;
}

static struct cpufreq_driver imx7ulp_cpufreq_driver = {
	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
	.verify = cpufreq_generic_frequency_table_verify,
	.target_index = imx7ulp_set_target,
	.get = cpufreq_generic_get,
	.init = imx7ulp_cpufreq_init,
	.name = "imx7ulp-cpufreq",
	.attr = cpufreq_generic_attr,
#ifdef CONFIG_PM
	.suspend = cpufreq_generic_suspend,
#endif
};

static int imx7ulp_cpufreq_probe(struct platform_device *pdev)
{
	struct device_node *np;
	int ret;

	cpu_dev = get_cpu_device(0);
	if (!cpu_dev) {
		pr_err("failed to get cpu0 device\n");
		return -ENOENT;
	}

	np = of_node_get(cpu_dev->of_node);
	if (!np) {
		dev_err(cpu_dev, "failed to find the cpu0 node\n");
		return -ENOENT;
	}

	arm_clk = clk_get(cpu_dev, "arm");
	sys_sel = clk_get(cpu_dev, "sys_sel");
	core_div = clk_get(cpu_dev, "core_div");
	hsrun_sys_sel = clk_get(cpu_dev, "hsrun_sys_sel");
	hsrun_core = clk_get(cpu_dev, "hsrun_core");
	spll_pfd0 = clk_get(cpu_dev, "spll_pfd0");
	spll_sel = clk_get(cpu_dev, "spll_sel");
	firc_clk = clk_get(cpu_dev, "firc");
	spll = clk_get(cpu_dev, "spll");

	if (IS_ERR(arm_clk) || IS_ERR(sys_sel) || IS_ERR(spll_sel) ||
	    IS_ERR(spll_sel) || IS_ERR(firc_clk) || IS_ERR(hsrun_sys_sel) ||
	    IS_ERR(hsrun_core) || IS_ERR(spll)) {
		dev_err(cpu_dev, "failed to get cpu clock\n");
		ret = -ENOENT;
		goto put_clk;
	}

	arm_reg = regulator_get(cpu_dev, "arm");
	if (IS_ERR(arm_reg)) {
		dev_err(cpu_dev, "failed to get regulator\n");
		ret = -ENOENT;
		goto put_reg;
	}

	ret = dev_pm_opp_of_add_table(cpu_dev);
	if (ret < 0) {
		dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
		goto put_reg;
	}

	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
	if (ret) {
		dev_err(cpu_dev, "failed to init cpufreq table\n");
		goto put_reg;
	}

	if (of_property_read_u32(np, "clock-latency", &transition_latency))
		transition_latency = CPUFREQ_ETERNAL;

	ret = cpufreq_register_driver(&imx7ulp_cpufreq_driver);
	if (ret) {
		dev_err(cpu_dev, "failed to register driver\n");
		goto free_opp_table;
	}

	return 0;

free_opp_table:
	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
put_reg:
	regulator_put(arm_reg);
put_clk:
	if (!IS_ERR(arm_clk))
		clk_put(arm_clk);
	if (!IS_ERR(sys_sel))
		clk_put(sys_sel);
	if (!IS_ERR(core_div))
		clk_put(core_div);
	if (!IS_ERR(hsrun_sys_sel))
		clk_put(hsrun_sys_sel);
	if (!IS_ERR(hsrun_core))
		clk_put(hsrun_core);
	if (!IS_ERR(spll_pfd0))
		clk_put(spll_pfd0);
	if (!IS_ERR(spll_sel))
		clk_put(spll_sel);
	if (!IS_ERR(firc_clk))
		clk_put(firc_clk);
	if (!IS_ERR(spll))
		clk_put(spll);

	return ret;
}

static int imx7ulp_cpufreq_remove(struct platform_device *pdev)
{
	cpufreq_unregister_driver(&imx7ulp_cpufreq_driver);
	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);

	regulator_put(arm_reg);
	clk_put(arm_clk);
	clk_put(sys_sel);
	clk_put(core_div);
	clk_put(hsrun_sys_sel);
	clk_put(hsrun_core);
	clk_put(spll_pfd0);
	clk_put(spll_sel);
	clk_put(firc_clk);
	clk_put(spll);

	return 0;
}

static struct platform_driver imx7ulp_cpufreq_platdrv = {
	.driver = {
		.name	= "imx7ulp-cpufreq",
		.owner	= THIS_MODULE,
	},
	.probe		= imx7ulp_cpufreq_probe,
	.remove		= imx7ulp_cpufreq_remove,
};

module_platform_driver(imx7ulp_cpufreq_platdrv);

MODULE_DESCRIPTION("NXP i.MX7ULP cpufreq driver");
MODULE_LICENSE("GPL v2");

