/*
 * Copyright (C) 2014 Free Electrons
 *
 * License Terms: GNU General Public License v2
 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
 *
 * Allwinner A31 AR100 clock driver
 *
 */

#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#define SUN6I_AR100_MAX_PARENTS		4
#define SUN6I_AR100_SHIFT_MASK		0x3
#define SUN6I_AR100_SHIFT_MAX		SUN6I_AR100_SHIFT_MASK
#define SUN6I_AR100_SHIFT_SHIFT		4
#define SUN6I_AR100_DIV_MASK		0x1f
#define SUN6I_AR100_DIV_MAX		(SUN6I_AR100_DIV_MASK + 1)
#define SUN6I_AR100_DIV_SHIFT		8
#define SUN6I_AR100_MUX_MASK		0x3
#define SUN6I_AR100_MUX_SHIFT		16

struct ar100_clk {
	struct clk_hw hw;
	void __iomem *reg;
};

static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw)
{
	return container_of(hw, struct ar100_clk, hw);
}

static unsigned long ar100_recalc_rate(struct clk_hw *hw,
				       unsigned long parent_rate)
{
	struct ar100_clk *clk = to_ar100_clk(hw);
	u32 val = readl(clk->reg);
	int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK;
	int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK;

	return (parent_rate >> shift) / (div + 1);
}

static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate,
				 unsigned long *best_parent_rate,
				 struct clk **best_parent_clk)
{
	int nparents = __clk_get_num_parents(hw->clk);
	long best_rate = -EINVAL;
	int i;

	*best_parent_clk = NULL;

	for (i = 0; i < nparents; i++) {
		unsigned long parent_rate;
		unsigned long tmp_rate;
		struct clk *parent;
		unsigned long div;
		int shift;

		parent = clk_get_parent_by_index(hw->clk, i);
		parent_rate = __clk_get_rate(parent);
		div = DIV_ROUND_UP(parent_rate, rate);

		/*
		 * The AR100 clk contains 2 divisors:
		 * - one power of 2 divisor
		 * - one regular divisor
		 *
		 * First check if we can safely shift (or divide by a power
		 * of 2) without losing precision on the requested rate.
		 */
		shift = ffs(div) - 1;
		if (shift > SUN6I_AR100_SHIFT_MAX)
			shift = SUN6I_AR100_SHIFT_MAX;

		div >>= shift;

		/*
		 * Then if the divisor is still bigger than what the HW
		 * actually supports, use a bigger shift (or power of 2
		 * divider) value and accept to lose some precision.
		 */
		while (div > SUN6I_AR100_DIV_MAX) {
			shift++;
			div >>= 1;
			if (shift > SUN6I_AR100_SHIFT_MAX)
				break;
		}

		/*
		 * If the shift value (or power of 2 divider) is bigger
		 * than what the HW actually support, skip this parent.
		 */
		if (shift > SUN6I_AR100_SHIFT_MAX)
			continue;

		tmp_rate = (parent_rate >> shift) / div;
		if (!*best_parent_clk || tmp_rate > best_rate) {
			*best_parent_clk = parent;
			*best_parent_rate = parent_rate;
			best_rate = tmp_rate;
		}
	}

	return best_rate;
}

static int ar100_set_parent(struct clk_hw *hw, u8 index)
{
	struct ar100_clk *clk = to_ar100_clk(hw);
	u32 val = readl(clk->reg);

	if (index >= SUN6I_AR100_MAX_PARENTS)
		return -EINVAL;

	val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT);
	val |= (index << SUN6I_AR100_MUX_SHIFT);
	writel(val, clk->reg);

	return 0;
}

static u8 ar100_get_parent(struct clk_hw *hw)
{
	struct ar100_clk *clk = to_ar100_clk(hw);
	return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) &
	       SUN6I_AR100_MUX_MASK;
}

static int ar100_set_rate(struct clk_hw *hw, unsigned long rate,
			  unsigned long parent_rate)
{
	unsigned long div = parent_rate / rate;
	struct ar100_clk *clk = to_ar100_clk(hw);
	u32 val = readl(clk->reg);
	int shift;

	if (parent_rate % rate)
		return -EINVAL;

	shift = ffs(div) - 1;
	if (shift > SUN6I_AR100_SHIFT_MAX)
		shift = SUN6I_AR100_SHIFT_MAX;

	div >>= shift;

	if (div > SUN6I_AR100_DIV_MAX)
		return -EINVAL;

	val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) |
		 (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT));
	val |= (shift << SUN6I_AR100_SHIFT_SHIFT) |
	       (div << SUN6I_AR100_DIV_SHIFT);
	writel(val, clk->reg);

	return 0;
}

struct clk_ops ar100_ops = {
	.recalc_rate = ar100_recalc_rate,
	.determine_rate = ar100_determine_rate,
	.set_parent = ar100_set_parent,
	.get_parent = ar100_get_parent,
	.set_rate = ar100_set_rate,
};

static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev)
{
	const char *parents[SUN6I_AR100_MAX_PARENTS];
	struct device_node *np = pdev->dev.of_node;
	const char *clk_name = np->name;
	struct clk_init_data init;
	struct ar100_clk *ar100;
	struct resource *r;
	struct clk *clk;
	int nparents;
	int i;

	ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL);
	if (!ar100)
		return -ENOMEM;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ar100->reg = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(ar100->reg))
		return PTR_ERR(ar100->reg);

	nparents = of_clk_get_parent_count(np);
	if (nparents > SUN6I_AR100_MAX_PARENTS)
		nparents = SUN6I_AR100_MAX_PARENTS;

	for (i = 0; i < nparents; i++)
		parents[i] = of_clk_get_parent_name(np, i);

	of_property_read_string(np, "clock-output-names", &clk_name);

	init.name = clk_name;
	init.ops = &ar100_ops;
	init.parent_names = parents;
	init.num_parents = nparents;
	init.flags = 0;

	ar100->hw.init = &init;

	clk = clk_register(&pdev->dev, &ar100->hw);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	return of_clk_add_provider(np, of_clk_src_simple_get, clk);
}

const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
	{ .compatible = "allwinner,sun6i-a31-ar100-clk" },
	{ /* sentinel */ }
};

static struct platform_driver sun6i_a31_ar100_clk_driver = {
	.driver = {
		.name = "sun6i-a31-ar100-clk",
		.owner = THIS_MODULE,
		.of_match_table = sun6i_a31_ar100_clk_dt_ids,
	},
	.probe = sun6i_a31_ar100_clk_probe,
};
module_platform_driver(sun6i_a31_ar100_clk_driver);

MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>");
MODULE_DESCRIPTION("Allwinner A31 AR100 clock Driver");
MODULE_LICENSE("GPL v2");
