/*
 * Copyright 2013 Broadcom Corporation.
 *
 * SPDX-License-Identifier:      GPL-2.0+
 */

/*
 *
 * bcm281xx architecture clock framework
 *
 */

#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <bitfield.h>
#include <asm/arch/sysmap.h>
#include <asm/kona-common/clk.h>
#include "clk-core.h"

#define CLK_WR_ACCESS_PASSWORD	0x00a5a501
#define WR_ACCESS_OFFSET	0	/* common to all clock blocks */
#define POLICY_CTL_GO		1	/* Load and refresh policy masks */
#define POLICY_CTL_GO_ATL	4	/* Active Load */

/* Helper function */
int clk_get_and_enable(char *clkstr)
{
	int ret = 0;
	struct clk *c;

	debug("%s: %s\n", __func__, clkstr);

	c = clk_get(clkstr);
	if (c) {
		ret = clk_enable(c);
		if (ret)
			return ret;
	} else {
		printf("%s: Couldn't find %s\n", __func__, clkstr);
		return -EINVAL;
	}
	return ret;
}

/*
 * Poll a register in a CCU's address space, returning when the
 * specified bit in that register's value is set (or clear).  Delay
 * a microsecond after each read of the register.  Returns true if
 * successful, or false if we gave up trying.
 *
 * Caller must ensure the CCU lock is held.
 */
#define CLK_GATE_DELAY_USEC 2000
static inline int wait_bit(void *base, u32 offset, u32 bit, bool want)
{
	unsigned int tries;
	u32 bit_mask = 1 << bit;

	for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) {
		u32 val;
		bool bit_val;

		val = readl(base + offset);
		bit_val = (val & bit_mask) ? 1 : 0;
		if (bit_val == want)
			return 0;	/* success */
		udelay(1);
	}

	debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n",
	      __func__, base + offset, bit, want);

	return -ETIMEDOUT;
}

/* Enable a peripheral clock */
static int peri_clk_enable(struct clk *c, int enable)
{
	int ret = 0;
	u32 reg;
	struct peri_clock *peri_clk = to_peri_clk(c);
	struct peri_clk_data *cd = peri_clk->data;
	struct bcm_clk_gate *gate = &cd->gate;
	void *base = (void *)c->ccu_clk_mgr_base;


	debug("%s: %s\n", __func__, c->name);

	clk_get_rate(c);	/* Make sure rate and sel are filled in */

	/* enable access */
	writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);

	if (enable) {
		debug("%s %s set rate %lu div %lu sel %d parent %lu\n",
		      __func__, c->name, c->rate, c->div, c->sel,
		      c->parent->rate);

		/*
		 * clkgate - only software controllable gates are
		 * supported by u-boot which includes all clocks
		 * that matter. This avoids bringing in a lot of extra
		 * complexity as done in the kernel framework.
		 */
		if (gate_exists(gate)) {
			reg = readl(base + cd->gate.offset);
			reg |= (1 << cd->gate.en_bit);
			writel(reg, base + cd->gate.offset);
		}

		/* div and pll select */
		if (divider_exists(&cd->div)) {
			reg = readl(base + cd->div.offset);
			bitfield_replace(reg, cd->div.shift, cd->div.width,
					 c->div - 1);
			writel(reg, base + cd->div.offset);
		}

		/* frequency selector */
		if (selector_exists(&cd->sel)) {
			reg = readl(base + cd->sel.offset);
			bitfield_replace(reg, cd->sel.shift, cd->sel.width,
					 c->sel);
			writel(reg, base + cd->sel.offset);
		}

		/* trigger */
		if (trigger_exists(&cd->trig)) {
			writel((1 << cd->trig.bit), base + cd->trig.offset);

			/* wait for trigger status bit to go to 0 */
			ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0);
			if (ret)
				return ret;
		}

		/* wait for running (status_bit = 1) */
		ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1);
		if (ret)
			return ret;
	} else {
		debug("%s disable clock %s\n", __func__, c->name);

		/* clkgate */
		reg = readl(base + cd->gate.offset);
		reg &= ~(1 << cd->gate.en_bit);
		writel(reg, base + cd->gate.offset);

		/* wait for stop (status_bit = 0) */
		ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0);
	}

	/* disable access */
	writel(0, base + WR_ACCESS_OFFSET);

	return ret;
}

