/*
 *	kirkwood_freq.c: cpufreq driver for the Marvell kirkwood
 *
 *	Copyright (C) 2013 Andrew Lunn <andrew@lunn.ch>
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpufreq.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/proc-fns.h>

#define CPU_SW_INT_BLK BIT(28)

static struct priv
{
	struct clk *cpu_clk;
	struct clk *ddr_clk;
	struct clk *powersave_clk;
	struct device *dev;
	void __iomem *base;
} priv;

#define STATE_CPU_FREQ 0x01
#define STATE_DDR_FREQ 0x02

/*
 * Kirkwood can swap the clock to the CPU between two clocks:
 *
 * - cpu clk
 * - ddr clk
 *
 * The frequencies are set at runtime before registering this *
 * table.
 */
static struct cpufreq_frequency_table kirkwood_freq_table[] = {
	{STATE_CPU_FREQ,	0}, /* CPU uses cpuclk */
	{STATE_DDR_FREQ,	0}, /* CPU uses ddrclk */
	{0,			CPUFREQ_TABLE_END},
};

static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
{
	if (__clk_is_enabled(priv.powersave_clk))
		return kirkwood_freq_table[1].frequency;
	return kirkwood_freq_table[0].frequency;
}

static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy,
		unsigned int index)
{
	struct cpufreq_freqs freqs;
	unsigned int state = kirkwood_freq_table[index].index;
	unsigned long reg;

	freqs.old = kirkwood_cpufreq_get_cpu_frequency(0);
	freqs.new = kirkwood_freq_table[index].frequency;

	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

	dev_dbg(priv.dev, "Attempting to set frequency to %i KHz\n",
		kirkwood_freq_table[index].frequency);
	dev_dbg(priv.dev, "old frequency was %i KHz\n",
		kirkwood_cpufreq_get_cpu_frequency(0));

	if (freqs.old != freqs.new) {
		local_irq_disable();

		/* Disable interrupts to the CPU */
		reg = readl_relaxed(priv.base);
		reg |= CPU_SW_INT_BLK;
		writel_relaxed(reg, priv.base);

		switch (state) {
		case STATE_CPU_FREQ:
			clk_disable(priv.powersave_clk);
			break;
		case STATE_DDR_FREQ:
			clk_enable(priv.powersave_clk);
			break;
		}

		/* Wait-for-Interrupt, while the hardware changes frequency */
		cpu_do_idle();

		/* Enable interrupts to the CPU */
		reg = readl_relaxed(priv.base);
		reg &= ~CPU_SW_INT_BLK;
		writel_relaxed(reg, priv.base);

		local_irq_enable();
	}
	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
};

static int kirkwood_cpufreq_verify(struct cpufreq_policy *policy)
{
	return cpufreq_frequency_table_verify(policy, kirkwood_freq_table);
}

static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
			    unsigned int target_freq,
			    unsigned int relation)
{
	unsigned int index = 0;

	if (cpufreq_frequency_table_target(policy, kirkwood_freq_table,
				target_freq, relation, &index))
		return -EINVAL;

	kirkwood_cpufreq_set_cpu_state(policy, index);

	return 0;
}

/* Module init and exit code */
static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
	int result;

	/* cpuinfo and default policy values */
	policy->cpuinfo.transition_latency = 5000; /* 5uS */
	policy->cur = kirkwood_cpufreq_get_cpu_frequency(0);

	result = cpufreq_frequency_table_cpuinfo(policy, kirkwood_freq_table);
	if (result)
		return result;

	cpufreq_frequency_table_get_attr(kirkwood_freq_table, policy->cpu);

	return 0;
}

static int kirkwood_cpufreq_cpu_exit(struct cpufreq_policy *policy)
{
	cpufreq_frequency_table_put_attr(policy->cpu);
	return 0;
}

static struct freq_attr *kirkwood_cpufreq_attr[] = {
	&cpufreq_freq_attr_scaling_available_freqs,
	NULL,
};

static struct cpufreq_driver kirkwood_cpufreq_driver = {
	.get	= kirkwood_cpufreq_get_cpu_frequency,
	.verify	= kirkwood_cpufreq_verify,
	.target	= kirkwood_cpufreq_target,
	.init	= kirkwood_cpufreq_cpu_init,
	.exit	= kirkwood_cpufreq_cpu_exit,
	.name	= "kirkwood-cpufreq",
	.owner	= THIS_MODULE,
	.attr	= kirkwood_cpufreq_attr,
};

static int kirkwood_cpufreq_probe(struct platform_device *pdev)
{
	struct device_node *np;
	struct resource *res;
	int err;

	priv.dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Cannot get memory resource\n");
		return -ENODEV;
	}
	priv.base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv.base))
		return PTR_ERR(priv.base);

	np = of_find_node_by_path("/cpus/cpu@0");
	if (!np)
		return -ENODEV;

	priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
	if (IS_ERR(priv.cpu_clk)) {
		dev_err(priv.dev, "Unable to get cpuclk");
		return PTR_ERR(priv.cpu_clk);
	}

	clk_prepare_enable(priv.cpu_clk);
	kirkwood_freq_table[0].frequency = clk_get_rate(priv.cpu_clk) / 1000;

	priv.ddr_clk = of_clk_get_by_name(np, "ddrclk");
	if (IS_ERR(priv.ddr_clk)) {
		dev_err(priv.dev, "Unable to get ddrclk");
		err = PTR_ERR(priv.ddr_clk);
		goto out_cpu;
	}

	clk_prepare_enable(priv.ddr_clk);
	kirkwood_freq_table[1].frequency = clk_get_rate(priv.ddr_clk) / 1000;

	priv.powersave_clk = of_clk_get_by_name(np, "powersave");
	if (IS_ERR(priv.powersave_clk)) {
		dev_err(priv.dev, "Unable to get powersave");
		err = PTR_ERR(priv.powersave_clk);
		goto out_ddr;
	}
	clk_prepare(priv.powersave_clk);

	of_node_put(np);
	np = NULL;

	err = cpufreq_register_driver(&kirkwood_cpufreq_driver);
	if (!err)
		return 0;

	dev_err(priv.dev, "Failed to register cpufreq driver");

	clk_disable_unprepare(priv.powersave_clk);
out_ddr:
	clk_disable_unprepare(priv.ddr_clk);
out_cpu:
	clk_disable_unprepare(priv.cpu_clk);
	of_node_put(np);

	return err;
}

static int kirkwood_cpufreq_remove(struct platform_device *pdev)
{
	cpufreq_unregister_driver(&kirkwood_cpufreq_driver);

	clk_disable_unprepare(priv.powersave_clk);
	clk_disable_unprepare(priv.ddr_clk);
	clk_disable_unprepare(priv.cpu_clk);

	return 0;
}

static struct platform_driver kirkwood_cpufreq_platform_driver = {
	.probe = kirkwood_cpufreq_probe,
	.remove = kirkwood_cpufreq_remove,
	.driver = {
		.name = "kirkwood-cpufreq",
		.owner = THIS_MODULE,
	},
};

module_platform_driver(kirkwood_cpufreq_platform_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch");
MODULE_DESCRIPTION("cpufreq driver for Marvell's kirkwood CPU");
MODULE_ALIAS("platform:kirkwood-cpufreq");
