// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2021 NXP
 */

#include <common.h>
#include <div64.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/cgc.h>
#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <linux/delay.h>

DECLARE_GLOBAL_DATA_PTR;

static struct cgc1_regs *cgc1_regs = (struct cgc1_regs *)0x292C0000UL;
static struct cgc2_regs *cgc2_regs = (struct cgc2_regs *)0x2da60000UL;

void cgc1_soscdiv_init(void)
{
	/* Configure SOSC/FRO DIV1 ~ DIV3 */
	clrbits_le32(&cgc1_regs->soscdiv, BIT(7));
	clrbits_le32(&cgc1_regs->soscdiv, BIT(15));
	clrbits_le32(&cgc1_regs->soscdiv, BIT(23));
	clrbits_le32(&cgc1_regs->soscdiv, BIT(31));

	clrbits_le32(&cgc1_regs->frodiv, BIT(7));
}

void cgc1_pll2_init(void)
{
	u32 reg;

	if (readl(&cgc1_regs->pll2csr) & BIT(23))
		clrbits_le32(&cgc1_regs->pll2csr, BIT(23));

	/* Disable PLL2 */
	clrbits_le32(&cgc1_regs->pll2csr, BIT(0));
	mdelay(1);

	/* wait valid bit false */
	while ((readl(&cgc1_regs->pll2csr) & BIT(24)))
		;

	/* Select SOSC as source, freq = 31 * 24 =744mhz */
	reg = 31 << 16;
	writel(reg, &cgc1_regs->pll2cfg);

	/* Enable PLL2 */
	setbits_le32(&cgc1_regs->pll2csr, BIT(0));

	/* Wait for PLL2 clock ready */
	while (!(readl(&cgc1_regs->pll2csr) & BIT(24)))
		;
}

static void cgc1_set_a35_clk(u32 clk_src, u32 div_core)
{
	u32 reg;

	/* ulock */
	if (readl(&cgc1_regs->ca35clk) & BIT(31))
		clrbits_le32(&cgc1_regs->ca35clk, BIT(31));

	reg = readl(&cgc1_regs->ca35clk);
	reg &= ~GENMASK(29, 21);
	reg |= ((clk_src & 0x3) << 28);
	reg |= (((div_core - 1) & 0x3f) << 21);
	writel(reg, &cgc1_regs->ca35clk);

	while (!(readl(&cgc1_regs->ca35clk) & BIT(27)))
		;
}

void cgc1_init_core_clk(void)
{
	u32 reg = readl(&cgc1_regs->ca35clk);

	/* if already selected to PLL2, switch to FRO firstly */
	if (((reg >> 28) & 0x3) == 0x1)
		cgc1_set_a35_clk(0, 1);

	/* Set pll2 to 750Mhz for 1V  */
	cgc1_pll2_init();

	/* Set A35 clock to pll2 */
	cgc1_set_a35_clk(1, 1);
}

void cgc1_enet_stamp_sel(u32 clk_src)
{
	writel((clk_src & 0x7) << 24, &cgc1_regs->enetstamp);
}

void cgc1_pll3_init(void)
{
	/* Gate off VCO */
	setbits_le32(&cgc1_regs->pll3div_vco, BIT(7));

	/* Disable PLL3 */
	clrbits_le32(&cgc1_regs->pll3csr, BIT(0));

	/* Gate off PFDxDIV */
	setbits_le32(&cgc1_regs->pll3div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31));
	setbits_le32(&cgc1_regs->pll3div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31));

	/* Gate off PFDx */
	setbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7));
	setbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15));
	setbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23));
	setbits_le32(&cgc1_regs->pll3pfdcfg, BIT(31));

	/* Select SOSC as source */
	clrbits_le32(&cgc1_regs->pll3cfg, BIT(0));

	//setbits_le32(&cgc1_regs->pll3cfg, 22 << 16);
	writel(22 << 16, &cgc1_regs->pll3cfg);

	writel(578, &cgc1_regs->pll3num);
	writel(1000, &cgc1_regs->pll3denom);

	/* Enable PLL3 */
	setbits_le32(&cgc1_regs->pll3csr, BIT(0));

	/* Wait for PLL3 clock ready */
	while (!(readl(&cgc1_regs->pll3csr) & BIT(24)))
		;
	/* Gate on VCO */
	clrbits_le32(&cgc1_regs->pll3div_vco, BIT(7));

	/*
	 * PFD0: 380MHz/396/396/328
	 */
	clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F);
	setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0);
	clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7));
	while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(6)))
		;

	clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 8);
	setbits_le32(&cgc1_regs->pll3pfdcfg, 24 << 8);
	clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15));
	while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(14)))
		;

	clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 16);
	setbits_le32(&cgc1_regs->pll3pfdcfg, 24 << 16);
	clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23));
	while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(22)))
		;

	clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 24);
	setbits_le32(&cgc1_regs->pll3pfdcfg, 29 << 24);
	clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(31));
	while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(30)))
		;

	clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(7));
	clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(15));
	clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(23));
	clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(31));

	clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(7));
	clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(15));
	clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(23));
	clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(31));
}

