/*
 * Alchemy clocks.
 *
 * Exposes all configurable internal clock sources to the clk framework.
 *
 * We have:
 *  - Root source, usually 12MHz supplied by an external crystal
 *  - 3 PLLs which generate multiples of root rate [AUX, CPU, AUX2]
 *
 * Dividers:
 *  - 6 clock dividers with:
 *   * selectable source [one of the PLLs],
 *   * output divided between [2 .. 512 in steps of 2] (!Au1300)
 *     or [1 .. 256 in steps of 1] (Au1300),
 *   * can be enabled individually.
 *
 * - up to 6 "internal" (fixed) consumers which:
 *   * take either AUXPLL or one of the above 6 dividers as input,
 *   * divide this input by 1, 2, or 4 (and 3 on Au1300).
 *   * can be disabled separately.
 *
 * Misc clocks:
 * - sysbus clock: CPU core clock (CPUPLL) divided by 2, 3 or 4.
 *    depends on board design and should be set by bootloader, read-only.
 * - peripheral clock: half the rate of sysbus clock, source for a lot
 *    of peripheral blocks, read-only.
 * - memory clock: clk rate to main memory chips, depends on board
 *    design and is read-only,
 * - lrclk: the static bus clock signal for synchronous operation.
 *    depends on board design, must be set by bootloader,
 *    but may be required to correctly configure devices attached to
 *    the static bus. The Au1000/1500/1100 manuals call it LCLK, on
 *    later models it's called RCLK.
 */

#include <linux/init.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <asm/mach-au1x00/au1000.h>

/* Base clock: 12MHz is the default in all databooks, and I haven't
 * found any board yet which uses a different rate.
 */
#define ALCHEMY_ROOTCLK_RATE	12000000

/*
 * the internal sources which can be driven by the PLLs and dividers.
 * Names taken from the databooks, refer to them for more information,
 * especially which ones are share a clock line.
 */
static const char * const alchemy_au1300_intclknames[] = {
	"lcd_intclk", "gpemgp_clk", "maempe_clk", "maebsa_clk",
	"EXTCLK0", "EXTCLK1"
};

static const char * const alchemy_au1200_intclknames[] = {
	"lcd_intclk", NULL, NULL, NULL, "EXTCLK0", "EXTCLK1"
};

static const char * const alchemy_au1550_intclknames[] = {
	"usb_clk", "psc0_intclk", "psc1_intclk", "pci_clko",
	"EXTCLK0", "EXTCLK1"
};

static const char * const alchemy_au1100_intclknames[] = {
	"usb_clk", "lcd_intclk", NULL, "i2s_clk", "EXTCLK0", "EXTCLK1"
};

static const char * const alchemy_au1500_intclknames[] = {
	NULL, "usbd_clk", "usbh_clk", "pci_clko", "EXTCLK0", "EXTCLK1"
};

static const char * const alchemy_au1000_intclknames[] = {
	"irda_clk", "usbd_clk", "usbh_clk", "i2s_clk", "EXTCLK0",
	"EXTCLK1"
};

/* aliases for a few on-chip sources which are either shared
 * or have gone through name changes.
 */
