// SPDX-License-Identifier: GPL-2.0+

/*
 * sun9i specific clock code
 *
 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
 *
 * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
 *                    Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
 */

#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/prcm.h>
#include <asm/arch/sys_proto.h>

#ifdef CONFIG_XPL_BUILD

static void clock_set_pll2(unsigned int clk)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
	const int p = 0;

	/* Switch cluster 1 to 24MHz clock while changing PLL2 */
	clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK,
			C1_CPUX_CLK_SRC_OSC24M);

	writel(CCM_PLL2_CTRL_EN | CCM_PLL2_CTRL_P(p) |
	       CCM_PLL2_CLOCK_TIME_2 | CCM_PLL2_CTRL_N(clk / 24000000),
	       &ccm->pll2_c1_cfg);

	sdelay(2000);

	/* Switch cluster 1 back to PLL2 */
	clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK,
			C1_CPUX_CLK_SRC_PLL2);
}

static void clock_set_pll4(unsigned int clk)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	writel(CCM_PLL4_CTRL_EN | CCM_PLL4_CTRL_N(clk / 24000000),
	       &ccm->pll4_periph0_cfg);

	sdelay(2000);
}

static void clock_set_pll12(unsigned int clk)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	if (readl(&ccm->pll12_periph1_cfg) & CCM_PLL12_CTRL_EN)
		return;

	writel(CCM_PLL12_CTRL_EN | CCM_PLL12_CTRL_N(clk / 24000000),
	       &ccm->pll12_periph1_cfg);

	sdelay(2000);
}

void clock_init_safe(void)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	/* Set up PLL12 (peripheral 1) */
	clock_set_pll12(1200000000);

	/* Set up PLL1 (cluster 0) and PLL2 (cluster 1) */
	clock_set_pll1(408000000);
	clock_set_pll2(408000000);

	/* Set up PLL4 (peripheral 0) */
	clock_set_pll4(960000000);

	/* Set up dividers for AXI0 and APB0 on cluster 0: PLL1 / 2 = 204MHz */
	writel(C0_CFG_AXI0_CLK_DIV_RATIO(2) |
	       C0_CFG_APB0_CLK_DIV_RATIO(2), &ccm->c0_cfg);

	/* AHB0: 120 MHz (PLL_PERIPH0 / 8) */
	writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(8),
	       &ccm->ahb0_cfg);
	/* AHB1: 240 MHz (PLL_PERIPH0 / 4) */
	writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(4),
	       &ccm->ahb1_cfg);
	/* AHB2: 120 MHz (PLL_PERIPH0 / 8) */
	writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(8),
	       &ccm->ahb2_cfg);
	/* APB0: 120 MHz (PLL_PERIPH0 / 8) */
	writel(APB0_SRC_PLL_PERIPH0 | APB0_CLK_DIV_RATIO(8),
	       &ccm->apb0_cfg);

	/* GTBUS: 400MHz (PERIPH0 div 3) */
	writel(GTBUS_SRC_PLL_PERIPH1 | GTBUS_CLK_DIV_RATIO(3),
	       &ccm->gtbus_cfg);
	/* CCI400: 480MHz (PERIPH1 div 2) */
	writel(CCI400_SRC_PLL_PERIPH0 | CCI400_CLK_DIV_RATIO(2),
	       &ccm->cci400_cfg);

	/* Deassert DMA reset and open clock gating for DMA */
	setbits_le32(&ccm->ahb_reset1_cfg, (1 << 24));
	setbits_le32(&ccm->apb1_gate, (1 << 24));

	/* set enable-bit in TSTAMP_CTRL_REG */
	writel(1, 0x01720000);
}

void clock_init_uart(void)
{
	struct sunxi_ccm_reg *const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	/* open the clock for uart */
	setbits_le32(&ccm->apb1_gate,
		     CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT +
				       CONFIG_CONS_INDEX - 1));
	/* deassert uart reset */
	setbits_le32(&ccm->apb1_reset_cfg,
		     1 << (APB1_RESET_UART_SHIFT +
			   CONFIG_CONS_INDEX - 1));
}

void clock_set_pll1(unsigned int clk)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
	const int p = 0;

	/* Switch cluster 0 to 24MHz clock while changing PLL1 */
	clrsetbits_le32(&ccm->cpu_clk_source, C0_CPUX_CLK_SRC_MASK,
			C0_CPUX_CLK_SRC_OSC24M);

	writel(CCM_PLL1_CTRL_EN | CCM_PLL1_CTRL_P(p) |
	       CCM_PLL1_CLOCK_TIME_2 |
	       CCM_PLL1_CTRL_N(clk / 24000000),
	       &ccm->pll1_c0_cfg);
	/*
	 * Don't bother with the stable-time registers, as it doesn't
	 * wait until the PLL is stable.  Note, that even Allwinner
	 * just uses a delay loop (or rather the AVS timer) for this
	 * instead of the PLL_STABLE_STATUS register.
	 */
	sdelay(2000);

	/* Switch cluster 0 back to PLL1 */
	clrsetbits_le32(&ccm->cpu_clk_source, C0_CPUX_CLK_SRC_MASK,
			C0_CPUX_CLK_SRC_PLL1);
}

void clock_set_pll6(unsigned int clk)
{
	struct sunxi_ccm_reg * const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
	const int p = 0;

	writel(CCM_PLL6_CTRL_EN | CCM_PLL6_CFG_UPDATE | CCM_PLL6_CTRL_P(p)
	       | CCM_PLL6_CTRL_N(clk / 24000000),
	       &ccm->pll6_ddr_cfg);
	do { } while (!(readl(&ccm->pll_stable_status) & PLL_DDR_STATUS));

	sdelay(2000);
}

int clock_twi_onoff(int port, int state)
{
	struct sunxi_ccm_reg *const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	if (port > 4)
		return -1;

	/* set the apb reset and clock gate for twi */
	if (state) {
		setbits_le32(&ccm->apb1_gate,
			     CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
		setbits_le32(&ccm->apb1_reset_cfg,
			     1 << (APB1_RESET_TWI_SHIFT + port));
	} else {
		clrbits_le32(&ccm->apb1_reset_cfg,
			     1 << (APB1_RESET_TWI_SHIFT + port));
		clrbits_le32(&ccm->apb1_gate,
			     CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
	}

	return 0;
}
#endif /* CONFIG_XPL_BUILD */

/* PLL_PERIPH0 clock (used by the MMC driver) */
unsigned int clock_get_pll4_periph0(void)
{
	struct sunxi_ccm_reg *const ccm =
		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
	uint32_t rval = readl(&ccm->pll4_periph0_cfg);
	int n = ((rval & CCM_PLL4_CTRL_N_MASK) >> CCM_PLL4_CTRL_N_SHIFT);
	int p = ((rval & CCM_PLL4_CTRL_P_MASK) >> CCM_PLL4_CTRL_P_SHIFT);
	int m = ((rval & CCM_PLL4_CTRL_M_MASK) >> CCM_PLL4_CTRL_M_SHIFT) + 1;
	const int k = 1;

	return ((24000000 * n * k) >> p) / m;
}
