/*
 * Copyright 2018-2023 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdbool.h>

#include <lib/mmio.h>
#include <platform_def.h>

#define IMX_CCM_IP_BASE				(IMX_CCM_BASE + 0xa000)
#define DRAM_SEL_CFG				(IMX_CCM_BASE + 0x9800)
#define CCM_IP_CLK_ROOT_GEN_TAGET(i)		(IMX_CCM_IP_BASE + 0x80 * (i) + 0x00)
#define CCM_IP_CLK_ROOT_GEN_TAGET_SET(i)	(IMX_CCM_IP_BASE + 0x80 * (i) + 0x04)
#define CCM_IP_CLK_ROOT_GEN_TAGET_CLR(i)	(IMX_CCM_IP_BASE + 0x80 * (i) + 0x08)
#define PLL_FREQ_800M	U(0x00ece580)
#define PLL_FREQ_400M	U(0x00ec6984)
#define PLL_FREQ_167M	U(0x00f5a406)

void ddr_pll_bypass_100mts(void)
{
	/* change the clock source of dram_alt_clk_root to source 2 --100MHz */
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x2 << 24));

	/* change the clock source of dram_apb_clk_root to source 2 --40MHz/2 */
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x2 << 24) | (0x1 << 16));

	/* configure pll bypass mode */
	mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
}

void ddr_pll_bypass_400mts(void)
{
	/* change the clock source of dram_alt_clk_root to source 1 --400MHz */
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x1 << 24) | (0x1 << 16));

	/* change the clock source of dram_apb_clk_root to source 3 --160MHz/2 */
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x3 << 24) | (0x1 << 16));

	/* configure pll bypass mode */
	mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
}

void ddr_pll_unbypass(void)
{
	mmio_write_32(DRAM_SEL_CFG + 0x8, BIT(24));
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
	/* to source 4 --800MHz/5 */
	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x4 << 24) | (0x4 << 16));
}

#if defined(PLAT_imx8mq)
void dram_pll_init(unsigned int drate)
{
	/* bypass the PLL */
	mmio_setbits_32(HW_DRAM_PLL_CFG0, 0x30);

	switch (drate) {
	case 3200:
		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_800M);
		break;
	case 1600:
		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_400M);
		break;
	case 667:
		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_167M);
		break;
	default:
		break;
	}

	/* unbypass the PLL */
	mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
	while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) {
		;
	}
}
#else
void dram_pll_init(unsigned int drate)
{
	/* bypass the PLL */
	mmio_setbits_32(DRAM_PLL_CTRL, (1 << 16));
	mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9));

	switch (drate) {
	case 4000:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
		break;
	case 3200:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (200 << 12) | (3 << 4) | 1);
		break;
	case 2400:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
		break;
	case 1600:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3);
		break;
	case 1066:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3);
		break;
	case 667:
		mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4);
		break;
	default:
		break;
	}

	mmio_setbits_32(DRAM_PLL_CTRL, BIT(9));
	/* wait for PLL locked */
	while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
		;
	}

	/* unbypass the PLL */
	mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16));
}
#endif

/* change the dram clock frequency */
void dram_clock_switch(unsigned int target_drate, bool bypass_mode)
{
	if (bypass_mode) {
		switch (target_drate) {
		case 400:
			ddr_pll_bypass_400mts();
			break;
		case 100:
			ddr_pll_bypass_100mts();
			break;
		default:
			ddr_pll_unbypass();
			break;
		}
	} else {
		dram_pll_init(target_drate);
	}
}