void cgc2_pll4_init(void)
{
	/* Disable PFD DIV and clear DIV */
	writel(0x80808080, &cgc2_regs->pll4div_pfd0);
	writel(0x80808080, &cgc2_regs->pll4div_pfd1);

	/* Gate off and clear PFD  */
	writel(0x80808080, &cgc2_regs->pll4pfdcfg);

	/* Disable PLL4 */
	writel(0x0, &cgc2_regs->pll4csr);

	/* Configure PLL4 to 528Mhz and clock source from SOSC */
	writel(22 << 16, &cgc2_regs->pll4cfg);
	writel(0x1, &cgc2_regs->pll4csr);

	/* wait for PLL4 output valid */
	while (!(readl(&cgc2_regs->pll4csr) & BIT(24)))
		;

	/* Enable all 4 PFDs */
	setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0);
	setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */
	setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16);
	setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24);

	clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) | BIT(15) | BIT(23) | BIT(31));

	while ((readl(&cgc2_regs->pll4pfdcfg) & (BIT(30) | BIT(22) | BIT(14) | BIT(6)))
		!= (BIT(30) | BIT(22) | BIT(14) | BIT(6)))
		;

	/* Enable PFD DIV */
	clrbits_le32(&cgc2_regs->pll4div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31));
	clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31));
}

void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd)
{
	void __iomem *reg = &cgc2_regs->pll4div_pfd0;
	u32 halt_mask = BIT(7) | BIT(15);
	u32 pfd_shift = (pllpfd - PLL4_PFD0) * 8;
	u32 val;

	if (pllpfd < PLL4_PFD0 || pllpfd > PLL4_PFD3)
		return;

	if ((pllpfd - PLL4_PFD0) >> 1)
		reg = &cgc2_regs->pll4div_pfd1;

	halt_mask = halt_mask << (((pllpfd - PLL4_PFD0) & 0x1) * 16);

	/* halt pfd div */
	setbits_le32(reg, halt_mask);

	/* gate pfd */
	setbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) << pfd_shift);

	val = readl(&cgc2_regs->pll4pfdcfg);
	val &= ~(0x3f << pfd_shift);
	val |= (pfd << pfd_shift);
	writel(val, &cgc2_regs->pll4pfdcfg);

	/* ungate */
	clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) << pfd_shift);

	/* Wait stable */
	while ((readl(&cgc2_regs->pll4pfdcfg) & (BIT(6) << pfd_shift))
		!= (BIT(6) << pfd_shift))
		;

	/* enable pfd div */
	clrbits_le32(reg, halt_mask);
}

void cgc2_pll4_pfddiv_config(enum cgc_clk pllpfddiv, u32 div)
{
	void __iomem *reg = &cgc2_regs->pll4div_pfd0;
	u32 shift = ((pllpfddiv - PLL4_PFD0_DIV1) & 0x3) * 8;

	if (pllpfddiv < PLL4_PFD0_DIV1 || pllpfddiv > PLL4_PFD3_DIV2)
		return;

	if ((pllpfddiv - PLL4_PFD0_DIV1) >> 2)
		reg = &cgc2_regs->pll4div_pfd1;

	/* Halt pfd div */
	setbits_le32(reg, BIT(7) << shift);

	/* Clear div */
	clrbits_le32(reg, 0x3f << shift);

	/* Set div*/
	setbits_le32(reg, div << shift);

	/* Enable pfd div */
	clrbits_le32(reg, BIT(7) << shift);
}

void cgc2_ddrclk_config(u32 src, u32 div)
{
	/* If reg lock is set, wait until unlock by HW */
	/* This lock is triggered by div updating and ddrclk halt status change, */
	while ((readl(&cgc2_regs->ddrclk) & BIT(31)))
		;

	writel((src << 28) | (div << 21), &cgc2_regs->ddrclk);
	/* wait for DDRCLK switching done */
	while (!(readl(&cgc2_regs->ddrclk) & BIT(27)))
		;
}

