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