/*
 * Copyright (C) 2015 Purna Chandra Mandal <purna.mandal@microchip.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 */

#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <div64.h>
#include <wait_bit.h>
#include <dm/lists.h>
#include <asm/io.h>
#include <mach/pic32.h>
#include <dt-bindings/clock/microchip,clock.h>

DECLARE_GLOBAL_DATA_PTR;

/* Primary oscillator */
#define SYS_POSC_CLK_HZ	24000000

/* FRC clk rate */
#define SYS_FRC_CLK_HZ	8000000

/* Clock Registers */
#define OSCCON		0x0000
#define OSCTUNE		0x0010
#define SPLLCON		0x0020
#define REFO1CON	0x0080
#define REFO1TRIM	0x0090
#define PB1DIV		0x0140

/* SPLL */
#define ICLK_MASK	0x00000080
#define PLLIDIV_MASK	0x00000007
#define PLLODIV_MASK	0x00000007
#define CUROSC_MASK	0x00000007
#define PLLMUL_MASK	0x0000007F
#define FRCDIV_MASK	0x00000007

/* PBCLK */
#define PBDIV_MASK	0x00000007

/* SYSCLK MUX */
#define SCLK_SRC_FRC1	0
#define SCLK_SRC_SPLL	1
#define SCLK_SRC_POSC	2
#define SCLK_SRC_FRC2	7

/* Reference Oscillator Control Reg fields */
#define REFO_SEL_MASK	0x0f
#define REFO_SEL_SHIFT	0
#define REFO_ACTIVE	BIT(8)
#define REFO_DIVSW_EN	BIT(9)
#define REFO_OE		BIT(12)
#define REFO_ON		BIT(15)
#define REFO_DIV_SHIFT	16
#define REFO_DIV_MASK	0x7fff

/* Reference Oscillator Trim Register Fields */
#define REFO_TRIM_REG	0x10
#define REFO_TRIM_MASK	0x1ff
#define REFO_TRIM_SHIFT	23
#define REFO_TRIM_MAX	511

#define ROCLK_SRC_SCLK		0x0
#define ROCLK_SRC_SPLL		0x7
#define ROCLK_SRC_ROCLKI	0x8

/* Memory PLL */
#define MPLL_IDIV		0x3f
#define MPLL_MULT		0xff
#define MPLL_ODIV1		0x7
#define MPLL_ODIV2		0x7
#define MPLL_VREG_RDY		BIT(23)
#define MPLL_RDY		BIT(31)
#define MPLL_IDIV_SHIFT		0
#define MPLL_MULT_SHIFT		8
#define MPLL_ODIV1_SHIFT	24
#define MPLL_ODIV2_SHIFT	27
#define MPLL_IDIV_INIT		0x03
#define MPLL_MULT_INIT		0x32
#define MPLL_ODIV1_INIT		0x02
#define MPLL_ODIV2_INIT		0x01

struct pic32_clk_priv {
	void __iomem *iobase;
	void __iomem *syscfg_base;
};

static ulong pic32_get_pll_rate(struct pic32_clk_priv *priv)
{
	u32 iclk, idiv, odiv, mult;
	ulong plliclk, v;

	v = readl(priv->iobase + SPLLCON);
	iclk = (v & ICLK_MASK);
	idiv = ((v >> 8) & PLLIDIV_MASK) + 1;
	odiv = ((v >> 24) & PLLODIV_MASK);
	mult = ((v >> 16) & PLLMUL_MASK) + 1;

	plliclk = iclk ? SYS_FRC_CLK_HZ : SYS_POSC_CLK_HZ;

	if (odiv < 2)
		odiv = 2;
	else if (odiv < 5)
		odiv = (1 << odiv);
	else
		odiv = 32;

	return ((plliclk / idiv) * mult) / odiv;
}

static ulong pic32_get_sysclk(struct pic32_clk_priv *priv)
{
	ulong v;
	ulong hz;
	ulong div, frcdiv;
	ulong curr_osc;

	/* get clk source */
	v = readl(priv->iobase + OSCCON);
	curr_osc = (v >> 12) & CUROSC_MASK;
	switch (curr_osc) {
	case SCLK_SRC_FRC1:
	case SCLK_SRC_FRC2:
		frcdiv = ((v >> 24) & FRCDIV_MASK);
		div = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7));
		hz = SYS_FRC_CLK_HZ / div;
		break;

	case SCLK_SRC_SPLL:
		hz = pic32_get_pll_rate(priv);
		break;

	case SCLK_SRC_POSC:
		hz = SYS_POSC_CLK_HZ;
		break;

	default:
		hz = 0;
		printf("clk: unknown sclk_src.\n");
		break;
	}

	return hz;
}