void cgc2_ddrclk_wait_unlock(void)
{
	while ((readl(&cgc2_regs->ddrclk) & BIT(31)))
		;
}

void cgc2_lpav_init(enum cgc_clk clk)
{
	u32 i, scs, reg;
	const enum cgc_clk src[] = {FRO, PLL4_PFD1, SOSC, LVDS};

	reg = readl(&cgc2_regs->niclpavclk);
	scs = (reg >> 28) & 0x3;

	for (i = 0; i < 4; i++) {
		if (clk == src[i]) {
			if (scs == i)
				return;

			reg &= ~(0x3 << 28);
			reg |= (i << 28);

			writel(reg, &cgc2_regs->niclpavclk);
			break;
		}
	}

	if (i == 4)
		printf("Invalid clock source [%u] for LPAV\n", clk);
}

u32 cgc2_nic_get_rate(enum cgc_clk clk)
{
	u32 reg, rate;
	u32 scs, lpav_axi_clk, lpav_ahb_clk, lpav_bus_clk;
	const enum cgc_clk src[] = {FRO, PLL4_PFD1, SOSC, LVDS};

	reg = readl(&cgc2_regs->niclpavclk);
	scs = (reg >> 28) & 0x3;
	lpav_axi_clk = ((reg >> 21) & 0x3f) + 1;
	lpav_ahb_clk = ((reg >> 14) & 0x3f) + 1;
	lpav_bus_clk = ((reg >> 7) & 0x3f) + 1;

	rate = cgc_clk_get_rate(src[scs]);

	switch (clk) {
	case LPAV_AXICLK:
		rate = rate / lpav_axi_clk;
		break;
	case LPAV_AHBCLK:
		rate = rate / (lpav_axi_clk * lpav_ahb_clk);
		break;
	case LPAV_BUSCLK:
		rate = rate / (lpav_axi_clk * lpav_bus_clk);
		break;
	default:
		return 0;
	}

	return rate;
}

u32 decode_pll(enum cgc_clk pll)
{
	u32 reg, infreq, mult;
	u32 num, denom;

	infreq = 24000000U;
	/*
	 * Alought there are four choices for the bypass src,
	 * we choose SOSC 24M which is the default set in ROM.
	 * TODO: check more the comments
	 */
	switch (pll) {
	case PLL2:
		reg = readl(&cgc1_regs->pll2csr);
		if (!(reg & BIT(24)))
			return 0;

		reg = readl(&cgc1_regs->pll2cfg);
		mult = (reg >> 16) & 0x7F;
		denom = readl(&cgc1_regs->pll2denom) & 0x3FFFFFFF;
		num = readl(&cgc1_regs->pll2num) & 0x3FFFFFFF;

		return (u64)infreq * mult + (u64)infreq * num / denom;
	case PLL3:
		reg = readl(&cgc1_regs->pll3csr);
		if (!(reg & BIT(24)))
			return 0;

		reg = readl(&cgc1_regs->pll3cfg);
		mult = (reg >> 16) & 0x7F;
		denom = readl(&cgc1_regs->pll3denom) & 0x3FFFFFFF;
		num = readl(&cgc1_regs->pll3num) & 0x3FFFFFFF;

		return (u64)infreq * mult + (u64)infreq * num / denom;
	case PLL4:
		reg = readl(&cgc2_regs->pll4csr);
		if (!(reg & BIT(24)))
			return 0;

		reg = readl(&cgc2_regs->pll4cfg);
		mult = (reg >> 16) & 0x7F;
		denom = readl(&cgc2_regs->pll4denom) & 0x3FFFFFFF;
		num = readl(&cgc2_regs->pll4num) & 0x3FFFFFFF;

		return (u64)infreq * mult + (u64)infreq * num / denom;
	default:
		printf("Unsupported pll clocks %d\n", pll);
		break;
	}

	return 0;
}

u32 cgc_pll_vcodiv_rate(enum cgc_clk clk)
{
	u32 reg, gate, div;
	void __iomem *plldiv_vco;
	enum cgc_clk pll;

	if (clk == PLL3_VCODIV) {
		plldiv_vco = &cgc1_regs->pll3div_vco;
		pll = PLL3;
	} else {
		plldiv_vco = &cgc2_regs->pll4div_vco;
		pll = PLL4;
	}

	reg = readl(plldiv_vco);
	gate = BIT(7) & reg;
	div = reg & 0x3F;

	return gate ? 0 : decode_pll(pll) / (div + 1);
}