static struct clk_aliastable {
	char *alias;
	char *base;
	int cputype;
} alchemy_clk_aliases[] __initdata = {
	{ "usbh_clk", "usb_clk",    ALCHEMY_CPU_AU1100 },
	{ "usbd_clk", "usb_clk",    ALCHEMY_CPU_AU1100 },
	{ "irda_clk", "usb_clk",    ALCHEMY_CPU_AU1100 },
	{ "usbh_clk", "usb_clk",    ALCHEMY_CPU_AU1550 },
	{ "usbd_clk", "usb_clk",    ALCHEMY_CPU_AU1550 },
	{ "psc2_intclk", "usb_clk", ALCHEMY_CPU_AU1550 },
	{ "psc3_intclk", "EXTCLK0", ALCHEMY_CPU_AU1550 },
	{ "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1200 },
	{ "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1200 },
	{ "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 },
	{ "psc2_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 },
	{ "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 },
	{ "psc3_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 },

	{ NULL, NULL, 0 },
};

#define IOMEM(x)	((void __iomem *)(KSEG1ADDR(CPHYSADDR(x))))

/* access locks to SYS_FREQCTRL0/1 and SYS_CLKSRC registers */
static spinlock_t alchemy_clk_fg0_lock;
static spinlock_t alchemy_clk_fg1_lock;
static spinlock_t alchemy_clk_csrc_lock;

/* CPU Core clock *****************************************************/

static unsigned long alchemy_clk_cpu_recalc(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	unsigned long t;

	/*
	 * On early Au1000, sys_cpupll was write-only. Since these
	 * silicon versions of Au1000 are not sold, we don't bend
	 * over backwards trying to determine the frequency.
	 */
	if (unlikely(au1xxx_cpu_has_pll_wo()))
		t = 396000000;
	else {
		t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f;
		if (alchemy_get_cputype() < ALCHEMY_CPU_AU1300)
			t &= 0x3f;
		t *= parent_rate;
	}

	return t;
}

void __init alchemy_set_lpj(void)
{
	preset_lpj = alchemy_clk_cpu_recalc(NULL, ALCHEMY_ROOTCLK_RATE);
	preset_lpj /= 2 * HZ;
}

static struct clk_ops alchemy_clkops_cpu = {
	.recalc_rate	= alchemy_clk_cpu_recalc,
};

static struct clk __init *alchemy_clk_setup_cpu(const char *parent_name,
						int ctype)
{
	struct clk_init_data id;
	struct clk_hw *h;

	h = kzalloc(sizeof(*h), GFP_KERNEL);
	if (!h)
		return ERR_PTR(-ENOMEM);

	id.name = ALCHEMY_CPU_CLK;
	id.parent_names = &parent_name;
	id.num_parents = 1;
	id.flags = CLK_IS_BASIC;
	id.ops = &alchemy_clkops_cpu;
	h->init = &id;

	return clk_register(NULL, h);
}

/* AUXPLLs ************************************************************/

struct alchemy_auxpll_clk {
	struct clk_hw hw;
	unsigned long reg;	/* au1300 has also AUXPLL2 */
	int maxmult;		/* max multiplier */
};
#define to_auxpll_clk(x) container_of(x, struct alchemy_auxpll_clk, hw)

static unsigned long alchemy_clk_aux_recalc(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);

	return (alchemy_rdsys(a->reg) & 0xff) * parent_rate;
}

static int alchemy_clk_aux_setr(struct clk_hw *hw,
				unsigned long rate,
				unsigned long parent_rate)
{
	struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
	unsigned long d = rate;

	if (rate)
		d /= parent_rate;
	else
		d = 0;

	/* minimum is 84MHz, max is 756-1032 depending on variant */
	if (((d < 7) && (d != 0)) || (d > a->maxmult))
		return -EINVAL;

	alchemy_wrsys(d, a->reg);
	return 0;
}

static long alchemy_clk_aux_roundr(struct clk_hw *hw,
					    unsigned long rate,
					    unsigned long *parent_rate)
{
	struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
	unsigned long mult;

	if (!rate || !*parent_rate)
		return 0;

	mult = rate / (*parent_rate);

	if (mult && (mult < 7))
		mult = 7;
	if (mult > a->maxmult)
		mult = a->maxmult;

	return (*parent_rate) * mult;
}

static struct clk_ops alchemy_clkops_aux = {
	.recalc_rate	= alchemy_clk_aux_recalc,
	.set_rate	= alchemy_clk_aux_setr,
	.round_rate	= alchemy_clk_aux_roundr,
};

static struct clk __init *alchemy_clk_setup_aux(const char *parent_name,
						char *name, int maxmult,
						unsigned long reg)
{
	struct clk_init_data id;
	struct clk *c;
	struct alchemy_auxpll_clk *a;

	a = kzalloc(sizeof(*a), GFP_KERNEL);
	if (!a)
		return ERR_PTR(-ENOMEM);

	id.name = name;
	id.parent_names = &parent_name;
	id.num_parents = 1;
	id.flags = CLK_GET_RATE_NOCACHE;
	id.ops = &alchemy_clkops_aux;

	a->reg = reg;
	a->maxmult = maxmult;
	a->hw.init = &id;

	c = clk_register(NULL, &a->hw);
	if (!IS_ERR(c))
		clk_register_clkdev(c, name, NULL);
	else
		kfree(a);

	return c;
}

/* sysbus_clk *********************************************************/

static struct clk __init  *alchemy_clk_setup_sysbus(const char *pn)
{
	unsigned long v = (alchemy_rdsys(AU1000_SYS_POWERCTRL) & 3) + 2;
	struct clk *c;

	c = clk_register_fixed_factor(NULL, ALCHEMY_SYSBUS_CLK,
				      pn, 0, 1, v);
	if (!IS_ERR(c))
		clk_register_clkdev(c, ALCHEMY_SYSBUS_CLK, NULL);
	return c;
}

/* Peripheral Clock ***************************************************/

static struct clk __init *alchemy_clk_setup_periph(const char *pn)
{
	/* Peripheral clock runs at half the rate of sysbus clk */
	struct clk *c;

	c = clk_register_fixed_factor(NULL, ALCHEMY_PERIPH_CLK,
				      pn, 0, 1, 2);
	if (!IS_ERR(c))
		clk_register_clkdev(c, ALCHEMY_PERIPH_CLK, NULL);
	return c;
}

/* mem clock **********************************************************/

static struct clk __init *alchemy_clk_setup_mem(const char *pn, int ct)
{
	void __iomem *addr = IOMEM(AU1000_MEM_PHYS_ADDR);
	unsigned long v;
	struct clk *c;
	int div;

	switch (ct) {
	case ALCHEMY_CPU_AU1550:
	case ALCHEMY_CPU_AU1200:
		v = __raw_readl(addr + AU1550_MEM_SDCONFIGB);
		div = (v & (1 << 15)) ? 1 : 2;
		break;
	case ALCHEMY_CPU_AU1300:
		v = __raw_readl(addr + AU1550_MEM_SDCONFIGB);
		div = (v & (1 << 31)) ? 1 : 2;
		break;
	case ALCHEMY_CPU_AU1000:
	case ALCHEMY_CPU_AU1500:
	case ALCHEMY_CPU_AU1100:
	default:
		div = 2;
		break;
	}

	c = clk_register_fixed_factor(NULL, ALCHEMY_MEM_CLK, pn,
				      0, 1, div);
	if (!IS_ERR(c))
		clk_register_clkdev(c, ALCHEMY_MEM_CLK, NULL);
	return c;
}

/* lrclk: external synchronous static bus clock ***********************/

static struct clk __init *alchemy_clk_setup_lrclk(const char *pn, int t)
{
	/* Au1000, Au1500: MEM_STCFG0[11]: If bit is set, lrclk=pclk/5,
	 * otherwise lrclk=pclk/4.
	 * All other variants: MEM_STCFG0[15:13] = divisor.
	 * L/RCLK = periph_clk / (divisor + 1)
	 * On Au1000, Au1500, Au1100 it's called LCLK,
	 * on later models it's called RCLK, but it's the same thing.
	 */
	struct clk *c;
	unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0);

	switch (t) {
	case ALCHEMY_CPU_AU1000:
	case ALCHEMY_CPU_AU1500:
		v = 4 + ((v >> 11) & 1);
		break;
	default:	/* all other models */
		v = ((v >> 13) & 7) + 1;
	}
	c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK,
				      pn, 0, 1, v);
	if (!IS_ERR(c))
		clk_register_clkdev(c, ALCHEMY_LR_CLK, NULL);
	return c;
}

/* Clock dividers and muxes *******************************************/

/* data for fgen and csrc mux-dividers */
struct alchemy_fgcs_clk {
	struct clk_hw hw;
	spinlock_t *reglock;	/* register lock		  */
	unsigned long reg;	/* SYS_FREQCTRL0/1		  */
	int shift;		/* offset in register		  */
	int parent;		/* parent before disable [Au1300] */
	int isen;		/* is it enabled?		  */
	int *dt;		/* dividertable for csrc	  */
};
#define to_fgcs_clk(x) container_of(x, struct alchemy_fgcs_clk, hw)

static long alchemy_calc_div(unsigned long rate, unsigned long prate,
			       int scale, int maxdiv, unsigned long *rv)
{
	long div1, div2;

	div1 = prate / rate;
	if ((prate / div1) > rate)
		div1++;

	if (scale == 2) {	/* only div-by-multiple-of-2 possible */
		if (div1 & 1)
			div1++;	/* stay <=prate */
	}

	div2 = (div1 / scale) - 1;	/* value to write to register */

	if (div2 > maxdiv)
		div2 = maxdiv;
	if (rv)
		*rv = div2;

	div1 = ((div2 + 1) * scale);
	return div1;
}

static int alchemy_clk_fgcs_detr(struct clk_hw *hw,
				 struct clk_rate_request *req,
				 int scale, int maxdiv)
{
	struct clk_hw *pc, *bpc, *free;
	long tdv, tpr, pr, nr, br, bpr, diff, lastdiff;
	int j;

	lastdiff = INT_MAX;
	bpr = 0;
	bpc = NULL;
	br = -EINVAL;
	free = NULL;

	/* look at the rates each enabled parent supplies and select
	 * the one that gets closest to but not over the requested rate.
	 */
	for (j = 0; j < 7; j++) {
		pc = clk_hw_get_parent_by_index(hw, j);
		if (!pc)
			break;

		/* if this parent is currently unused, remember it.
		 * XXX: we would actually want clk_has_active_children()
		 * but this is a good-enough approximation for now.
		 */
		if (!clk_hw_is_prepared(pc)) {
			if (!free)
				free = pc;
		}

		pr = clk_hw_get_rate(pc);
		if (pr < req->rate)
			continue;

		/* what can hardware actually provide */
		tdv = alchemy_calc_div(req->rate, pr, scale, maxdiv, NULL);
		nr = pr / tdv;
		diff = req->rate - nr;
		if (nr > req->rate)
			continue;

		if (diff < lastdiff) {
			lastdiff = diff;
			bpr = pr;
			bpc = pc;
			br = nr;
		}
		if (diff == 0)
			break;
	}

	/* if we couldn't get the exact rate we wanted from the enabled
	 * parents, maybe we can tell an available disabled/inactive one
	 * to give us a rate we can divide down to the requested rate.
	 */
	if (lastdiff && free) {
		for (j = (maxdiv == 4) ? 1 : scale; j <= maxdiv; j += scale) {
			tpr = req->rate * j;
			if (tpr < 0)
				break;
			pr = clk_hw_round_rate(free, tpr);

			tdv = alchemy_calc_div(req->rate, pr, scale, maxdiv,
					       NULL);
			nr = pr / tdv;
			diff = req->rate - nr;
			if (nr > req->rate)
				continue;
			if (diff < lastdiff) {
				lastdiff = diff;
				bpr = pr;
				bpc = free;
				br = nr;
			}
			if (diff == 0)
				break;
		}
	}

	if (br < 0)
		return br;

	req->best_parent_rate = bpr;
	req->best_parent_hw = bpc;
	req->rate = br;

	return 0;
}

static int alchemy_clk_fgv1_en(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v, flags;

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v |= (1 << 1) << c->shift;
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static int alchemy_clk_fgv1_isen(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 1);

	return v & 1;
}

static void alchemy_clk_fgv1_dis(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v, flags;

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~((1 << 1) << c->shift);
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);
}

static int alchemy_clk_fgv1_setp(struct clk_hw *hw, u8 index)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v, flags;

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	if (index)
		v |= (1 << c->shift);
	else
		v &= ~(1 << c->shift);
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static u8 alchemy_clk_fgv1_getp(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);

	return (alchemy_rdsys(c->reg) >> c->shift) & 1;
}

static int alchemy_clk_fgv1_setr(struct clk_hw *hw, unsigned long rate,
				 unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long div, v, flags, ret;
	int sh = c->shift + 2;

	if (!rate || !parent_rate || rate > (parent_rate / 2))
		return -EINVAL;
	ret = alchemy_calc_div(rate, parent_rate, 2, 512, &div);
	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~(0xff << sh);
	v |= div << sh;
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 2);

	v = ((v & 0xff) + 1) * 2;
	return parent_rate / v;
}

