From 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:13:47 +0200 Subject: Adding upstream version 2.8.0+dfsg. Signed-off-by: Daniel Baumann --- plat/imx/imx8m/ddr/clock.c | 136 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 plat/imx/imx8m/ddr/clock.c (limited to 'plat/imx/imx8m/ddr/clock.c') diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c new file mode 100644 index 0000000..7fb5730 --- /dev/null +++ b/plat/imx/imx8m/ddr/clock.c @@ -0,0 +1,136 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#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) & (1 << 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 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); + } +} -- cgit v1.2.3