blob: 9349cf772fc430eaf51faccf922a8f67720c6faf [file] [log] [blame]
Patrick Rudolph305035c2016-11-11 18:38:50 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Damien Zammit <damien@zamaudio.com>
5 * Copyright (C) 2014 Vladimir Serbinenko <phcoder@gmail.com>
6 * Copyright (C) 2016 Patrick Rudolph <siro@das-labor.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <console/console.h>
19#include <console/usb.h>
20#include <cpu/x86/msr.h>
21#include <delay.h>
22#include "raminit_native.h"
23#include "raminit_common.h"
24
25/* Frequency multiplier. */
26static u32 get_FRQ(u32 tCK)
27{
28 u32 FRQ;
29 FRQ = 256000 / (tCK * BASEFREQ);
30 if (FRQ > 8)
31 return 8;
32 if (FRQ < 3)
33 return 3;
34 return FRQ;
35}
36
37static u32 get_REFI(u32 tCK)
38{
39 /* Get REFI based on MCU frequency using the following rule:
40 * _________________________________________
41 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
42 * REFI: | 3120 | 4160 | 5200 | 6240 | 7280 | 8320 |
43 */
44 static const u32 frq_refi_map[] =
45 { 3120, 4160, 5200, 6240, 7280, 8320 };
46 return frq_refi_map[get_FRQ(tCK) - 3];
47}
48
49static u8 get_XSOffset(u32 tCK)
50{
51 /* Get XSOffset based on MCU frequency using the following rule:
52 * _________________________
53 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
54 * XSOffset : | 4 | 6 | 7 | 8 | 10 | 11 |
55 */
56 static const u8 frq_xs_map[] = { 4, 6, 7, 8, 10, 11 };
57 return frq_xs_map[get_FRQ(tCK) - 3];
58}
59
60static u8 get_MOD(u32 tCK)
61{
62 /* Get MOD based on MCU frequency using the following rule:
63 * _____________________________
64 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
65 * MOD : | 12 | 12 | 12 | 12 | 15 | 16 |
66 */
67 static const u8 frq_mod_map[] = { 12, 12, 12, 12, 15, 16 };
68 return frq_mod_map[get_FRQ(tCK) - 3];
69}
70
71static u8 get_WLO(u32 tCK)
72{
73 /* Get WLO based on MCU frequency using the following rule:
74 * _______________________
75 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
76 * WLO : | 4 | 5 | 6 | 6 | 8 | 8 |
77 */
78 static const u8 frq_wlo_map[] = { 4, 5, 6, 6, 8, 8 };
79 return frq_wlo_map[get_FRQ(tCK) - 3];
80}
81
82static u8 get_CKE(u32 tCK)
83{
84 /* Get CKE based on MCU frequency using the following rule:
85 * _______________________
86 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
87 * CKE : | 3 | 3 | 4 | 4 | 5 | 6 |
88 */
89 static const u8 frq_cke_map[] = { 3, 3, 4, 4, 5, 6 };
90 return frq_cke_map[get_FRQ(tCK) - 3];
91}
92
93static u8 get_XPDLL(u32 tCK)
94{
95 /* Get XPDLL based on MCU frequency using the following rule:
96 * _____________________________
97 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
98 * XPDLL : | 10 | 13 | 16 | 20 | 23 | 26 |
99 */
100 static const u8 frq_xpdll_map[] = { 10, 13, 16, 20, 23, 26 };
101 return frq_xpdll_map[get_FRQ(tCK) - 3];
102}
103
104static u8 get_XP(u32 tCK)
105{
106 /* Get XP based on MCU frequency using the following rule:
107 * _______________________
108 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
109 * XP : | 3 | 4 | 4 | 5 | 6 | 7 |
110 */
111 static const u8 frq_xp_map[] = { 3, 4, 4, 5, 6, 7 };
112 return frq_xp_map[get_FRQ(tCK) - 3];
113}
114
115static u8 get_AONPD(u32 tCK)
116{
117 /* Get AONPD based on MCU frequency using the following rule:
118 * ________________________
119 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
120 * AONPD : | 4 | 5 | 6 | 8 | 8 | 10 |
121 */
122 static const u8 frq_aonpd_map[] = { 4, 5, 6, 8, 8, 10 };
123 return frq_aonpd_map[get_FRQ(tCK) - 3];
124}
125
126static u32 get_COMP2(u32 tCK)
127{
128 /* Get COMP2 based on MCU frequency using the following rule:
129 * ___________________________________________________________
130 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
131 * COMP : | D6BEDCC | CE7C34C | CA57A4C | C6369CC | C42514C | C21410C |
132 */
133 static const u32 frq_comp2_map[] = { 0xD6BEDCC, 0xCE7C34C, 0xCA57A4C,
134 0xC6369CC, 0xC42514C, 0xC21410C
135 };
136 return frq_comp2_map[get_FRQ(tCK) - 3];
137}
138
139static void dram_timing(ramctr_timing * ctrl)
140{
141 u8 val;
142 u32 val32;
143
144 /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure
145 * we cap it if we have faster DIMMs.
146 * Then, align it to the closest JEDEC standard frequency */
147 if (ctrl->tCK <= TCK_1066MHZ) {
148 ctrl->tCK = TCK_1066MHZ;
149 ctrl->edge_offset[0] = 16;
150 ctrl->edge_offset[1] = 7;
151 ctrl->edge_offset[2] = 7;
152 ctrl->timC_offset[0] = 18;
153 ctrl->timC_offset[1] = 7;
154 ctrl->timC_offset[2] = 7;
155 ctrl->reg_320c_range_threshold = 13;
156 } else if (ctrl->tCK <= TCK_933MHZ) {
157 ctrl->tCK = TCK_933MHZ;
158 ctrl->edge_offset[0] = 14;
159 ctrl->edge_offset[1] = 6;
160 ctrl->edge_offset[2] = 6;
161 ctrl->timC_offset[0] = 15;
162 ctrl->timC_offset[1] = 6;
163 ctrl->timC_offset[2] = 6;
164 ctrl->reg_320c_range_threshold = 15;
165 } else if (ctrl->tCK <= TCK_800MHZ) {
166 ctrl->tCK = TCK_800MHZ;
167 ctrl->edge_offset[0] = 13;
168 ctrl->edge_offset[1] = 5;
169 ctrl->edge_offset[2] = 5;
170 ctrl->timC_offset[0] = 14;
171 ctrl->timC_offset[1] = 5;
172 ctrl->timC_offset[2] = 5;
173 ctrl->reg_320c_range_threshold = 15;
174 } else if (ctrl->tCK <= TCK_666MHZ) {
175 ctrl->tCK = TCK_666MHZ;
176 ctrl->edge_offset[0] = 10;
177 ctrl->edge_offset[1] = 4;
178 ctrl->edge_offset[2] = 4;
179 ctrl->timC_offset[0] = 11;
180 ctrl->timC_offset[1] = 4;
181 ctrl->timC_offset[2] = 4;
182 ctrl->reg_320c_range_threshold = 16;
183 } else if (ctrl->tCK <= TCK_533MHZ) {
184 ctrl->tCK = TCK_533MHZ;
185 ctrl->edge_offset[0] = 8;
186 ctrl->edge_offset[1] = 3;
187 ctrl->edge_offset[2] = 3;
188 ctrl->timC_offset[0] = 9;
189 ctrl->timC_offset[1] = 3;
190 ctrl->timC_offset[2] = 3;
191 ctrl->reg_320c_range_threshold = 17;
192 } else {
193 ctrl->tCK = TCK_400MHZ;
194 ctrl->edge_offset[0] = 6;
195 ctrl->edge_offset[1] = 2;
196 ctrl->edge_offset[2] = 2;
197 ctrl->timC_offset[0] = 6;
198 ctrl->timC_offset[1] = 2;
199 ctrl->timC_offset[2] = 2;
200 ctrl->reg_320c_range_threshold = 17;
201 }
202
203 /* Initial phase between CLK/CMD pins */
204 ctrl->reg_c14_offset = (256000 / ctrl->tCK) / 66;
205
206 /* DLL_CONFIG_MDLL_W_TIMER */
207 ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
208
209 val32 = (1000 << 8) / ctrl->tCK;
210 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
211
212 /* Find CAS latency */
213 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
214 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
215 /* Find lowest supported CAS latency that satisfies the minimum value */
216 while (!((ctrl->cas_supported >> (val - MIN_CAS)) & 1)
217 && (ctrl->cas_supported >> (val - MIN_CAS))) {
218 val++;
219 }
220 /* Is CAS supported */
221 if (!(ctrl->cas_supported & (1 << (val - MIN_CAS)))) {
222 printk(BIOS_ERR, "CAS %uT not supported. ", val);
223 val = MAX_CAS;
224 /* Find highest supported CAS latency */
225 while (!((ctrl->cas_supported >> (val - MIN_CAS)) & 1))
226 val--;
227
228 printk(BIOS_ERR, "Using CAS %uT instead.\n", val);
229 }
230
231 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
232 ctrl->CAS = val;
233 ctrl->CWL = get_CWL(ctrl->tCK);
234 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
235
236 /* Find tRCD */
237 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
238 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
239
240 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
241 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
242
243 /* Find tRAS */
244 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
245 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
246
247 /* Find tWR */
248 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
249 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
250
251 /* Find tFAW */
252 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
253 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
254
255 /* Find tRRD */
256 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
257 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
258
259 /* Find tRTP */
260 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
261 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
262
263 /* Find tWTR */
264 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
265 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
266
267 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
268 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
269 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
270
271 ctrl->tREFI = get_REFI(ctrl->tCK);
272 ctrl->tMOD = get_MOD(ctrl->tCK);
273 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
274 ctrl->tWLO = get_WLO(ctrl->tCK);
275 ctrl->tCKE = get_CKE(ctrl->tCK);
276 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
277 ctrl->tXP = get_XP(ctrl->tCK);
278 ctrl->tAONPD = get_AONPD(ctrl->tCK);
279}
280
281static void dram_freq(ramctr_timing * ctrl)
282{
283 if (ctrl->tCK > TCK_400MHZ) {
284 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
285 ctrl->tCK = TCK_400MHZ;
286 }
287 while (1) {
288 u8 val2;
289 u32 reg1 = 0;
290
291 /* Step 1 - Set target PCU frequency */
292
293 if (ctrl->tCK <= TCK_1066MHZ) {
294 ctrl->tCK = TCK_1066MHZ;
295 } else if (ctrl->tCK <= TCK_933MHZ) {
296 ctrl->tCK = TCK_933MHZ;
297 } else if (ctrl->tCK <= TCK_800MHZ) {
298 ctrl->tCK = TCK_800MHZ;
299 } else if (ctrl->tCK <= TCK_666MHZ) {
300 ctrl->tCK = TCK_666MHZ;
301 } else if (ctrl->tCK <= TCK_533MHZ) {
302 ctrl->tCK = TCK_533MHZ;
303 } else if (ctrl->tCK <= TCK_400MHZ) {
304 ctrl->tCK = TCK_400MHZ;
305 } else {
306 die ("No lock frequency found");
307 }
308
309 /* Frequency multiplier. */
310 u32 FRQ = get_FRQ(ctrl->tCK);
311
312 /* The PLL will never lock if the required frequency is
313 * already set. Exit early to prevent a system hang.
314 */
315 reg1 = MCHBAR32(MC_BIOS_DATA);
316 val2 = (u8) reg1;
317 if (val2)
318 return;
319
320 /* Step 2 - Select frequency in the MCU */
321 reg1 = FRQ;
322 reg1 |= 0x80000000; // set running bit
323 MCHBAR32(MC_BIOS_REQ) = reg1;
324 int i=0;
325 printk(BIOS_DEBUG, "PLL busy... ");
326 while (reg1 & 0x80000000) {
327 udelay(10);
328 i++;
329 reg1 = MCHBAR32(MC_BIOS_REQ);
330 }
331 printk(BIOS_DEBUG, "done in %d us\n", i * 10);
332
333 /* Step 3 - Verify lock frequency */
334 reg1 = MCHBAR32(MC_BIOS_DATA);
335 val2 = (u8) reg1;
336 if (val2 >= FRQ) {
337 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
338 (1000 << 8) / ctrl->tCK);
339 return;
340 }
341 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
342 ctrl->tCK++;
343 }
344}
345
346static void dram_ioregs(ramctr_timing * ctrl)
347{
348 u32 reg, comp2;
349
350 int channel;
351
352 // IO clock
353 FOR_ALL_CHANNELS {
354 MCHBAR32(0xc00 + 0x100 * channel) = ctrl->rankmap[channel];
355 }
356
357 // IO command
358 FOR_ALL_CHANNELS {
359 MCHBAR32(0x3200 + 0x100 * channel) = ctrl->rankmap[channel];
360 }
361
362 // IO control
363 FOR_ALL_POPULATED_CHANNELS {
364 program_timings(ctrl, channel);
365 }
366
367 // Rcomp
368 printram("RCOMP...");
369 reg = 0;
370 while (reg == 0) {
371 reg = MCHBAR32(0x5084) & 0x10000;
372 }
373 printram("done\n");
374
375 // Set comp2
376 comp2 = get_COMP2(ctrl->tCK);
377 MCHBAR32(0x3714) = comp2;
378 printram("COMP2 done\n");
379
380 // Set comp1
381 FOR_ALL_POPULATED_CHANNELS {
382 reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
383 reg = (reg & ~0xe00) | (1 << 9); //odt
384 reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
385 reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
386 MCHBAR32(0x1810 + channel * 0x100) = reg;
387 }
388 printram("COMP1 done\n");
389
390 printram("FORCE RCOMP and wait 20us...");
391 MCHBAR32(0x5f08) |= 0x100;
392 udelay(20);
393 printram("done\n");
394}
395
396int try_init_dram_ddr3_ivy(ramctr_timing *ctrl, int fast_boot,
397 int s3_resume, int me_uma_size)
398{
399 int err;
400
401 printk(BIOS_DEBUG, "Starting RAM training (%d).\n", fast_boot);
402
403 if (!fast_boot) {
404 /* Find fastest common supported parameters */
405 dram_find_common_params(ctrl);
406
407 dram_dimm_mapping(ctrl);
408 }
409
410 /* Set MCU frequency */
411 dram_freq(ctrl);
412
413 if (!fast_boot) {
414 /* Calculate timings */
415 dram_timing(ctrl);
416 }
417
418 /* Set version register */
419 MCHBAR32(0x5034) = 0xC04EB002;
420
421 /* Enable crossover */
422 dram_xover(ctrl);
423
424 /* Set timing and refresh registers */
425 dram_timing_regs(ctrl);
426
427 /* Power mode preset */
428 MCHBAR32(0x4e80) = 0x5500;
429
430 /* Set scheduler parameters */
431 MCHBAR32(0x4c20) = 0x10100005;
432
433 /* Set CPU specific register */
434 set_4f8c();
435
436 /* Clear IO reset bit */
437 MCHBAR32(0x5030) &= ~0x20;
438
439 /* Set MAD-DIMM registers */
440 dram_dimm_set_mapping(ctrl);
441 printk(BIOS_DEBUG, "Done dimm mapping\n");
442
443 /* Zone config */
444 dram_zones(ctrl, 1);
445
446 /* Set memory map */
447 dram_memorymap(ctrl, me_uma_size);
448 printk(BIOS_DEBUG, "Done memory map\n");
449
450 /* Set IO registers */
451 dram_ioregs(ctrl);
452 printk(BIOS_DEBUG, "Done io registers\n");
453
454 udelay(1);
455
456 if (fast_boot) {
457 restore_timings(ctrl);
458 } else {
459 /* Do jedec ddr3 reset sequence */
460 dram_jedecreset(ctrl);
461 printk(BIOS_DEBUG, "Done jedec reset\n");
462
463 /* MRS commands */
464 dram_mrscommands(ctrl);
465 printk(BIOS_DEBUG, "Done MRS commands\n");
466
467 /* Prepare for memory training */
468 prepare_training(ctrl);
469
470 err = read_training(ctrl);
471 if (err)
472 return err;
473
474 err = write_training(ctrl);
475 if (err)
476 return err;
477
478 printram("CP5a\n");
479
480 err = discover_edges(ctrl);
481 if (err)
482 return err;
483
484 printram("CP5b\n");
485
486 err = command_training(ctrl);
487 if (err)
488 return err;
489
490 printram("CP5c\n");
491
492 err = discover_edges_write(ctrl);
493 if (err)
494 return err;
495
496 err = discover_timC_write(ctrl);
497 if (err)
498 return err;
499
500 normalize_training(ctrl);
501 }
502
503 set_4008c(ctrl);
504
505 write_controller_mr(ctrl);
506
507 if (!s3_resume) {
508 err = channel_test(ctrl);
509 if (err)
510 return err;
511 }
512
513 return 0;
514}