static int alchemy_clk_fgv1_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	return alchemy_clk_fgcs_detr(hw, req, 2, 512);
}

/* Au1000, Au1100, Au15x0, Au12x0 */
static struct clk_ops alchemy_clkops_fgenv1 = {
	.recalc_rate	= alchemy_clk_fgv1_recalc,
	.determine_rate	= alchemy_clk_fgv1_detr,
	.set_rate	= alchemy_clk_fgv1_setr,
	.set_parent	= alchemy_clk_fgv1_setp,
	.get_parent	= alchemy_clk_fgv1_getp,
	.enable		= alchemy_clk_fgv1_en,
	.disable	= alchemy_clk_fgv1_dis,
	.is_enabled	= alchemy_clk_fgv1_isen,
};

static void __alchemy_clk_fgv2_en(struct alchemy_fgcs_clk *c)
{
	unsigned long v = alchemy_rdsys(c->reg);

	v &= ~(3 << c->shift);
	v |= (c->parent & 3) << c->shift;
	alchemy_wrsys(v, c->reg);
	c->isen = 1;
}

static int alchemy_clk_fgv2_en(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long flags;

	/* enable by setting the previous parent clock */
	spin_lock_irqsave(c->reglock, flags);
	__alchemy_clk_fgv2_en(c);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static int alchemy_clk_fgv2_isen(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);

	return ((alchemy_rdsys(c->reg) >> c->shift) & 3) != 0;
}

