xref: /OK3568_Linux_fs/u-boot/drivers/ram/rockchip/sdram_rv1108.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
enable_ddr_io_ret(struct dram_info * priv)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 
rkdclk_init(struct dram_info * priv,struct sdram_params * params_priv)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 
phy_pctrl_reset_cru(struct dram_info * priv)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 
pctl_cfg_grf(struct dram_info * priv,struct sdram_params * params_priv)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 
ddr_msch_cfg(struct dram_info * priv,struct sdram_params * params_priv)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 
ddr_msch_cfg_rbc(struct sdram_params * params_priv,struct dram_info * priv)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 
ddr_phy_skew_cfg(struct dram_info * priv)129 void ddr_phy_skew_cfg(struct dram_info *priv)
130 {
131 }
132 
set_ds_odt(struct dram_info * priv,struct sdram_params * params_priv)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 
ddr_phy_dqs_rx_dll_cfg(struct dram_info * priv,u32 freq)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 
ddr_msch_get_max_col(struct dram_info * priv,struct ddr_schedule * sch_priv)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 
ddr_msch_get_max_row(struct dram_info * priv,struct ddr_schedule * sch_priv)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 
get_base_addr(unsigned int * reg,unsigned int offset)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 
modify_data_training(struct dram_info * priv,struct sdram_params * params_priv)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 
check_rd_gate(struct dram_info * priv)196 int check_rd_gate(struct dram_info *priv)
197 {
198 	return 0;
199 }
200 
enable_low_power(struct dram_info * priv,struct sdram_params * params_priv)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 
get_ddr_param(struct dram_info * sdram_priv,struct ddr_param * ddr_param)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 
sdram_init(void)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