// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015 Chen-Yu Tsai
 *
 * Chen-Yu Tsai <wens@csie.org>
 *
 * Allwinner A80 CPUS clock driver
 *
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/of.h>
#include <linux/of_address.h>

static DEFINE_SPINLOCK(sun9i_a80_cpus_lock);


#define SUN9I_CPUS_MAX_PARENTS		4
#define SUN9I_CPUS_MUX_PARENT_PLL4	3
#define SUN9I_CPUS_MUX_SHIFT		16
#define SUN9I_CPUS_MUX_MASK		GENMASK(17, 16)
#define SUN9I_CPUS_MUX_GET_PARENT(reg)	((reg & SUN9I_CPUS_MUX_MASK) >> \
						SUN9I_CPUS_MUX_SHIFT)

#define SUN9I_CPUS_DIV_SHIFT		4
#define SUN9I_CPUS_DIV_MASK		GENMASK(5, 4)
#define SUN9I_CPUS_DIV_GET(reg)		((reg & SUN9I_CPUS_DIV_MASK) >> \
						SUN9I_CPUS_DIV_SHIFT)
#define SUN9I_CPUS_DIV_SET(reg, div)	((reg & ~SUN9I_CPUS_DIV_MASK) | \
						(div << SUN9I_CPUS_DIV_SHIFT))
#define SUN9I_CPUS_PLL4_DIV_SHIFT	8
#define SUN9I_CPUS_PLL4_DIV_MASK	GENMASK(12, 8)
#define SUN9I_CPUS_PLL4_DIV_GET(reg)	((reg & SUN9I_CPUS_PLL4_DIV_MASK) >> \
						SUN9I_CPUS_PLL4_DIV_SHIFT)
#define SUN9I_CPUS_PLL4_DIV_SET(reg, div) ((reg & ~SUN9I_CPUS_PLL4_DIV_MASK) | \
						(div << SUN9I_CPUS_PLL4_DIV_SHIFT))

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

#define to_sun9i_a80_cpus_clk(_hw) container_of(_hw, struct sun9i_a80_cpus_clk, hw)

static unsigned long sun9i_a80_cpus_clk_recalc_rate(struct clk_hw *hw,
						    unsigned long parent_rate)
{
	struct sun9i_a80_cpus_clk *cpus = to_sun9i_a80_cpus_clk(hw);
	unsigned long rate;
	u32 reg;

	/* Fetch the register value */
	reg = readl(cpus->reg);

	/* apply pre-divider first if parent is pll4 */
	if (SUN9I_CPUS_MUX_GET_PARENT(reg) == SUN9I_CPUS_MUX_PARENT_PLL4)
		parent_rate /= SUN9I_CPUS_PLL4_DIV_GET(reg) + 1;

	/* clk divider */
	rate = parent_rate / (SUN9I_CPUS_DIV_GET(reg) + 1);

	return rate;
}

static long sun9i_a80_cpus_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp,
				     u8 parent, unsigned long parent_rate)
{
	u8 div, pre_div = 1;

	/*
	 * clock can only divide, so we will never be able to achieve
	 * frequencies higher than the parent frequency
	 */
	if (parent_rate && rate > parent_rate)
		rate = parent_rate;

	div = DIV_ROUND_UP(parent_rate, rate);

	/* calculate pre-divider if parent is pll4 */
	if (parent == SUN9I_CPUS_MUX_PARENT_PLL4 && div > 4) {
		/* pre-divider is 1 ~ 32 */
		if (div < 32) {
			pre_div = div;
			div = 1;
		} else if (div < 64) {
			pre_div = DIV_ROUND_UP(div, 2);
			div = 2;
		} else if (div < 96) {
			pre_div = DIV_ROUND_UP(div, 3);
			div = 3;
		} else {
			pre_div = DIV_ROUND_UP(div, 4);
			div = 4;
		}
	}

	/* we were asked to pass back divider values */
	if (divp) {
		*divp = div - 1;
		*pre_divp = pre_div - 1;
	}

	return parent_rate / pre_div / div;
}

static int sun9i_a80_cpus_clk_determine_rate(struct clk_hw *clk,
					     struct clk_rate_request *req)
{
	struct clk_hw *parent, *best_parent = NULL;
	int i, num_parents;
	unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
	unsigned long rate = req->rate;