static void alchemy_clk_fgv2_dis(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v, flags;

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~(3 << c->shift);	/* set input mux to "disabled" state */
	alchemy_wrsys(v, c->reg);
	c->isen = 0;
	spin_unlock_irqrestore(c->reglock, flags);
}

static int alchemy_clk_fgv2_setp(struct clk_hw *hw, u8 index)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long flags;

	spin_lock_irqsave(c->reglock, flags);
	c->parent = index + 1;	/* value to write to register */
	if (c->isen)
		__alchemy_clk_fgv2_en(c);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static u8 alchemy_clk_fgv2_getp(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long flags, v;

	spin_lock_irqsave(c->reglock, flags);
	v = c->parent - 1;
	spin_unlock_irqrestore(c->reglock, flags);
	return v;
}

/* fg0-2 and fg4-6 share a "scale"-bit. With this bit cleared, the
 * dividers behave exactly as on previous models (dividers are multiples
 * of 2); with the bit set, dividers are multiples of 1, halving their
 * range, but making them also much more flexible.
 */
static int alchemy_clk_fgv2_setr(struct clk_hw *hw, unsigned long rate,
				 unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int sh = c->shift + 2;
	unsigned long div, v, flags, ret;

	if (!rate || !parent_rate || rate > parent_rate)
		return -EINVAL;

	v = alchemy_rdsys(c->reg) & (1 << 30); /* test "scale" bit */
	ret = alchemy_calc_div(rate, parent_rate, v ? 1 : 2,
			       v ? 256 : 512, &div);

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~(0xff << sh);
	v |= (div & 0xff) << sh;
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int sh = c->shift + 2;
	unsigned long v, t;

	v = alchemy_rdsys(c->reg);
	t = parent_rate / (((v >> sh) & 0xff) + 1);
	if ((v & (1 << 30)) == 0)		/* test scale bit */
		t /= 2;

	return t;
}