static ulong pic32_get_pbclk(struct pic32_clk_priv *priv, int periph)
{
	void __iomem *reg;
	ulong div, clk_freq;

	WARN_ON((periph < PB1CLK) || (periph > PB7CLK));

	clk_freq = pic32_get_sysclk(priv);

	reg = priv->iobase + PB1DIV + (periph - PB1CLK) * 0x10;
	div = (readl(reg) & PBDIV_MASK) + 1;

	return clk_freq / div;
}

static ulong pic32_get_cpuclk(struct pic32_clk_priv *priv)
{
	return pic32_get_pbclk(priv, PB7CLK);
}

static ulong pic32_set_refclk(struct pic32_clk_priv *priv, int periph,
			      int parent_rate, int rate, int parent_id)
{
	void __iomem *reg;
	u32 div, trim, v;
	u64 frac;

	WARN_ON((periph < REF1CLK) || (periph > REF5CLK));

	/* calculate dividers,
	 *   rate = parent_rate / [2 * (div + (trim / 512))]
	 */
	if (parent_rate <= rate) {
		div = 0;
		trim = 0;
	} else {
		div = parent_rate / (rate << 1);
		frac = parent_rate;
		frac <<= 8;
		do_div(frac, rate);
		frac -= (u64)(div << 9);
		trim = (frac >= REFO_TRIM_MAX) ? REFO_TRIM_MAX : (u32)frac;
	}

	reg = priv->iobase + REFO1CON + (periph - REF1CLK) * 0x20;

	/* disable clk */
	writel(REFO_ON | REFO_OE, reg + _CLR_OFFSET);

	/* wait till previous src change is active */
	wait_for_bit_le32(reg, REFO_DIVSW_EN | REFO_ACTIVE,
			  false, CONFIG_SYS_HZ, false);

	/* parent_id */
	v = readl(reg);
	v &= ~(REFO_SEL_MASK << REFO_SEL_SHIFT);
	v |= (parent_id << REFO_SEL_SHIFT);

	/* apply rodiv */
	v &= ~(REFO_DIV_MASK << REFO_DIV_SHIFT);
	v |= (div << REFO_DIV_SHIFT);
	writel(v, reg);

	/* apply trim */
	v = readl(reg + REFO_TRIM_REG);
	v &= ~(REFO_TRIM_MASK << REFO_TRIM_SHIFT);
	v |= (trim << REFO_TRIM_SHIFT);
	writel(v, reg + REFO_TRIM_REG);

	/* enable clk */
	writel(REFO_ON | REFO_OE, reg + _SET_OFFSET);

	/* switch divider */
	writel(REFO_DIVSW_EN, reg + _SET_OFFSET);

	/* wait for divider switching to complete */
	return wait_for_bit_le32(reg, REFO_DIVSW_EN, false,
				 CONFIG_SYS_HZ, false);
}

static ulong pic32_get_refclk(struct pic32_clk_priv *priv, int periph)
{
	u32 rodiv, rotrim, rosel, v, parent_rate;
	void __iomem *reg;
	u64 rate64;

	WARN_ON((periph < REF1CLK) || (periph > REF5CLK));

	reg = priv->iobase + REFO1CON + (periph - REF1CLK) * 0x20;
	v = readl(reg);
	/* get rosel */
	rosel = (v >> REFO_SEL_SHIFT) & REFO_SEL_MASK;
	/* get div */
	rodiv = (v >> REFO_DIV_SHIFT) & REFO_DIV_MASK;

	/* get trim */
	v = readl(reg + REFO_TRIM_REG);
	rotrim = (v >> REFO_TRIM_SHIFT) & REFO_TRIM_MASK;

	if (!rodiv)
		return 0;

	/* get parent rate */
	switch (rosel) {
	case ROCLK_SRC_SCLK:
		parent_rate = pic32_get_cpuclk(priv);
		break;
	case ROCLK_SRC_SPLL:
		parent_rate = pic32_get_pll_rate(priv);
		break;
	default:
		parent_rate = 0;
		break;
	}

	/* Calculation
	 * rate = parent_rate / [2 * (div + (trim / 512))]
	 */
	if (rotrim) {
		rodiv <<= 9;
		rodiv += rotrim;
		rate64 = parent_rate;
		rate64 <<= 8;
		do_div(rate64, rodiv);
		v = (u32)rate64;
	} else {
		v = parent_rate / (rodiv << 1);
	}
	return v;
}

