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