static int alchemy_clk_fgv2_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int scale, maxdiv;

	if (alchemy_rdsys(c->reg) & (1 << 30)) {
		scale = 1;
		maxdiv = 256;
	} else {
		scale = 2;
		maxdiv = 512;
	}

	return alchemy_clk_fgcs_detr(hw, req, scale, maxdiv);
}

/* Au1300 larger input mux, no separate disable bit, flexible divider */
static struct clk_ops alchemy_clkops_fgenv2 = {
	.recalc_rate	= alchemy_clk_fgv2_recalc,
	.determine_rate	= alchemy_clk_fgv2_detr,
	.set_rate	= alchemy_clk_fgv2_setr,
	.set_parent	= alchemy_clk_fgv2_setp,
	.get_parent	= alchemy_clk_fgv2_getp,
	.enable		= alchemy_clk_fgv2_en,
	.disable	= alchemy_clk_fgv2_dis,
	.is_enabled	= alchemy_clk_fgv2_isen,
};

static const char * const alchemy_clk_fgv1_parents[] = {
	ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK
};

static const char * const alchemy_clk_fgv2_parents[] = {
	ALCHEMY_AUXPLL2_CLK, ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK
};

static const char * const alchemy_clk_fgen_names[] = {
	ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK,
	ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK };

static int __init alchemy_clk_init_fgens(int ctype)
{
	struct clk *c;
	struct clk_init_data id;
	struct alchemy_fgcs_clk *a;
	unsigned long v;
	int i, ret;

	switch (ctype) {
	case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200:
		id.ops = &alchemy_clkops_fgenv1;
		id.parent_names = alchemy_clk_fgv1_parents;
		id.num_parents = 2;
		break;
	case ALCHEMY_CPU_AU1300:
		id.ops = &alchemy_clkops_fgenv2;
		id.parent_names = alchemy_clk_fgv2_parents;
		id.num_parents = 3;
		break;
	default:
		return -ENODEV;
	}
	id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;

	a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL);
	if (!a)
		return -ENOMEM;

	spin_lock_init(&alchemy_clk_fg0_lock);
	spin_lock_init(&alchemy_clk_fg1_lock);
	ret = 0;
	for (i = 0; i < 6; i++) {
		id.name = alchemy_clk_fgen_names[i];
		a->shift = 10 * (i < 3 ? i : i - 3);
		if (i > 2) {
			a->reg = AU1000_SYS_FREQCTRL1;
			a->reglock = &alchemy_clk_fg1_lock;
		} else {
			a->reg = AU1000_SYS_FREQCTRL0;
			a->reglock = &alchemy_clk_fg0_lock;
		}

		/* default to first parent if bootloader has set
		 * the mux to disabled state.
		 */
		if (ctype == ALCHEMY_CPU_AU1300) {
			v = alchemy_rdsys(a->reg);
			a->parent = (v >> a->shift) & 3;
			if (!a->parent) {
				a->parent = 1;
				a->isen = 0;
			} else
				a->isen = 1;
		}

		a->hw.init = &id;
		c = clk_register(NULL, &a->hw);
		if (IS_ERR(c))
			ret++;
		else
			clk_register_clkdev(c, id.name, NULL);
		a++;
	}

	return ret;
}

