// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2020 MediaTek Inc.
 */

#include <linux/bitfield.h>
#include <linux/cpufreq.h>
#include <linux/energy_model.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>

#define LUT_MAX_ENTRIES			32U
#define LUT_FREQ			GENMASK(11, 0)
#define LUT_ROW_SIZE			0x4
#define CPUFREQ_HW_STATUS		BIT(0)
#define SVS_HW_STATUS			BIT(1)
#define POLL_USEC			1000
#define TIMEOUT_USEC			300000

enum {
	REG_FREQ_LUT_TABLE,
	REG_FREQ_ENABLE,
	REG_FREQ_PERF_STATE,
	REG_FREQ_HW_STATE,
	REG_EM_POWER_TBL,
	REG_FREQ_LATENCY,

	REG_ARRAY_SIZE,
};

struct mtk_cpufreq_data {
	struct cpufreq_frequency_table *table;
	void __iomem *reg_bases[REG_ARRAY_SIZE];
	int nr_opp;
};

static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
	[REG_FREQ_LUT_TABLE]	= 0x0,
	[REG_FREQ_ENABLE]	= 0x84,
	[REG_FREQ_PERF_STATE]	= 0x88,
	[REG_FREQ_HW_STATE]	= 0x8c,
	[REG_EM_POWER_TBL]	= 0x90,
	[REG_FREQ_LATENCY]	= 0x110,
};

static int __maybe_unused
mtk_cpufreq_get_cpu_power(unsigned long *mW,
			  unsigned long *KHz, struct device *cpu_dev)
{
	struct mtk_cpufreq_data *data;
	struct cpufreq_policy *policy;
	int i;

	policy = cpufreq_cpu_get_raw(cpu_dev->id);
	if (!policy)
		return 0;

	data = policy->driver_data;

	for (i = 0; i < data->nr_opp; i++) {
		if (data->table[i].frequency < *KHz)
			break;
	}
	i--;

	*KHz = data->table[i].frequency;
	*mW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] +
			    i * LUT_ROW_SIZE) / 1000;

	return 0;
}

static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
				       unsigned int index)
{
	struct mtk_cpufreq_data *data = policy->driver_data;

	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);

	return 0;
}

static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
{
	struct mtk_cpufreq_data *data;
	struct cpufreq_policy *policy;
	unsigned int index;

	policy = cpufreq_cpu_get_raw(cpu);
	if (!policy)
		return 0;

	data = policy->driver_data;

	index = readl_relaxed(data->reg_bases[REG_FREQ_PERF_STATE]);
	index = min(index, LUT_MAX_ENTRIES - 1);

	return data->table[index].frequency;
}

static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
					       unsigned int target_freq)
{
	struct mtk_cpufreq_data *data = policy->driver_data;
	unsigned int index;

	index = cpufreq_table_find_index_dl(policy, target_freq);

	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);

	return policy->freq_table[index].frequency;
}

static int mtk_cpu_create_freq_table(struct platform_device *pdev,
				     struct mtk_cpufreq_data *data)
{
	struct device *dev = &pdev->dev;
	u32 temp, i, freq, prev_freq = 0;
	void __iomem *base_table;

	data->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
				   sizeof(*data->table), GFP_KERNEL);
	if (!data->table)
		return -ENOMEM;

	base_table = data->reg_bases[REG_FREQ_LUT_TABLE];

	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
		temp = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
		freq = FIELD_GET(LUT_FREQ, temp) * 1000;

		if (freq == prev_freq)
			break;

		data->table[i].frequency = freq;

		dev_dbg(dev, "index=%d freq=%d\n", i, data->table[i].frequency);

		prev_freq = freq;
	}

	data->table[i].frequency = CPUFREQ_TABLE_END;
	data->nr_opp = i;

	return 0;
}

