/*
 * 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 min_rate,
				 unsigned long max_rate,
				 unsigned long *best_parent_rate,
				 struct clk_hw **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 = __clk_get_hw(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;
}

static 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);
}

static 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",
		.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");