/* Set the rate of a peripheral clock */
static int peri_clk_set_rate(struct clk *c, unsigned long rate)
{
	int ret = 0;
	int i;
	unsigned long diff;
	unsigned long new_rate = 0, div = 1;
	struct peri_clock *peri_clk = to_peri_clk(c);
	struct peri_clk_data *cd = peri_clk->data;
	const char **clock;

	debug("%s: %s\n", __func__, c->name);
	diff = rate;

	i = 0;
	for (clock = cd->clocks; *clock; clock++, i++) {
		struct refclk *ref = refclk_str_to_clk(*clock);
		if (!ref) {
			printf("%s: Lookup of %s failed\n", __func__, *clock);
			return -EINVAL;
		}

		/* round to the new rate */
		div = ref->clk.rate / rate;
		if (div == 0)
			div = 1;

		new_rate = ref->clk.rate / div;

		/* get the min diff */
		if (abs(new_rate - rate) < diff) {
			diff = abs(new_rate - rate);
			c->sel = i;
			c->parent = &ref->clk;
			c->rate = new_rate;
			c->div = div;
		}
	}

	debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__,
	      c->name, c->rate, c->div, c->sel, c->parent->rate);
	return ret;
}

/* Get the rate of a peripheral clock */
static unsigned long peri_clk_get_rate(struct clk *c)
{
	struct peri_clock *peri_clk = to_peri_clk(c);
	struct peri_clk_data *cd = peri_clk->data;
	void *base = (void *)c->ccu_clk_mgr_base;
	int div = 1;
	const char **clock;
	struct refclk *ref;
	u32 reg;

	debug("%s: %s\n", __func__, c->name);
	if (selector_exists(&cd->sel)) {
		reg = readl(base + cd->sel.offset);
		c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width);
	} else {
		/*
		 * For peri clocks that don't have a selector, the single
		 * reference clock will always exist at index 0.
		 */
		c->sel = 0;
	}

	if (divider_exists(&cd->div)) {
		reg = readl(base + cd->div.offset);
		div = bitfield_extract(reg, cd->div.shift, cd->div.width);
		div += 1;
	}

	clock = cd->clocks;
	ref = refclk_str_to_clk(clock[c->sel]);
	if (!ref) {
		printf("%s: Can't lookup %s\n", __func__, clock[c->sel]);
		return 0;
	}

	c->parent = &ref->clk;
	c->div = div;
	c->rate = c->parent->rate / c->div;
	debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__,
	      c->parent->rate, div, c->sel, c->rate);

	return c->rate;
}

/* Peripheral clock operations */
struct clk_ops peri_clk_ops = {
	.enable = peri_clk_enable,
	.set_rate = peri_clk_set_rate,
	.get_rate = peri_clk_get_rate,
};

/* Enable a CCU clock */
static int ccu_clk_enable(struct clk *c, int enable)
{
	struct ccu_clock *ccu_clk = to_ccu_clk(c);
	void *base = (void *)c->ccu_clk_mgr_base;
	int ret = 0;
	u32 reg;

	debug("%s: %s\n", __func__, c->name);
	if (!enable)
		return -EINVAL;	/* CCU clock cannot shutdown */

	/* enable access */
	writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);

	/* config enable for policy engine */
	writel(1, base + ccu_clk->lvm_en_offset);

	/* wait for bit to go to 0 */
	ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
	if (ret)
		return ret;

	/* freq ID */
	if (!ccu_clk->freq_bit_shift)
		ccu_clk->freq_bit_shift = 8;

	/* Set frequency id for each of the 4 policies */
	reg = ccu_clk->freq_id |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
	writel(reg, base + ccu_clk->policy_freq_offset);

	/* enable all clock mask */
	writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);

	if (ccu_clk->num_policy_masks == 2) {
		writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
	}

	/* start policy engine */
	reg = readl(base + ccu_clk->policy_ctl_offset);
	reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
	writel(reg, base + ccu_clk->policy_ctl_offset);

	/* wait till started */
	ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
	if (ret)
		return ret;

	/* disable access */
	writel(0, base + WR_ACCESS_OFFSET);

	return ret;
}

/* Get the CCU clock rate */
static unsigned long ccu_clk_get_rate(struct clk *c)
{
	struct ccu_clock *ccu_clk = to_ccu_clk(c);
	debug("%s: %s\n", __func__, c->name);
	c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
	return c->rate;
}

/* CCU clock operations */
struct clk_ops ccu_clk_ops = {
	.enable = ccu_clk_enable,
	.get_rate = ccu_clk_get_rate,
};