static int mtk_cpu_resources_init(struct platform_device *pdev,
				  struct cpufreq_policy *policy,
				  const u16 *offsets)
{
	struct mtk_cpufreq_data *data;
	struct device *dev = &pdev->dev;
	void __iomem *base;
	int ret, i;
	int index;

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

	index = of_perf_domain_get_sharing_cpumask(policy->cpu, "performance-domains",
						   "#performance-domain-cells",
						   policy->cpus);
	if (index < 0)
		return index;

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

	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
		data->reg_bases[i] = base + offsets[i];

	ret = mtk_cpu_create_freq_table(pdev, data);
	if (ret) {
		dev_info(dev, "Domain-%d failed to create freq table\n", index);
		return ret;
	}

	policy->freq_table = data->table;
	policy->driver_data = data;

	return 0;
}

static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
{
	struct platform_device *pdev = cpufreq_get_driver_data();
	int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
	struct mtk_cpufreq_data *data;
	unsigned int latency;
	int ret;

	/* Get the bases of cpufreq for domains */
	ret = mtk_cpu_resources_init(pdev, policy, platform_get_drvdata(pdev));
	if (ret) {
		dev_info(&pdev->dev, "CPUFreq resource init failed\n");
		return ret;
	}

	data = policy->driver_data;

	latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000;
	if (!latency)
		latency = CPUFREQ_ETERNAL;

	policy->cpuinfo.transition_latency = latency;
	policy->fast_switch_possible = true;

	/* HW should be in enabled state to proceed now */
	writel_relaxed(0x1, data->reg_bases[REG_FREQ_ENABLE]);
	if (readl_poll_timeout(data->reg_bases[REG_FREQ_HW_STATE], sig,
			       (sig & pwr_hw) == pwr_hw, POLL_USEC,
			       TIMEOUT_USEC)) {
		if (!(sig & CPUFREQ_HW_STATUS)) {
			pr_info("cpufreq hardware of CPU%d is not enabled\n",
				policy->cpu);
			return -ENODEV;
		}

		pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
	}

	return 0;
}

static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
{
	struct mtk_cpufreq_data *data = policy->driver_data;

	/* HW should be in paused state now */
	writel_relaxed(0x0, data->reg_bases[REG_FREQ_ENABLE]);

	return 0;
}

static void mtk_cpufreq_register_em(struct cpufreq_policy *policy)
{
	struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
	struct mtk_cpufreq_data *data = policy->driver_data;

	em_dev_register_perf_domain(get_cpu_device(policy->cpu), data->nr_opp,
				    &em_cb, policy->cpus, true);
}

static struct cpufreq_driver cpufreq_mtk_hw_driver = {
	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
			  CPUFREQ_IS_COOLING_DEV,
	.verify		= cpufreq_generic_frequency_table_verify,
	.target_index	= mtk_cpufreq_hw_target_index,
	.get		= mtk_cpufreq_hw_get,
	.init		= mtk_cpufreq_hw_cpu_init,
	.exit		= mtk_cpufreq_hw_cpu_exit,
	.register_em	= mtk_cpufreq_register_em,
	.fast_switch	= mtk_cpufreq_hw_fast_switch,
	.name		= "mtk-cpufreq-hw",
	.attr		= cpufreq_generic_attr,
};

static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
{
	const void *data;
	int ret;

	data = of_device_get_match_data(&pdev->dev);
	if (!data)
		return -EINVAL;

	platform_set_drvdata(pdev, (void *) data);
	cpufreq_mtk_hw_driver.driver_data = pdev;

	ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);
	if (ret)
		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");

	return ret;
}

static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev)
{
	return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver);
}

static const struct of_device_id mtk_cpufreq_hw_match[] = {
	{ .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },
	{}
};

static struct platform_driver mtk_cpufreq_hw_driver = {
	.probe = mtk_cpufreq_hw_driver_probe,
	.remove = mtk_cpufreq_hw_driver_remove,
	.driver = {
		.name = "mtk-cpufreq-hw",
		.of_match_table = mtk_cpufreq_hw_match,
	},
};
module_platform_driver(mtk_cpufreq_hw_driver);

MODULE_AUTHOR("Hector Yuan <hector.yuan@mediatek.com>");
MODULE_DESCRIPTION("Mediatek cpufreq-hw driver");
MODULE_LICENSE("GPL v2");
