blob: c39cbb8111a14f35b864d3b1db0354102771513a [file] [log] [blame]
Kever Yangecbea442018-12-20 11:33:41 +08001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
huang linda98a5b2015-11-17 14:20:26 +08002/*
Kever Yangecbea442018-12-20 11:33:41 +08003 * (C) Copyright 2015 Rockchip Electronics Co., Ltd
huang linda98a5b2015-11-17 14:20:26 +08004 */
5#include <common.h>
6#include <asm/io.h>
7#include <asm/types.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +08008#include <asm/arch-rockchip/cru_rk3036.h>
9#include <asm/arch-rockchip/grf_rk3036.h>
10#include <asm/arch-rockchip/hardware.h>
11#include <asm/arch-rockchip/sdram_rk3036.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080012#include <asm/arch-rockchip/uart.h>
huang linda98a5b2015-11-17 14:20:26 +080013
14/*
15 * we can not fit the code to access the device tree in SPL
16 * (due to 4K SRAM size limits), so these are hard-coded
17 */
18#define CRU_BASE 0x20000000
19#define GRF_BASE 0x20008000
20#define DDR_PHY_BASE 0x2000a000
21#define DDR_PCTL_BASE 0x20004000
22#define CPU_AXI_BUS_BASE 0x10128000
23
24struct rk3036_sdram_priv {
25 struct rk3036_cru *cru;
26 struct rk3036_grf *grf;
27 struct rk3036_ddr_phy *phy;
28 struct rk3036_ddr_pctl *pctl;
29 struct rk3036_service_sys *axi_bus;
30
31 /* ddr die config */
32 struct rk3036_ddr_config ddr_config;
33};
34
Kever Yangae0ec2c2017-11-30 16:51:19 +080035/*
36 * use integer mode, dpll output 792MHz and ddr get 396MHz
huang linda98a5b2015-11-17 14:20:26 +080037 * refdiv, fbdiv, postdiv1, postdiv2
38 */
Kever Yangae0ec2c2017-11-30 16:51:19 +080039const struct pll_div dpll_init_cfg = {1, 66, 2, 1};
huang linda98a5b2015-11-17 14:20:26 +080040
41/* 396Mhz ddr timing */
42const struct rk3036_ddr_timing ddr_timing = {0x18c,
43 {0x18c, 0xc8, 0x1f4, 0x27, 0x4e,
44 0x4, 0x8b, 0x06, 0x03, 0x0, 0x06, 0x05, 0x0f, 0x15, 0x06, 0x04, 0x04,
45 0x06, 0x04, 0x200, 0x03, 0x0a, 0x40, 0x2710, 0x01, 0x05, 0x05, 0x03,
46 0x0c, 0x28, 0x100, 0x0, 0x04, 0x0},
47 {{0x420, 0x42, 0x0, 0x0}, 0x01, 0x60},
48 {0x24717315} };
49
50/*
51 * [7:6] bank(n:n bit bank)
52 * [5:4] row(13+n)
53 * [3] cs(0:1 cs, 1:2 cs)
54 * [2:1] bank(n:n bit bank)
55 * [0] col(10+n)
56 */
57const char ddr_cfg_2_rbc[] = {
58 ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 1),
59 ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 0),
60 ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 0),
61 ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 0),
62 ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 1),
63 ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 1),
64 ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 1),
65 ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 0),
66 ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 1),
67 ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 0),
68 ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 1),
69 ((1 << 6) | (2 << 4) | (0 << 3) | (2 << 1) | 0),
70 ((3 << 6) | (2 << 4) | (0 << 3) | (0 << 1) | 1),
71 ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 0),
72};
73
74/* DDRPHY REG */
75enum {
76 /* DDRPHY_REG1 */
77 SOFT_RESET_MASK = 3,
78 SOFT_RESET_SHIFT = 2,
79
80 /* DDRPHY_REG2 */
81 MEMORY_SELECT_DDR3 = 0 << 6,
82 DQS_SQU_CAL_NORMAL_MODE = 0 << 1,
83 DQS_SQU_CAL_START = 1 << 0,
84 DQS_SQU_NO_CAL = 0 << 0,
85
86 /* DDRPHY_REG2A */
87 CMD_DLL_BYPASS = 1 << 4,
88 CMD_DLL_BYPASS_DISABLE = 0 << 4,
89 HIGH_8BIT_DLL_BYPASS = 1 << 3,
90 HIGH_8BIT_DLL_BYPASS_DISABLE = 0 << 3,
91 LOW_8BIT_DLL_BYPASS = 1 << 2,
92 LOW_8BIT_DLL_BYPASS_DISABLE = 0 << 2,
93
94 /* DDRPHY_REG19 */
95 CMD_FEEDBACK_ENABLE = 1 << 5,
96 CMD_SLAVE_DLL_INVERSE_MODE = 1 << 4,
97 CMD_SLAVE_DLL_NO_INVERSE_MODE = 0 << 4,
98 CMD_SLAVE_DLL_ENALBE = 1 << 3,
99 CMD_TX_SLAVE_DLL_DELAY_MASK = 7,
100 CMD_TX_SLAVE_DLL_DELAY_SHIFT = 0,
101
102 /* DDRPHY_REG6 */
103 LEFT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
104 LEFT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
105 LEFT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
106 LEFT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
107 LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
108
109 /* DDRPHY_REG8 */
110 LEFT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
111 LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
112
113 /* DDRPHY_REG9 */
114 RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
115 RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
116 RIGHT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
117 RIGHT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
118 RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
119
120 /* DDRPHY_REG11 */
121 RIGHT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
122 RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
123
124 /* DDRPHY_REG62 */
125 CAL_DONE_MASK = 3,
126 HIGH_8BIT_CAL_DONE = 1 << 1,
127 LOW_8BIT_CAL_DONE = 1 << 0,
128};
129
130/* PTCL */
131enum {
132 /* PCTL_DFISTCFG0 */
133 DFI_INIT_START = 1 << 0,
134 DFI_DATA_BYTE_DISABLE_EN = 1 << 2,
135
136 /* PCTL_DFISTCFG1 */
137 DFI_DRAM_CLK_SR_EN = 1 << 0,
138 DFI_DRAM_CLK_DPD_EN = 1 << 1,
139
140 /* PCTL_DFISTCFG2 */
141 DFI_PARITY_INTR_EN = 1 << 0,
142 DFI_PARITY_EN = 1 << 1,
143
144 /* PCTL_DFILPCFG0 */
145 TLP_RESP_TIME_SHIFT = 16,
146 LP_SR_EN = 1 << 8,
147 LP_PD_EN = 1 << 0,
148
149 /* PCTL_DFIODTCFG */
150 RANK0_ODT_WRITE_SEL = 1 << 3,
151 RANK1_ODT_WRITE_SEL = 1 << 11,
152
153 /* PCTL_DFIODTCFG1 */
154 ODT_LEN_BL8_W_SHIFT = 16,
155
156 /* PCTL_MCFG */
157 TFAW_CFG_MASK = 3,
158 TFAW_CFG_SHIFT = 18,
159 PD_EXIT_SLOW_MODE = 0 << 17,
160 PD_ACTIVE_POWER_DOWN = 1 << 16,
161 PD_IDLE_MASK = 0xff,
162 PD_IDLE_SHIFT = 8,
163 MEM_BL4 = 0 << 0,
164 MEM_BL8 = 1 << 0,
165
166 /* PCTL_MCFG1 */
167 HW_EXIT_IDLE_EN_MASK = 1,
168 HW_EXIT_IDLE_EN_SHIFT = 31,
169 SR_IDLE_MASK = 0x1ff,
170 SR_IDLE_SHIFT = 0,
171
172 /* PCTL_SCFG */
173 HW_LOW_POWER_EN = 1 << 0,
174
175 /* PCTL_POWCTL */
176 POWER_UP_START = 1 << 0,
177
178 /* PCTL_POWSTAT */
179 POWER_UP_DONE = 1 << 0,
180
181 /* PCTL_MCMD */
182 START_CMD = 1 << 31,
183 BANK_ADDR_MASK = 7,
184 BANK_ADDR_SHIFT = 17,
185 CMD_ADDR_MASK = 0x1fff,
186 CMD_ADDR_SHIFT = 4,
187 DESELECT_CMD = 0,
188 PREA_CMD,
189 REF_CMD,
190 MRS_CMD,
191 ZQCS_CMD,
192 ZQCL_CMD,
193 RSTL_CMD,
194 MRR_CMD = 8,
195
196 /* PCTL_STAT */
197 INIT_MEM = 0,
198 CONFIG,
199 CONFIG_REQ,
200 ACCESS,
201 ACCESS_REQ,
202 LOW_POWER,
203 LOW_POWER_ENTRY_REQ,
204 LOW_POWER_EXIT_REQ,
205 PCTL_STAT_MASK = 7,
206
207 /* PCTL_SCTL */
208 INIT_STATE = 0,
209 CFG_STATE = 1,
210 GO_STATE = 2,
211 SLEEP_STATE = 3,
212 WAKEUP_STATE = 4,
213};
214
215/* GRF_SOC_CON2 */
216#define MSCH4_MAINDDR3 (1 << 7)
217#define PHY_DRV_ODT_SET(n) ((n << 4) | n)
218#define DDR3_DLL_RESET (1 << 8)
219
220/* CK pull up/down driver strength control */
221enum {
222 PHY_RON_DISABLE = 0,
223 PHY_RON_309OHM = 1,
224 PHY_RON_155OHM,
225 PHY_RON_103OHM = 3,
226 PHY_RON_63OHM = 5,
227 PHY_RON_45OHM = 7,
228 PHY_RON_77OHM,
229 PHY_RON_62OHM,
230 PHY_RON_52OHM,
231 PHY_RON_44OHM,
232 PHY_RON_39OHM,
233 PHY_RON_34OHM,
234 PHY_RON_31OHM,
235 PHY_RON_28OHM,
236};
237
238/* DQ pull up/down control */
239enum {
240 PHY_RTT_DISABLE = 0,
241 PHY_RTT_861OHM = 1,
242 PHY_RTT_431OHM,
243 PHY_RTT_287OHM,
244 PHY_RTT_216OHM,
245 PHY_RTT_172OHM,
246 PHY_RTT_145OHM,
247 PHY_RTT_124OHM,
248 PHY_RTT_215OHM,
249 PHY_RTT_144OHM = 0xa,
250 PHY_RTT_123OHM,
251 PHY_RTT_108OHM,
252 PHY_RTT_96OHM,
253 PHY_RTT_86OHM,
254 PHY_RTT_78OHM,
255};
256
257/* DQS squelch DLL delay */
258enum {
259 DQS_DLL_NO_DELAY = 0,
260 DQS_DLL_22P5_DELAY,
261 DQS_DLL_45_DELAY,
262 DQS_DLL_67P5_DELAY,
263 DQS_DLL_90_DELAY,
264 DQS_DLL_112P5_DELAY,
265 DQS_DLL_135_DELAY,
266 DQS_DLL_157P5_DELAY,
267};
268
269/* GRF_OS_REG1 */
270enum {
271 /*
272 * 000: lpddr
273 * 001: ddr
274 * 010: ddr2
275 * 011: ddr3
276 * 100: lpddr2-s2
277 * 101: lpddr2-s4
278 * 110: lpddr3
279 */
280 DDR_TYPE_MASK = 7,
281 DDR_TYPE_SHIFT = 13,
282
283 /* 0: 1 chn, 1: 2 chn */
284 DDR_CHN_CNT_SHIFT = 12,
285
286 /* 0: 1 rank, 1: 2 rank */
287 DDR_RANK_CNT_MASK = 1,
288 DDR_RANK_CNT_SHIFT = 11,
289
290 /*
291 * 00: 9col
292 * 01: 10col
293 * 10: 11col
294 * 11: 12col
295 */
296 DDR_COL_MASK = 3,
297 DDR_COL_SHIFT = 9,
298
299 /* 0: 8 bank, 1: 4 bank*/
300 DDR_BANK_MASK = 1,
301 DDR_BANK_SHIFT = 8,
302
303 /*
304 * 00: 13 row
305 * 01: 14 row
306 * 10: 15 row
307 * 11: 16 row
308 */
309 DDR_CS0_ROW_MASK = 3,
310 DDR_CS0_ROW_SHIFT = 6,
311 DDR_CS1_ROW_MASK = 3,
312 DDR_CS1_ROW_SHIFT = 4,
313
314 /*
315 * 00: 32 bit
316 * 01: 16 bit
317 * 10: 8 bit
318 * rk3036 only support 16bit
319 */
320 DDR_BW_MASK = 3,
321 DDR_BW_SHIFT = 2,
322 DDR_DIE_BW_MASK = 3,
323 DDR_DIE_BW_SHIFT = 0,
324};
325
326static void rkdclk_init(struct rk3036_sdram_priv *priv)
327{
328 struct rk3036_pll *pll = &priv->cru->pll[1];
329
330 /* pll enter slow-mode */
Kever Yangf6019302017-11-30 16:51:20 +0800331 rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
huang linda98a5b2015-11-17 14:20:26 +0800332 DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
333
334 /* use integer mode */
Kever Yang2fe4e512017-11-30 16:51:21 +0800335 rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
huang linda98a5b2015-11-17 14:20:26 +0800336
337 rk_clrsetreg(&pll->con0,
Kever Yangf6019302017-11-30 16:51:20 +0800338 PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
huang linda98a5b2015-11-17 14:20:26 +0800339 (dpll_init_cfg.postdiv1 << PLL_POSTDIV1_SHIFT) |
340 dpll_init_cfg.fbdiv);
Kever Yangf6019302017-11-30 16:51:20 +0800341 rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
342 (dpll_init_cfg.postdiv2 << PLL_POSTDIV2_SHIFT |
343 dpll_init_cfg.refdiv << PLL_REFDIV_SHIFT));
huang linda98a5b2015-11-17 14:20:26 +0800344
345 /* waiting for pll lock */
346 while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
Kever Yang0a778db2019-07-09 22:00:24 +0800347 udelay(1);
huang linda98a5b2015-11-17 14:20:26 +0800348
349 /* PLL enter normal-mode */
Kever Yangf6019302017-11-30 16:51:20 +0800350 rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
huang linda98a5b2015-11-17 14:20:26 +0800351 DPLL_MODE_NORM << DPLL_MODE_SHIFT);
352}
353
354static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
355{
356 int i;
357
358 for (i = 0; i < n / sizeof(u32); i++) {
359 writel(*src, dest);
360 src++;
361 dest++;
362 }
363}
364
365void phy_pctrl_reset(struct rk3036_sdram_priv *priv)
366{
367 struct rk3036_ddr_phy *ddr_phy = priv->phy;
368
369 rk_clrsetreg(&priv->cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
370 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
371 1 << DDRPHY_SRST_SHIFT,
372 1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
373 1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
374
Kever Yang0a778db2019-07-09 22:00:24 +0800375 udelay(10);
huang linda98a5b2015-11-17 14:20:26 +0800376
377 rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
378 1 << DDRPHY_SRST_SHIFT);
Kever Yang0a778db2019-07-09 22:00:24 +0800379 udelay(10);
huang linda98a5b2015-11-17 14:20:26 +0800380
381 rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
382 1 << DDRCTRL_SRST_SHIFT);
Kever Yang0a778db2019-07-09 22:00:24 +0800383 udelay(10);
huang linda98a5b2015-11-17 14:20:26 +0800384
385 clrsetbits_le32(&ddr_phy->ddrphy_reg1,
386 SOFT_RESET_MASK << SOFT_RESET_SHIFT,
387 0 << SOFT_RESET_SHIFT);
Kever Yang0a778db2019-07-09 22:00:24 +0800388 udelay(10);
huang linda98a5b2015-11-17 14:20:26 +0800389 clrsetbits_le32(&ddr_phy->ddrphy_reg1,
390 SOFT_RESET_MASK << SOFT_RESET_SHIFT,
391 3 << SOFT_RESET_SHIFT);
392
Kever Yang0a778db2019-07-09 22:00:24 +0800393 udelay(1);
huang linda98a5b2015-11-17 14:20:26 +0800394}
395
396void phy_dll_bypass_set(struct rk3036_sdram_priv *priv, unsigned int freq)
397{
398 struct rk3036_ddr_phy *ddr_phy = priv->phy;
399
400 if (freq < ddr_timing.freq) {
401 writel(CMD_DLL_BYPASS | HIGH_8BIT_DLL_BYPASS |
402 LOW_8BIT_DLL_BYPASS, &ddr_phy->ddrphy_reg2a);
403
404 writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_90 |
405 LEFT_CHN_TX_DQ_DLL_ENABLE |
406 (0 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
407 LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg6);
408
409 writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 |
410 RIGHT_CHN_TX_DQ_DLL_ENABLE |
411 (0 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
412 RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
413 &ddr_phy->ddrphy_reg9);
414 } else {
415 writel(CMD_DLL_BYPASS_DISABLE | HIGH_8BIT_DLL_BYPASS_DISABLE |
416 LOW_8BIT_DLL_BYPASS_DISABLE, &ddr_phy->ddrphy_reg2a);
417
418 writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_0 |
419 LEFT_CHN_TX_DQ_DLL_ENABLE |
420 (4 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
421 LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT,
422 &ddr_phy->ddrphy_reg6);
423
424 writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 |
425 RIGHT_CHN_TX_DQ_DLL_ENABLE |
426 (4 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
427 RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
428 &ddr_phy->ddrphy_reg9);
429 }
430
431 writel(CMD_SLAVE_DLL_NO_INVERSE_MODE | CMD_SLAVE_DLL_ENALBE |
432 (0 & CMD_TX_SLAVE_DLL_DELAY_MASK) <<
433 CMD_TX_SLAVE_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg19);
434
435 /* 45 degree delay */
436 writel((DQS_DLL_45_DELAY & LEFT_CHN_RX_DQS_DELAY_TAP_MASK) <<
437 LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg8);
438 writel((DQS_DLL_45_DELAY & RIGHT_CHN_RX_DQS_DELAY_TAP_MASK) <<
439 RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg11);
440}
441
442static void send_command(struct rk3036_ddr_pctl *pctl,
443 u32 rank, u32 cmd, u32 arg)
444{
445 writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
Kever Yang0a778db2019-07-09 22:00:24 +0800446 udelay(1);
huang linda98a5b2015-11-17 14:20:26 +0800447 while (readl(&pctl->mcmd) & START_CMD)
448 ;
449}
450
451static void memory_init(struct rk3036_sdram_priv *priv)
452{
453 struct rk3036_ddr_pctl *pctl = priv->pctl;
454
455 send_command(pctl, 3, DESELECT_CMD, 0);
Kever Yang0a778db2019-07-09 22:00:24 +0800456 udelay(1);
huang linda98a5b2015-11-17 14:20:26 +0800457 send_command(pctl, 3, PREA_CMD, 0);
458 send_command(pctl, 3, MRS_CMD,
459 (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
460 (ddr_timing.phy_timing.mr[2] & CMD_ADDR_MASK) <<
461 CMD_ADDR_SHIFT);
462
463 send_command(pctl, 3, MRS_CMD,
464 (0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
465 (ddr_timing.phy_timing.mr[3] & CMD_ADDR_MASK) <<
466 CMD_ADDR_SHIFT);
467
468 send_command(pctl, 3, MRS_CMD,
469 (0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
470 (ddr_timing.phy_timing.mr[1] & CMD_ADDR_MASK) <<
471 CMD_ADDR_SHIFT);
472
473 send_command(pctl, 3, MRS_CMD,
474 (0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
475 (ddr_timing.phy_timing.mr[0] & CMD_ADDR_MASK) <<
476 CMD_ADDR_SHIFT | DDR3_DLL_RESET);
477
478 send_command(pctl, 3, ZQCL_CMD, 0);
479}
480
481static void data_training(struct rk3036_sdram_priv *priv)
482{
483 struct rk3036_ddr_phy *ddr_phy = priv->phy;
484 struct rk3036_ddr_pctl *pctl = priv->pctl;
485 u32 value;
486
487 /* disable auto refresh */
488 value = readl(&pctl->trefi),
489 writel(0, &pctl->trefi);
490
491 clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
492 DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_CAL_START);
493
Kever Yang0a778db2019-07-09 22:00:24 +0800494 udelay(1);
huang linda98a5b2015-11-17 14:20:26 +0800495 while ((readl(&ddr_phy->ddrphy_reg62) & CAL_DONE_MASK) !=
496 (HIGH_8BIT_CAL_DONE | LOW_8BIT_CAL_DONE)) {
497 ;
498 }
499
500 clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
501 DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_NO_CAL);
502
503 /*
504 * since data training will take about 20us, so send some auto
505 * refresh(about 7.8us) to complement the lost time
506 */
507 send_command(pctl, 3, REF_CMD, 0);
508 send_command(pctl, 3, REF_CMD, 0);
509 send_command(pctl, 3, REF_CMD, 0);
510
511 writel(value, &pctl->trefi);
512}
513
514static void move_to_config_state(struct rk3036_sdram_priv *priv)
515{
516 unsigned int state;
517 struct rk3036_ddr_pctl *pctl = priv->pctl;
518
519 while (1) {
520 state = readl(&pctl->stat) & PCTL_STAT_MASK;
521 switch (state) {
522 case LOW_POWER:
523 writel(WAKEUP_STATE, &pctl->sctl);
524 while ((readl(&pctl->stat) & PCTL_STAT_MASK)
525 != ACCESS)
526 ;
527 /*
528 * If at low power state, need wakeup first, and then
529 * enter the config, so fallthrough
530 */
531 case ACCESS:
532 /* fallthrough */
533 case INIT_MEM:
534 writel(CFG_STATE, &pctl->sctl);
535 while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
536 ;
537 break;
538 case CONFIG:
539 return;
540 default:
541 break;
542 }
543 }
544}
545
546static void move_to_access_state(struct rk3036_sdram_priv *priv)
547{
548 unsigned int state;
549 struct rk3036_ddr_pctl *pctl = priv->pctl;
550
551 while (1) {
552 state = readl(&pctl->stat) & PCTL_STAT_MASK;
553 switch (state) {
554 case LOW_POWER:
555 writel(WAKEUP_STATE, &pctl->sctl);
556 while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
557 ;
558 break;
559 case INIT_MEM:
560 writel(CFG_STATE, &pctl->sctl);
561 while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
562 ;
563 /* fallthrough */
564 case CONFIG:
565 writel(GO_STATE, &pctl->sctl);
566 while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
567 ;
568 break;
569 case ACCESS:
570 return;
571 default:
572 break;
573 }
574 }
575}
576
577static void pctl_cfg(struct rk3036_sdram_priv *priv)
578{
579 struct rk3036_ddr_pctl *pctl = priv->pctl;
580 u32 burst_len;
581 u32 reg;
582
583 writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &pctl->dfistcfg0);
584 writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, &pctl->dfistcfg1);
585 writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
586 writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
587 &pctl->dfilpcfg0);
588
589 writel(1, &pctl->dfitphyupdtype0);
590 writel(0x0d, &pctl->dfitphyrdlat);
591
592 /* cs0 and cs1 write odt enable */
593 writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
594 &pctl->dfiodtcfg);
595
596 /* odt write length */
597 writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
598
599 /* phyupd and ctrlupd disabled */
600 writel(0, &pctl->dfiupdcfg);
601
602 if ((ddr_timing.noc_timing.burstlen << 1) == 4)
603 burst_len = MEM_BL4;
604 else
605 burst_len = MEM_BL8;
606
607 copy_to_reg(&pctl->togcnt1u, &ddr_timing.pctl_timing.togcnt1u,
608 sizeof(struct rk3036_pctl_timing));
609 reg = readl(&pctl->tcl);
610 writel(reg - 3, &pctl->dfitrddataen);
611 reg = readl(&pctl->tcwl);
612 writel(reg - 1, &pctl->dfitphywrlat);
613
614 writel(burst_len | (1 & TFAW_CFG_MASK) << TFAW_CFG_SHIFT |
615 PD_EXIT_SLOW_MODE | PD_ACTIVE_POWER_DOWN |
616 (0 & PD_IDLE_MASK) << PD_IDLE_SHIFT,
617 &pctl->mcfg);
618
619 writel(RK_SETBITS(MSCH4_MAINDDR3), &priv->grf->soc_con2);
620 setbits_le32(&pctl->scfg, HW_LOW_POWER_EN);
621}
622
623static void phy_cfg(struct rk3036_sdram_priv *priv)
624{
625 struct rk3036_ddr_phy *ddr_phy = priv->phy;
626 struct rk3036_service_sys *axi_bus = priv->axi_bus;
627
628 writel(ddr_timing.noc_timing.noc_timing, &axi_bus->ddrtiming);
629 writel(0x3f, &axi_bus->readlatency);
630
631 writel(MEMORY_SELECT_DDR3 | DQS_SQU_CAL_NORMAL_MODE,
632 &ddr_phy->ddrphy_reg2);
633
634 clrsetbits_le32(&ddr_phy->ddrphy_reg3, 1, ddr_timing.phy_timing.bl);
635 writel(ddr_timing.phy_timing.cl_al, &ddr_phy->ddrphy_reg4a);
636 writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg16);
637 writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg22);
638 writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg25);
639 writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg26);
640 writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg27);
641 writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg28);
642}
643
644void dram_cfg_rbc(struct rk3036_sdram_priv *priv)
645{
646 char noc_config;
647 int i = 0;
648 struct rk3036_ddr_config config = priv->ddr_config;
649 struct rk3036_service_sys *axi_bus = priv->axi_bus;
650
651 move_to_config_state(priv);
652
653 /* 2bit in BIT1, 2 */
654 if (config.rank == 2) {
655 noc_config = (config.cs0_row - 13) << 4 | config.bank << 1 |
656 1 << 3 | (config.col - 10);
657 if (noc_config == ddr_cfg_2_rbc[9]) {
658 i = 9;
659 goto finish;
660 } else if (noc_config == ddr_cfg_2_rbc[10]) {
661 i = 10;
662 goto finish;
663 }
664 }
665
666 noc_config = (config.cs0_row - 13) << 4 | config.bank << 1 |
667 (config.col - 10);
668
669 for (i = 0; i < sizeof(ddr_cfg_2_rbc); i++) {
670 if (noc_config == ddr_cfg_2_rbc[i])
671 goto finish;
672 }
673
674 /* bank: 1 bit in BIT6,7, 1bit in BIT1, 2 */
675 noc_config = 1 << 6 | (config.cs0_row - 13) << 4 |
676 2 << 1 | (config.col - 10);
677 if (noc_config == ddr_cfg_2_rbc[11]) {
678 i = 11;
679 goto finish;
680 }
681
682 /* bank: 2bit in BIT6,7 */
683 noc_config = (config.bank << 6) | (config.cs0_row - 13) << 4 |
684 (config.col - 10);
685
686 if (noc_config == ddr_cfg_2_rbc[0])
687 i = 0;
688 else if (noc_config == ddr_cfg_2_rbc[12])
689 i = 12;
690 else if (noc_config == ddr_cfg_2_rbc[13])
691 i = 13;
692finish:
693 writel(i, &axi_bus->ddrconf);
694 move_to_access_state(priv);
695}
696
697static void sdram_all_config(struct rk3036_sdram_priv *priv)
698{
699 u32 os_reg = 0;
huang lin69917382015-12-07 11:08:56 +0800700 u32 cs1_row = 0;
huang linda98a5b2015-11-17 14:20:26 +0800701 struct rk3036_ddr_config config = priv->ddr_config;
702
huang lin69917382015-12-07 11:08:56 +0800703 if (config.rank > 1)
704 cs1_row = config.cs1_row - 13;
705
huang linda98a5b2015-11-17 14:20:26 +0800706 os_reg = config.ddr_type << DDR_TYPE_SHIFT |
707 0 << DDR_CHN_CNT_SHIFT |
708 (config.rank - 1) << DDR_RANK_CNT_SHIFT |
Kever Yange71e2482017-06-13 16:10:46 +0800709 (config.col - 9) << DDR_COL_SHIFT |
huang linda98a5b2015-11-17 14:20:26 +0800710 (config.bank == 3 ? 0 : 1) << DDR_BANK_SHIFT |
711 (config.cs0_row - 13) << DDR_CS0_ROW_SHIFT |
huang lin69917382015-12-07 11:08:56 +0800712 cs1_row << DDR_CS1_ROW_SHIFT |
Kever Yange71e2482017-06-13 16:10:46 +0800713 1 << DDR_BW_SHIFT |
714 (2 >> config.bw) << DDR_DIE_BW_SHIFT;
huang linda98a5b2015-11-17 14:20:26 +0800715 writel(os_reg, &priv->grf->os_reg[1]);
716}
717
718size_t sdram_size(void)
719{
720 u32 size, os_reg, cs0_row, cs1_row, col, bank, rank;
721 struct rk3036_grf *grf = (void *)GRF_BASE;
722
723 os_reg = readl(&grf->os_reg[1]);
724
725 cs0_row = 13 + ((os_reg >> DDR_CS0_ROW_SHIFT) & DDR_CS0_ROW_MASK);
726 cs1_row = 13 + ((os_reg >> DDR_CS1_ROW_SHIFT) & DDR_CS1_ROW_MASK);
727 col = 9 + ((os_reg >> DDR_COL_SHIFT) & DDR_COL_MASK);
728 bank = 3 - ((os_reg >> DDR_BANK_SHIFT) & DDR_BANK_MASK);
729 rank = 1 + ((os_reg >> DDR_RANK_CNT_SHIFT) & DDR_RANK_CNT_MASK);
730
731 /* row + col + bank + bw(rk3036 only support 16bit, so fix in 1) */
732 size = 1 << (cs0_row + col + bank + 1);
733
734 if (rank > 1)
735 size += size >> (cs0_row - cs1_row);
736
737 return size;
738}
739
740void sdram_init(void)
741{
742 struct rk3036_sdram_priv sdram_priv;
743
744 sdram_priv.cru = (void *)CRU_BASE;
745 sdram_priv.grf = (void *)GRF_BASE;
746 sdram_priv.phy = (void *)DDR_PHY_BASE;
747 sdram_priv.pctl = (void *)DDR_PCTL_BASE;
748 sdram_priv.axi_bus = (void *)CPU_AXI_BUS_BASE;
749
750 get_ddr_config(&sdram_priv.ddr_config);
751 sdram_all_config(&sdram_priv);
752 rkdclk_init(&sdram_priv);
753 phy_pctrl_reset(&sdram_priv);
754 phy_dll_bypass_set(&sdram_priv, ddr_timing.freq);
755 pctl_cfg(&sdram_priv);
756 phy_cfg(&sdram_priv);
757 writel(POWER_UP_START, &sdram_priv.pctl->powctl);
758 while (!(readl(&sdram_priv.pctl->powstat) & POWER_UP_DONE))
759 ;
760 memory_init(&sdram_priv);
761 move_to_config_state(&sdram_priv);
762 data_training(&sdram_priv);
763 move_to_access_state(&sdram_priv);
764 dram_cfg_rbc(&sdram_priv);
765}