/* internal sources muxes *********************************************/

static int alchemy_clk_csrc_isen(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v = alchemy_rdsys(c->reg);

	return (((v >> c->shift) >> 2) & 7) != 0;
}

static void __alchemy_clk_csrc_en(struct alchemy_fgcs_clk *c)
{
	unsigned long v = alchemy_rdsys(c->reg);

	v &= ~((7 << 2) << c->shift);
	v |= ((c->parent & 7) << 2) << c->shift;
	alchemy_wrsys(v, c->reg);
	c->isen = 1;
}

static int alchemy_clk_csrc_en(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long flags;

	/* enable by setting the previous parent clock */
	spin_lock_irqsave(c->reglock, flags);
	__alchemy_clk_csrc_en(c);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static void alchemy_clk_csrc_dis(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v, flags;

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~((3 << 2) << c->shift);	/* mux to "disabled" state */
	alchemy_wrsys(v, c->reg);
	c->isen = 0;
	spin_unlock_irqrestore(c->reglock, flags);
}

static int alchemy_clk_csrc_setp(struct clk_hw *hw, u8 index)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long flags;

	spin_lock_irqsave(c->reglock, flags);
	c->parent = index + 1;	/* value to write to register */
	if (c->isen)
		__alchemy_clk_csrc_en(c);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static u8 alchemy_clk_csrc_getp(struct clk_hw *hw)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);

	return c->parent - 1;
}

