blob: d23d4231798925e2bfc58ce3d40b153da9049ea5 [file] [log] [blame]
Kever Yang6fc9ebf2018-12-20 11:33:42 +08001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
Heiko Stübner37c7cab2017-02-18 19:46:37 +01002/*
3 * (C) Copyright 2015 Google, Inc
4 * Copyright 2014 Rockchip Inc.
5 *
Heiko Stübner37c7cab2017-02-18 19:46:37 +01006 * Adapted from the very similar rk3288 ddr init.
7 */
8
9#include <common.h>
10#include <clk.h>
11#include <dm.h>
12#include <dt-structs.h>
13#include <errno.h>
Simon Glassf11478f2019-12-28 10:45:07 -070014#include <hang.h>
Simon Glass97589732020-05-10 11:40:02 -060015#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -060016#include <log.h>
Heiko Stübner37c7cab2017-02-18 19:46:37 +010017#include <ram.h>
18#include <regmap.h>
19#include <syscon.h>
20#include <asm/io.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080021#include <asm/arch-rockchip/clock.h>
22#include <asm/arch-rockchip/cru_rk3188.h>
23#include <asm/arch-rockchip/ddr_rk3188.h>
24#include <asm/arch-rockchip/grf_rk3188.h>
Quentin Schulz5e38edb2024-03-11 13:01:56 +010025#include <asm/arch-rockchip/hardware.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080026#include <asm/arch-rockchip/pmu_rk3188.h>
Kever Yange47db832019-11-15 11:04:33 +080027#include <asm/arch-rockchip/sdram.h>
Kever Yangcdbb38a2019-11-15 11:04:32 +080028#include <asm/arch-rockchip/sdram_rk3288.h>
Simon Glassdbd79542020-05-10 11:40:11 -060029#include <linux/delay.h>
Heiko Stübner37c7cab2017-02-18 19:46:37 +010030#include <linux/err.h>
31
Heiko Stübner37c7cab2017-02-18 19:46:37 +010032struct chan_info {
33 struct rk3288_ddr_pctl *pctl;
34 struct rk3288_ddr_publ *publ;
35 struct rk3188_msch *msch;
36};
37
38struct dram_info {
39 struct chan_info chan[1];
40 struct ram_info info;
41 struct clk ddr_clk;
42 struct rk3188_cru *cru;
43 struct rk3188_grf *grf;
44 struct rk3188_sgrf *sgrf;
45 struct rk3188_pmu *pmu;
46};
47
48struct rk3188_sdram_params {
49#if CONFIG_IS_ENABLED(OF_PLATDATA)
50 struct dtd_rockchip_rk3188_dmc of_plat;
51#endif
52 struct rk3288_sdram_channel ch[2];
53 struct rk3288_sdram_pctl_timing pctl_timing;
54 struct rk3288_sdram_phy_timing phy_timing;
55 struct rk3288_base_params base;
56 int num_channels;
57 struct regmap *map;
58};
59
60const int ddrconf_table[] = {
61 /*
62 * [5:4] row(13+n)
63 * [1:0] col(9+n), assume bw=2
64 * row col,bw
65 */
66 0,
67 ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
68 ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
69 ((0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
70 ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
71 ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
72 ((0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
73 ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
74 ((0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
75 0,
76 0,
77 0,
78 0,
79 0,
80 0,
81 0,
82};
83
84#define TEST_PATTEN 0x5aa5f00f
85#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
86#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
87
88#ifdef CONFIG_SPL_BUILD
89static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
90{
91 int i;
92
93 for (i = 0; i < n / sizeof(u32); i++) {
94 writel(*src, dest);
95 src++;
96 dest++;
97 }
98}
99
100static void ddr_reset(struct rk3188_cru *cru, u32 ch, u32 ctl, u32 phy)
101{
102 u32 phy_ctl_srstn_shift = 13;
103 u32 ctl_psrstn_shift = 11;
104 u32 ctl_srstn_shift = 10;
105 u32 phy_psrstn_shift = 9;
106 u32 phy_srstn_shift = 8;
107
108 rk_clrsetreg(&cru->cru_softrst_con[5],
109 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
110 1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
111 1 << phy_srstn_shift,
112 phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
113 ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
114 phy << phy_srstn_shift);
115}
116
117static void ddr_phy_ctl_reset(struct rk3188_cru *cru, u32 ch, u32 n)
118{
119 u32 phy_ctl_srstn_shift = 13;
120
121 rk_clrsetreg(&cru->cru_softrst_con[5],
122 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
123}
124
125static void phy_pctrl_reset(struct rk3188_cru *cru,
126 struct rk3288_ddr_publ *publ,
127 int channel)
128{
129 int i;
130
131 ddr_reset(cru, channel, 1, 1);
132 udelay(1);
133 clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
134 for (i = 0; i < 4; i++)
135 clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
136
137 udelay(10);
138 setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
139 for (i = 0; i < 4; i++)
140 setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
141
142 udelay(10);
143 ddr_reset(cru, channel, 1, 0);
144 udelay(10);
145 ddr_reset(cru, channel, 0, 0);
146 udelay(10);
147}
148
149static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
150 u32 freq)
151{
152 int i;
153
154 if (freq <= 250000000) {
155 if (freq <= 150000000)
156 clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
157 else
158 setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
159 setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
160 for (i = 0; i < 4; i++)
161 setbits_le32(&publ->datx8[i].dxdllcr,
162 DXDLLCR_DLLDIS);
163
164 setbits_le32(&publ->pir, PIR_DLLBYP);
165 } else {
166 clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
167 clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
168 for (i = 0; i < 4; i++) {
169 clrbits_le32(&publ->datx8[i].dxdllcr,
170 DXDLLCR_DLLDIS);
171 }
172
173 clrbits_le32(&publ->pir, PIR_DLLBYP);
174 }
175}
176
177static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
178{
179 writel(DFI_INIT_START, &pctl->dfistcfg0);
180 writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
181 &pctl->dfistcfg1);
182 writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
183 writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
184 &pctl->dfilpcfg0);
185
186 writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
187 writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
188 writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
189 writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
190 writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
191 writel(1, &pctl->dfitphyupdtype0);
192
193 /* cs0 and cs1 write odt enable */
194 writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
195 &pctl->dfiodtcfg);
196 /* odt write length */
197 writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
198 /* phyupd and ctrlupd disabled */
199 writel(0, &pctl->dfiupdcfg);
200}
201
202static void ddr_set_enable(struct rk3188_grf *grf, uint channel, bool enable)
203{
204 uint val = 0;
205
206 if (enable)
207 val = 1 << DDR_16BIT_EN_SHIFT;
208
209 rk_clrsetreg(&grf->ddrc_con0, 1 << DDR_16BIT_EN_SHIFT, val);
210}
211
212static void ddr_set_ddr3_mode(struct rk3188_grf *grf, uint channel,
213 bool ddr3_mode)
214{
215 uint mask, val;
216
217 mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
218 val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
219 rk_clrsetreg(&grf->soc_con2, mask, val);
220}
221
222static void ddr_rank_2_row15en(struct rk3188_grf *grf, bool enable)
223{
224 uint mask, val;
225
226 mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
227 val = enable << RANK_TO_ROW15_EN_SHIFT;
228 rk_clrsetreg(&grf->soc_con2, mask, val);
229}
230
231static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
232 struct rk3188_sdram_params *sdram_params,
233 struct rk3188_grf *grf)
234{
235 copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
236 sizeof(sdram_params->pctl_timing));
237 switch (sdram_params->base.dramtype) {
238 case DDR3:
239 if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
240 writel(sdram_params->pctl_timing.tcl - 3,
241 &pctl->dfitrddataen);
242 } else {
243 writel(sdram_params->pctl_timing.tcl - 2,
244 &pctl->dfitrddataen);
245 }
246 writel(sdram_params->pctl_timing.tcwl - 1,
247 &pctl->dfitphywrlat);
248 writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
249 DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
250 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
251 &pctl->mcfg);
252 ddr_set_ddr3_mode(grf, channel, true);
253 ddr_set_enable(grf, channel, true);
254 break;
255 }
256
257 setbits_le32(&pctl->scfg, 1);
258}
259
260static void phy_cfg(const struct chan_info *chan, int channel,
261 struct rk3188_sdram_params *sdram_params)
262{
263 struct rk3288_ddr_publ *publ = chan->publ;
264 struct rk3188_msch *msch = chan->msch;
265 uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
266 u32 dinit2;
267 int i;
268
269 dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
270 /* DDR PHY Timing */
271 copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
272 sizeof(sdram_params->phy_timing));
273 writel(sdram_params->base.noc_timing, &msch->ddrtiming);
274 writel(0x3f, &msch->readlatency);
275 writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
276 DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
277 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
278 writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
279 DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
280 &publ->ptr[1]);
281 writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
282 DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
283 &publ->ptr[2]);
284
285 switch (sdram_params->base.dramtype) {
286 case DDR3:
287 clrbits_le32(&publ->pgcr, 0x1f);
288 clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
289 DDRMD_DDR3 << DDRMD_SHIFT);
290 break;
291 }
292 if (sdram_params->base.odt) {
293 /*dynamic RTT enable */
294 for (i = 0; i < 4; i++)
295 setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
296 } else {
297 /*dynamic RTT disable */
298 for (i = 0; i < 4; i++)
299 clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
300 }
301}
302
303static void phy_init(struct rk3288_ddr_publ *publ)
304{
305 setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
306 | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
307 udelay(1);
308 while ((readl(&publ->pgsr) &
309 (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
310 (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
311 ;
312}
313
314static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
315 u32 cmd, u32 arg)
316{
317 writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
318 udelay(1);
319 while (readl(&pctl->mcmd) & START_CMD)
320 ;
321}
322
323static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
324 u32 rank, u32 cmd, u32 ma, u32 op)
325{
326 send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
327 (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
328}
329
330static void memory_init(struct rk3288_ddr_publ *publ,
331 u32 dramtype)
332{
333 setbits_le32(&publ->pir,
334 (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
335 | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
336 | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
337 udelay(1);
338 while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
339 != (PGSR_IDONE | PGSR_DLDONE))
340 ;
341}
342
343static void move_to_config_state(struct rk3288_ddr_publ *publ,
344 struct rk3288_ddr_pctl *pctl)
345{
346 unsigned int state;
347
348 while (1) {
349 state = readl(&pctl->stat) & PCTL_STAT_MSK;
350
351 switch (state) {
352 case LOW_POWER:
353 writel(WAKEUP_STATE, &pctl->sctl);
354 while ((readl(&pctl->stat) & PCTL_STAT_MSK)
355 != ACCESS)
356 ;
357 /* wait DLL lock */
358 while ((readl(&publ->pgsr) & PGSR_DLDONE)
359 != PGSR_DLDONE)
360 ;
361 /*
362 * if at low power state,need wakeup first,
363 * and then enter the config, so
364 * fallthrough
365 */
366 case ACCESS:
367 /* fallthrough */
368 case INIT_MEM:
369 writel(CFG_STATE, &pctl->sctl);
370 while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
371 ;
372 break;
373 case CONFIG:
374 return;
375 default:
376 break;
377 }
378 }
379}
380
381static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
382 u32 n, struct rk3188_grf *grf)
383{
384 struct rk3288_ddr_pctl *pctl = chan->pctl;
385 struct rk3288_ddr_publ *publ = chan->publ;
386 struct rk3188_msch *msch = chan->msch;
387
388 if (n == 1) {
389 setbits_le32(&pctl->ppcfg, 1);
390 ddr_set_enable(grf, channel, 1);
391 setbits_le32(&msch->ddrtiming, 1 << 31);
392 /* Data Byte disable*/
393 clrbits_le32(&publ->datx8[2].dxgcr, 1);
394 clrbits_le32(&publ->datx8[3].dxgcr, 1);
395 /* disable DLL */
396 setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
397 setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
398 } else {
399 clrbits_le32(&pctl->ppcfg, 1);
400 ddr_set_enable(grf, channel, 0);
401 clrbits_le32(&msch->ddrtiming, 1 << 31);
402 /* Data Byte enable*/
403 setbits_le32(&publ->datx8[2].dxgcr, 1);
404 setbits_le32(&publ->datx8[3].dxgcr, 1);
405
406 /* enable DLL */
407 clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
408 clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
409 /* reset DLL */
410 clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
411 clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
412 udelay(10);
413 setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
414 setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
415 }
416 setbits_le32(&pctl->dfistcfg0, 1 << 2);
417}
418
419static int data_training(const struct chan_info *chan, int channel,
420 struct rk3188_sdram_params *sdram_params)
421{
422 unsigned int j;
423 int ret = 0;
424 u32 rank;
425 int i;
426 u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
427 struct rk3288_ddr_publ *publ = chan->publ;
428 struct rk3288_ddr_pctl *pctl = chan->pctl;
429
430 /* disable auto refresh */
431 writel(0, &pctl->trefi);
432
433 if (sdram_params->base.dramtype != LPDDR3)
434 setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
435 rank = sdram_params->ch[channel].rank | 1;
436 for (j = 0; j < ARRAY_SIZE(step); j++) {
437 /*
438 * trigger QSTRN and RVTRN
439 * clear DTDONE status
440 */
441 setbits_le32(&publ->pir, PIR_CLRSR);
442
443 /* trigger DTT */
444 setbits_le32(&publ->pir,
445 PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
446 PIR_CLRSR);
447 udelay(1);
448 /* wait echo byte DTDONE */
449 while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
450 != rank)
451 ;
452 while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
453 != rank)
454 ;
455 if (!(readl(&pctl->ppcfg) & 1)) {
456 while ((readl(&publ->datx8[2].dxgsr[0])
457 & rank) != rank)
458 ;
459 while ((readl(&publ->datx8[3].dxgsr[0])
460 & rank) != rank)
461 ;
462 }
463 if (readl(&publ->pgsr) &
464 (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
465 ret = -1;
466 break;
467 }
468 }
469 /* send some auto refresh to complement the lost while DTT */
470 for (i = 0; i < (rank > 1 ? 8 : 4); i++)
471 send_command(pctl, rank, REF_CMD, 0);
472
473 if (sdram_params->base.dramtype != LPDDR3)
474 clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
475
476 /* resume auto refresh */
477 writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
478
479 return ret;
480}
481
482static void move_to_access_state(const struct chan_info *chan)
483{
484 struct rk3288_ddr_publ *publ = chan->publ;
485 struct rk3288_ddr_pctl *pctl = chan->pctl;
486 unsigned int state;
487
488 while (1) {
489 state = readl(&pctl->stat) & PCTL_STAT_MSK;
490
491 switch (state) {
492 case LOW_POWER:
493 if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
494 LP_TRIG_MASK) == 1)
495 return;
496
497 writel(WAKEUP_STATE, &pctl->sctl);
498 while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
499 ;
500 /* wait DLL lock */
501 while ((readl(&publ->pgsr) & PGSR_DLDONE)
502 != PGSR_DLDONE)
503 ;
504 break;
505 case INIT_MEM:
506 writel(CFG_STATE, &pctl->sctl);
507 while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
508 ;
509 /* fallthrough */
510 case CONFIG:
511 writel(GO_STATE, &pctl->sctl);
512 while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
513 ;
514 break;
515 case ACCESS:
516 return;
517 default:
518 break;
519 }
520 }
521}
522
523static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
524 struct rk3188_sdram_params *sdram_params)
525{
526 struct rk3288_ddr_publ *publ = chan->publ;
527
528 if (sdram_params->ch[chnum].bk == 3)
529 clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
530 1 << PDQ_SHIFT);
531 else
532 clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
533
534 writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
535}
536
537static void dram_all_config(const struct dram_info *dram,
538 struct rk3188_sdram_params *sdram_params)
539{
540 unsigned int chan;
541 u32 sys_reg = 0;
542
543 sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
544 sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
545 for (chan = 0; chan < sdram_params->num_channels; chan++) {
546 const struct rk3288_sdram_channel *info =
547 &sdram_params->ch[chan];
548
549 sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
550 sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
551 sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
552 sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
553 sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
554 sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
555 sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
556 sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
557 sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
558
559 dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
560 }
561 if (sdram_params->ch[0].rank == 2)
562 ddr_rank_2_row15en(dram->grf, 0);
563 else
564 ddr_rank_2_row15en(dram->grf, 1);
565
566 writel(sys_reg, &dram->pmu->sys_reg[2]);
567}
568
569static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
570 struct rk3188_sdram_params *sdram_params)
571{
572 int reg;
573 int need_trainig = 0;
574 const struct chan_info *chan = &dram->chan[channel];
575 struct rk3288_ddr_publ *publ = chan->publ;
576
577 ddr_rank_2_row15en(dram->grf, 0);
578
579 if (data_training(chan, channel, sdram_params) < 0) {
580 printf("first data training fail!\n");
581 reg = readl(&publ->datx8[0].dxgsr[0]);
582 /* Check the result for rank 0 */
583 if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
584 printf("data training fail!\n");
585 return -EIO;
586 }
587
588 /* Check the result for rank 1 */
589 if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
590 sdram_params->ch[channel].rank = 1;
591 clrsetbits_le32(&publ->pgcr, 0xF << 18,
592 sdram_params->ch[channel].rank << 18);
593 need_trainig = 1;
594 }
595 reg = readl(&publ->datx8[2].dxgsr[0]);
596 if (reg & (1 << 4)) {
597 sdram_params->ch[channel].bw = 1;
598 set_bandwidth_ratio(chan, channel,
599 sdram_params->ch[channel].bw,
600 dram->grf);
601 need_trainig = 1;
602 }
603 }
604 /* Assume the Die bit width are the same with the chip bit width */
605 sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
606
607 if (need_trainig &&
608 (data_training(chan, channel, sdram_params) < 0)) {
609 if (sdram_params->base.dramtype == LPDDR3) {
610 ddr_phy_ctl_reset(dram->cru, channel, 1);
611 udelay(10);
612 ddr_phy_ctl_reset(dram->cru, channel, 0);
613 udelay(10);
614 }
615 printf("2nd data training failed!");
616 return -EIO;
617 }
618
619 return 0;
620}
621
622/*
623 * Detect ram columns and rows.
624 * @dram: dram info struct
625 * @channel: channel number to handle
626 * @sdram_params: sdram parameters, function will fill in col and row values
627 *
628 * Returns 0 or negative on error.
629 */
630static int sdram_col_row_detect(struct dram_info *dram, int channel,
631 struct rk3188_sdram_params *sdram_params)
632{
633 int row, col;
634 unsigned int addr;
635 const struct chan_info *chan = &dram->chan[channel];
636 struct rk3288_ddr_pctl *pctl = chan->pctl;
637 struct rk3288_ddr_publ *publ = chan->publ;
638 int ret = 0;
639
640 /* Detect col */
641 for (col = 11; col >= 9; col--) {
Tom Rinibb4dd962022-11-16 13:10:37 -0500642 writel(0, CFG_SYS_SDRAM_BASE);
643 addr = CFG_SYS_SDRAM_BASE +
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100644 (1 << (col + sdram_params->ch[channel].bw - 1));
645 writel(TEST_PATTEN, addr);
646 if ((readl(addr) == TEST_PATTEN) &&
Tom Rinibb4dd962022-11-16 13:10:37 -0500647 (readl(CFG_SYS_SDRAM_BASE) == 0))
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100648 break;
649 }
650 if (col == 8) {
651 printf("Col detect error\n");
652 ret = -EINVAL;
653 goto out;
654 } else {
655 sdram_params->ch[channel].col = col;
656 }
657
658 ddr_rank_2_row15en(dram->grf, 1);
659 move_to_config_state(publ, pctl);
660 writel(1, &chan->msch->ddrconf);
661 move_to_access_state(chan);
662 /* Detect row, max 15,min13 in rk3188*/
663 for (row = 16; row >= 13; row--) {
Tom Rinibb4dd962022-11-16 13:10:37 -0500664 writel(0, CFG_SYS_SDRAM_BASE);
665 addr = CFG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100666 writel(TEST_PATTEN, addr);
667 if ((readl(addr) == TEST_PATTEN) &&
Tom Rinibb4dd962022-11-16 13:10:37 -0500668 (readl(CFG_SYS_SDRAM_BASE) == 0))
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100669 break;
670 }
671 if (row == 12) {
672 printf("Row detect error\n");
673 ret = -EINVAL;
674 } else {
675 sdram_params->ch[channel].cs1_row = row;
676 sdram_params->ch[channel].row_3_4 = 0;
677 debug("chn %d col %d, row %d\n", channel, col, row);
678 sdram_params->ch[channel].cs0_row = row;
679 }
680
681out:
682 return ret;
683}
684
685static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
686{
Kever Yang87e0c062017-09-25 16:33:22 +0800687 int i, tmp, size, row, ret = 0;
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100688
Kever Yang87e0c062017-09-25 16:33:22 +0800689 row = sdram_params->ch[0].cs0_row;
690 /*
691 * RK3188 share the rank and row bit15, we use same ddr config for 15bit
692 * and 16bit row
693 */
694 if (row == 16)
695 row = 15;
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100696 tmp = sdram_params->ch[0].col - 9;
697 tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
Kever Yang87e0c062017-09-25 16:33:22 +0800698 tmp |= ((row - 13) << 4);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100699 size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
700 for (i = 0; i < size; i++)
701 if (tmp == ddrconf_table[i])
702 break;
703 if (i >= size) {
704 printf("niu config not found\n");
705 ret = -EINVAL;
706 } else {
707 debug("niu config %d\n", i);
708 sdram_params->base.ddrconfig = i;
709 }
710
711 return ret;
712}
713
714static int sdram_init(struct dram_info *dram,
715 struct rk3188_sdram_params *sdram_params)
716{
717 int channel;
718 int zqcr;
719 int ret;
720
721 if ((sdram_params->base.dramtype == DDR3 &&
722 sdram_params->base.ddr_freq > 800000000)) {
723 printf("SDRAM frequency is too high!");
724 return -E2BIG;
725 }
726
727 ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
728 if (ret) {
729 printf("Could not set DDR clock\n");
730 return ret;
731 }
732
733 for (channel = 0; channel < 1; channel++) {
734 const struct chan_info *chan = &dram->chan[channel];
735 struct rk3288_ddr_pctl *pctl = chan->pctl;
736 struct rk3288_ddr_publ *publ = chan->publ;
737
738 phy_pctrl_reset(dram->cru, publ, channel);
739 phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
740
741 dfi_cfg(pctl, sdram_params->base.dramtype);
742
743 pctl_cfg(channel, pctl, sdram_params, dram->grf);
744
745 phy_cfg(chan, channel, sdram_params);
746
747 phy_init(publ);
748
749 writel(POWER_UP_START, &pctl->powctl);
750 while (!(readl(&pctl->powstat) & POWER_UP_DONE))
751 ;
752
753 memory_init(publ, sdram_params->base.dramtype);
754 move_to_config_state(publ, pctl);
755
756 /* Using 32bit bus width for detect */
757 sdram_params->ch[channel].bw = 2;
758 set_bandwidth_ratio(chan, channel,
759 sdram_params->ch[channel].bw, dram->grf);
760 /*
761 * set cs, using n=3 for detect
762 * CS0, n=1
763 * CS1, n=2
764 * CS0 & CS1, n = 3
765 */
Johan Jonker3251d3f2022-01-12 17:32:11 +0100766 sdram_params->ch[channel].rank = 2;
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100767 clrsetbits_le32(&publ->pgcr, 0xF << 18,
768 (sdram_params->ch[channel].rank | 1) << 18);
769
770 /* DS=40ohm,ODT=155ohm */
771 zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
772 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
773 0x19 << PD_OUTPUT_SHIFT;
774 writel(zqcr, &publ->zq1cr[0]);
775 writel(zqcr, &publ->zq0cr[0]);
776
777 /* Detect the rank and bit-width with data-training */
778 writel(1, &chan->msch->ddrconf);
779 sdram_rank_bw_detect(dram, channel, sdram_params);
780
781 if (sdram_params->base.dramtype == LPDDR3) {
782 u32 i;
783 writel(0, &pctl->mrrcfg0);
784 for (i = 0; i < 17; i++)
785 send_command_op(pctl, 1, MRR_CMD, i, 0);
786 }
787 writel(4, &chan->msch->ddrconf);
788 move_to_access_state(chan);
789 /* DDR3 and LPDDR3 are always 8 bank, no need detect */
790 sdram_params->ch[channel].bk = 3;
791 /* Detect Col and Row number*/
792 ret = sdram_col_row_detect(dram, channel, sdram_params);
793 if (ret)
794 goto error;
795 }
796 /* Find NIU DDR configuration */
797 ret = sdram_get_niu_config(sdram_params);
798 if (ret)
799 goto error;
800
801 dram_all_config(dram, sdram_params);
802 debug("%s done\n", __func__);
803
804 return 0;
805error:
806 printf("DRAM init failed!\n");
807 hang();
808}
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100809
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100810static int setup_sdram(struct udevice *dev)
811{
812 struct dram_info *priv = dev_get_priv(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700813 struct rk3188_sdram_params *params = dev_get_plat(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100814
815 return sdram_init(priv, params);
816}
817
Simon Glassaad29ae2020-12-03 16:55:21 -0700818static int rk3188_dmc_of_to_plat(struct udevice *dev)
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100819{
Simon Glassfa20e932020-12-03 16:55:20 -0700820 struct rk3188_sdram_params *params = dev_get_plat(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100821 int ret;
822
Simon Glass6d70ba02021-08-07 07:24:06 -0600823 if (!CONFIG_IS_ENABLED(OF_REAL))
824 return 0;
825
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100826 /* rk3188 supports only one-channel */
827 params->num_channels = 1;
Philipp Tomsich0250c232017-06-07 18:46:03 +0200828 ret = dev_read_u32_array(dev, "rockchip,pctl-timing",
829 (u32 *)&params->pctl_timing,
830 sizeof(params->pctl_timing) / sizeof(u32));
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100831 if (ret) {
832 printf("%s: Cannot read rockchip,pctl-timing\n", __func__);
833 return -EINVAL;
834 }
Philipp Tomsich0250c232017-06-07 18:46:03 +0200835 ret = dev_read_u32_array(dev, "rockchip,phy-timing",
836 (u32 *)&params->phy_timing,
837 sizeof(params->phy_timing) / sizeof(u32));
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100838 if (ret) {
839 printf("%s: Cannot read rockchip,phy-timing\n", __func__);
840 return -EINVAL;
841 }
Philipp Tomsich0250c232017-06-07 18:46:03 +0200842 ret = dev_read_u32_array(dev, "rockchip,sdram-params",
843 (u32 *)&params->base,
844 sizeof(params->base) / sizeof(u32));
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100845 if (ret) {
846 printf("%s: Cannot read rockchip,sdram-params\n", __func__);
847 return -EINVAL;
848 }
Masahiro Yamadae4873e32018-04-19 12:14:03 +0900849 ret = regmap_init_mem(dev_ofnode(dev), &params->map);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100850 if (ret)
851 return ret;
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100852
853 return 0;
854}
855#endif /* CONFIG_SPL_BUILD */
856
857#if CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glassb75b15b2020-12-03 16:55:23 -0700858static int conv_of_plat(struct udevice *dev)
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100859{
Simon Glassfa20e932020-12-03 16:55:20 -0700860 struct rk3188_sdram_params *plat = dev_get_plat(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100861 struct dtd_rockchip_rk3188_dmc *of_plat = &plat->of_plat;
862 int ret;
863
864 memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
865 sizeof(plat->pctl_timing));
866 memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
867 sizeof(plat->phy_timing));
868 memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
869 /* rk3188 supports dual-channel, set default channel num to 2 */
870 plat->num_channels = 1;
Johan Jonker2e304a22023-03-13 01:30:46 +0100871 ret = regmap_init_mem_plat(dev, of_plat->reg, sizeof(of_plat->reg[0]),
Simon Glassb75b15b2020-12-03 16:55:23 -0700872 ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100873 if (ret)
874 return ret;
875
876 return 0;
877}
878#endif
879
880static int rk3188_dmc_probe(struct udevice *dev)
881{
882#ifdef CONFIG_SPL_BUILD
Simon Glassfa20e932020-12-03 16:55:20 -0700883 struct rk3188_sdram_params *plat = dev_get_plat(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100884 struct regmap *map;
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100885 struct udevice *dev_clk;
Kever Yang6c15a542017-06-23 16:11:06 +0800886 int ret;
887#endif
888 struct dram_info *priv = dev_get_priv(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100889
Kever Yang6c15a542017-06-23 16:11:06 +0800890 priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
891
892#ifdef CONFIG_SPL_BUILD
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100893#if CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glassb75b15b2020-12-03 16:55:23 -0700894 ret = conv_of_plat(dev);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100895 if (ret)
896 return ret;
897#endif
898 map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
899 if (IS_ERR(map))
900 return PTR_ERR(map);
901 priv->chan[0].msch = regmap_get_range(map, 0);
902
903 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100904
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100905 priv->chan[0].pctl = regmap_get_range(plat->map, 0);
906 priv->chan[0].publ = regmap_get_range(plat->map, 1);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100907
908 ret = rockchip_get_clk(&dev_clk);
909 if (ret)
910 return ret;
911 priv->ddr_clk.id = CLK_DDR;
912 ret = clk_request(dev_clk, &priv->ddr_clk);
913 if (ret)
914 return ret;
915
916 priv->cru = rockchip_get_cru();
917 if (IS_ERR(priv->cru))
918 return PTR_ERR(priv->cru);
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100919 ret = setup_sdram(dev);
920 if (ret)
921 return ret;
Kever Yang6c15a542017-06-23 16:11:06 +0800922#else
Tom Rinibb4dd962022-11-16 13:10:37 -0500923 priv->info.base = CFG_SYS_SDRAM_BASE;
Kever Yang6c15a542017-06-23 16:11:06 +0800924 priv->info.size = rockchip_sdram_size(
925 (phys_addr_t)&priv->pmu->sys_reg[2]);
926#endif
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100927
928 return 0;
929}
930
931static int rk3188_dmc_get_info(struct udevice *dev, struct ram_info *info)
932{
933 struct dram_info *priv = dev_get_priv(dev);
934
935 *info = priv->info;
936
937 return 0;
938}
939
940static struct ram_ops rk3188_dmc_ops = {
941 .get_info = rk3188_dmc_get_info,
942};
943
944static const struct udevice_id rk3188_dmc_ids[] = {
945 { .compatible = "rockchip,rk3188-dmc" },
946 { }
947};
948
Walter Lozano2901ac62020-06-25 01:10:04 -0300949U_BOOT_DRIVER(rockchip_rk3188_dmc) = {
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100950 .name = "rockchip_rk3188_dmc",
951 .id = UCLASS_RAM,
952 .of_match = rk3188_dmc_ids,
953 .ops = &rk3188_dmc_ops,
954#ifdef CONFIG_SPL_BUILD
Simon Glassaad29ae2020-12-03 16:55:21 -0700955 .of_to_plat = rk3188_dmc_of_to_plat,
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100956#endif
957 .probe = rk3188_dmc_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700958 .priv_auto = sizeof(struct dram_info),
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100959#ifdef CONFIG_SPL_BUILD
Simon Glass71fa5b42020-12-03 16:55:18 -0700960 .plat_auto = sizeof(struct rk3188_sdram_params),
Heiko Stübner37c7cab2017-02-18 19:46:37 +0100961#endif
962};