/* Enable a bus clock */
static int bus_clk_enable(struct clk *c, int enable)
{
	struct bus_clock *bus_clk = to_bus_clk(c);
	struct bus_clk_data *cd = bus_clk->data;
	void *base = (void *)c->ccu_clk_mgr_base;
	int ret = 0;
	u32 reg;

	debug("%s: %s\n", __func__, c->name);
	/* enable access */
	writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);

	/* enable gating */
	reg = readl(base + cd->gate.offset);
	if (!!(reg & (1 << cd->gate.status_bit)) == !!enable)
		debug("%s already %s\n", c->name,
		      enable ? "enabled" : "disabled");
	else {
		int want = (enable) ? 1 : 0;
		reg |= (1 << cd->gate.hw_sw_sel_bit);

		if (enable)
			reg |= (1 << cd->gate.en_bit);
		else
			reg &= ~(1 << cd->gate.en_bit);

		writel(reg, base + cd->gate.offset);
		ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit,
			       want);
		if (ret)
			return ret;
	}

	/* disable access */
	writel(0, base + WR_ACCESS_OFFSET);

	return ret;
}

/* Get the rate of a bus clock */
static unsigned long bus_clk_get_rate(struct clk *c)
{
	struct bus_clock *bus_clk = to_bus_clk(c);
	struct ccu_clock *ccu_clk;

	debug("%s: %s\n", __func__, c->name);
	ccu_clk = to_ccu_clk(c->parent);

	c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
	c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
	return c->rate;
}

/* Bus clock operations */
struct clk_ops bus_clk_ops = {
	.enable = bus_clk_enable,
	.get_rate = bus_clk_get_rate,
};

/* Enable a reference clock */
static int ref_clk_enable(struct clk *c, int enable)
{
	debug("%s: %s\n", __func__, c->name);
	return 0;
}

/* Reference clock operations */
struct clk_ops ref_clk_ops = {
	.enable = ref_clk_enable,
};

/*
 * clk.h implementation follows
 */

/* Initialize the clock framework */
int clk_init(void)
{
	debug("%s:\n", __func__);
	return 0;
}

/* Get a clock handle, give a name string */
struct clk *clk_get(const char *con_id)
{
	int i;
	struct clk_lookup *clk_tblp;

	debug("%s: %s\n", __func__, con_id);

	clk_tblp = arch_clk_tbl;
	for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) {
		if (clk_tblp->con_id) {
			if (!con_id || strcmp(clk_tblp->con_id, con_id))
				continue;
			return clk_tblp->clk;
		}
	}
	return NULL;
}

/* Enable a clock */
int clk_enable(struct clk *c)
{
	int ret = 0;

	debug("%s: %s\n", __func__, c->name);
	if (!c->ops || !c->ops->enable)
		return -1;

	/* enable parent clock first */
	if (c->parent)
		ret = clk_enable(c->parent);

	if (ret)
		return ret;

	if (!c->use_cnt) {
		c->use_cnt++;
		ret = c->ops->enable(c, 1);
	}

	return ret;
}

/* Disable a clock */
void clk_disable(struct clk *c)
{
	debug("%s: %s\n", __func__, c->name);
	if (!c->ops || !c->ops->enable)
		return;

	if (c->use_cnt) {
		c->use_cnt--;
		c->ops->enable(c, 0);
	}

	/* disable parent */
	if (c->parent)
		clk_disable(c->parent);
}

/* Get the clock rate */
unsigned long clk_get_rate(struct clk *c)
{
	unsigned long rate;

	debug("%s: %s\n", __func__, c->name);
	if (!c || !c->ops || !c->ops->get_rate)
		return 0;

	rate = c->ops->get_rate(c);
	debug("%s: rate = %ld\n", __func__, rate);
	return rate;
}

/* Set the clock rate */
int clk_set_rate(struct clk *c, unsigned long rate)
{
	int ret;

	debug("%s: %s rate=%ld\n", __func__, c->name, rate);
	if (!c || !c->ops || !c->ops->set_rate)
		return -EINVAL;

	if (c->use_cnt)
		return -EINVAL;

	ret = c->ops->set_rate(c, rate);

	return ret;
}

/* Not required for this arch */
/*
long clk_round_rate(struct clk *clk, unsigned long rate);
int clk_set_parent(struct clk *clk, struct clk *parent);
struct clk *clk_get_parent(struct clk *clk);
*/