u32 cgc_pll_pfd_rate(enum cgc_clk clk)
{
	u32 index, gate, vld, reg;
	void __iomem *pllpfdcfg;
	enum cgc_clk pll;

	switch (clk) {
	case PLL3_PFD0:
	case PLL3_PFD1:
	case PLL3_PFD2:
	case PLL3_PFD3:
		index = clk - PLL3_PFD0;
		pllpfdcfg = &cgc1_regs->pll3pfdcfg;
		pll = PLL3;
		break;
	case PLL4_PFD0:
	case PLL4_PFD1:
	case PLL4_PFD2:
	case PLL4_PFD3:
		index = clk - PLL4_PFD0;
		pllpfdcfg = &cgc2_regs->pll4pfdcfg;
		pll = PLL4;
		break;
	default:
		return 0;
	}

	reg = readl(pllpfdcfg);
	gate = reg & (BIT(7) << (index * 8));
	vld = reg & (BIT(6) << (index * 8));

	if (gate || !vld)
		return 0;

	return (u64)decode_pll(pll) * 18 / ((reg >> (index * 8)) & 0x3F);
}

u32 cgc_pll_pfd_div(enum cgc_clk clk)
{
	void __iomem *base;
	u32 pfd, index, gate, reg;

	switch (clk) {
	case PLL3_PFD0_DIV1:
	case PLL3_PFD0_DIV2:
		base = &cgc1_regs->pll3div_pfd0;
		pfd = PLL3_PFD0;
		index = clk - PLL3_PFD0_DIV1;
		break;
	case PLL3_PFD1_DIV1:
	case PLL3_PFD1_DIV2:
		base = &cgc1_regs->pll3div_pfd0;
		pfd = PLL3_PFD1;
		index = clk - PLL3_PFD0_DIV1;
		break;
	case PLL3_PFD2_DIV1:
	case PLL3_PFD2_DIV2:
		base = &cgc1_regs->pll3div_pfd1;
		pfd = PLL3_PFD2;
		index = clk - PLL3_PFD2_DIV1;
		break;
	case PLL3_PFD3_DIV1:
	case PLL3_PFD3_DIV2:
		base = &cgc1_regs->pll3div_pfd1;
		pfd = PLL3_PFD3;
		index = clk - PLL3_PFD2_DIV1;
		break;
	case PLL4_PFD0_DIV1:
	case PLL4_PFD0_DIV2:
		base = &cgc2_regs->pll4div_pfd0;
		pfd = PLL4_PFD0;
		index = clk - PLL4_PFD0_DIV1;
		break;
	case PLL4_PFD1_DIV1:
	case PLL4_PFD1_DIV2:
		base = &cgc2_regs->pll4div_pfd0;
		pfd = PLL4_PFD1;
		index = clk - PLL4_PFD0_DIV1;
		break;
	case PLL4_PFD2_DIV1:
	case PLL4_PFD2_DIV2:
		base = &cgc2_regs->pll4div_pfd1;
		pfd = PLL4_PFD2;
		index = clk - PLL4_PFD2_DIV1;
		break;
	case PLL4_PFD3_DIV1:
	case PLL4_PFD3_DIV2:
		base = &cgc2_regs->pll4div_pfd1;
		pfd = PLL4_PFD3;
		index = clk - PLL4_PFD2_DIV1;
		break;
	default:
		return 0;
	}

	reg = readl(base);
	gate = reg & (BIT(7) << (index * 8));

	if (gate)
		return 0;

	return cgc_pll_pfd_rate(pfd) / (((reg >> (index * 8)) & 0x3F) + 1);
}

