 /*
 * 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 struct mutex set_cpufreq_lock;

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;

	mutex_lock(&set_cpufreq_lock);

	new_freq = freq_table[index].frequency;
	freq_hz = new_freq * 1000;
	old_freq = clk_get_rate(arm_clk) / 1000;

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

	rcu_read_unlock();
	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);
			mutex_unlock(&set_cpufreq_lock);
			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;
		}
	}

	mutex_unlock(&set_cpufreq_lock);
	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;

	mutex_init(&set_cpufreq_lock);
	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");

