1 /* 2 * Copyright 2018-2023 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdbool.h> 8 #include <lib/mmio.h> 9 10 #include <dram.h> 11 #include <platform_def.h> 12 13 #define SRC_DDR1_RCR (IMX_SRC_BASE + 0x1000) 14 #define SRC_DDR2_RCR (IMX_SRC_BASE + 0x1004) 15 16 #define PU_PGC_UP_TRG 0xf8 17 #define PU_PGC_DN_TRG 0x104 18 #define GPC_PU_PWRHSK (IMX_GPC_BASE + 0x01FC) 19 #define CCM_SRC_CTRL_OFFSET (IMX_CCM_BASE + 0x800) 20 #define CCM_CCGR_OFFSET (IMX_CCM_BASE + 0x4000) 21 #define CCM_TARGET_ROOT_OFFSET (IMX_CCM_BASE + 0x8000) 22 #define CCM_SRC_CTRL(n) (CCM_SRC_CTRL_OFFSET + 0x10 * (n)) 23 #define CCM_CCGR(n) (CCM_CCGR_OFFSET + 0x10 * (n)) 24 #define CCM_TARGET_ROOT(n) (CCM_TARGET_ROOT_OFFSET + 0x80 * (n)) 25 26 #define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50) 27 28 #define DBGCAM_EMPTY 0x36000000 29 30 static void rank_setting_update(void) 31 { 32 uint32_t i, offset; 33 uint32_t pstate_num = dram_info.num_fsp; 34 35 /* only support maximum 3 setpoints */ 36 pstate_num = (pstate_num > MAX_FSP_NUM) ? MAX_FSP_NUM : pstate_num; 37 38 for (i = 0U; i < pstate_num; i++) { 39 offset = i ? (i + 1) * 0x1000 : 0U; 40 mmio_write_32(DDRC_DRAMTMG2(0) + offset, dram_info.rank_setting[i][0]); 41 if (dram_info.dram_type != DDRC_LPDDR4) { 42 mmio_write_32(DDRC_DRAMTMG9(0) + offset, dram_info.rank_setting[i][1]); 43 } 44 45 #if !defined(PLAT_imx8mq) 46 mmio_write_32(DDRC_RANKCTL(0) + offset, 47 dram_info.rank_setting[i][2]); 48 #endif 49 } 50 #if defined(PLAT_imx8mq) 51 mmio_write_32(DDRC_RANKCTL(0), dram_info.rank_setting[0][2]); 52 #endif 53 } 54 55 void dram_enter_retention(void) 56 { 57 /* Wait DBGCAM to be empty */ 58 while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) { 59 ; 60 } 61 62 /* Block AXI ports from taking anymore transactions */ 63 mmio_write_32(DDRC_PCTRL_0(0), 0x0); 64 /* Wait until all AXI ports are idle */ 65 while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) { 66 ; 67 } 68 69 /* Enter self refresh */ 70 mmio_write_32(DDRC_PWRCTL(0), 0xaa); 71 72 /* LPDDR4 & DDR4/DDR3L need to check different status */ 73 if (dram_info.dram_type == DDRC_LPDDR4) { 74 while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) { 75 ; 76 } 77 } else { 78 while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) { 79 ; 80 } 81 } 82 83 mmio_write_32(DDRC_DFIMISC(0), 0x0); 84 mmio_write_32(DDRC_SWCTL(0), 0x0); 85 mmio_write_32(DDRC_DFIMISC(0), 0x1f00); 86 mmio_write_32(DDRC_DFIMISC(0), 0x1f20); 87 88 while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) { 89 ; 90 } 91 92 mmio_write_32(DDRC_DFIMISC(0), 0x1f00); 93 /* wait DFISTAT.dfi_init_complete to 1 */ 94 while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) { 95 ; 96 } 97 98 mmio_write_32(DDRC_SWCTL(0), 0x1); 99 100 /* should check PhyInLP3 pub reg */ 101 dwc_ddrphy_apb_wr(0xd0000, 0x0); 102 if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) { 103 INFO("PhyInLP3 = 1\n"); 104 } 105 dwc_ddrphy_apb_wr(0xd0000, 0x1); 106 107 #if defined(PLAT_imx8mq) 108 /* pwrdnreqn_async adbm/adbs of ddr */ 109 mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1)); 110 while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) { 111 ; 112 } 113 mmio_setbits_32(GPC_PU_PWRHSK, BIT(1)); 114 #else 115 /* pwrdnreqn_async adbm/adbs of ddr */ 116 mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2)); 117 while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) { 118 ; 119 } 120 mmio_setbits_32(GPC_PU_PWRHSK, BIT(2)); 121 #endif 122 /* remove PowerOk */ 123 mmio_write_32(SRC_DDR1_RCR, 0x8F000008); 124 125 mmio_write_32(CCM_CCGR(5), 0); 126 mmio_write_32(CCM_SRC_CTRL(15), 2); 127 128 /* enable the phy iso */ 129 mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1); 130 mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5)); 131 132 VERBOSE("dram enter retention\n"); 133 } 134 135 void dram_exit_retention(void) 136 { 137 VERBOSE("dram exit retention\n"); 138 /* assert all reset */ 139 #if defined(PLAT_imx8mq) 140 mmio_write_32(SRC_DDR2_RCR, 0x8F000003); 141 mmio_write_32(SRC_DDR1_RCR, 0x8F00000F); 142 mmio_write_32(SRC_DDR2_RCR, 0x8F000000); 143 #else 144 mmio_write_32(SRC_DDR1_RCR, 0x8F00001F); 145 mmio_write_32(SRC_DDR1_RCR, 0x8F00000F); 146 #endif 147 mmio_write_32(CCM_CCGR(5), 2); 148 mmio_write_32(CCM_SRC_CTRL(15), 2); 149 150 /* change the clock source of dram_apb_clk_root */ 151 mmio_write_32(CCM_TARGET_ROOT(65) + 0x8, (0x7 << 24) | (0x7 << 16)); 152 mmio_write_32(CCM_TARGET_ROOT(65) + 0x4, (0x4 << 24) | (0x3 << 16)); 153 154 /* disable iso */ 155 mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5)); 156 mmio_write_32(SRC_DDR1_RCR, 0x8F000006); 157 158 /* wait dram pll locked */ 159 while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) { 160 ; 161 } 162 163 /* ddrc re-init */ 164 dram_umctl2_init(dram_info.timing_info); 165 166 /* 167 * Skips the DRAM init routine and starts up in selfrefresh mode 168 * Program INIT0.skip_dram_init = 2'b11 169 */ 170 mmio_setbits_32(DDRC_INIT0(0), 0xc0000000); 171 /* Keeps the controller in self-refresh mode */ 172 mmio_write_32(DDRC_PWRCTL(0), 0xaa); 173 mmio_write_32(DDRC_DBG1(0), 0x0); 174 mmio_write_32(SRC_DDR1_RCR, 0x8F000004); 175 mmio_write_32(SRC_DDR1_RCR, 0x8F000000); 176 177 /* before write Dynamic reg, sw_done should be 0 */ 178 mmio_write_32(DDRC_SWCTL(0), 0x0); 179 180 #if !PLAT_imx8mn 181 if (dram_info.dram_type == DDRC_LPDDR4) { 182 mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */ 183 } 184 #endif /* !PLAT_imx8mn */ 185 186 mmio_write_32(DDRC_DFIMISC(0), 0x0); 187 188 /* dram phy re-init */ 189 dram_phy_init(dram_info.timing_info); 190 191 /* workaround for rank-to-rank issue */ 192 rank_setting_update(); 193 194 /* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */ 195 dwc_ddrphy_apb_wr(0xd0000, 0x0); 196 while (dwc_ddrphy_apb_rd(0x20097)) { 197 ; 198 } 199 dwc_ddrphy_apb_wr(0xd0000, 0x1); 200 201 /* before write Dynamic reg, sw_done should be 0 */ 202 mmio_write_32(DDRC_SWCTL(0), 0x0); 203 mmio_write_32(DDRC_DFIMISC(0), 0x20); 204 /* wait DFISTAT.dfi_init_complete to 1 */ 205 while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) { 206 ; 207 } 208 209 /* clear DFIMISC.dfi_init_start */ 210 mmio_write_32(DDRC_DFIMISC(0), 0x0); 211 /* set DFIMISC.dfi_init_complete_en */ 212 mmio_write_32(DDRC_DFIMISC(0), 0x1); 213 214 /* set SWCTL.sw_done to enable quasi-dynamic register programming */ 215 mmio_write_32(DDRC_SWCTL(0), 0x1); 216 /* wait SWSTAT.sw_done_ack to 1 */ 217 while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) { 218 ; 219 } 220 221 mmio_write_32(DDRC_PWRCTL(0), 0x88); 222 /* wait STAT to normal state */ 223 while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) { 224 ; 225 } 226 227 mmio_write_32(DDRC_PCTRL_0(0), 0x1); 228 /* dis_auto-refresh is set to 0 */ 229 mmio_write_32(DDRC_RFSHCTL3(0), 0x0); 230 231 /* should check PhyInLP3 pub reg */ 232 dwc_ddrphy_apb_wr(0xd0000, 0x0); 233 if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) { 234 VERBOSE("PHYInLP3 = 0\n"); 235 } 236 dwc_ddrphy_apb_wr(0xd0000, 0x1); 237 } 238