u32 cgc1_nic_get_rate(enum cgc_clk clk)
{
	u32 reg, rate;
	u32 scs, nic_ad_divplat, nic_per_divplat;
	u32 xbar_ad_divplat, xbar_divbus, ad_slow;
	const enum cgc_clk src[] = {FRO, PLL3_PFD0, SOSC, LVDS};

	reg = readl(&cgc1_regs->nicclk);
	scs = (reg >> 28) & 0x3;
	nic_ad_divplat = ((reg >> 21) & 0x3f) + 1;
	nic_per_divplat = ((reg >> 14) & 0x3f) + 1;

	reg = readl(&cgc1_regs->xbarclk);
	xbar_ad_divplat = ((reg >> 14) & 0x3f) + 1;
	xbar_divbus = ((reg >> 7) & 0x3f) + 1;
	ad_slow = (reg & 0x3f) + 1;

	rate = cgc_clk_get_rate(src[scs]);

	switch (clk) {
	case NIC_APCLK:
		rate = rate / nic_ad_divplat;
		break;
	case NIC_PERCLK:
		rate = rate / (nic_ad_divplat * nic_per_divplat);
		break;
	case XBAR_APCLK:
		rate = rate / (nic_ad_divplat * xbar_ad_divplat);
		break;
	case XBAR_BUSCLK:
		rate = rate / (nic_ad_divplat * xbar_ad_divplat * xbar_divbus);
		break;
	case AD_SLOWCLK:
		rate = rate / (nic_ad_divplat * xbar_ad_divplat * ad_slow);
		break;
	default:
		return 0;
	}

	return rate;
}

u32 cgc1_sosc_div(enum cgc_clk clk)
{
	u32 reg, gate, index;

	switch (clk) {
	case SOSC:
		return 24000000;
	case SOSC_DIV1:
		index = 0;
		break;
	case SOSC_DIV2:
		index = 1;
		break;
	case SOSC_DIV3:
		index = 2;
		break;
	default:
		return 0;
	}

	reg = readl(&cgc1_regs->soscdiv);
	gate = reg & (BIT(7) << (index * 8));

	if (gate)
		return 0;

	return 24000000 / (((reg >> (index * 8)) & 0x3F) + 1);
}

u32 cgc1_fro_div(enum cgc_clk clk)
{
	u32 reg, gate, vld, index;

	switch (clk) {
	case FRO:
		return 192000000;
	case FRO_DIV1:
		index = 0;
		break;
	case FRO_DIV2:
		index = 1;
		break;
	case FRO_DIV3:
		index = 2;
		break;
	default:
		return 0;
	}

	reg = readl(&cgc1_regs->frodiv);
	gate = reg & (BIT(7) << (index * 8));
	vld = reg & (BIT(6) << (index * 8));

	if (gate || !vld)
		return 0;

	return 24000000 / (((reg >> (index * 8)) & 0x3F) + 1);
}

u32 cgc_clk_get_rate(enum cgc_clk clk)
{
	switch (clk) {
	case LVDS:
		return 0; /* No external LVDS clock used */
	case SOSC:
	case SOSC_DIV1:
	case SOSC_DIV2:
	case SOSC_DIV3:
		return cgc1_sosc_div(clk);
	case FRO:
	case FRO_DIV1:
	case FRO_DIV2:
	case FRO_DIV3:
		return cgc1_fro_div(clk);
	case PLL2:
	case PLL3:
	case PLL4:
		return decode_pll(clk);
	case PLL3_VCODIV:
	case PLL4_VCODIV:
		return cgc_pll_vcodiv_rate(clk);
	case PLL3_PFD0:
	case PLL3_PFD1:
	case PLL3_PFD2:
	case PLL3_PFD3:
	case PLL4_PFD0:
	case PLL4_PFD1:
	case PLL4_PFD2:
	case PLL4_PFD3:
		return cgc_pll_pfd_rate(clk);
	case PLL3_PFD0_DIV1:
	case PLL3_PFD0_DIV2:
	case PLL3_PFD1_DIV1:
	case PLL3_PFD1_DIV2:
	case PLL3_PFD2_DIV1:
	case PLL3_PFD2_DIV2:
	case PLL3_PFD3_DIV1:
	case PLL3_PFD3_DIV2:
	case PLL4_PFD0_DIV1:
	case PLL4_PFD0_DIV2:
	case PLL4_PFD1_DIV1:
	case PLL4_PFD1_DIV2:
	case PLL4_PFD2_DIV1:
	case PLL4_PFD2_DIV2:
	case PLL4_PFD3_DIV1:
	case PLL4_PFD3_DIV2:
		return cgc_pll_pfd_div(clk);
	case NIC_APCLK:
	case NIC_PERCLK:
	case XBAR_APCLK:
	case XBAR_BUSCLK:
	case AD_SLOWCLK:
		return cgc1_nic_get_rate(clk);
	case LPAV_AXICLK:
	case LPAV_AHBCLK:
	case LPAV_BUSCLK:
		return cgc2_nic_get_rate(clk);
	default:
		printf("Unsupported cgc clock: %d\n", clk);
		return 0;
	}
}