static unsigned long alchemy_clk_csrc_recalc(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long v = (alchemy_rdsys(c->reg) >> c->shift) & 3;

	return parent_rate / c->dt[v];
}

static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate,
				 unsigned long parent_rate)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	unsigned long d, v, flags;
	int i;

	if (!rate || !parent_rate || rate > parent_rate)
		return -EINVAL;

	d = (parent_rate + (rate / 2)) / rate;
	if (d > 4)
		return -EINVAL;
	if ((d == 3) && (c->dt[2] != 3))
		d = 4;

	for (i = 0; i < 4; i++)
		if (c->dt[i] == d)
			break;

	if (i >= 4)
		return -EINVAL;	/* oops */

	spin_lock_irqsave(c->reglock, flags);
	v = alchemy_rdsys(c->reg);
	v &= ~(3 << c->shift);
	v |= (i & 3) << c->shift;
	alchemy_wrsys(v, c->reg);
	spin_unlock_irqrestore(c->reglock, flags);

	return 0;
}

static int alchemy_clk_csrc_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int scale = c->dt[2] == 3 ? 1 : 2; /* au1300 check */

	return alchemy_clk_fgcs_detr(hw, req, scale, 4);
}

static struct clk_ops alchemy_clkops_csrc = {
	.recalc_rate	= alchemy_clk_csrc_recalc,
	.determine_rate	= alchemy_clk_csrc_detr,
	.set_rate	= alchemy_clk_csrc_setr,
	.set_parent	= alchemy_clk_csrc_setp,
	.get_parent	= alchemy_clk_csrc_getp,
	.enable		= alchemy_clk_csrc_en,
	.disable	= alchemy_clk_csrc_dis,
	.is_enabled	= alchemy_clk_csrc_isen,
};

static const char * const alchemy_clk_csrc_parents[] = {
	/* disabled at index 0 */ ALCHEMY_AUXPLL_CLK,
	ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK,
	ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK
};

/* divider tables */
static int alchemy_csrc_dt1[] = { 1, 4, 1, 2 };	/* rest */
static int alchemy_csrc_dt2[] = { 1, 4, 3, 2 };	/* Au1300 */

