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