7cea7b6ae38478909c7a39284e7f3c3f02bea0e6
[rpi-open-firmware.git] / sdram.c
1 /*=============================================================================
2 Copyright (C) 2016-2017 Authors of rpi-open-firmware
3 Copyright (C) 2016 Julian Brown
4 All rights reserved.
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 FILE DESCRIPTION
17 VideoCoreIV SDRAM initialization code.
18
19 =============================================================================*/
20
21 #include <lib/runtime.h>
22 #include <hardware.h>
23
24 /*
25 Registers
26 =========
27
28 SC: AC Timing (Page 202)
29 SB: ???
30 SD: AC Timing (Page 202)
31 SE: AC Timing (Page 202)
32
33 PT1:
34 Minimum Idle time after first CKE assertion
35 Minimum CKE low time after completion of power ramp
36 PT2:
37 DAI Duration
38 */
39
40 extern uint32_t g_CPUID;
41
42 #define MR_REQUEST_SUCCESS(x) ((SD_MR_TIMEOUT_SET & x) != SD_MR_TIMEOUT_SET)
43 #define MR_GET_RDATA(x) ((x & SD_MR_RDATA_SET) >> SD_MR_RDATA_LSB)
44
45 #define SIP_DEBUG(x) x
46 #define SCLKU_DEBUG(x) //SIP_DEBUG(x)
47
48 #define BIST_pvt 0x20
49 #define BIST_reset 0x10
50
51 #define PVT_calibrate_request 0x1
52
53 #define logf(fmt, ...) printf("[SDRAM:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);
54
55 uint32_t g_RAMSize = RAM_SIZE_UNKNOWN;
56
57 static const char* lpddr2_manufacturer_name(uint32_t mr) {
58 switch (mr) {
59 case 1:
60 return "Samsung";
61 case 2:
62 return "Qimonda";
63 case 3:
64 return "Elpida";
65 case 4:
66 return "Etron";
67 case 5:
68 return "Nanya";
69 case 6:
70 return "Hynix";
71 default:
72 return "Unknown";
73 }
74 }
75
76 #define MR8_DENSITY_SHIFT 0x2
77 #define MR8_DENSITY_MASK (0xF << 0x2)
78
79 static unsigned lpddr2_size(uint32_t mr) {
80 switch (mr) {
81 case 0x58:
82 return RAM_SIZE_1GB;
83 case 0x18:
84 return RAM_SIZE_512MB;
85 case 0x14:
86 return RAM_SIZE_256MB;
87 case 0x10:
88 return RAM_SIZE_128MB;
89 default:
90 return RAM_SIZE_UNKNOWN;
91 }
92 }
93
94 const char* size_to_string[] = {
95 "1GB",
96 "512MB",
97 "256MB",
98 "128MB",
99 "UNKNOWN"
100 };
101
102 /*****************************************************************************
103 * Guts
104 *****************************************************************************/
105
106 ALWAYS_INLINE inline void clkman_update_begin() {
107 CM_SDCCTL |= CM_PASSWORD | CM_SDCCTL_UPDATE_SET;
108 SCLKU_DEBUG(logf("waiting for ACCPT (%X) ...\n", CM_SDCCTL));
109 for (;;) if (CM_SDCCTL & CM_SDCCTL_ACCPT_SET) break;
110 SCLKU_DEBUG(logf("ACCPT received! (%X)\n", CM_SDCCTL));
111 }
112
113 ALWAYS_INLINE inline void clkman_update_end() {
114 CM_SDCCTL = CM_PASSWORD | (CM_SDCCTL & CM_SDCCTL_UPDATE_CLR);
115 SCLKU_DEBUG(logf("waiting for ACCPT clear (%X) ...\n", CM_SDCCTL));
116 for (;;) if ((CM_SDCCTL & CM_SDCCTL_ACCPT_SET) == 0) break;
117 SCLKU_DEBUG(logf("ACCPT cleared! (%X)\n", CM_SDCCTL));
118 }
119
120 ALWAYS_INLINE void reset_phy_dll() {
121 SIP_DEBUG(logf("resetting aphy and dphy dlls ...\n", __FUNCTION__));
122
123 /* politely tell sdc that we'll be messing with address lines */
124 APHY_CSR_PHY_BIST_CNTRL_SPR = 0x30;
125
126 DPHY_CSR_GLBL_DQ_DLL_RESET = 0x1;
127 APHY_CSR_GLBL_ADDR_DLL_RESET = 0x1;
128
129 /* stall ... */
130 SD_CS;
131 SD_CS;
132 SD_CS;
133 SD_CS;
134
135 DPHY_CSR_GLBL_DQ_DLL_RESET = 0x0;
136 APHY_CSR_GLBL_ADDR_DLL_RESET = 0x0;
137
138 SIP_DEBUG(logf("waiting for dphy master dll to lock ...\n", __FUNCTION__));
139 for (;;) if ((DPHY_CSR_GLBL_MSTR_DLL_LOCK_STAT & 0xFFFF) == 0xFFFF) break;
140 SIP_DEBUG(logf("dphy master dll locked!\n", __FUNCTION__));
141 }
142
143 typedef struct {
144 uint32_t max_freq;
145 uint32_t RL;
146 uint32_t tRPab;
147 uint32_t tRPpb;
148 uint32_t tRCD;
149 uint32_t tWR;
150 uint32_t tRASmin;
151 uint32_t tRRD;
152 uint32_t tWTR;
153 uint32_t tXSR;
154 uint32_t tXP;
155 uint32_t tRFCab;
156 uint32_t tRTP;
157 uint32_t tCKE;
158 uint32_t tCKESR;
159 uint32_t tDQSCKMAXx2;
160 uint32_t tRASmax;
161 uint32_t tFAW;
162 uint32_t tRC;
163 uint32_t tREFI;
164
165 uint32_t tINIT1;
166 uint32_t tINIT3;
167 uint32_t tINIT5;
168
169 uint32_t rowbits;
170 uint32_t colbits;
171 uint32_t banklow;
172 } lpddr2_timings_t;
173
174 // 7.8 / (1.0 / 400)
175
176 lpddr2_timings_t g_InitSdramParameters = {
177 /* SA (us) */
178 .tREFI = 3113, //Refresh rate: 3113 * (1.0 / 400) = 7.78us
179 /* SC (ns) */
180 .tRFCab = 50,
181 .tRRD = 2,
182 .tWR = 7,
183 .tWTR = 4,
184 /* SD (ns) */
185 .tRPab = 7,
186 .tRC = 24,
187 .tXP = 1,
188 .tRASmin = 15,
189 .tRPpb = 6,
190 .tRCD = 6,
191 /* SE (ns) */
192 .tFAW = 18,
193 .tRTP = 1,
194 .tXSR = 54,
195 /* PT */
196 .tINIT1 = 40, // Minimum CKE low time after completion of power ramp: 40 * (1.0 / 0.4) = 100ns
197 .tINIT3 = 79800, // Minimum Idle time after first CKE assertion: 79800 * (1.0 / 400) = 199.5us ~ 200us
198 .tINIT5 = 3990, //Max DAI: 3990* (1.0 / 400) = 9.9us ~ 10us
199 /* SB */
200 .rowbits = 2,
201 .colbits = 1,
202 .banklow = 2
203 };
204
205 void reset_with_timing(lpddr2_timings_t* T) {
206 uint32_t ctrl = 0x4;
207
208 SD_CS = (SD_CS & ~(SD_CS_DEL_KEEP_SET|SD_CS_DPD_SET|SD_CS_RESTRT_SET)) | SD_CS_STBY_SET;
209
210 /* wait for SDRAM controller to go down */
211 SIP_DEBUG(logf("waiting for SDRAM controller to go down (%X) ...\n", SD_CS));
212 for (;;) if ((SD_CS & SD_CS_SDUP_SET) == 0) break;
213 SIP_DEBUG(logf("SDRAM controller down!\n"));
214
215 /* disable SDRAM clock */
216 clkman_update_begin();
217 CM_SDCCTL = (CM_SDCCTL & ~(CM_SDCCTL_ENAB_SET|CM_SDCCTL_CTRL_SET)) | CM_PASSWORD;
218 clkman_update_end();
219
220 SIP_DEBUG(logf("SDRAM clock disabled!\n"));
221
222 /*
223 * Migrate over to master PLL.
224 */
225
226 APHY_CSR_DDR_PLL_PWRDWN = 0;
227 APHY_CSR_DDR_PLL_GLOBAL_RESET = 0;
228 APHY_CSR_DDR_PLL_POST_DIV_RESET = 0;
229
230 /* 400MHz */
231 APHY_CSR_DDR_PLL_VCO_FREQ_CNTRL0 = (1 << 16) | 0x53;
232 APHY_CSR_DDR_PLL_VCO_FREQ_CNTRL1 = 0;
233 APHY_CSR_DDR_PLL_MDIV_VALUE = 0;
234
235 APHY_CSR_DDR_PLL_GLOBAL_RESET = 1;
236
237 SIP_DEBUG(logf("waiting for master ddr pll to lock ...\n"));
238 for (;;) if (APHY_CSR_DDR_PLL_LOCK_STATUS & (1 << 16)) break;
239 SIP_DEBUG(logf("master ddr pll locked!\n"));
240
241 APHY_CSR_DDR_PLL_POST_DIV_RESET = 1;
242
243 clkman_update_begin();
244 CM_SDCCTL = CM_PASSWORD | (ctrl << CM_SDCCTL_CTRL_LSB) | (CM_SDCCTL & CM_SDCCTL_CTRL_CLR);
245 clkman_update_end();
246
247 SD_SA =
248 (T->tREFI << SD_SA_RFSH_T_LSB)
249 | SD_SA_PGEHLDE_SET
250 | SD_SA_CLKSTOP_SET
251 | SD_SA_POWSAVE_SET
252 | 0x3214;
253
254 SD_SB =
255 SD_SB_REORDER_SET
256 | (T->banklow << SD_SB_BANKLOW_LSB)
257 | SD_SB_EIGHTBANK_SET
258 | (T->rowbits << SD_SB_ROWBITS_LSB)
259 | (T->colbits << SD_SB_COLBITS_LSB);
260
261 logf("SDRAM Addressing Mode: Bank=%d Row=%d Col=%d SB=0x%X\n", T->banklow, T->rowbits, T->colbits, SD_SB);
262
263 SD_SC =
264 (T->tRFCab << SD_SC_T_RFC_LSB)
265 | (T->tRRD << SD_SC_T_RRD_LSB)
266 | (T->tWR << SD_SC_T_WR_LSB)
267 | (T->tWTR << SD_SC_T_WTR_LSB)
268 | (3 << SD_SC_WL_LSB);
269
270 SD_SD =
271 (T->tRPab << SD_SD_T_RPab_LSB)
272 | (T->tRC << SD_SD_T_RC_LSB)
273 | (T->tXP << SD_SD_T_XP_LSB)
274 | (T->tRASmin << SD_SD_T_RAS_LSB)
275 | (T->tRPpb << SD_SD_T_RPpb_LSB)
276 | (T->tRCD << SD_SD_T_RCD_LSB);
277
278 SD_SE =
279 (1 << SD_SE_RL_EN_LSB)
280 | (4 << SD_SE_RL_LSB)
281 | (T->tFAW << SD_SE_T_FAW_LSB)
282 | (T->tRTP << SD_SE_T_RTP_LSB)
283 | (T->tXSR << SD_SE_T_XSR_LSB);
284
285 SD_PT1 =
286 (T->tINIT3 << SD_PT1_T_INIT3_LSB)
287 | (T->tINIT1 << SD_PT1_T_INIT1_LSB);
288
289 SD_PT2 =
290 T->tINIT5 << SD_PT2_T_INIT5_LSB;
291
292 SD_MRT =
293 0x3 << SD_MRT_T_MRW_LSB;
294
295 reset_phy_dll();
296
297 /* wait for address line pll to come back */
298 SIP_DEBUG(logf("waiting for address dll to lock ...\n"));
299 for (;;) if (APHY_CSR_GLBL_ADR_DLL_LOCK_STAT == 3) break;
300 SIP_DEBUG(logf("address dll locked!\n"));
301
302 /* tell sdc we're done messing with address lines */
303 APHY_CSR_PHY_BIST_CNTRL_SPR = 0x0;
304
305 /* woo, turn on sdram! */
306 SD_CS =
307 (((4 << SD_CS_ASHDN_T_LSB)
308 | SD_CS_STATEN_SET
309 | SD_CS_EN_SET)
310 & ~(SD_CS_STOP_SET|SD_CS_STBY_SET)) | SD_CS_RESTRT_SET;
311 }
312
313 unsigned int read_mr(unsigned int addr) {
314 while ((SD_MR & SD_MR_DONE_SET) != SD_MR_DONE_SET) {}
315 SD_MR = addr & 0xFF;
316 unsigned int mrr;
317 while (((mrr = SD_MR) & SD_MR_DONE_SET) != SD_MR_DONE_SET) {}
318 return mrr;
319 }
320
321 unsigned int write_mr(unsigned int addr, unsigned int data, bool wait) {
322 while ((SD_MR & SD_MR_DONE_SET) != SD_MR_DONE_SET) {}
323
324 SD_MR = (addr & 0xFF) | ((data & 0xFF) << 8) | SD_MR_RW_SET;
325
326 if (wait) {
327 unsigned int mrr;
328 while (((mrr = SD_MR) & SD_MR_DONE_SET) != SD_MR_DONE_SET) {}
329
330 if (mrr & SD_MR_TIMEOUT_SET)
331 panic("MR write timed out (addr=%d data=0x%X)", addr, data);
332
333 return mrr;
334 } else {
335 return 0;
336 }
337 }
338
339 void reset_phy() {
340 logf("%s: resetting SDRAM PHY ...\n", __FUNCTION__);
341
342 /* reset PHYC */
343 SD_PHYC = SD_PHYC_PHYRST_SET;
344 udelay(64);
345 SD_PHYC = 0;
346
347 logf("%s: resetting DPHY CTRL ...\n", __FUNCTION__);
348
349 DPHY_CSR_DQ_PHY_MISC_CTRL = 0x7;
350 DPHY_CSR_DQ_PAD_MISC_CTRL = 0x0;
351 DPHY_CSR_BOOT_READ_DQS_GATE_CTRL = 0x11;
352
353 reset_phy_dll();
354
355 APHY_CSR_PHY_BIST_CNTRL_SPR = 0x0;
356 }
357
358 static void switch_to_cprman_clock(unsigned int source, unsigned int div) {
359 CM_SDCDIV = CM_PASSWORD | (div << CM_SDCDIV_DIV_LSB);
360 CM_SDCCTL = CM_PASSWORD | (CM_SDCCTL & CM_SDCCTL_SRC_CLR) | source;
361 CM_SDCCTL |= CM_PASSWORD | CM_SDCCTL_ENAB_SET;
362
363 logf("switching sdram to cprman clock (src=%d, div=%d), waiting for busy (%X) ...\n", source, div, CM_SDCCTL);
364
365 for (;;) if (CM_SDCCTL & CM_SDCCTL_BUSY_SET) break;
366
367 logf("busy set, switch complete!\n");
368 }
369
370 static void init_clkman() {
371 uint32_t ctrl = 0;
372
373 clkman_update_begin();
374 CM_SDCCTL = CM_PASSWORD | (ctrl << CM_SDCCTL_CTRL_LSB) | (CM_SDCCTL & CM_SDCCTL_CTRL_CLR);
375 clkman_update_end();
376 }
377
378 #define CALL_INIT_CLKMAN init_clkman();
379
380
381 /*****************************************************************************
382 * Calibration
383 *****************************************************************************/
384
385 static void calibrate_pvt_early() {
386 /* some hw revisions require different slews */
387 bool st = ((g_CPUID >> 4) & 0xFFF) == 0x14;
388 uint32_t dq_slew = (st ? 2 : 3);
389
390 /* i don't get it, the spec says do not use this register */
391 write_mr(0xFF, 0, true);
392 /* RL = 6 / WL = 3 */
393 write_mr(LPDDR2_MR_DEVICE_FEATURE_2, 4, true);
394
395 APHY_CSR_ADDR_PAD_DRV_SLEW_CTRL = 0x333;
396 DPHY_CSR_DQ_PAD_DRV_SLEW_CTRL = (dq_slew << 8) | (dq_slew << 4) | 3;
397
398 logf("DPHY_CSR_DQ_PAD_DRV_SLEW_CTRL = 0x%X\n", DPHY_CSR_DQ_PAD_DRV_SLEW_CTRL);
399
400 /* tell sdc we want to calibrate */
401 APHY_CSR_PHY_BIST_CNTRL_SPR = BIST_pvt;
402
403 /* pvt compensation */
404 APHY_CSR_ADDR_PVT_COMP_CTRL = PVT_calibrate_request;
405 logf("waiting for address PVT calibration ...\n");
406 for (;;) if (APHY_CSR_ADDR_PVT_COMP_STATUS & 2) break;
407
408 DPHY_CSR_DQ_PVT_COMP_CTRL = PVT_calibrate_request;
409 logf("waiting for data PVT calibration ...\n");
410 for (;;) if (DPHY_CSR_DQ_PVT_COMP_STATUS & 2) break;
411
412 /* tell sdc we're done calibrating */
413 APHY_CSR_PHY_BIST_CNTRL_SPR = 0x0;
414
415 /* send calibration command */
416 uint32_t old_mrt = SD_MRT;
417 SD_MRT = 20;
418 logf("waiting for SDRAM calibration command ...\n");
419 SD_MR = LPDDR2_MR_CALIBRATION | (0xFF << 8) | SD_MR_RW_SET | SD_MR_HI_Z_SET;
420 while ((SD_MR & SD_MR_DONE_SET) != SD_MR_DONE_SET) {}
421 SD_MRT = old_mrt;
422
423 write_mr(LPDDR2_MR_IO_CONFIG, st ? 3 : 2, false);
424 }
425
426
427 /*****************************************************************************
428 * Late init
429 *****************************************************************************/
430
431 static void init_late() {
432 }
433
434 /*****************************************************************************
435 * Self-test
436 *****************************************************************************/
437
438 #define RT_BASE 0xC0000000
439
440 #define RT_PAT0 0xAAAAAAAA
441 #define RT_PAT1 0xFF00AA00
442 #define RT_PAT2 0x99999999
443
444 #define RT_ASSERT(i_, expected) \
445 if (ram[(i_)] != expected) { \
446 logf("ERROR: At 0x%X, was expecting 0x%X from read, got 0x%X instead!\n", \
447 (uint32_t)&ram[(i_)], \
448 expected, \
449 ram[(i_)]); \
450 panic("SDRAM self test failed!"); \
451 }
452
453 static void selftest_at(uint32_t addr) {
454 volatile uint32_t* ram = (volatile uint32_t*)addr;
455
456 logf("Testing region at 0x%X ...\n", addr);
457
458 for (int i = 0; i < 0x1000; i += 4) {
459 ram[i] = RT_PAT0;
460 ram[i + 1] = RT_PAT1;
461 ram[i + 2] = RT_PAT2;
462 ram[i + 3] = RT_PAT0;
463 }
464
465 for (int i = 0; i < 0x1000; i += 4) {
466 RT_ASSERT(i, RT_PAT0);
467 RT_ASSERT(i + 1, RT_PAT1);
468 RT_ASSERT(i + 2, RT_PAT2);
469 RT_ASSERT(i + 3, RT_PAT0);
470 }
471 }
472
473 static void selftest() {
474 logf("Starting self test ...\n");
475
476 selftest_at(RT_BASE);
477
478 if (g_RAMSize == RAM_SIZE_256MB || g_RAMSize == RAM_SIZE_512MB || g_RAMSize == RAM_SIZE_1GB) {
479 selftest_at(RT_BASE + 0xFF00000);
480 }
481 if (g_RAMSize == RAM_SIZE_512MB || g_RAMSize == RAM_SIZE_1GB) {
482 selftest_at(RT_BASE + 0x1FF00000);
483 }
484 if (g_RAMSize == RAM_SIZE_1GB) {
485 selftest_at(RT_BASE + 0x2FF00000);
486 selftest_at(RT_BASE + 0x3FF00000);
487 }
488
489 logf("Self test successful!\n");
490 }
491
492 #undef RT_ASSERT
493
494 void sdram_init() {
495 uint32_t vendor_id, bc;
496
497 logf("(0) SD_CS = 0x%X\n", SD_CS);
498
499 PM_SMPS = PM_PASSWORD | 0x1;
500 A2W_SMPS_LDO1 = A2W_PASSWORD | 0x40000;
501 A2W_SMPS_LDO0 = A2W_PASSWORD | 0x0;
502
503 A2W_XOSC_CTRL |= A2W_PASSWORD | A2W_XOSC_CTRL_DDREN_SET;
504
505 /*
506 * STEP 1:
507 * configure the low-frequency PLL and enable SDC and perform
508 * the calibration sequence.
509 */
510
511 switch_to_cprman_clock(CM_SRC_OSC, 1);
512
513 CALL_INIT_CLKMAN;
514
515 reset_phy();
516
517 /* magic values */
518 SD_SA = 0x006E3395;
519 SD_SB = 0x0F9;
520 SD_SC = 0x6000431;
521 SD_SD = 0x10000011;
522 SD_SE = 0x10106000;
523 SD_PT1 = 0x0AF002;
524 SD_PT2 = 0x8C;
525 SD_MRT = 0x3;
526 SD_CS = 0x200042;
527
528 /* wait for SDRAM controller */
529 logf("waiting for SDUP (%X) ...\n", SD_CS);
530 for (;;) if (SD_CS & SD_CS_SDUP_SET) break;
531 logf("SDRAM controller has arrived! (%X)\n", SD_CS);
532
533 /* RL = 6 / WL = 3 */
534 write_mr(LPDDR2_MR_DEVICE_FEATURE_2, 4, false);
535 calibrate_pvt_early();
536
537 /* identify installed memory */
538 vendor_id = read_mr(LPDDR2_MR_MANUFACTURER_ID);
539 if (!MR_REQUEST_SUCCESS(vendor_id)) {
540 panic("vendor id memory register read timed out");
541 }
542 vendor_id = MR_GET_RDATA(vendor_id);
543
544 bc = read_mr(LPDDR2_MR_METRICS);
545 if (!MR_REQUEST_SUCCESS(bc)) {
546 panic("basic configuration memory register read timed out");
547 }
548 bc = MR_GET_RDATA(bc);
549
550 g_RAMSize = lpddr2_size(bc);
551
552 logf("SDRAM Type: %s %s LPDDR2 (BC=0x%X)\n",
553 lpddr2_manufacturer_name(vendor_id),
554 size_to_string[g_RAMSize],
555 bc);
556
557 if (g_RAMSize == RAM_SIZE_UNKNOWN)
558 panic("unknown ram size (MR8 response was 0x%X)", bc);
559
560 /*
561 * STEP 2:
562 * after calibration, enable high-freq SDRAM PLL. because we're
563 * running from cache, we can freely mess with SDRAM clock without
564 * any issues, removing the need to copy the SDRAM late init stuff
565 * to bootrom ram. if later code that's running from SDRAM wants to
566 * mess with SDRAM clock it would need to do that.
567 */
568
569 if (g_RAMSize == RAM_SIZE_1GB) {
570 g_InitSdramParameters.colbits = 3;
571 g_InitSdramParameters.rowbits = 3;
572 g_InitSdramParameters.banklow = 3;
573 } else if (g_RAMSize == RAM_SIZE_512MB) {
574 g_InitSdramParameters.colbits = 2;
575 }
576
577 reset_with_timing(&g_InitSdramParameters);
578 init_late();
579 selftest();
580 }
This page took 0.137596 seconds and 3 git commands to generate.