static int __init alchemy_clk_setup_imux(int ctype)
{
	struct alchemy_fgcs_clk *a;
	const char * const *names;
	struct clk_init_data id;
	unsigned long v;
	int i, ret, *dt;
	struct clk *c;

	id.ops = &alchemy_clkops_csrc;
	id.parent_names = alchemy_clk_csrc_parents;
	id.num_parents = 7;
	id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;

	dt = alchemy_csrc_dt1;
	switch (ctype) {
	case ALCHEMY_CPU_AU1000:
		names = alchemy_au1000_intclknames;
		break;
	case ALCHEMY_CPU_AU1500:
		names = alchemy_au1500_intclknames;
		break;
	case ALCHEMY_CPU_AU1100:
		names = alchemy_au1100_intclknames;
		break;
	case ALCHEMY_CPU_AU1550:
		names = alchemy_au1550_intclknames;
		break;
	case ALCHEMY_CPU_AU1200:
		names = alchemy_au1200_intclknames;
		break;
	case ALCHEMY_CPU_AU1300:
		dt = alchemy_csrc_dt2;
		names = alchemy_au1300_intclknames;
		break;
	default:
		return -ENODEV;
	}

	a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL);
	if (!a)
		return -ENOMEM;

	spin_lock_init(&alchemy_clk_csrc_lock);
	ret = 0;

	for (i = 0; i < 6; i++) {
		id.name = names[i];
		if (!id.name)
			goto next;

		a->shift = i * 5;
		a->reg = AU1000_SYS_CLKSRC;
		a->reglock = &alchemy_clk_csrc_lock;
		a->dt = dt;

		/* default to first parent clock if mux is initially
		 * set to disabled state.
		 */
		v = alchemy_rdsys(a->reg);
		a->parent = ((v >> a->shift) >> 2) & 7;
		if (!a->parent) {
			a->parent = 1;
			a->isen = 0;
		} else
			a->isen = 1;

		a->hw.init = &id;
		c = clk_register(NULL, &a->hw);
		if (IS_ERR(c))
			ret++;
		else
			clk_register_clkdev(c, id.name, NULL);
next:
		a++;
	}

	return ret;
}


/**********************************************************************/


#define ERRCK(x)						\
	if (IS_ERR(x)) {					\
		ret = PTR_ERR(x);				\
		goto out;					\
	}

static int __init alchemy_clk_init(void)
{
	int ctype = alchemy_get_cputype(), ret, i;
	struct clk_aliastable *t = alchemy_clk_aliases;
	struct clk *c;

	/* Root of the Alchemy clock tree: external 12MHz crystal osc */
	c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL,
					   0, ALCHEMY_ROOTCLK_RATE);
	ERRCK(c)

	/* CPU core clock */
	c = alchemy_clk_setup_cpu(ALCHEMY_ROOT_CLK, ctype);
	ERRCK(c)

	/* AUXPLLs: max 1GHz on Au1300, 748MHz on older models */
	i = (ctype == ALCHEMY_CPU_AU1300) ? 84 : 63;
	c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK, ALCHEMY_AUXPLL_CLK,
				  i, AU1000_SYS_AUXPLL);
	ERRCK(c)

	if (ctype == ALCHEMY_CPU_AU1300) {
		c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK,
					  ALCHEMY_AUXPLL2_CLK, i,
					  AU1300_SYS_AUXPLL2);
		ERRCK(c)
	}

	/* sysbus clock: cpu core clock divided by 2, 3 or 4 */
	c = alchemy_clk_setup_sysbus(ALCHEMY_CPU_CLK);
	ERRCK(c)

	/* peripheral clock: runs at half rate of sysbus clk */
	c = alchemy_clk_setup_periph(ALCHEMY_SYSBUS_CLK);
	ERRCK(c)

	/* SDR/DDR memory clock */
	c = alchemy_clk_setup_mem(ALCHEMY_SYSBUS_CLK, ctype);
	ERRCK(c)

	/* L/RCLK: external static bus clock for synchronous mode */
	c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK, ctype);
	ERRCK(c)

	/* Frequency dividers 0-5 */
	ret = alchemy_clk_init_fgens(ctype);
	if (ret) {
		ret = -ENODEV;
		goto out;
	}

	/* diving muxes for internal sources */
	ret = alchemy_clk_setup_imux(ctype);
	if (ret) {
		ret = -ENODEV;
		goto out;
	}

	/* set up aliases drivers might look for */
	while (t->base) {
		if (t->cputype == ctype)
			clk_add_alias(t->alias, NULL, t->base, NULL);
		t++;
	}

	pr_info("Alchemy clocktree installed\n");
	return 0;

out:
	return ret;
}
postcore_initcall(alchemy_clk_init);
