1 /* 2 * Copyright (C) 2018 Rockchip Electronics Co., Ltd 3 * Author: Zhihuan He <huan.he@rock-chips.com> 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 #include <common.h> 7 #include <dm.h> 8 #include <dm/root.h> 9 #include <dt-structs.h> 10 #include <ram.h> 11 #include <regmap.h> 12 #include <asm/io.h> 13 #include <asm/types.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/arch/sdram_rv1108_pctl_phy.h> 16 #include <asm/arch/timer.h> 17 #include <asm/arch/sdram_common.h> 18 19 #if defined(CONFIG_ROCKCHIP_RV1108) 20 #include <asm/arch/sdram_rv1108.h> 21 #elif defined(CONFIG_ROCKCHIP_RK3308) 22 #include <asm/arch/sdram_rk3308.h> 23 #endif 24 25 /* 26 * we can not fit the code to access the device tree in SPL 27 * (due to 6K SRAM size limits), so these are hard-coded 28 */ 29 30 static void copy_to_reg(u32 *dest, const u32 *src, u32 n) 31 { 32 int i; 33 34 for (i = 0; i < n / sizeof(u32); i++) { 35 writel(*src, dest); 36 src++; 37 dest++; 38 } 39 } 40 41 static void phy_pctrl_reset(struct dram_info *priv) 42 { 43 phy_pctrl_reset_cru(priv); 44 clrsetbits_le32(&priv->phy->phy_reg0, 45 RESET_DIGITAL_CORE_MASK | RESET_ANALOG_LOGIC_MASK, 46 RESET_DIGITAL_CORE_ACT << RESET_DIGITAL_CORE_SHIFT | 47 RESET_ANALOG_LOGIC_ACT << RESET_ANALOG_LOGIC_SHIFT); 48 udelay(1); 49 clrsetbits_le32(&priv->phy->phy_reg0, 50 RESET_ANALOG_LOGIC_MASK, 51 RESET_ANALOG_LOGIC_DIS << RESET_ANALOG_LOGIC_SHIFT); 52 udelay(5); 53 clrsetbits_le32(&priv->phy->phy_reg0, 54 RESET_DIGITAL_CORE_MASK, 55 RESET_DIGITAL_CORE_DIS << RESET_DIGITAL_CORE_SHIFT); 56 udelay(1); 57 } 58 59 static void phy_dll_bypass_set(struct dram_info *priv, unsigned int freq) 60 { 61 clrsetbits_le32(&priv->phy->phy_reg13, CMD_DLL_BYPASS_MASK, 62 CMD_DLL_BYPASS << CMD_DLL_BYPASS_SHIFT); 63 64 writel(CK_DLL_BYPASS_DISABLE << CK_DLL_BYPASS_SHIFT, 65 &priv->phy->phy_reg14); 66 67 clrsetbits_le32(&priv->phy->phy_reg26, LEFT_CHN_A_DQ_DLL_BYPASS_MASK, 68 LEFT_CHN_A_DQ_DLL_BYPASS << LEFT_CHN_A_DQ_DLL_SHIFT); 69 writel(LEFT_CHN_A_DQS_DLL_BYPASS_DIS << 70 LEFT_CHN_A_DQS_DLL_SHIFT, &priv->phy->phy_reg27); 71 72 clrsetbits_le32(&priv->phy->phy_reg36, RIGHT_CHN_A_DQ_DLL_BYPASS_MASK, 73 RIGHT_CHN_A_DQ_DLL_BYPASS << 74 RIGHT_CHN_A_DQ_DLL_SHIFT); 75 writel(RIGHT_CHN_A_DQS_DLL_BYPASS_DIS << 76 RIGHT_CHN_A_DQS_DLL_SHIFT, &priv->phy->phy_reg37); 77 78 if (freq <= PHY_LOW_SPEED_MHZ) { 79 writel(RIGHT_CHN_A_TX_DQ_BYPASS_SET << 80 RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT | 81 LEFT_CHN_A_TX_DQ_BYPASS_SET << 82 LEFT_CHN_A_TX_DQ_BYPASS_SHIFT | 83 CMD_CK_DLL_BYPASS_SET << CMD_CK_DLL_BYPASS_SHIFT, 84 &priv->phy->phy_regdll); 85 } else { 86 writel(RIGHT_CHN_A_TX_DQ_BYPASS_DIS << 87 RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT | 88 LEFT_CHN_A_TX_DQ_BYPASS_DIS << 89 LEFT_CHN_A_TX_DQ_BYPASS_SHIFT | 90 CMD_CK_DLL_BYPASS_DIS << CMD_CK_DLL_BYPASS_SHIFT, 91 &priv->phy->phy_regdll); 92 } 93 94 /* 45 degree delay */ 95 writel(LEFT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg28); 96 writel(RIGHT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg38); 97 } 98 99 static void send_command(struct dram_info *priv, 100 u32 rank, u32 cmd, u32 arg) 101 { 102 writel((START_CMD | (rank << RANK_SEL_SHIFT) | arg | cmd), 103 &priv->pctl->mcmd); 104 while (readl(&priv->pctl->mcmd) & START_CMD) 105 ; 106 } 107 108 static void memory_init(struct dram_info *priv, 109 struct sdram_params *params_priv) 110 { 111 send_command(priv, RANK_SEL_CS0_CS1, DESELECT_CMD, 0); 112 udelay(1); 113 send_command(priv, RANK_SEL_CS0_CS1, PREA_CMD, 0); 114 115 send_command(priv, RANK_SEL_CS0_CS1, DESELECT_CMD, 0); 116 udelay(1); 117 send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD, 118 (MR2 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT | 119 (params_priv->ddr_timing_t.phy_timing.mr[2] & 120 CMD_ADDR_MASK) << CMD_ADDR_SHIFT); 121 122 send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD, 123 (MR3 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT | 124 (params_priv->ddr_timing_t.phy_timing.mr[3] & 125 CMD_ADDR_MASK) << CMD_ADDR_SHIFT); 126 127 send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD, 128 (MR1 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT | 129 (params_priv->ddr_timing_t.phy_timing.mr[1] & 130 CMD_ADDR_MASK) << CMD_ADDR_SHIFT); 131 132 send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD, 133 (MR0 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT | 134 (params_priv->ddr_timing_t.phy_timing.mr[0] & 135 CMD_ADDR_MASK) << CMD_ADDR_SHIFT | DDR3_DLL_RESET); 136 137 send_command(priv, RANK_SEL_CS0_CS1, ZQCL_CMD, 0); 138 } 139 140 static void set_bw(struct dram_info *priv, 141 struct sdram_params *params_priv) 142 { 143 if (readl(¶ms_priv->ddr_config.bw) == 1) { 144 clrsetbits_le32(&priv->pctl->ppcfg, PPMEM_EN_MASK, PPMEM_EN); 145 clrsetbits_le32(&priv->phy->phy_reg0, DQ_16BIT_EN_MASK, 146 DQ_16BIT_EN); 147 set_bw_grf(priv); 148 clrsetbits_le32(&priv->service_msch->ddrtiming, 149 BWRATIO_HALF_BW, BWRATIO_HALF_BW); 150 } 151 } 152 153 static void move_to_config_state(struct dram_info *priv) 154 { 155 unsigned int state; 156 157 while (1) { 158 state = readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK; 159 switch (state) { 160 case LOW_POWER: 161 writel(WAKEUP_STATE, &priv->pctl->sctl); 162 while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK) 163 != ACCESS) 164 ; 165 /* 166 * If at low power state, need wakeup first, and then 167 * enter the config, so fallthrough 168 */ 169 case ACCESS: 170 case INIT_MEM: 171 writel(CFG_STATE, &priv->pctl->sctl); 172 while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK) 173 != CONFIG) 174 ; 175 break; 176 case CONFIG: 177 return; 178 default: 179 break; 180 } 181 } 182 } 183 184 static void move_to_access_state(struct dram_info *priv) 185 { 186 unsigned int state; 187 188 while (1) { 189 state = readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK; 190 switch (state) { 191 case LOW_POWER: 192 writel(WAKEUP_STATE, &priv->pctl->sctl); 193 while ((readl(&priv->pctl->stat) & 194 PCTL_CTL_STAT_MASK) != ACCESS) 195 ; 196 break; 197 case INIT_MEM: 198 writel(CFG_STATE, &priv->pctl->sctl); 199 while ((readl(&priv->pctl->stat) & 200 PCTL_CTL_STAT_MASK) != CONFIG) 201 ; 202 /* fallthrough */ 203 case CONFIG: 204 writel(GO_STATE, &priv->pctl->sctl); 205 while ((readl(&priv->pctl->stat) & 206 PCTL_CTL_STAT_MASK) != ACCESS) 207 ; 208 break; 209 case ACCESS: 210 return; 211 default: 212 break; 213 } 214 } 215 } 216 217 static void pctl_cfg(struct dram_info *priv, 218 struct sdram_params *params_priv) 219 { 220 u32 reg; 221 222 /* DFI config */ 223 writel(DFI_DATA_BYTE_DISABLE_EN << DFI_DATA_BYTE_DISABLE_EN_SHIFT | 224 DFI_INIT_START_EN << DFI_INIT_START_SHIFT, 225 &priv->pctl->dfistcfg0); 226 writel(DFI_DRAM_CLK_DISABLE_EN_DPD << 227 DFI_DRAM_CLK_DISABLE_EN_DPD_SHIFT | 228 DFI_DRAM_CLK_DISABLE_EN << DFI_DRAM_CLK_DISABLE_EN_SHIFT, 229 &priv->pctl->dfistcfg1); 230 writel(PARITY_EN << PARITY_EN_SHIFT | 231 PARITY_INTR_EN << PARITY_INTR_EN_SHIFT, &priv->pctl->dfistcfg2); 232 writel(DFI_LP_EN_SR << DFI_LP_EN_SR_SHIFT | 233 DFI_LP_WAKEUP_SR_32_CYCLES << DFI_LP_WAKEUP_SR_SHIFT | 234 DFI_TLP_RESP << DFI_TLP_RESP_SHIFT, 235 &priv->pctl->dfilpcfg0); 236 237 writel(TPHYUPD_TYPE0, &priv->pctl->dfitphyupdtype0); 238 writel(TPHY_RDLAT, &priv->pctl->dfitphyrdlat); 239 writel(TPHY_WRDATA, &priv->pctl->dfitphywrdata); 240 241 writel(DFI_PHYUPD_DISABLE | DFI_CTRLUPD_DISABLE, 242 &priv->pctl->dfiupdcfg); 243 244 copy_to_reg(&priv->pctl->togcnt1u, 245 &(params_priv->ddr_timing_t.pctl_timing.togcnt1u), 246 sizeof(struct pctl_timing)); 247 248 writel((RANK0_ODT_WRITE_SEL << RANK0_ODT_WRITE_SEL_SHIFT | 249 RANK1_ODT_WRITE_SEL << RANK1_ODT_WRITE_SEL_SHIFT), 250 &priv->pctl->dfiodtcfg); 251 252 writel(ODT_LEN_BL8_W << ODT_LEN_BL8_W_SHIFT, 253 &priv->pctl->dfiodtcfg1); 254 255 reg = readl(&priv->pctl->tcl); 256 writel((reg - 1) / 2 - 1, &priv->pctl->dfitrddataen); 257 reg = readl(&priv->pctl->tcwl); 258 writel((reg - 1) / 2 - 1, &priv->pctl->dfitphywrlat); 259 260 writel(params_priv->ddr_timing_t.pctl_timing.trsth, &priv->pctl->trsth); 261 writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | DDR3_EN | MEM_BL_8 | 262 TFAW_CFG_5_TDDR | PD_EXIT_SLOW_EXIT_MODE | 263 PD_TYPE_ACT_PD | PD_IDLE_DISABLE, &priv->pctl->mcfg); 264 265 pctl_cfg_grf(priv); 266 setbits_le32(&priv->pctl->scfg, HW_LOW_POWER_EN); 267 } 268 269 static void phy_cfg(struct dram_info *priv, 270 struct sdram_params *params_priv) 271 { 272 writel((readl(&priv->service_msch->ddrtiming) & BWRATIO_HALF_BW)| 273 params_priv->ddr_timing_t.noc_timing, 274 &priv->service_msch->ddrtiming); 275 writel(params_priv->ddr_timing_t.readlatency, 276 &priv->service_msch->readlatency); 277 writel(params_priv->ddr_timing_t.activate, 278 &priv->service_msch->activate); 279 writel(params_priv->ddr_timing_t.devtodev, 280 &priv->service_msch->devtodev); 281 282 writel(MEMORY_SELECT_DDR3 | PHY_BL_8, &priv->phy->phy_reg1); 283 284 writel(params_priv->ddr_timing_t.phy_timing.cl_al, 285 &priv->phy->phy_regb); 286 writel(params_priv->ddr_timing_t.pctl_timing.tcwl, 287 &priv->phy->phy_regc); 288 289 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg11); 290 clrsetbits_le32(&priv->phy->phy_reg12, CMD_PRCOMP_MASK, 291 PHY_RON_RTT_34OHM << CMD_PRCOMP_SHIFT); 292 writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg16); 293 writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg18); 294 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg20); 295 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg2f); 296 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg30); 297 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg3f); 298 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg21); 299 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg2e); 300 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg31); 301 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg3e); 302 } 303 304 static void dram_cfg_rbc(struct dram_info *priv, 305 struct sdram_params *params_priv) 306 { 307 int i = 0; 308 309 move_to_config_state(priv); 310 #if defined(CONFIG_ROCKCHIP_RV1108) 311 if (params_priv->ddr_config.col == 10) 312 i = 2; 313 else 314 i = 3; 315 #elif defined(CONFIG_ROCKCHIP_RK3308) 316 317 #endif 318 writel(i, &priv->service_msch->ddrconf); 319 move_to_access_state(priv); 320 } 321 322 static void enable_low_power(struct dram_info *priv) 323 { 324 move_to_config_state(priv); 325 326 clrsetbits_le32(&priv->pctl->mcfg, PD_IDLE_MASK, 327 PD_IDLE << PD_IDLE_SHIFT); 328 clrsetbits_le32(&priv->pctl->mcfg1, SR_IDLE_MASK | HW_EXIT_IDLE_EN_MASK, 329 SR_IDLE | HW_EXIT_IDLE_EN); 330 331 /* uPCTL in low_power status because of auto self-refreh */ 332 writel(GO_STATE, &priv->pctl->sctl); 333 } 334 335 static void data_training(struct dram_info *priv) 336 { 337 u32 value; 338 u32 tmp = 0; 339 340 /* disable auto refresh */ 341 value = readl(&priv->pctl->trefi); 342 writel(UPD_REF, &priv->pctl->trefi); 343 344 writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS, 345 &priv->phy->phy_reg2); 346 writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_ACT, 347 &priv->phy->phy_reg2); 348 349 /* delay untill data training done */ 350 while (tmp != (CHN_A_HIGH_8BIT_TRAINING_DONE | 351 CHN_A_LOW_8BIT_TRAINING_DONE)) { 352 udelay(1); 353 tmp = (readl(&priv->phy->phy_regff) & CHN_A_TRAINING_DONE_MASK); 354 } 355 356 writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS, 357 &priv->phy->phy_reg2); 358 359 send_command(priv, RANK_SEL_CS0_CS1, PREA_CMD, 0); 360 361 writel(value | UPD_REF, &priv->pctl->trefi); 362 } 363 364 static u32 sdram_detect(struct dram_info *priv, 365 struct sdram_params *params_priv) 366 { 367 u32 row, col, row_max, col_max; 368 u32 test_addr; 369 370 move_to_config_state(priv); 371 #if defined(CONFIG_ROCKCHIP_RV1108) 372 writel(1, &priv->service_msch->ddrconf); 373 col_max = 11; 374 row_max = 16; 375 #elif defined(CONFIG_ROCKCHIP_RK3308) 376 377 #endif 378 move_to_access_state(priv); 379 380 /* detect col */ 381 for (col = col_max; col >= 10; col--) { 382 writel(0, SDRAM_BEGIN_ADDR); 383 test_addr = SDRAM_BEGIN_ADDR + (1u << (col + 384 params_priv->ddr_config.bw - 1u)); 385 writel(PATTERN, test_addr); 386 if ((readl(test_addr) == PATTERN) && 387 (readl(SDRAM_BEGIN_ADDR) == 0)) 388 break; 389 } 390 if (col <= 8) 391 goto cap_err; 392 params_priv->ddr_config.col = col; 393 394 /* detect row */ 395 col = col_max; 396 for (row = row_max; row >= 12; row--) { 397 writel(0, SDRAM_BEGIN_ADDR); 398 test_addr = SDRAM_BEGIN_ADDR + (1u << (row + 399 params_priv->ddr_config.bank + col + 400 params_priv->ddr_config.bw - 1u)); 401 writel(PATTERN, test_addr); 402 if ((readl(test_addr) == PATTERN) && 403 (readl(SDRAM_BEGIN_ADDR) == 0)) 404 break; 405 } 406 if (row <= 11) 407 goto cap_err; 408 params_priv->ddr_config.cs0_row = row; 409 return 0; 410 cap_err: 411 return 1; 412 } 413 414 static void sdram_all_config(struct dram_info *priv, 415 struct sdram_params *params_priv) 416 { 417 u32 os_reg = 0; 418 u32 cs1_row = 0; 419 420 if (params_priv->ddr_config.rank > 1) 421 cs1_row = params_priv->ddr_config.cs1_row - 13; 422 423 os_reg = params_priv->ddr_config.ddr_type << SYS_REG_DDRTYPE_SHIFT | 424 params_priv->ddr_config.chn_cnt << SYS_REG_NUM_CH_SHIFT | 425 (params_priv->ddr_config.rank - 1) << SYS_REG_RANK_SHIFT(0) | 426 (params_priv->ddr_config.col - 9) << SYS_REG_COL_SHIFT(0) | 427 (params_priv->ddr_config.bank == 3 ? 0 : 1) << 428 SYS_REG_BK_SHIFT(0) | 429 (params_priv->ddr_config.cs0_row - 13) << 430 SYS_REG_CS0_ROW_SHIFT(0) | 431 cs1_row << SYS_REG_CS1_ROW_SHIFT(0) | 432 params_priv->ddr_config.bw << SYS_REG_BW_SHIFT(0) | 433 params_priv->ddr_config.dbw << SYS_REG_DBW_SHIFT(0); 434 435 writel(os_reg, &priv->grf->os_reg2); 436 } 437 438 int rv1108_sdram_init(struct dram_info *sdram_priv, 439 struct sdram_params *params_priv) 440 { 441 /* pmu enable ddr io retention */ 442 enable_ddr_io_ret(sdram_priv); 443 rkdclk_init(sdram_priv, params_priv); 444 phy_pctrl_reset(sdram_priv); 445 phy_dll_bypass_set(sdram_priv, params_priv->ddr_timing_t.freq); 446 pctl_cfg(sdram_priv, params_priv); 447 phy_cfg(sdram_priv, params_priv); 448 449 writel(POWER_UP_START, &sdram_priv->pctl->powctl); 450 while (!(readl(&sdram_priv->pctl->powstat) & POWER_UP_DONE)) 451 ; 452 453 memory_init(sdram_priv, params_priv); 454 move_to_config_state(sdram_priv); 455 set_bw(sdram_priv, params_priv); 456 data_training(sdram_priv); 457 move_to_access_state(sdram_priv); 458 if (sdram_detect(sdram_priv, params_priv)) { 459 while (1) 460 ; 461 } 462 dram_cfg_rbc(sdram_priv, params_priv); 463 sdram_all_config(sdram_priv, params_priv); 464 enable_low_power(sdram_priv); 465 466 return 0; 467 } 468