1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2020 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <debug_uart.h> 8 #include <dm.h> 9 #include <dm/root.h> 10 #include <dt-structs.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.h> 16 #include <asm/arch/timer.h> 17 #include <asm/arch/sdram.h> 18 19 struct dram_info info; 20 21 struct rockchip_dmc_plat { 22 #if CONFIG_IS_ENABLED(OF_PLATDATA) 23 struct dtd_rockchip_rv1108_dmc dtplat; 24 #else 25 struct sdram_params params; 26 #endif 27 struct regmap *map; 28 }; 29 30 void enable_ddr_io_ret(struct dram_info *priv) 31 { 32 writel(DDR_IO_RET_EN, &priv->pmu->sft_con); 33 rk_clrsetreg(&priv->pmu_grf->soc_con[0], 34 DDRPHY_BUFFEREN_CORE_MASK, 35 DDRPHY_BUFFEREN_CORE_EN); 36 } 37 38 void rkdclk_init(struct dram_info *priv, 39 struct sdram_params *params_priv) 40 { 41 rk_clrsetreg(&priv->cru->pll[1].con3, WORK_MODE_MASK, 42 WORK_MODE_SLOW << WORK_MODE_SHIFT); 43 rk_clrsetreg(&priv->cru->pll[1].con3, GLOBAL_POWER_DOWN_MASK, 44 GLOBAL_POWER_DOWN << GLOBAL_POWER_DOWN_SHIFT); 45 rk_clrsetreg(&priv->cru->pll[1].con3, DSMPD_MASK, 46 INTEGER_MODE << DSMPD_SHIFT); 47 rk_clrsetreg(&priv->cru->pll[1].con0, FBDIV_MASK, 48 params_priv->dpll_init_cfg.fbdiv << FBDIV_SHIFT); 49 rk_clrsetreg(&priv->cru->pll[1].con1, 50 POSTDIV2_MASK | POSTDIV1_MASK | REFDIV_MASK, 51 params_priv->dpll_init_cfg.postdiv2 << POSTDIV2_SHIFT | 52 params_priv->dpll_init_cfg.postdiv1 << POSTDIV1_SHIFT | 53 params_priv->dpll_init_cfg.refdiv << REFDIV_SHIFT); 54 rk_clrsetreg(&priv->cru->pll[1].con3, GLOBAL_POWER_DOWN_MASK, 55 GLOBAL_POWER_UP << GLOBAL_POWER_DOWN_SHIFT); 56 while (!(readl(&priv->cru->pll[1].con2) & (1u << LOCK_STA_SHIFT))) 57 udelay(1); 58 59 rk_clrsetreg(&priv->cru->clksel_con[4], CLK_DDR_PLL_SEL_MASK | 60 CLK_DDR_DIV_CON_MASK, 0 << CLK_DDR_PLL_SEL_SHIFT | 61 0 << CLK_DDR_DIV_CON_SHIFT); 62 rk_clrsetreg(&priv->cru->pll[1].con3, WORK_MODE_MASK, 63 WORK_MODE_NORMAL << WORK_MODE_SHIFT); 64 } 65 66 void phy_pctrl_reset_cru(struct dram_info *priv) 67 { 68 rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK | 69 DDRUPCTL_NSRSTN_REQ_MASK, 70 DDRUPCTL_PSRSTN_REQ << DDRUPCTL_PSRSTN_REQ_SHIFT | 71 DDRUPCTL_NSRSTN_REQ << DDRUPCTL_NSRSTN_REQ_SHIFT); 72 rk_clrsetreg(&priv->cru->softrst_con[1], 73 DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK | 74 DDRPHY_PSRSTN_REQ_MASK, 75 DDRPHY_SRSTN_CLKDIV_REQ << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT | 76 DDRPHY_SRSTN_REQ << DDRPHY_SRSTN_REQ_SHIFT | 77 DDRPHY_PSRSTN_REQ << DDRPHY_PSRSTN_REQ_SHIFT); 78 79 udelay(10); 80 81 rk_clrsetreg(&priv->cru->softrst_con[1], 82 DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK | 83 DDRPHY_PSRSTN_REQ_MASK, 84 DDRPHY_SRSTN_CLKDIV_DIS << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT | 85 DDRPHY_PSRSTN_DIS << DDRPHY_PSRSTN_REQ_SHIFT | 86 DDRPHY_SRSTN_DIS << DDRPHY_SRSTN_REQ_SHIFT); 87 udelay(10); 88 89 rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK | 90 DDRUPCTL_NSRSTN_REQ_MASK, 91 DDRUPCTL_PSRSTN_DIS << DDRUPCTL_PSRSTN_REQ_SHIFT | 92 DDRUPCTL_NSRSTN_DIS << DDRUPCTL_NSRSTN_REQ_SHIFT); 93 udelay(10); 94 } 95 96 void pctl_cfg_grf(struct dram_info *priv, 97 struct sdram_params *params_priv) 98 { 99 writel(RK_SETBITS(MSCH_MAINDDR3 | MSCH_MAINPARTIALPOP), 100 &priv->grf->soc_con0); 101 } 102 103 void ddr_msch_cfg(struct dram_info *priv, 104 struct sdram_params *params_priv) 105 { 106 writel((readl(&priv->service_msch->ddrtiming) & BWRATIO_HALF_BW) | 107 params_priv->ddr_timing_t.noc_timing.d32, 108 &priv->service_msch->ddrtiming); 109 writel(params_priv->ddr_timing_t.readlatency, 110 &priv->service_msch->readlatency); 111 writel(params_priv->ddr_timing_t.activate.d32, 112 &priv->service_msch->activate); 113 writel(params_priv->ddr_timing_t.devtodev, 114 &priv->service_msch->devtodev); 115 } 116 117 void ddr_msch_cfg_rbc(struct sdram_params *params_priv, 118 struct dram_info *priv) 119 { 120 int i = 0; 121 122 if (params_priv->ddr_config_t.col == 10) 123 i = 2; 124 else 125 i = 3; 126 writel(i, &priv->service_msch->ddrconf); 127 } 128 129 void ddr_phy_skew_cfg(struct dram_info *priv) 130 { 131 } 132 133 void set_ds_odt(struct dram_info *priv, 134 struct sdram_params *params_priv) 135 { 136 /* set phy drive impedance */ 137 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg11); 138 clrsetbits_le32(&priv->phy->phy_reg12, CMD_PRCOMP_MASK, 139 PHY_RON_RTT_34OHM << CMD_PRCOMP_SHIFT); 140 141 writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg16); 142 writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg18); 143 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg20); 144 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg2f); 145 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg30); 146 writel(PHY_RON_RTT_34OHM, &priv->phy->phy_reg3f); 147 148 /*set phy odt*/ 149 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg21); 150 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg2e); 151 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg31); 152 writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg3e); 153 } 154 155 void ddr_phy_dqs_rx_dll_cfg(struct dram_info *priv, u32 freq) 156 { 157 /* 45 degree delay */ 158 writel(LEFT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg28); 159 writel(RIGHT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg38); 160 } 161 162 void ddr_msch_get_max_col(struct dram_info *priv, 163 struct ddr_schedule *sch_priv) 164 { 165 writel(1, &priv->service_msch->ddrconf); 166 sch_priv->col = 11; 167 sch_priv->bank = 3; 168 } 169 170 void ddr_msch_get_max_row(struct dram_info *priv, 171 struct ddr_schedule *sch_priv) 172 { 173 writel(1, &priv->service_msch->ddrconf); 174 sch_priv->row = 16; 175 sch_priv->col = 11; 176 sch_priv->bank = 3; 177 } 178 179 void *get_base_addr(unsigned int *reg, unsigned int offset) 180 { 181 u32 p = *(reg + 2 * offset); 182 183 return (void *)p; 184 } 185 186 void modify_data_training(struct dram_info *priv, 187 struct sdram_params *params_priv) 188 { 189 printascii("REGFB: 0x"); 190 printhex8(readl(&priv->phy->phy_regfb)); 191 printascii(", 0x"); 192 printhex8(readl(&priv->phy->phy_regfc)); 193 printascii("\n"); 194 } 195 196 int check_rd_gate(struct dram_info *priv) 197 { 198 return 0; 199 } 200 201 void enable_low_power(struct dram_info *priv, 202 struct sdram_params *params_priv) 203 { 204 move_to_config_state(priv); 205 206 clrsetbits_le32(&priv->pctl->mcfg, PD_IDLE_MASK, 207 PD_IDLE << PD_IDLE_SHIFT); 208 clrsetbits_le32(&priv->pctl->mcfg1, 209 SR_IDLE_MASK | HW_EXIT_IDLE_EN_MASK, 210 SR_IDLE | HW_EXIT_IDLE_EN); 211 212 /* uPCTL in low_power status because of auto self-refresh */ 213 writel(GO_STATE, &priv->pctl->sctl); 214 } 215 216 void get_ddr_param(struct dram_info *sdram_priv, 217 struct ddr_param *ddr_param) 218 { 219 size_t ram_size = 220 rockchip_sdram_size((phys_addr_t)&sdram_priv->grf->os_reg2); 221 222 ddr_param->count = 1; 223 ddr_param->para[0] = CONFIG_SYS_SDRAM_BASE; 224 ddr_param->para[1] = ram_size; 225 } 226 227 int sdram_init(void) 228 { 229 int ret; 230 struct ddr_param ddr_param; 231 struct dram_info *sdram_priv = &info; 232 struct driver_info *info = 233 ll_entry_start(struct driver_info, driver_info); 234 #if CONFIG_IS_ENABLED(OF_PLATDATA) 235 struct dtd_rockchip_rv1108_dmc *dtplat = (void *)info->platdata; 236 struct sdram_params *params = (void *)dtplat->rockchip_sdram_params; 237 238 sdram_priv->pctl = get_base_addr((void *)dtplat->reg, 0); 239 sdram_priv->phy = get_base_addr((void *)dtplat->reg, 1); 240 sdram_priv->service_msch = get_base_addr((void *)dtplat->reg, 2); 241 sdram_priv->grf = get_base_addr((void *)dtplat->reg, 3); 242 sdram_priv->pmu_grf = get_base_addr((void *)dtplat->reg, 4); 243 sdram_priv->cru = get_base_addr((void *)dtplat->reg, 5); 244 sdram_priv->pmu = get_base_addr((void *)dtplat->reg, 6); 245 #else 246 struct sdram_params *params = (void *)info->platdata; 247 #endif 248 ret = rv1108_sdram_init(sdram_priv, params); 249 if (ret) 250 debug("rv1108_sdram_init() fail!"); 251 252 get_ddr_param(sdram_priv, &ddr_param); 253 rockchip_setup_ddr_param(&ddr_param); 254 255 return ret; 256 } 257