1 /* 2 * Copyright 2018-2023 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdbool.h> 8 9 #include <lib/mmio.h> 10 #include <platform_def.h> 11 12 #define IMX_CCM_IP_BASE (IMX_CCM_BASE + 0xa000) 13 #define DRAM_SEL_CFG (IMX_CCM_BASE + 0x9800) 14 #define CCM_IP_CLK_ROOT_GEN_TAGET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x00) 15 #define CCM_IP_CLK_ROOT_GEN_TAGET_SET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x04) 16 #define CCM_IP_CLK_ROOT_GEN_TAGET_CLR(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x08) 17 #define PLL_FREQ_800M U(0x00ece580) 18 #define PLL_FREQ_400M U(0x00ec6984) 19 #define PLL_FREQ_167M U(0x00f5a406) 20 21 void ddr_pll_bypass_100mts(void) 22 { 23 /* change the clock source of dram_alt_clk_root to source 2 --100MHz */ 24 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16)); 25 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x2 << 24)); 26 27 /* change the clock source of dram_apb_clk_root to source 2 --40MHz/2 */ 28 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16)); 29 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x2 << 24) | (0x1 << 16)); 30 31 /* configure pll bypass mode */ 32 mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24)); 33 } 34 35 void ddr_pll_bypass_400mts(void) 36 { 37 /* change the clock source of dram_alt_clk_root to source 1 --400MHz */ 38 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16)); 39 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x1 << 24) | (0x1 << 16)); 40 41 /* change the clock source of dram_apb_clk_root to source 3 --160MHz/2 */ 42 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16)); 43 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x3 << 24) | (0x1 << 16)); 44 45 /* configure pll bypass mode */ 46 mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24)); 47 } 48 49 void ddr_pll_unbypass(void) 50 { 51 mmio_write_32(DRAM_SEL_CFG + 0x8, BIT(24)); 52 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16)); 53 /* to source 4 --800MHz/5 */ 54 mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x4 << 24) | (0x4 << 16)); 55 } 56 57 #if defined(PLAT_imx8mq) 58 void dram_pll_init(unsigned int drate) 59 { 60 /* bypass the PLL */ 61 mmio_setbits_32(HW_DRAM_PLL_CFG0, 0x30); 62 63 switch (drate) { 64 case 3200: 65 mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_800M); 66 break; 67 case 1600: 68 mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_400M); 69 break; 70 case 667: 71 mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_167M); 72 break; 73 default: 74 break; 75 } 76 77 /* unbypass the PLL */ 78 mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30); 79 while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) { 80 ; 81 } 82 } 83 #else 84 void dram_pll_init(unsigned int drate) 85 { 86 /* bypass the PLL */ 87 mmio_setbits_32(DRAM_PLL_CTRL, (1 << 16)); 88 mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9)); 89 90 switch (drate) { 91 case 4000: 92 mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1); 93 break; 94 case 3734: 95 case 3733: 96 case 3732: 97 mmio_write_32(DRAM_PLL_CTRL + 0x4, (311 << 12) | (4 << 4) | 1); 98 break; 99 case 3600: 100 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (8 << 4) | 0); 101 break; 102 case 3200: 103 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (9 << 4) | 0); 104 break; 105 case 2400: 106 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2); 107 break; 108 case 1600: 109 mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3); 110 break; 111 case 1066: 112 mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3); 113 break; 114 case 667: 115 mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4); 116 break; 117 default: 118 break; 119 } 120 121 mmio_setbits_32(DRAM_PLL_CTRL, BIT(9)); 122 /* wait for PLL locked */ 123 while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) { 124 ; 125 } 126 127 /* unbypass the PLL */ 128 mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16)); 129 } 130 #endif 131 132 /* change the dram clock frequency */ 133 void dram_clock_switch(unsigned int target_drate, bool bypass_mode) 134 { 135 if (bypass_mode) { 136 switch (target_drate) { 137 case 400: 138 ddr_pll_bypass_400mts(); 139 break; 140 case 100: 141 ddr_pll_bypass_100mts(); 142 break; 143 default: 144 ddr_pll_unbypass(); 145 break; 146 } 147 } else { 148 dram_pll_init(target_drate); 149 } 150 } 151