static ulong pic32_get_mpll_rate(struct pic32_clk_priv *priv)
{
	u32 v, idiv, mul;
	u32 odiv1, odiv2;
	u64 rate;

	v = readl(priv->syscfg_base + CFGMPLL);
	idiv = v & MPLL_IDIV;
	mul = (v >> MPLL_MULT_SHIFT) & MPLL_MULT;
	odiv1 = (v >> MPLL_ODIV1_SHIFT) & MPLL_ODIV1;
	odiv2 = (v >> MPLL_ODIV2_SHIFT) & MPLL_ODIV2;

	rate = (SYS_POSC_CLK_HZ / idiv) * mul;
	do_div(rate, odiv1);
	do_div(rate, odiv2);

	return (ulong)rate;
}

static int pic32_mpll_init(struct pic32_clk_priv *priv)
{
	u32 v, mask;

	/* initialize */
	v = (MPLL_IDIV_INIT << MPLL_IDIV_SHIFT) |
	    (MPLL_MULT_INIT << MPLL_MULT_SHIFT) |
	    (MPLL_ODIV1_INIT << MPLL_ODIV1_SHIFT) |
	    (MPLL_ODIV2_INIT << MPLL_ODIV2_SHIFT);

	writel(v, priv->syscfg_base + CFGMPLL);

	/* Wait for ready */
	mask = MPLL_RDY | MPLL_VREG_RDY;
	return wait_for_bit_le32(priv->syscfg_base + CFGMPLL, mask,
				 true, get_tbclk(), false);
}

static void pic32_clk_init(struct udevice *dev)
{
	const void *blob = gd->fdt_blob;
	struct pic32_clk_priv *priv;
	ulong rate, pll_hz;
	char propname[50];
	int i;

	priv = dev_get_priv(dev);
	pll_hz = pic32_get_pll_rate(priv);

	/* Initialize REFOs as not initialized and enabled on reset. */
	for (i = REF1CLK; i <= REF5CLK; i++) {
		snprintf(propname, sizeof(propname),
			 "microchip,refo%d-frequency", i - REF1CLK + 1);
		rate = fdtdec_get_int(blob, dev_of_offset(dev), propname, 0);
		if (rate)
			pic32_set_refclk(priv, i, pll_hz, rate, ROCLK_SRC_SPLL);
	}

	/* Memory PLL */
	pic32_mpll_init(priv);
}

static ulong pic32_get_rate(struct clk *clk)
{
	struct pic32_clk_priv *priv = dev_get_priv(clk->dev);
	ulong rate;

	switch (clk->id) {
	case PB1CLK ... PB7CLK:
		rate = pic32_get_pbclk(priv, clk->id);
		break;
	case REF1CLK ... REF5CLK:
		rate = pic32_get_refclk(priv, clk->id);
		break;
	case PLLCLK:
		rate = pic32_get_pll_rate(priv);
		break;
	case MPLL:
		rate = pic32_get_mpll_rate(priv);
		break;
	default:
		rate = 0;
		break;
	}

	return rate;
}

static ulong pic32_set_rate(struct clk *clk, ulong rate)
{
	struct pic32_clk_priv *priv = dev_get_priv(clk->dev);
	ulong pll_hz;

	switch (clk->id) {
	case REF1CLK ... REF5CLK:
		pll_hz = pic32_get_pll_rate(priv);
		pic32_set_refclk(priv, clk->id, pll_hz, rate, ROCLK_SRC_SPLL);
		break;
	default:
		break;
	}

	return rate;
}

static struct clk_ops pic32_pic32_clk_ops = {
	.set_rate = pic32_set_rate,
	.get_rate = pic32_get_rate,
};

static int pic32_clk_probe(struct udevice *dev)
{
	struct pic32_clk_priv *priv = dev_get_priv(dev);
	fdt_addr_t addr;
	fdt_size_t size;

	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
				    &size);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->iobase = ioremap(addr, size);
	if (!priv->iobase)
		return -EINVAL;

	priv->syscfg_base = pic32_get_syscfg_base();

	/* initialize clocks */
	pic32_clk_init(dev);

	return 0;
}

static const struct udevice_id pic32_clk_ids[] = {
	{ .compatible = "microchip,pic32mzda-clk"},
	{}
};

U_BOOT_DRIVER(pic32_clk) = {
	.name		= "pic32_clk",
	.id		= UCLASS_CLK,
	.of_match	= pic32_clk_ids,
	.flags		= DM_FLAG_PRE_RELOC,
	.ops		= &pic32_pic32_clk_ops,
	.probe		= pic32_clk_probe,
	.priv_auto_alloc_size = sizeof(struct pic32_clk_priv),
};