	/* find the parent that can help provide the fastest rate <= rate */
	num_parents = clk_hw_get_num_parents(clk);
	for (i = 0; i < num_parents; i++) {
		parent = clk_hw_get_parent_by_index(clk, i);
		if (!parent)
			continue;
		if (clk_hw_get_flags(clk) & CLK_SET_RATE_PARENT)
			parent_rate = clk_hw_round_rate(parent, rate);
		else
			parent_rate = clk_hw_get_rate(parent);

		child_rate = sun9i_a80_cpus_clk_round(rate, NULL, NULL, i,
						      parent_rate);

		if (child_rate <= rate && child_rate > best_child_rate) {
			best_parent = parent;
			best = parent_rate;
			best_child_rate = child_rate;
		}
	}

	if (!best_parent)
		return -EINVAL;

	req->best_parent_hw = best_parent;
	req->best_parent_rate = best;
	req->rate = best_child_rate;

	return 0;
}

static int sun9i_a80_cpus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
				       unsigned long parent_rate)
{
	struct sun9i_a80_cpus_clk *cpus = to_sun9i_a80_cpus_clk(hw);
	unsigned long flags;
	u8 div, pre_div, parent;
	u32 reg;

	spin_lock_irqsave(&sun9i_a80_cpus_lock, flags);

	reg = readl(cpus->reg);

	/* need to know which parent is used to apply pre-divider */
	parent = SUN9I_CPUS_MUX_GET_PARENT(reg);
	sun9i_a80_cpus_clk_round(rate, &div, &pre_div, parent, parent_rate);

	reg = SUN9I_CPUS_DIV_SET(reg, div);
	reg = SUN9I_CPUS_PLL4_DIV_SET(reg, pre_div);
	writel(reg, cpus->reg);

	spin_unlock_irqrestore(&sun9i_a80_cpus_lock, flags);

	return 0;
}

static const struct clk_ops sun9i_a80_cpus_clk_ops = {
	.determine_rate	= sun9i_a80_cpus_clk_determine_rate,
	.recalc_rate	= sun9i_a80_cpus_clk_recalc_rate,
	.set_rate	= sun9i_a80_cpus_clk_set_rate,
};

/**
 * sun9i_a80_cpus_setup() - Setup function for a80 cpus composite clk
 * @node: &struct device_node for the clock
 */
static void sun9i_a80_cpus_setup(struct device_node *node)
{
	const char *clk_name = node->name;
	const char *parents[SUN9I_CPUS_MAX_PARENTS];
	struct resource res;
	struct sun9i_a80_cpus_clk *cpus;
	struct clk_mux *mux;
	struct clk *clk;
	int ret;

	cpus = kzalloc(sizeof(*cpus), GFP_KERNEL);
	if (!cpus)
		return;

	cpus->reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(cpus->reg))
		goto err_free_cpus;

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

	/* we have a mux, we will have >1 parents */
	ret = of_clk_parent_fill(node, parents, SUN9I_CPUS_MAX_PARENTS);

	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
	if (!mux)
		goto err_unmap;

	/* set up clock properties */
	mux->reg = cpus->reg;
	mux->shift = SUN9I_CPUS_MUX_SHIFT;
	/* un-shifted mask is what mux_clk expects */
	mux->mask = SUN9I_CPUS_MUX_MASK >> SUN9I_CPUS_MUX_SHIFT;
	mux->lock = &sun9i_a80_cpus_lock;

	clk = clk_register_composite(NULL, clk_name, parents, ret,
				     &mux->hw, &clk_mux_ops,
				     &cpus->hw, &sun9i_a80_cpus_clk_ops,
				     NULL, NULL, 0);
	if (IS_ERR(clk))
		goto err_free_mux;

	ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
	if (ret)
		goto err_unregister;

	return;

err_unregister:
	clk_unregister(clk);
err_free_mux:
	kfree(mux);
err_unmap:
	iounmap(cpus->reg);
	of_address_to_resource(node, 0, &res);
	release_mem_region(res.start, resource_size(&res));
err_free_cpus:
	kfree(cpus);
}
CLK_OF_DECLARE(sun9i_a80_cpus, "allwinner,sun9i-a80-cpus-clk",
	       sun9i_a80_cpus_setup);
