blob: 7490ff7f291161292b602d3f7c7d1d85d7453b08 [file] [log] [blame]
Stefan Reinauer00636b02012-04-04 00:08:51 +02001/*
2 * This file is part of the coreboot project.
3 *
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004 * Copyright (C) 2014 Damien Zammit <damien@zamaudio.com>
5 * Copyright (C) 2014 Vladimir Serbinenko <phcoder@gmail.com>
Stefan Reinauer00636b02012-04-04 00:08:51 +02006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
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.
Stefan Reinauer00636b02012-04-04 00:08:51 +020015 */
16
17#include <console/console.h>
Kyösti Mälkki1d7541f2014-02-17 21:34:42 +020018#include <console/usb.h>
Kyösti Mälkki5687fc92013-11-28 18:11:49 +020019#include <bootmode.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020020#include <string.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020021#include <arch/io.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020022#include <cbmem.h>
23#include <arch/cbfs.h>
24#include <cbfs.h>
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070025#include <halt.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020026#include <ip_checksum.h>
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +010027#include <timestamp.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020028#include <pc80/mc146818rtc.h>
Duncan Laurie7b508dd2012-04-09 12:30:43 -070029#include <device/pci_def.h>
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070030#include "raminit_native.h"
Stefan Reinauer00636b02012-04-04 00:08:51 +020031#include "sandybridge.h"
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070032#include <delay.h>
33#include <lib.h>
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +010034#include <device/device.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020035
36/* Management Engine is in the southbridge */
37#include "southbridge/intel/bd82x6x/me.h"
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070038/* For SPD. */
39#include "southbridge/intel/bd82x6x/smbus.h"
40#include "arch/cpu.h"
41#include "cpu/x86/msr.h"
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +010042#include <northbridge/intel/sandybridge/chip.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020043
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070044/* FIXME: no ECC support. */
45/* FIXME: no support for 3-channel chipsets. */
Stefan Reinauer00636b02012-04-04 00:08:51 +020046
Patrick Rudolph371d2912015-10-09 13:33:25 +020047/*
48 * Register description:
49 * Intel provides a command queue of depth four.
50 * Every command is configured by using multiple registers.
51 * On executing the command queue you have to provide the depth used.
52 *
53 * Known registers:
54 * Channel X = [0, 1]
55 * Command queue index Y = [0, 1, 2, 3]
56 *
57 * DEFAULT_MCHBAR + 0x4220 + 0x400 * X + 4 * Y: command io register
58 * Controls the DRAM command signals
59 * Bit 0: !RAS
60 * Bit 1: !CAS
61 * Bit 2: !WE
62 *
63 * DEFAULT_MCHBAR + 0x4200 + 0x400 * X + 4 * Y: addr bankslot io register
64 * Controls the address, bank address and slotrank signals
65 * Bit 0-15 : Address
66 * Bit 20-22: Bank Address
67 * Bit 24-25: slotrank
68 *
69 * DEFAULT_MCHBAR + 0x4230 + 0x400 * X + 4 * Y: idle register
70 * Controls the idle time after issuing this DRAM command
71 * Bit 16-32: number of clock-cylces to idle
72 *
73 * DEFAULT_MCHBAR + 0x4284 + 0x400 * channel: execute command queue
74 * Starts to execute all queued commands
75 * Bit 0 : start DRAM command execution
76 * Bit 16-20: (number of queued commands - 1) * 4
77 */
78
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070079#define BASEFREQ 133
80#define tDLLK 512
Stefan Reinauer00636b02012-04-04 00:08:51 +020081
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070082#define IS_SANDY_CPU(x) ((x & 0xffff0) == 0x206a0)
83#define IS_SANDY_CPU_C(x) ((x & 0xf) == 4)
84#define IS_SANDY_CPU_D0(x) ((x & 0xf) == 5)
85#define IS_SANDY_CPU_D1(x) ((x & 0xf) == 6)
86#define IS_SANDY_CPU_D2(x) ((x & 0xf) == 7)
Stefan Reinauer00636b02012-04-04 00:08:51 +020087
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070088#define IS_IVY_CPU(x) ((x & 0xffff0) == 0x306a0)
89#define IS_IVY_CPU_C(x) ((x & 0xf) == 4)
90#define IS_IVY_CPU_K(x) ((x & 0xf) == 5)
91#define IS_IVY_CPU_D(x) ((x & 0xf) == 6)
92#define IS_IVY_CPU_E(x) ((x & 0xf) >= 8)
Stefan Reinauer00636b02012-04-04 00:08:51 +020093
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070094#define NUM_CHANNELS 2
95#define NUM_SLOTRANKS 4
96#define NUM_SLOTS 2
97#define NUM_LANES 8
Stefan Reinauer00636b02012-04-04 00:08:51 +020098
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070099/* FIXME: Vendor BIOS uses 64 but our algorithms are less
100 performant and even 1 seems to be enough in practice. */
101#define NUM_PATTERNS 4
Stefan Reinauer00636b02012-04-04 00:08:51 +0200102
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700103typedef struct odtmap_st {
104 u16 rttwr;
105 u16 rttnom;
106} odtmap;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200107
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700108typedef struct dimm_info_st {
109 dimm_attr dimm[NUM_CHANNELS][NUM_SLOTS];
110} dimm_info;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200111
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700112struct ram_rank_timings {
113 /* Register 4024. One byte per slotrank. */
114 u8 val_4024;
115 /* Register 4028. One nibble per slotrank. */
116 u8 val_4028;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200117
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700118 int val_320c;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200119
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700120 struct ram_lane_timings {
121 /* lane register offset 0x10. */
122 u16 timA; /* bits 0 - 5, bits 16 - 18 */
123 u8 rising; /* bits 8 - 14 */
124 u8 falling; /* bits 20 - 26. */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200125
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700126 /* lane register offset 0x20. */
127 int timC; /* bit 0 - 5, 19. */
128 u16 timB; /* bits 8 - 13, 15 - 17. */
129 } lanes[NUM_LANES];
130};
Stefan Reinauer00636b02012-04-04 00:08:51 +0200131
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700132struct ramctr_timing_st;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200133
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700134typedef struct ramctr_timing_st {
135 int mobile;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200136
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700137 u16 cas_supported;
138 /* tLatencies are in units of ns, scaled by x256 */
139 u32 tCK;
140 u32 tAA;
141 u32 tWR;
142 u32 tRCD;
143 u32 tRRD;
144 u32 tRP;
145 u32 tRAS;
146 u32 tRFC;
147 u32 tWTR;
148 u32 tRTP;
149 u32 tFAW;
150 /* Latencies in terms of clock cycles
151 * They are saved separately as they are needed for DRAM MRS commands*/
152 u8 CAS; /* CAS read latency */
153 u8 CWL; /* CAS write latency */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200154
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700155 u32 tREFI;
156 u32 tMOD;
157 u32 tXSOffset;
158 u32 tWLO;
159 u32 tCKE;
160 u32 tXPDLL;
161 u32 tXP;
162 u32 tAONPD;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200163
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700164 u16 reg_5064b0; /* bits 0-11. */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200165
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700166 u8 rankmap[NUM_CHANNELS];
167 int ref_card_offset[NUM_CHANNELS];
168 u32 mad_dimm[NUM_CHANNELS];
169 int channel_size_mb[NUM_CHANNELS];
170 u32 cmd_stretch[NUM_CHANNELS];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200171
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700172 int reg_c14_offset;
173 int reg_320c_range_threshold;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200174
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700175 int edge_offset[3];
176 int timC_offset[3];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200177
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700178 int extended_temperature_range;
179 int auto_self_refresh;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200180
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700181 int rank_mirror[NUM_CHANNELS][NUM_SLOTRANKS];
182
183 struct ram_rank_timings timings[NUM_CHANNELS][NUM_SLOTRANKS];
184} ramctr_timing;
185
186#define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0)
187#define NORTHBRIDGE PCI_DEV(0, 0x0, 0)
188#define FOR_ALL_LANES for (lane = 0; lane < NUM_LANES; lane++)
189#define FOR_ALL_CHANNELS for (channel = 0; channel < NUM_CHANNELS; channel++)
190#define FOR_ALL_POPULATED_RANKS for (slotrank = 0; slotrank < NUM_SLOTRANKS; slotrank++) if (ctrl->rankmap[channel] & (1 << slotrank))
191#define FOR_ALL_POPULATED_CHANNELS for (channel = 0; channel < NUM_CHANNELS; channel++) if (ctrl->rankmap[channel])
192#define MAX_EDGE_TIMING 71
193#define MAX_TIMC 127
194#define MAX_TIMB 511
195#define MAX_TIMA 127
196
197static void program_timings(ramctr_timing * ctrl, int channel);
198
199static const char *ecc_decoder[] = {
Stefan Reinauer00636b02012-04-04 00:08:51 +0200200 "inactive",
201 "active on IO",
202 "disabled on IO",
203 "active"
204};
205
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700206static void wait_txt_clear(void)
207{
208 struct cpuid_result cp;
209
210 cp = cpuid_ext(0x1, 0x0);
211 /* Check if TXT is supported? */
212 if (!(cp.ecx & 0x40))
213 return;
214 /* Some TXT public bit. */
215 if (!(read32((void *)0xfed30010) & 1))
216 return;
217 /* Wait for TXT clear. */
218 while (!(read8((void *)0xfed40000) & (1 << 7))) ;
219}
220
221static void sfence(void)
222{
223 asm volatile ("sfence");
224}
225
Patrick Rudolph9b515682015-10-09 13:43:51 +0200226static void toggle_io_reset(void) {
227 /* toggle IO reset bit */
228 u32 r32 = read32(DEFAULT_MCHBAR + 0x5030);
229 write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
230 udelay(1);
231 write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
232 udelay(1);
233}
234
Stefan Reinauer00636b02012-04-04 00:08:51 +0200235/*
236 * Dump in the log memory controller configuration as read from the memory
237 * controller registers.
238 */
239static void report_memory_config(void)
240{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700241 u32 addr_decoder_common, addr_decode_ch[NUM_CHANNELS];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200242 int i;
243
244 addr_decoder_common = MCHBAR32(0x5000);
245 addr_decode_ch[0] = MCHBAR32(0x5004);
246 addr_decode_ch[1] = MCHBAR32(0x5008);
247
248 printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700249 (MCHBAR32(0x5e04) * 13333 * 2 + 50) / 100);
Stefan Reinauer00636b02012-04-04 00:08:51 +0200250 printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700251 addr_decoder_common & 3, (addr_decoder_common >> 2) & 3,
Stefan Reinauer00636b02012-04-04 00:08:51 +0200252 (addr_decoder_common >> 4) & 3);
253
254 for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
255 u32 ch_conf = addr_decode_ch[i];
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700256 printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i,
257 ch_conf);
Stefan Reinauer00636b02012-04-04 00:08:51 +0200258 printk(BIOS_DEBUG, " ECC %s\n",
259 ecc_decoder[(ch_conf >> 24) & 3]);
260 printk(BIOS_DEBUG, " enhanced interleave mode %s\n",
261 ((ch_conf >> 22) & 1) ? "on" : "off");
262 printk(BIOS_DEBUG, " rank interleave %s\n",
263 ((ch_conf >> 21) & 1) ? "on" : "off");
264 printk(BIOS_DEBUG, " DIMMA %d MB width x%d %s rank%s\n",
265 ((ch_conf >> 0) & 0xff) * 256,
266 ((ch_conf >> 19) & 1) ? 16 : 8,
267 ((ch_conf >> 17) & 1) ? "dual" : "single",
268 ((ch_conf >> 16) & 1) ? "" : ", selected");
269 printk(BIOS_DEBUG, " DIMMB %d MB width x%d %s rank%s\n",
270 ((ch_conf >> 8) & 0xff) * 256,
271 ((ch_conf >> 20) & 1) ? 16 : 8,
272 ((ch_conf >> 18) & 1) ? "dual" : "single",
273 ((ch_conf >> 16) & 1) ? ", selected" : "");
274 }
275}
276
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700277void read_spd(spd_raw_data * spd, u8 addr)
Stefan Reinauer00636b02012-04-04 00:08:51 +0200278{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700279 int j;
280 for (j = 0; j < 256; j++)
281 (*spd)[j] = do_smbus_read_byte(SMBUS_IO_BASE, addr, j);
282}
283
284static void dram_find_spds_ddr3(spd_raw_data * spd, dimm_info * dimm,
285 ramctr_timing * ctrl)
286{
287 int dimms = 0;
288 int channel, slot, spd_slot;
289
290 memset (ctrl->rankmap, 0, sizeof (ctrl->rankmap));
291
292 ctrl->extended_temperature_range = 1;
293 ctrl->auto_self_refresh = 1;
294
295 FOR_ALL_CHANNELS {
296 ctrl->channel_size_mb[channel] = 0;
297
298 for (slot = 0; slot < NUM_SLOTS; slot++) {
299 spd_slot = 2 * channel + slot;
300 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
301 if (dimm->dimm[channel][slot].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) {
302 // set dimm invalid
303 dimm->dimm[channel][slot].ranks = 0;
304 dimm->dimm[channel][slot].size_mb = 0;
305 continue;
306 }
307
308 dram_print_spd_ddr3(&dimm->dimm[channel][slot]);
309 dimms++;
310 ctrl->rank_mirror[channel][slot * 2] = 0;
311 ctrl->rank_mirror[channel][slot * 2 + 1] = dimm->dimm[channel][slot].flags.pins_mirrored;
312 ctrl->channel_size_mb[channel] += dimm->dimm[channel][slot].size_mb;
313
314 ctrl->auto_self_refresh &= dimm->dimm[channel][slot].flags.asr;
315 ctrl->extended_temperature_range &= dimm->dimm[channel][slot].flags.ext_temp_refresh;
316
317 ctrl->rankmap[channel] |= ((1 << dimm->dimm[channel][slot].ranks) - 1) << (2 * slot);
318 printk(BIOS_DEBUG, "rankmap[%d] = 0x%x\n", channel, ctrl->rankmap[channel]);
319 }
320 if ((ctrl->rankmap[channel] & 3) && (ctrl->rankmap[channel] & 0xc)
321 && dimm->dimm[channel][0].reference_card <= 5 && dimm->dimm[channel][1].reference_card <= 5) {
322 const int ref_card_offset_table[6][6] = {
323 { 0, 0, 0, 0, 2, 2, },
324 { 0, 0, 0, 0, 2, 2, },
325 { 0, 0, 0, 0, 2, 2, },
326 { 0, 0, 0, 0, 1, 1, },
327 { 2, 2, 2, 1, 0, 0, },
328 { 2, 2, 2, 1, 0, 0, },
329 };
330 ctrl->ref_card_offset[channel] = ref_card_offset_table[dimm->dimm[channel][0].reference_card]
331 [dimm->dimm[channel][1].reference_card];
332 } else
333 ctrl->ref_card_offset[channel] = 0;
334 }
335
336 if (!dimms)
337 die("No DIMMs were found");
338}
339
340static void dram_find_common_params(const dimm_info * dimms,
341 ramctr_timing * ctrl)
342{
343 size_t valid_dimms;
344 int channel, slot;
345 ctrl->cas_supported = 0xff;
346 valid_dimms = 0;
347 FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) {
348 const dimm_attr *dimm = &dimms->dimm[channel][slot];
349 if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
350 continue;
351 valid_dimms++;
352
353 /* Find all possible CAS combinations */
354 ctrl->cas_supported &= dimm->cas_supported;
355
356 /* Find the smallest common latencies supported by all DIMMs */
357 ctrl->tCK = MAX(ctrl->tCK, dimm->tCK);
358 ctrl->tAA = MAX(ctrl->tAA, dimm->tAA);
359 ctrl->tWR = MAX(ctrl->tWR, dimm->tWR);
360 ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
361 ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
362 ctrl->tRP = MAX(ctrl->tRP, dimm->tRP);
363 ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
364 ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
365 ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
366 ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
367 ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
368 }
369
370 if (!ctrl->cas_supported)
371 die("Unsupported DIMM combination. "
372 "DIMMS do not support common CAS latency");
373 if (!valid_dimms)
374 die("No valid DIMMs found");
375}
376
377static u8 get_CWL(u8 CAS)
378{
379 /* Get CWL based on CAS using the following rule:
380 * _________________________________________
381 * CAS: | 4T | 5T | 6T | 7T | 8T | 9T | 10T | 11T |
382 * CWL: | 5T | 5T | 5T | 6T | 6T | 7T | 7T | 8T |
383 */
384 static const u8 cas_cwl_map[] = { 5, 5, 5, 6, 6, 7, 7, 8 };
385 if (CAS > 11)
386 return 8;
387 return cas_cwl_map[CAS - 4];
388}
389
390/* Frequency multiplier. */
391static u32 get_FRQ(u32 tCK)
392{
393 u32 FRQ;
394 FRQ = 256000 / (tCK * BASEFREQ);
395 if (FRQ > 8)
396 return 8;
397 if (FRQ < 3)
398 return 3;
399 return FRQ;
400}
401
402static u32 get_REFI(u32 tCK)
403{
404 /* Get REFI based on MCU frequency using the following rule:
405 * _________________________________________
406 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
407 * REFI: | 3120 | 4160 | 5200 | 6240 | 7280 | 8320 |
408 */
409 static const u32 frq_refi_map[] =
410 { 3120, 4160, 5200, 6240, 7280, 8320 };
411 return frq_refi_map[get_FRQ(tCK) - 3];
412}
413
414static u8 get_XSOffset(u32 tCK)
415{
416 /* Get XSOffset based on MCU frequency using the following rule:
417 * _________________________
418 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
419 * XSOffset : | 4 | 6 | 7 | 8 | 10 | 11 |
420 */
421 static const u8 frq_xs_map[] = { 4, 6, 7, 8, 10, 11 };
422 return frq_xs_map[get_FRQ(tCK) - 3];
423}
424
425static u8 get_MOD(u32 tCK)
426{
427 /* Get MOD based on MCU frequency using the following rule:
428 * _____________________________
429 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
430 * MOD : | 12 | 12 | 12 | 12 | 15 | 16 |
431 */
432 static const u8 frq_mod_map[] = { 12, 12, 12, 12, 15, 16 };
433 return frq_mod_map[get_FRQ(tCK) - 3];
434}
435
436static u8 get_WLO(u32 tCK)
437{
438 /* Get WLO based on MCU frequency using the following rule:
439 * _______________________
440 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
441 * WLO : | 4 | 5 | 6 | 6 | 8 | 8 |
442 */
443 static const u8 frq_wlo_map[] = { 4, 5, 6, 6, 8, 8 };
444 return frq_wlo_map[get_FRQ(tCK) - 3];
445}
446
447static u8 get_CKE(u32 tCK)
448{
449 /* Get CKE based on MCU frequency using the following rule:
450 * _______________________
451 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
452 * CKE : | 3 | 3 | 4 | 4 | 5 | 6 |
453 */
454 static const u8 frq_cke_map[] = { 3, 3, 4, 4, 5, 6 };
455 return frq_cke_map[get_FRQ(tCK) - 3];
456}
457
458static u8 get_XPDLL(u32 tCK)
459{
460 /* Get XPDLL based on MCU frequency using the following rule:
461 * _____________________________
462 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
463 * XPDLL : | 10 | 13 | 16 | 20 | 23 | 26 |
464 */
465 static const u8 frq_xpdll_map[] = { 10, 13, 16, 20, 23, 26 };
466 return frq_xpdll_map[get_FRQ(tCK) - 3];
467}
468
469static u8 get_XP(u32 tCK)
470{
471 /* Get XP based on MCU frequency using the following rule:
472 * _______________________
473 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
474 * XP : | 3 | 4 | 4 | 5 | 6 | 7 |
475 */
476 static const u8 frq_xp_map[] = { 3, 4, 4, 5, 6, 7 };
477 return frq_xp_map[get_FRQ(tCK) - 3];
478}
479
480static u8 get_AONPD(u32 tCK)
481{
482 /* Get AONPD based on MCU frequency using the following rule:
483 * ________________________
484 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
485 * AONPD : | 4 | 5 | 6 | 8 | 8 | 10 |
486 */
487 static const u8 frq_aonpd_map[] = { 4, 5, 6, 8, 8, 10 };
488 return frq_aonpd_map[get_FRQ(tCK) - 3];
489}
490
491static u32 get_COMP2(u32 tCK)
492{
493 /* Get COMP2 based on MCU frequency using the following rule:
494 * ___________________________________________________________
495 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
496 * COMP : | D6BEDCC | CE7C34C | CA57A4C | C6369CC | C42514C | C21410C |
497 */
498 static const u32 frq_comp2_map[] = { 0xD6BEDCC, 0xCE7C34C, 0xCA57A4C,
499 0xC6369CC, 0xC42514C, 0xC21410C
500 };
501 return frq_comp2_map[get_FRQ(tCK) - 3];
502}
503
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100504static u32 get_XOVER_CLK(u8 rankmap)
505{
506 return rankmap << 24;
507}
508
509static u32 get_XOVER_CMD(u8 rankmap)
510{
511 u32 reg;
512
513 // enable xover cmd
514 reg = 0x4000;
515
516 // enable xover ctl
517 if (rankmap & 0x3)
518 reg |= 0x20000;
519
520 if (rankmap & 0xc)
521 reg |= 0x4000000;
522
523 return reg;
524}
525
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700526static void dram_timing(ramctr_timing * ctrl)
527{
528 u8 val;
529 u32 val32;
530
531 /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure
532 * we cap it if we have faster DIMMs.
533 * Then, align it to the closest JEDEC standard frequency */
534 if (ctrl->tCK <= TCK_1066MHZ) {
535 ctrl->tCK = TCK_1066MHZ;
536 ctrl->edge_offset[0] = 16;
537 ctrl->edge_offset[1] = 7;
538 ctrl->edge_offset[2] = 7;
539 ctrl->timC_offset[0] = 18;
540 ctrl->timC_offset[1] = 7;
541 ctrl->timC_offset[2] = 7;
542 ctrl->reg_c14_offset = 16;
543 ctrl->reg_5064b0 = 0x218;
544 ctrl->reg_320c_range_threshold = 13;
545 } else if (ctrl->tCK <= TCK_933MHZ) {
546 ctrl->tCK = TCK_933MHZ;
547 ctrl->edge_offset[0] = 14;
548 ctrl->edge_offset[1] = 6;
549 ctrl->edge_offset[2] = 6;
550 ctrl->timC_offset[0] = 15;
551 ctrl->timC_offset[1] = 6;
552 ctrl->timC_offset[2] = 6;
553 ctrl->reg_c14_offset = 14;
554 ctrl->reg_5064b0 = 0x1d5;
555 ctrl->reg_320c_range_threshold = 15;
556 } else if (ctrl->tCK <= TCK_800MHZ) {
557 ctrl->tCK = TCK_800MHZ;
558 ctrl->edge_offset[0] = 13;
559 ctrl->edge_offset[1] = 5;
560 ctrl->edge_offset[2] = 5;
561 ctrl->timC_offset[0] = 14;
562 ctrl->timC_offset[1] = 5;
563 ctrl->timC_offset[2] = 5;
564 ctrl->reg_c14_offset = 12;
565 ctrl->reg_5064b0 = 0x193;
566 ctrl->reg_320c_range_threshold = 15;
567 } else if (ctrl->tCK <= TCK_666MHZ) {
568 ctrl->tCK = TCK_666MHZ;
569 ctrl->edge_offset[0] = 10;
570 ctrl->edge_offset[1] = 4;
571 ctrl->edge_offset[2] = 4;
572 ctrl->timC_offset[0] = 11;
573 ctrl->timC_offset[1] = 4;
574 ctrl->timC_offset[2] = 4;
575 ctrl->reg_c14_offset = 10;
576 ctrl->reg_5064b0 = 0x150;
577 ctrl->reg_320c_range_threshold = 16;
578 } else if (ctrl->tCK <= TCK_533MHZ) {
579 ctrl->tCK = TCK_533MHZ;
580 ctrl->edge_offset[0] = 8;
581 ctrl->edge_offset[1] = 3;
582 ctrl->edge_offset[2] = 3;
583 ctrl->timC_offset[0] = 9;
584 ctrl->timC_offset[1] = 3;
585 ctrl->timC_offset[2] = 3;
586 ctrl->reg_c14_offset = 8;
587 ctrl->reg_5064b0 = 0x10d;
588 ctrl->reg_320c_range_threshold = 17;
589 } else {
590 ctrl->tCK = TCK_400MHZ;
591 ctrl->edge_offset[0] = 6;
592 ctrl->edge_offset[1] = 2;
593 ctrl->edge_offset[2] = 2;
594 ctrl->timC_offset[0] = 6;
595 ctrl->timC_offset[1] = 2;
596 ctrl->timC_offset[2] = 2;
597 ctrl->reg_c14_offset = 8;
598 ctrl->reg_5064b0 = 0xcd;
599 ctrl->reg_320c_range_threshold = 17;
600 }
601
602 val32 = (1000 << 8) / ctrl->tCK;
603 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
604
605 /* Find CAS and CWL latencies */
606 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
607 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
608 /* Find lowest supported CAS latency that satisfies the minimum value */
609 while (!((ctrl->cas_supported >> (val - 4)) & 1)
610 && (ctrl->cas_supported >> (val - 4))) {
611 val++;
612 }
613 /* Is CAS supported */
614 if (!(ctrl->cas_supported & (1 << (val - 4))))
615 printk(BIOS_DEBUG, "CAS not supported\n");
616 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
617 ctrl->CAS = val;
618 ctrl->CWL = get_CWL(ctrl->CAS);
619 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
620
621 /* Find tRCD */
622 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
623 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
624
625 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
626 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
627
628 /* Find tRAS */
629 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
630 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
631
632 /* Find tWR */
633 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
634 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
635
636 /* Find tFAW */
637 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
638 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
639
640 /* Find tRRD */
641 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
642 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
643
644 /* Find tRTP */
645 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
646 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
647
648 /* Find tWTR */
649 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
650 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
651
652 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
653 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
654 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
655
656 ctrl->tREFI = get_REFI(ctrl->tCK);
657 ctrl->tMOD = get_MOD(ctrl->tCK);
658 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
659 ctrl->tWLO = get_WLO(ctrl->tCK);
660 ctrl->tCKE = get_CKE(ctrl->tCK);
661 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
662 ctrl->tXP = get_XP(ctrl->tCK);
663 ctrl->tAONPD = get_AONPD(ctrl->tCK);
664}
665
666static void dram_freq(ramctr_timing * ctrl)
667{
668 if (ctrl->tCK > TCK_400MHZ) {
669 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
670 ctrl->tCK = TCK_400MHZ;
671 }
672 while (1) {
673 u8 val2;
674 u32 reg1 = 0;
675
676 /* Step 1 - Set target PCU frequency */
677
678 if (ctrl->tCK <= TCK_1066MHZ) {
679 ctrl->tCK = TCK_1066MHZ;
680 } else if (ctrl->tCK <= TCK_933MHZ) {
681 ctrl->tCK = TCK_933MHZ;
682 } else if (ctrl->tCK <= TCK_800MHZ) {
683 ctrl->tCK = TCK_800MHZ;
684 } else if (ctrl->tCK <= TCK_666MHZ) {
685 ctrl->tCK = TCK_666MHZ;
686 } else if (ctrl->tCK <= TCK_533MHZ) {
687 ctrl->tCK = TCK_533MHZ;
688 } else if (ctrl->tCK <= TCK_400MHZ) {
689 ctrl->tCK = TCK_400MHZ;
690 } else {
691 die ("No lock frequency found");
692 }
693
694 /* Frequency mulitplier. */
695 u32 FRQ = get_FRQ(ctrl->tCK);
696
697 /* Step 2 - Select frequency in the MCU */
698 reg1 = FRQ;
699 reg1 |= 0x80000000; // set running bit
700 MCHBAR32(0x5e00) = reg1;
701 while (reg1 & 0x80000000) {
702 printk(BIOS_DEBUG, " PLL busy...");
703 reg1 = MCHBAR32(0x5e00);
704 }
705 printk(BIOS_DEBUG, "done\n");
706
707 /* Step 3 - Verify lock frequency */
708 reg1 = MCHBAR32(0x5e04);
709 val2 = (u8) reg1;
710 if (val2 >= FRQ) {
711 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
712 (1000 << 8) / ctrl->tCK);
713 return;
714 }
715 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
716 ctrl->tCK++;
717 }
718}
719
720static void dram_xover(ramctr_timing * ctrl)
721{
722 u32 reg;
723 int channel;
724
725 FOR_ALL_CHANNELS {
726 // enable xover clk
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100727 reg = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700728 printk(BIOS_DEBUG, "[%x] = %x\n", channel * 0x100 + 0xc14,
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100729 reg);
730 MCHBAR32(channel * 0x100 + 0xc14) = reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700731
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100732 // enable xover ctl & xover cmd
733 reg = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700734 printk(BIOS_DEBUG, "[%x] = %x\n", 0x100 * channel + 0x320c,
735 reg);
736 MCHBAR32(0x100 * channel + 0x320c) = reg;
737 }
738}
739
740static void dram_timing_regs(ramctr_timing * ctrl)
741{
742 u32 reg, addr, val32, cpu, stretch;
743 struct cpuid_result cpures;
744 int channel;
745
746 FOR_ALL_CHANNELS {
747 // DBP
748 reg = 0;
749 reg |= ctrl->tRCD;
750 reg |= (ctrl->tRP << 4);
751 reg |= (ctrl->CAS << 8);
752 reg |= (ctrl->CWL << 12);
753 reg |= (ctrl->tRAS << 16);
754 printk(BIOS_DEBUG, "[%x] = %x\n", 0x400 * channel + 0x4000,
755 reg);
756 MCHBAR32(0x400 * channel + 0x4000) = reg;
757
758 // RAP
759 reg = 0;
760 reg |= ctrl->tRRD;
761 reg |= (ctrl->tRTP << 4);
762 reg |= (ctrl->tCKE << 8);
763 reg |= (ctrl->tWTR << 12);
764 reg |= (ctrl->tFAW << 16);
765 reg |= (ctrl->tWR << 24);
766 reg |= (3 << 30);
767 printk(BIOS_DEBUG, "[%x] = %x\n", 0x400 * channel + 0x4004,
768 reg);
769 MCHBAR32(0x400 * channel + 0x4004) = reg;
770
771 // OTHP
772 addr = 0x400 * channel + 0x400c;
773 reg = 0;
774 reg |= ctrl->tXPDLL;
775 reg |= (ctrl->tXP << 5);
776 reg |= (ctrl->tAONPD << 8);
777 reg |= 0xa0000;
778 printk(BIOS_DEBUG, "[%x] = %x\n", addr, reg);
779 MCHBAR32(addr) = reg;
780
781 MCHBAR32(0x400 * channel + 0x4014) = 0;
782
783 MCHBAR32(addr) |= 0x00020000;
784
785 // ODT stretch
786 reg = 0;
787
788 cpures = cpuid(0);
789 cpu = cpures.eax;
790 if (IS_IVY_CPU(cpu)
791 || (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_D2(cpu))) {
792 stretch = 2;
793 addr = 0x400 * channel + 0x400c;
794 printk(BIOS_DEBUG, "[%x] = %x\n",
795 0x400 * channel + 0x400c, reg);
796 reg = MCHBAR32(addr);
797
798 if (((ctrl->rankmap[channel] & 3) == 0)
799 || (ctrl->rankmap[channel] & 0xc) == 0) {
800
801 // Rank 0 - operate on rank 2
802 reg = (reg & ~0xc0000) | (stretch << 18);
803
804 // Rank 2 - operate on rank 0
805 reg = (reg & ~0x30000) | (stretch << 16);
806
807 printk(BIOS_DEBUG, "[%x] = %x\n", addr, reg);
808 MCHBAR32(addr) = reg;
809 }
810
811 } else if (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_C(cpu)) {
812 stretch = 3;
813 addr = 0x400 * channel + 0x401c;
814 reg = MCHBAR32(addr);
815
816 if (((ctrl->rankmap[channel] & 3) == 0)
817 || (ctrl->rankmap[channel] & 0xc) == 0) {
818
819 // Rank 0 - operate on rank 2
820 reg = (reg & ~0x3000) | (stretch << 12);
821
822 // Rank 2 - operate on rank 0
823 reg = (reg & ~0xc00) | (stretch << 10);
824
825 printk(BIOS_DEBUG, "[%x] = %x\n", addr, reg);
826 MCHBAR32(addr) = reg;
827 }
828 } else {
829 stretch = 0;
830 }
831
832 // REFI
833 reg = 0;
834 val32 = ctrl->tREFI;
835 reg = (reg & ~0xffff) | val32;
836 val32 = ctrl->tRFC;
837 reg = (reg & ~0x1ff0000) | (val32 << 16);
838 val32 = (u32) (ctrl->tREFI * 9) / 1024;
839 reg = (reg & ~0xfe000000) | (val32 << 25);
840 printk(BIOS_DEBUG, "[%x] = %x\n", 0x400 * channel + 0x4298,
841 reg);
842 MCHBAR32(0x400 * channel + 0x4298) = reg;
843
844 MCHBAR32(0x400 * channel + 0x4294) |= 0xff;
845
846 // SRFTP
847 reg = 0;
848 val32 = tDLLK;
849 reg = (reg & ~0xfff) | val32;
850 val32 = ctrl->tXSOffset;
851 reg = (reg & ~0xf000) | (val32 << 12);
852 val32 = tDLLK - ctrl->tXSOffset;
853 reg = (reg & ~0x3ff0000) | (val32 << 16);
854 val32 = ctrl->tMOD - 8;
855 reg = (reg & ~0xf0000000) | (val32 << 28);
856 printk(BIOS_DEBUG, "[%x] = %x\n", 0x400 * channel + 0x42a4,
857 reg);
858 MCHBAR32(0x400 * channel + 0x42a4) = reg;
859 }
860}
861
862static void dram_dimm_mapping(dimm_info * info, ramctr_timing * ctrl)
863{
864 u32 reg, val32;
865 int channel;
866
867 FOR_ALL_CHANNELS {
868 dimm_attr *dimmA = 0;
869 dimm_attr *dimmB = 0;
870 reg = 0;
871 val32 = 0;
872 if (info->dimm[channel][0].size_mb >=
873 info->dimm[channel][1].size_mb) {
874 // dimm 0 is bigger, set it to dimmA
875 dimmA = &info->dimm[channel][0];
876 dimmB = &info->dimm[channel][1];
877 reg |= (0 << 16);
878 } else {
879 // dimm 1 is bigger, set it to dimmA
880 dimmA = &info->dimm[channel][1];
881 dimmB = &info->dimm[channel][0];
882 reg |= (1 << 16);
883 }
884 // dimmA
885 if (dimmA && (dimmA->ranks > 0)) {
886 val32 = dimmA->size_mb / 256;
887 reg = (reg & ~0xff) | val32;
888 val32 = dimmA->ranks - 1;
889 reg = (reg & ~0x20000) | (val32 << 17);
890 val32 = (dimmA->width / 8) - 1;
891 reg = (reg & ~0x80000) | (val32 << 19);
892 }
893 // dimmB
894 if (dimmB && (dimmB->ranks > 0)) {
895 val32 = dimmB->size_mb / 256;
896 reg = (reg & ~0xff00) | (val32 << 8);
897 val32 = dimmB->ranks - 1;
898 reg = (reg & ~0x40000) | (val32 << 18);
899 val32 = (dimmB->width / 8) - 1;
900 reg = (reg & ~0x100000) | (val32 << 20);
901 }
902 reg = (reg & ~0x200000) | (1 << 21); // rank interleave
903 reg = (reg & ~0x400000) | (1 << 22); // enhanced interleave
904
905 // Save MAD-DIMM register
906 if ((dimmA && (dimmA->ranks > 0))
907 || (dimmB && (dimmB->ranks > 0))) {
908 ctrl->mad_dimm[channel] = reg;
909 } else {
910 ctrl->mad_dimm[channel] = 0;
911 }
912 }
913}
914
915static void dram_dimm_set_mapping(ramctr_timing * ctrl)
916{
917 int channel;
918 FOR_ALL_CHANNELS {
919 MCHBAR32(0x5004 + channel * 4) = ctrl->mad_dimm[channel];
920 }
921}
922
923static void dram_zones(ramctr_timing * ctrl, int training)
924{
925 u32 reg, ch0size, ch1size;
926 u8 val;
927 reg = 0;
928 val = 0;
929 if (training) {
930 ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
931 ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
932 } else {
933 ch0size = ctrl->channel_size_mb[0];
934 ch1size = ctrl->channel_size_mb[1];
935 }
936
937 if (ch0size >= ch1size) {
938 reg = MCHBAR32(0x5014);
939 val = ch1size / 256;
940 reg = (reg & ~0xff000000) | val << 24;
941 reg = (reg & ~0xff0000) | (2 * val) << 16;
942 MCHBAR32(0x5014) = reg;
943 MCHBAR32(0x5000) = 0x24;
944 } else {
945 reg = MCHBAR32(0x5014);
946 val = ch0size / 256;
947 reg = (reg & ~0xff000000) | val << 24;
948 reg = (reg & ~0xff0000) | (2 * val) << 16;
949 MCHBAR32(0x5014) = reg;
950 MCHBAR32(0x5000) = 0x21;
951 }
952}
953
954static void dram_memorymap(ramctr_timing * ctrl, int me_uma_size)
955{
956 u32 reg, val, reclaim;
957 u32 tom, gfxstolen, gttsize;
958 size_t tsegsize, mmiosize, toludbase, touudbase, gfxstolenbase, gttbase,
959 tsegbase, mestolenbase;
960 size_t tsegbasedelta, remapbase, remaplimit;
961 uint16_t ggc;
962
963 mmiosize = 0x400;
964
965 ggc = pci_read_config16(NORTHBRIDGE, GGC);
966 if (!(ggc & 2)) {
967 gfxstolen = ((ggc >> 3) & 0x1f) * 32;
968 gttsize = ((ggc >> 8) & 0x3);
969 } else {
970 gfxstolen = 0;
971 gttsize = 0;
972 }
973
974 tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;
975
976 tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];
977
978 mestolenbase = tom - me_uma_size;
979
980 toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize,
981 tom - me_uma_size);
982 gfxstolenbase = toludbase - gfxstolen;
983 gttbase = gfxstolenbase - gttsize;
984
985 tsegbase = gttbase - tsegsize;
986
987 // Round tsegbase down to nearest address aligned to tsegsize
988 tsegbasedelta = tsegbase & (tsegsize - 1);
989 tsegbase &= ~(tsegsize - 1);
990
991 gttbase -= tsegbasedelta;
992 gfxstolenbase -= tsegbasedelta;
993 toludbase -= tsegbasedelta;
994
995 // Test if it is possible to reclaim a hole in the ram addressing
996 if (tom - me_uma_size > toludbase) {
997 // Reclaim is possible
998 reclaim = 1;
999 remapbase = MAX(4096, tom - me_uma_size);
1000 remaplimit =
1001 remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
1002 touudbase = remaplimit + 1;
1003 } else {
1004 // Reclaim not possible
1005 reclaim = 0;
1006 touudbase = tom - me_uma_size;
1007 }
1008
1009 // Update memory map in pci-e configuration space
1010
1011 // TOM (top of memory)
1012 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa0);
1013 val = tom & 0xfff;
1014 reg = (reg & ~0xfff00000) | (val << 20);
1015 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xa0, reg);
1016 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa0, reg);
1017
1018 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa4);
1019 val = tom & 0xfffff000;
1020 reg = (reg & ~0x000fffff) | (val >> 12);
1021 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xa4, reg);
1022 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa4, reg);
1023
1024 // TOLUD (top of low used dram)
1025 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xbc);
1026 val = toludbase & 0xfff;
1027 reg = (reg & ~0xfff00000) | (val << 20);
1028 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xbc, reg);
1029 pcie_write_config32(PCI_DEV(0, 0, 0), 0xbc, reg);
1030
1031 // TOUUD LSB (top of upper usable dram)
1032 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa8);
1033 val = touudbase & 0xfff;
1034 reg = (reg & ~0xfff00000) | (val << 20);
1035 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xa8, reg);
1036 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa8, reg);
1037
1038 // TOUUD MSB
1039 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xac);
1040 val = touudbase & 0xfffff000;
1041 reg = (reg & ~0x000fffff) | (val >> 12);
1042 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xac, reg);
1043 pcie_write_config32(PCI_DEV(0, 0, 0), 0xac, reg);
1044
1045 if (reclaim) {
1046 // REMAP BASE
1047 pcie_write_config32(PCI_DEV(0, 0, 0), 0x90, remapbase << 20);
1048 pcie_write_config32(PCI_DEV(0, 0, 0), 0x94, remapbase >> 12);
1049
1050 // REMAP LIMIT
1051 pcie_write_config32(PCI_DEV(0, 0, 0), 0x98, remaplimit << 20);
1052 pcie_write_config32(PCI_DEV(0, 0, 0), 0x9c, remaplimit >> 12);
1053 }
1054 // TSEG
1055 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb8);
1056 val = tsegbase & 0xfff;
1057 reg = (reg & ~0xfff00000) | (val << 20);
1058 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xb8, reg);
1059 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb8, reg);
1060
1061 // GFX stolen memory
1062 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb0);
1063 val = gfxstolenbase & 0xfff;
1064 reg = (reg & ~0xfff00000) | (val << 20);
1065 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xb0, reg);
1066 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb0, reg);
1067
1068 // GTT stolen memory
1069 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb4);
1070 val = gttbase & 0xfff;
1071 reg = (reg & ~0xfff00000) | (val << 20);
1072 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0xb4, reg);
1073 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb4, reg);
1074
1075 if (me_uma_size) {
1076 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x7c);
1077 val = (0x80000 - me_uma_size) & 0xfffff000;
1078 reg = (reg & ~0x000fffff) | (val >> 12);
1079 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0x7c, reg);
1080 pcie_write_config32(PCI_DEV(0, 0, 0), 0x7c, reg);
1081
1082 // ME base
1083 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x70);
1084 val = mestolenbase & 0xfff;
1085 reg = (reg & ~0xfff00000) | (val << 20);
1086 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0x70, reg);
1087 pcie_write_config32(PCI_DEV(0, 0, 0), 0x70, reg);
1088
1089 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x74);
1090 val = mestolenbase & 0xfffff000;
1091 reg = (reg & ~0x000fffff) | (val >> 12);
1092 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0x74, reg);
1093 pcie_write_config32(PCI_DEV(0, 0, 0), 0x74, reg);
1094
1095 // ME mask
1096 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x78);
1097 val = (0x80000 - me_uma_size) & 0xfff;
1098 reg = (reg & ~0xfff00000) | (val << 20);
1099 reg = (reg & ~0x400) | (1 << 10); // set lockbit on ME mem
1100
1101 reg = (reg & ~0x800) | (1 << 11); // set ME memory enable
1102 printk(BIOS_DEBUG, "PCI:[%x] = %x\n", 0x78, reg);
1103 pcie_write_config32(PCI_DEV(0, 0, 0), 0x78, reg);
1104 }
1105}
1106
1107static void dram_ioregs(ramctr_timing * ctrl)
1108{
1109 u32 reg, comp2;
1110
1111 int channel;
1112
1113 // IO clock
1114 FOR_ALL_CHANNELS {
1115 MCHBAR32(0xc00 + 0x100 * channel) = ctrl->rankmap[channel];
1116 }
1117
1118 // IO command
1119 FOR_ALL_CHANNELS {
1120 MCHBAR32(0x3200 + 0x100 * channel) = ctrl->rankmap[channel];
1121 }
1122
1123 // IO control
1124 FOR_ALL_POPULATED_CHANNELS {
1125 program_timings(ctrl, channel);
1126 }
1127
1128 // Rcomp
1129 printk(BIOS_DEBUG, "RCOMP...");
1130 reg = 0;
1131 while (reg == 0) {
1132 reg = MCHBAR32(0x5084) & 0x10000;
1133 }
1134 printk(BIOS_DEBUG, "done\n");
1135
1136 // Set comp2
1137 comp2 = get_COMP2(ctrl->tCK);
1138 MCHBAR32(0x3714) = comp2;
1139 printk(BIOS_DEBUG, "COMP2 done\n");
1140
1141 // Set comp1
1142 FOR_ALL_POPULATED_CHANNELS {
1143 reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
1144 reg = (reg & ~0xe00) | (1 << 9); //odt
1145 reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
1146 reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
1147 MCHBAR32(0x1810 + channel * 0x100) = reg;
1148 }
1149 printk(BIOS_DEBUG, "COMP1 done\n");
1150
1151 printk(BIOS_DEBUG, "FORCE RCOMP and wait 20us...");
1152 MCHBAR32(0x5f08) |= 0x100;
1153 udelay(20);
1154 printk(BIOS_DEBUG, "done\n");
1155}
1156
1157static void wait_428c(int channel)
1158{
1159 while (1) {
1160 if (read32(DEFAULT_MCHBAR + 0x428c + (channel << 10)) & 0x50)
1161 return;
1162 }
1163}
1164
1165static void write_reset(ramctr_timing * ctrl)
1166{
1167 int channel, slotrank;
1168
1169 /* choose a populated channel. */
1170 channel = (ctrl->rankmap[0]) ? 0 : 1;
1171
1172 wait_428c(channel);
1173
1174 /* choose a populated rank. */
1175 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
1176
Patrick Rudolph371d2912015-10-09 13:33:25 +02001177 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001178 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1179 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x80c01);
1180
1181 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1182 (slotrank << 24) | 0x60000);
1183
1184 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1185
1186 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x400001);
1187 wait_428c(channel);
1188}
1189
1190static void dram_jedecreset(ramctr_timing * ctrl)
1191{
1192 u32 reg, addr;
1193 int channel;
1194
1195 while (!(MCHBAR32(0x5084) & 0x10000)) ;
1196 do {
1197 reg = MCHBAR32(0x428c);
1198 } while ((reg & 0x14) == 0);
1199
1200 // Set state of memory controller
1201 reg = 0x112;
1202 MCHBAR32(0x5030) = reg;
1203 MCHBAR32(0x4ea0) = 0;
1204 reg |= 2; //ddr reset
1205 MCHBAR32(0x5030) = reg;
1206
1207 // Assert dimm reset signal
1208 reg = MCHBAR32(0x5030);
1209 reg &= ~0x2;
1210 MCHBAR32(0x5030) = reg;
1211
1212 // Wait 200us
1213 udelay(200);
1214
1215 // Deassert dimm reset signal
1216 MCHBAR32(0x5030) |= 2;
1217
1218 // Wait 500us
1219 udelay(500);
1220
1221 // Enable DCLK
1222 MCHBAR32(0x5030) |= 4;
1223
1224 // XXX Wait 20ns
1225 udelay(1);
1226
1227 FOR_ALL_CHANNELS {
1228 // Set valid rank CKE
1229 reg = 0;
1230 reg = (reg & ~0xf) | ctrl->rankmap[channel];
1231 addr = 0x400 * channel + 0x42a0;
1232 MCHBAR32(addr) = reg;
1233
1234 // Wait 10ns for ranks to settle
1235 //udelay(0.01);
1236
1237 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
1238 MCHBAR32(addr) = reg;
1239
1240 // Write reset using a NOP
1241 write_reset(ctrl);
1242 }
1243}
1244
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001245static odtmap get_ODT(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001246{
1247 /* Get ODT based on rankmap: */
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001248 int dimms_per_ch = (ctrl->rankmap[channel] & 1)
1249 + ((ctrl->rankmap[channel] >> 2) & 1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001250
1251 if (dimms_per_ch == 1) {
1252 return (const odtmap){60, 60};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001253 } else {
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001254 return (const odtmap){120, 30};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001255 }
1256}
1257
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001258static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001259 int reg, u32 val)
1260{
1261 wait_428c(channel);
1262
1263 printram("MRd: %x <= %x\n", reg, val);
1264
1265 if (ctrl->rank_mirror[channel][slotrank]) {
1266 /* DDR3 Rank1 Address mirror
1267 * swap the following pins:
1268 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1 */
1269 reg = ((reg >> 1) & 1) | ((reg << 1) & 2);
1270 val = (val & ~0x1f8) | ((val >> 1) & 0xa8)
1271 | ((val & 0xa8) << 1);
1272 }
1273
1274 printram("MRd: %x <= %x\n", reg, val);
1275
Patrick Rudolph371d2912015-10-09 13:33:25 +02001276 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001277 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
1278 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
1279 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1280 (slotrank << 24) | (reg << 20) | val | 0x60000);
1281 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1282
Patrick Rudolph371d2912015-10-09 13:33:25 +02001283 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001284 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
1285 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
1286 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
1287 (slotrank << 24) | (reg << 20) | val | 0x60000);
1288 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1289
Patrick Rudolph371d2912015-10-09 13:33:25 +02001290 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001291 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
1292 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1293 0x1001 | (ctrl->tMOD << 16));
1294 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1295 (slotrank << 24) | (reg << 20) | val | 0x60000);
1296 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1297 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
1298}
1299
1300static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
1301{
1302 u16 mr0reg, mch_cas, mch_wr;
1303 static const u8 mch_wr_t[12] = { 1, 2, 3, 4, 0, 5, 0, 6, 0, 7, 0, 0 };
Patrick Rudolph371d2912015-10-09 13:33:25 +02001304
1305 /* DLL Reset - self clearing - set after CLK frequency has been changed */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001306 mr0reg = 0x100;
1307
1308 // Convert CAS to MCH register friendly
1309 if (ctrl->CAS < 12) {
1310 mch_cas = (u16) ((ctrl->CAS - 4) << 1);
1311 } else {
1312 mch_cas = (u16) (ctrl->CAS - 12);
1313 mch_cas = ((mch_cas << 1) | 0x1);
1314 }
1315
1316 // Convert tWR to MCH register friendly
1317 mch_wr = mch_wr_t[ctrl->tWR - 5];
1318
1319 mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
1320 mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
1321 mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001322
1323 // Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001324 mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
1325 return mr0reg;
1326}
1327
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001328static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001329{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001330 write_mrreg(ctrl, channel, rank, 0,
1331 make_mr0(ctrl, rank));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001332}
1333
1334static u32 encode_odt(u32 odt)
1335{
1336 switch (odt) {
1337 case 30:
1338 return (1 << 9) | (1 << 2); // RZQ/8, RZQ/4
1339 case 60:
1340 return (1 << 2); // RZQ/4
1341 case 120:
1342 return (1 << 6); // RZQ/2
1343 default:
1344 case 0:
1345 return 0;
1346 }
1347}
1348
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001349static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001350{
1351 odtmap odt;
1352 u32 mr1reg;
1353
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001354 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001355 mr1reg = 0x2;
1356
1357 mr1reg |= encode_odt(odt.rttnom);
1358
1359 return mr1reg;
1360}
1361
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001362static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001363{
1364 u16 mr1reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001365
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001366 mr1reg = make_mr1(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001367
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001368 write_mrreg(ctrl, channel, rank, 1, mr1reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001369}
1370
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001371static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001372{
1373 u16 pasr, cwl, mr2reg;
1374 odtmap odt;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001375 int srt;
1376
1377 pasr = 0;
1378 cwl = ctrl->CWL - 5;
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001379 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001380
1381 srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;
1382
1383 mr2reg = 0;
1384 mr2reg = (mr2reg & ~0x7) | pasr;
1385 mr2reg = (mr2reg & ~0x38) | (cwl << 3);
1386 mr2reg = (mr2reg & ~0x40) | (ctrl->auto_self_refresh << 6);
1387 mr2reg = (mr2reg & ~0x80) | (srt << 7);
1388 mr2reg |= (odt.rttwr / 60) << 9;
1389
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001390 write_mrreg(ctrl, channel, rank, 2, mr2reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001391}
1392
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001393static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001394{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001395 write_mrreg(ctrl, channel, rank, 3, 0);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001396}
1397
1398static void dram_mrscommands(ramctr_timing * ctrl)
1399{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001400 u8 slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001401 u32 reg, addr;
1402 int channel;
1403
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001404 FOR_ALL_POPULATED_CHANNELS {
1405 FOR_ALL_POPULATED_RANKS {
1406 // MR2
1407 dram_mr2(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001408
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001409 // MR3
1410 dram_mr3(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001411
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001412 // MR1
1413 dram_mr1(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001414
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001415 // MR0
1416 dram_mr0(ctrl, slotrank, channel);
1417 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001418 }
1419
Patrick Rudolph371d2912015-10-09 13:33:25 +02001420 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001421 write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
1422 write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
1423 write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
1424 write32(DEFAULT_MCHBAR + 0x4e10, 0);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001425
1426 /* DRAM command ZQCL */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001427 write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
1428 write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
1429 write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
1430 write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001431
1432 /* execute command queue on all channels ? */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001433 write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
1434
1435 // Drain
1436 FOR_ALL_CHANNELS {
1437 // Wait for ref drained
1438 wait_428c(channel);
1439 }
1440
1441 // Refresh enable
1442 MCHBAR32(0x5030) |= 8;
1443
1444 FOR_ALL_POPULATED_CHANNELS {
1445 addr = 0x400 * channel + 0x4020;
1446 reg = MCHBAR32(addr);
1447 reg &= ~0x200000;
1448 MCHBAR32(addr) = reg;
1449
1450 wait_428c(channel);
1451
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001452 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001453
1454 // Drain
1455 wait_428c(channel);
1456
Patrick Rudolph371d2912015-10-09 13:33:25 +02001457 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001458 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1459 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
1460 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001461 (slotrank << 24) | 0x60000);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001462 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
1463 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x1);
1464
1465 // Drain
1466 wait_428c(channel);
1467 }
1468}
1469
1470const u32 lane_registers[] = {
1471 0x0000, 0x0200, 0x0400, 0x0600,
1472 0x1000, 0x1200, 0x1400, 0x1600,
1473 0x0800
1474};
1475
1476static void program_timings(ramctr_timing * ctrl, int channel)
1477{
1478 u32 reg32, reg_4024, reg_c14, reg_c18, reg_4028;
1479 int lane;
1480 int slotrank, slot;
1481 int full_shift = 0;
1482 u16 slot320c[NUM_SLOTS];
1483
1484 FOR_ALL_POPULATED_RANKS {
1485 if (full_shift < -ctrl->timings[channel][slotrank].val_320c)
1486 full_shift = -ctrl->timings[channel][slotrank].val_320c;
1487 }
1488
1489 for (slot = 0; slot < NUM_SLOTS; slot++)
1490 switch ((ctrl->rankmap[channel] >> (2 * slot)) & 3) {
1491 case 0:
1492 default:
1493 slot320c[slot] = 0x7f;
1494 break;
1495 case 1:
1496 slot320c[slot] =
1497 ctrl->timings[channel][2 * slot + 0].val_320c +
1498 full_shift;
1499 break;
1500 case 2:
1501 slot320c[slot] =
1502 ctrl->timings[channel][2 * slot + 1].val_320c +
1503 full_shift;
1504 break;
1505 case 3:
1506 slot320c[slot] =
1507 (ctrl->timings[channel][2 * slot].val_320c +
1508 ctrl->timings[channel][2 * slot +
1509 1].val_320c) / 2 +
1510 full_shift;
1511 break;
1512 }
1513
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001514 /* enable CMD XOVER */
1515 reg32 = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001516 reg32 |= ((slot320c[0] & 0x3f) << 6) | ((slot320c[0] & 0x40) << 9);
1517 reg32 |= (slot320c[1] & 0x7f) << 18;
1518 reg32 |= (full_shift & 0x3f) | ((full_shift & 0x40) << 6);
1519
1520 MCHBAR32(0x320c + 0x100 * channel) = reg32;
1521
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001522 /* enable CLK XOVER */
1523 reg_c14 = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001524 reg_c18 = 0;
1525
1526 FOR_ALL_POPULATED_RANKS {
1527 int shift =
1528 ctrl->timings[channel][slotrank].val_320c + full_shift;
1529 int offset_val_c14;
1530 if (shift < 0)
1531 shift = 0;
1532 offset_val_c14 = ctrl->reg_c14_offset + shift;
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001533 /* set CLK phase shift */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001534 reg_c14 |= (offset_val_c14 & 0x3f) << (6 * slotrank);
1535 reg_c18 |= ((offset_val_c14 >> 6) & 1) << slotrank;
1536 }
1537
1538 MCHBAR32(0xc14 + channel * 0x100) = reg_c14;
1539 MCHBAR32(0xc18 + channel * 0x100) = reg_c18;
1540
1541 reg_4028 = MCHBAR32(0x4028 + 0x400 * channel);
1542 reg_4028 &= 0xffff0000;
1543
1544 reg_4024 = 0;
1545
1546 FOR_ALL_POPULATED_RANKS {
1547 int post_timA_min_high = 7, post_timA_max_high = 0;
1548 int pre_timA_min_high = 7, pre_timA_max_high = 0;
1549 int shift_402x = 0;
1550 int shift =
1551 ctrl->timings[channel][slotrank].val_320c + full_shift;
1552
1553 if (shift < 0)
1554 shift = 0;
1555
1556 FOR_ALL_LANES {
1557 if (post_timA_min_high >
1558 ((ctrl->timings[channel][slotrank].lanes[lane].
1559 timA + shift) >> 6))
1560 post_timA_min_high =
1561 ((ctrl->timings[channel][slotrank].
1562 lanes[lane].timA + shift) >> 6);
1563 if (pre_timA_min_high >
1564 (ctrl->timings[channel][slotrank].lanes[lane].
1565 timA >> 6))
1566 pre_timA_min_high =
1567 (ctrl->timings[channel][slotrank].
1568 lanes[lane].timA >> 6);
1569 if (post_timA_max_high <
1570 ((ctrl->timings[channel][slotrank].lanes[lane].
1571 timA + shift) >> 6))
1572 post_timA_max_high =
1573 ((ctrl->timings[channel][slotrank].
1574 lanes[lane].timA + shift) >> 6);
1575 if (pre_timA_max_high <
1576 (ctrl->timings[channel][slotrank].lanes[lane].
1577 timA >> 6))
1578 pre_timA_max_high =
1579 (ctrl->timings[channel][slotrank].
1580 lanes[lane].timA >> 6);
1581 }
1582
1583 if (pre_timA_max_high - pre_timA_min_high <
1584 post_timA_max_high - post_timA_min_high)
1585 shift_402x = +1;
1586 else if (pre_timA_max_high - pre_timA_min_high >
1587 post_timA_max_high - post_timA_min_high)
1588 shift_402x = -1;
1589
1590 reg_4028 |=
1591 (ctrl->timings[channel][slotrank].val_4028 + shift_402x -
1592 post_timA_min_high) << (4 * slotrank);
1593 reg_4024 |=
1594 (ctrl->timings[channel][slotrank].val_4024 +
1595 shift_402x) << (8 * slotrank);
1596
1597 FOR_ALL_LANES {
1598 MCHBAR32(lane_registers[lane] + 0x10 + 0x100 * channel +
1599 4 * slotrank)
1600 =
1601 (((ctrl->timings[channel][slotrank].lanes[lane].
1602 timA + shift) & 0x3f)
1603 |
1604 ((ctrl->timings[channel][slotrank].lanes[lane].
1605 rising + shift) << 8)
1606 |
1607 (((ctrl->timings[channel][slotrank].lanes[lane].
1608 timA + shift -
1609 (post_timA_min_high << 6)) & 0x1c0) << 10)
1610 | (ctrl->timings[channel][slotrank].lanes[lane].
1611 falling << 20));
1612
1613 MCHBAR32(lane_registers[lane] + 0x20 + 0x100 * channel +
1614 4 * slotrank)
1615 =
1616 (((ctrl->timings[channel][slotrank].lanes[lane].
1617 timC + shift) & 0x3f)
1618 |
1619 (((ctrl->timings[channel][slotrank].lanes[lane].
1620 timB + shift) & 0x3f) << 8)
1621 |
1622 (((ctrl->timings[channel][slotrank].lanes[lane].
1623 timB + shift) & 0x1c0) << 9)
1624 |
1625 (((ctrl->timings[channel][slotrank].lanes[lane].
1626 timC + shift) & 0x40) << 13));
1627 }
1628 }
1629 MCHBAR32(0x4024 + 0x400 * channel) = reg_4024;
1630 MCHBAR32(0x4028 + 0x400 * channel) = reg_4028;
1631}
1632
1633static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
1634{
1635 wait_428c(channel);
1636
Patrick Rudolph371d2912015-10-09 13:33:25 +02001637 /* DRAM command MRS
1638 * write MR3 MPR enable
1639 * in this mode only RD and RDA are allowed
1640 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001641 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
1642 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1643 (0xc01 | (ctrl->tMOD << 16)));
1644 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1645 (slotrank << 24) | 0x360004);
1646 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1647
Patrick Rudolph371d2912015-10-09 13:33:25 +02001648 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001649 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
1650 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
1651 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
1652 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1653
Patrick Rudolph371d2912015-10-09 13:33:25 +02001654 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001655 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
1656 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1657 0x100f | ((ctrl->CAS + 36) << 16));
1658 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1659 (slotrank << 24) | 0x60000);
1660 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1661
Patrick Rudolph371d2912015-10-09 13:33:25 +02001662 /* DRAM command MRS
1663 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001664 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
1665 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
1666 (0xc01 | (ctrl->tMOD << 16)));
1667 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
1668 (slotrank << 24) | 0x360000);
1669 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
1670
1671 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
1672
1673 wait_428c(channel);
1674}
1675
1676static int does_lane_work(ramctr_timing * ctrl, int channel, int slotrank,
1677 int lane)
1678{
1679 u32 timA = ctrl->timings[channel][slotrank].lanes[lane].timA;
1680 return ((read32
1681 (DEFAULT_MCHBAR + lane_registers[lane] + channel * 0x100 + 4 +
1682 ((timA / 32) & 1) * 4)
1683 >> (timA % 32)) & 1);
1684}
1685
1686struct run {
1687 int middle;
1688 int end;
1689 int start;
1690 int all;
1691 int length;
1692};
1693
1694static struct run get_longest_zero_run(int *seq, int sz)
1695{
1696 int i, ls;
1697 int bl = 0, bs = 0;
1698 struct run ret;
1699
1700 ls = 0;
1701 for (i = 0; i < 2 * sz; i++)
1702 if (seq[i % sz]) {
1703 if (i - ls > bl) {
1704 bl = i - ls;
1705 bs = ls;
1706 }
1707 ls = i + 1;
1708 }
1709 if (bl == 0) {
1710 ret.middle = sz / 2;
1711 ret.start = 0;
1712 ret.end = sz;
1713 ret.all = 1;
1714 return ret;
1715 }
1716
1717 ret.start = bs % sz;
1718 ret.end = (bs + bl - 1) % sz;
1719 ret.middle = (bs + (bl - 1) / 2) % sz;
1720 ret.length = bl;
1721 ret.all = 0;
1722
1723 return ret;
1724}
1725
1726static void discover_timA_coarse(ramctr_timing * ctrl, int channel,
1727 int slotrank, int *upperA)
1728{
1729 int timA;
1730 int statistics[NUM_LANES][128];
1731 int lane;
1732
1733 for (timA = 0; timA < 128; timA++) {
1734 FOR_ALL_LANES {
1735 ctrl->timings[channel][slotrank].lanes[lane].timA = timA;
1736 }
1737 program_timings(ctrl, channel);
1738
1739 test_timA(ctrl, channel, slotrank);
1740
1741 FOR_ALL_LANES {
1742 statistics[lane][timA] =
1743 !does_lane_work(ctrl, channel, slotrank, lane);
1744 printram("Astat: %d, %d, %d, %x, %x\n",
1745 channel, slotrank, lane, timA,
1746 statistics[lane][timA]);
1747 }
1748 }
1749 FOR_ALL_LANES {
1750 struct run rn = get_longest_zero_run(statistics[lane], 128);
1751 ctrl->timings[channel][slotrank].lanes[lane].timA = rn.middle;
1752 upperA[lane] = rn.end;
1753 if (upperA[lane] < rn.middle)
1754 upperA[lane] += 128;
1755 printram("Aval: %d, %d, %d, %x\n", channel, slotrank,
1756 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1757 printram("Aend: %d, %d, %d, %x\n", channel, slotrank,
1758 lane, upperA[lane]);
1759 }
1760}
1761
1762static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
1763 int *upperA)
1764{
1765 int timA_delta;
1766 int statistics[NUM_LANES][51];
1767 int lane, i;
1768
1769 memset(statistics, 0, sizeof(statistics));
1770
1771 for (timA_delta = -25; timA_delta <= 25; timA_delta++) {
1772 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
1773 timA = upperA[lane] + timA_delta + 0x40;
1774 program_timings(ctrl, channel);
1775
1776 for (i = 0; i < 100; i++) {
1777 test_timA(ctrl, channel, slotrank);
1778 FOR_ALL_LANES {
1779 statistics[lane][timA_delta + 25] +=
1780 does_lane_work(ctrl, channel, slotrank,
1781 lane);
1782 }
1783 }
1784 }
1785 FOR_ALL_LANES {
1786 int last_zero, first_all;
1787
1788 for (last_zero = -25; last_zero <= 25; last_zero++)
1789 if (statistics[lane][last_zero + 25])
1790 break;
1791 last_zero--;
1792 for (first_all = -25; first_all <= 25; first_all++)
1793 if (statistics[lane][first_all + 25] == 100)
1794 break;
1795
1796 printram("lane %d: %d, %d\n", lane, last_zero,
1797 first_all);
1798
1799 ctrl->timings[channel][slotrank].lanes[lane].timA =
1800 (last_zero + first_all) / 2 + upperA[lane];
1801 printram("Aval: %d, %d, %d, %x\n", channel, slotrank,
1802 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1803 }
1804}
1805
1806static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
1807 int *upperA)
1808{
1809 int works[NUM_LANES];
1810 int lane;
1811 while (1) {
1812 int all_works = 1, some_works = 0;
1813 program_timings(ctrl, channel);
1814 test_timA(ctrl, channel, slotrank);
1815 FOR_ALL_LANES {
1816 works[lane] =
1817 !does_lane_work(ctrl, channel, slotrank, lane);
1818 if (works[lane])
1819 some_works = 1;
1820 else
1821 all_works = 0;
1822 }
1823 if (all_works)
1824 return;
1825 if (!some_works) {
1826 if (ctrl->timings[channel][slotrank].val_4024 < 2)
1827 die("402x discovery failed");
1828 ctrl->timings[channel][slotrank].val_4024 -= 2;
1829 printram("4024 -= 2;\n");
1830 continue;
1831 }
1832 ctrl->timings[channel][slotrank].val_4028 += 2;
1833 printram("4028 += 2;\n");
1834 if (ctrl->timings[channel][slotrank].val_4028 >= 0x10)
1835 die("402x discovery failed");
1836 FOR_ALL_LANES if (works[lane]) {
1837 ctrl->timings[channel][slotrank].lanes[lane].timA +=
1838 128;
1839 upperA[lane] += 128;
1840 printram("increment %d, %d, %d\n", channel,
1841 slotrank, lane);
1842 }
1843 }
1844}
1845
1846struct timA_minmax {
1847 int timA_min_high, timA_max_high;
1848};
1849
1850static void pre_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1851 struct timA_minmax *mnmx)
1852{
1853 int lane;
1854 mnmx->timA_min_high = 7;
1855 mnmx->timA_max_high = 0;
1856
1857 FOR_ALL_LANES {
1858 if (mnmx->timA_min_high >
1859 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1860 mnmx->timA_min_high =
1861 (ctrl->timings[channel][slotrank].lanes[lane].
1862 timA >> 6);
1863 if (mnmx->timA_max_high <
1864 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1865 mnmx->timA_max_high =
1866 (ctrl->timings[channel][slotrank].lanes[lane].
1867 timA >> 6);
1868 }
1869}
1870
1871static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1872 struct timA_minmax *mnmx)
1873{
1874 struct timA_minmax post;
1875 int shift_402x = 0;
1876
1877 /* Get changed maxima. */
1878 pre_timA_change(ctrl, channel, slotrank, &post);
1879
1880 if (mnmx->timA_max_high - mnmx->timA_min_high <
1881 post.timA_max_high - post.timA_min_high)
1882 shift_402x = +1;
1883 else if (mnmx->timA_max_high - mnmx->timA_min_high >
1884 post.timA_max_high - post.timA_min_high)
1885 shift_402x = -1;
1886 else
1887 shift_402x = 0;
1888
1889 ctrl->timings[channel][slotrank].val_4028 += shift_402x;
1890 ctrl->timings[channel][slotrank].val_4024 += shift_402x;
1891 printram("4024 += %d;\n", shift_402x);
1892 printram("4028 += %d;\n", shift_402x);
1893}
1894
Patrick Rudolph371d2912015-10-09 13:33:25 +02001895/* Compensate the skew between DQS and DQs.
1896 * To ease PCB design a small skew between Data Strobe signals and
1897 * Data Signals is allowed.
1898 * The controller has to measure and compensate this skew for every byte-lane.
1899 * By delaying either all DQs signals or DQS signal, a full phase
1900 * shift can be introduced.
1901 * It is assumed that one byte-lane's DQs signals have the same routing delay.
1902 *
1903 * To measure the actual skew, the DRAM is placed in "read leveling" mode.
1904 * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
1905 * The memory controller iterates over all possible values to do a full phase shift
1906 * and issues read commands.
1907 * With DQS and DQs in phase the data read is expected to alternate on every byte:
1908 * 0xFF 0x00 0xFF ...
1909 * Once the controller has detected this pattern a bit in the result register is
1910 * set for the current phase shift.
1911 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001912static void read_training(ramctr_timing * ctrl)
1913{
1914 int channel, slotrank, lane;
1915
1916 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001917 int all_high, some_high;
1918 int upperA[NUM_LANES];
1919 struct timA_minmax mnmx;
1920
1921 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001922
1923 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001924 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
1925 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1926 0xc01 | (ctrl->tRP << 16));
1927 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1928 (slotrank << 24) | 0x60400);
1929 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1930 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
1931
1932 write32(DEFAULT_MCHBAR + 0x3400, (slotrank << 2) | 0x8001);
1933
1934 ctrl->timings[channel][slotrank].val_4028 = 4;
1935 ctrl->timings[channel][slotrank].val_4024 = 55;
1936 program_timings(ctrl, channel);
1937
1938 discover_timA_coarse(ctrl, channel, slotrank, upperA);
1939
1940 all_high = 1;
1941 some_high = 0;
1942 FOR_ALL_LANES {
1943 if (ctrl->timings[channel][slotrank].lanes[lane].
1944 timA >= 0x40)
1945 some_high = 1;
1946 else
1947 all_high = 0;
1948 }
1949
1950 if (all_high) {
1951 ctrl->timings[channel][slotrank].val_4028--;
1952 printram("4028--;\n");
1953 FOR_ALL_LANES {
1954 ctrl->timings[channel][slotrank].lanes[lane].
1955 timA -= 0x40;
1956 upperA[lane] -= 0x40;
1957
1958 }
1959 } else if (some_high) {
1960 ctrl->timings[channel][slotrank].val_4024++;
1961 ctrl->timings[channel][slotrank].val_4028++;
1962 printram("4024++;\n");
1963 printram("4028++;\n");
1964 }
1965
1966 program_timings(ctrl, channel);
1967
1968 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1969
1970 discover_402x(ctrl, channel, slotrank, upperA);
1971
1972 post_timA_change(ctrl, channel, slotrank, &mnmx);
1973 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1974
1975 discover_timA_fine(ctrl, channel, slotrank, upperA);
1976
1977 post_timA_change(ctrl, channel, slotrank, &mnmx);
1978 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1979
1980 FOR_ALL_LANES {
1981 ctrl->timings[channel][slotrank].lanes[lane].timA -= mnmx.timA_min_high * 0x40;
1982 }
1983 ctrl->timings[channel][slotrank].val_4028 -= mnmx.timA_min_high;
1984 printram("4028 -= %d;\n", mnmx.timA_min_high);
1985
1986 post_timA_change(ctrl, channel, slotrank, &mnmx);
1987
1988 printram("4/8: %d, %d, %x, %x\n", channel, slotrank,
1989 ctrl->timings[channel][slotrank].val_4024,
1990 ctrl->timings[channel][slotrank].val_4028);
1991
1992 FOR_ALL_LANES
1993 printram("%d, %d, %d, %x\n", channel, slotrank,
1994 lane,
1995 ctrl->timings[channel][slotrank].lanes[lane].timA);
1996
1997 write32(DEFAULT_MCHBAR + 0x3400, 0);
1998
Patrick Rudolph9b515682015-10-09 13:43:51 +02001999 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002000 }
2001
2002 FOR_ALL_POPULATED_CHANNELS {
2003 program_timings(ctrl, channel);
2004 }
2005 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2006 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
2007 + 4 * lane, 0);
2008 }
2009}
2010
2011static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
2012{
2013 int lane;
2014
2015 FOR_ALL_LANES {
2016 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel + 4 * lane, 0);
2017 read32(DEFAULT_MCHBAR + 0x4140 + 0x400 * channel + 4 * lane);
2018 }
2019
2020 wait_428c(channel);
2021
Patrick Rudolph371d2912015-10-09 13:33:25 +02002022 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002023 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2024 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2025 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
2026 | 4 | (ctrl->tRCD << 16));
2027
2028 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2029 (slotrank << 24) | (6 << 16));
2030
2031 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
2032
Patrick Rudolph371d2912015-10-09 13:33:25 +02002033 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002034 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2035 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
2036 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2037 (slotrank << 24) | 8);
2038 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2039
Patrick Rudolph371d2912015-10-09 13:33:25 +02002040 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002041 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2042 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
2043 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2044 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2045
Patrick Rudolph371d2912015-10-09 13:33:25 +02002046 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002047 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2048 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2049 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2050 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2051 (slotrank << 24) | 8);
2052 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2053
2054 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2055
2056 wait_428c(channel);
2057
Patrick Rudolph371d2912015-10-09 13:33:25 +02002058 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002059 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2060 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2061 0xc01 | (ctrl->tRP << 16));
2062 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2063 (slotrank << 24) | 0x60400);
2064 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2065
Patrick Rudolph371d2912015-10-09 13:33:25 +02002066 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002067 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2068 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2069 (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
2070 | 8 | (ctrl->CAS << 16));
2071
2072 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2073 (slotrank << 24) | 0x60000);
2074
2075 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
2076
Patrick Rudolph371d2912015-10-09 13:33:25 +02002077 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002078 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2079 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2080 0x40011f4 | (max(ctrl->tRTP, 8) << 16));
2081 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2082 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2083
Patrick Rudolph371d2912015-10-09 13:33:25 +02002084 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002085 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2086 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2087 0xc01 | (ctrl->tRP << 16));
2088 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2089 (slotrank << 24) | 0x60400);
2090 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2091 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2092 wait_428c(channel);
2093}
2094
2095static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
2096{
2097 int timC;
2098 int statistics[NUM_LANES][MAX_TIMC + 1];
2099 int lane;
2100
2101 wait_428c(channel);
2102
Patrick Rudolph371d2912015-10-09 13:33:25 +02002103 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002104 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2105 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2106 0xc01 | (ctrl->tRP << 16));
2107 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2108 (slotrank << 24) | 0x60400);
2109 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2110 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2111
2112 for (timC = 0; timC <= MAX_TIMC; timC++) {
2113 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
2114 timC = timC;
2115 program_timings(ctrl, channel);
2116
2117 test_timC(ctrl, channel, slotrank);
2118
2119 FOR_ALL_LANES {
2120 statistics[lane][timC] =
2121 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2122 0x400 * channel);
2123 printram("Cstat: %d, %d, %d, %x, %x\n",
2124 channel, slotrank, lane, timC,
2125 statistics[lane][timC]);
2126 }
2127 }
2128 FOR_ALL_LANES {
2129 struct run rn =
2130 get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
2131 ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
2132 if (rn.all)
2133 printk(BIOS_CRIT, "timC discovery failed");
2134 printram("Cval: %d, %d, %d, %x\n", channel, slotrank,
2135 lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
2136 }
2137}
2138
2139static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
2140{
2141 int channel, ret = 0;
2142 FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
2143 ret++;
2144 return ret;
2145}
2146
2147static void fill_pattern0(ramctr_timing * ctrl, int channel, u32 a, u32 b)
2148{
2149 unsigned j;
2150 unsigned channel_offset =
2151 get_precedening_channels(ctrl, channel) * 0x40;
2152 printram("channel_offset=%x\n", channel_offset);
2153 for (j = 0; j < 16; j++)
2154 write32((void *)(0x04000000 + channel_offset + 4 * j), j & 2 ? b : a);
2155 sfence();
2156}
2157
2158static int num_of_channels(const ramctr_timing * ctrl)
2159{
2160 int ret = 0;
2161 int channel;
2162 FOR_ALL_POPULATED_CHANNELS ret++;
2163 return ret;
2164}
2165
2166static void fill_pattern1(ramctr_timing * ctrl, int channel)
2167{
2168 unsigned j;
2169 unsigned channel_offset =
2170 get_precedening_channels(ctrl, channel) * 0x40;
2171 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2172 for (j = 0; j < 16; j++)
2173 write32((void *)(0x04000000 + channel_offset + j * 4), 0xffffffff);
2174 for (j = 0; j < 16; j++)
2175 write32((void *)(0x04000000 + channel_offset + channel_step + j * 4), 0);
2176 sfence();
2177}
2178
2179static void precharge(ramctr_timing * ctrl)
2180{
2181 int channel, slotrank, lane;
2182
2183 FOR_ALL_POPULATED_CHANNELS {
2184 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2185 ctrl->timings[channel][slotrank].lanes[lane].falling =
2186 16;
2187 ctrl->timings[channel][slotrank].lanes[lane].rising =
2188 16;
2189 } program_timings(ctrl, channel);
2190
2191 FOR_ALL_POPULATED_RANKS {
2192 wait_428c(channel);
2193
Patrick Rudolph371d2912015-10-09 13:33:25 +02002194 /* DRAM command MRS
2195 * write MR3 MPR enable
2196 * in this mode only RD and RDA are allowed
2197 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002198 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2199 0x1f000);
2200 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2201 0xc01 | (ctrl->tMOD << 16));
2202 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2203 (slotrank << 24) | 0x360004);
2204 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2205
Patrick Rudolph371d2912015-10-09 13:33:25 +02002206 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002207 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2208 0x1f105);
2209 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2210 0x4041003);
2211 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2212 (slotrank << 24) | 0);
2213 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2214
Patrick Rudolph371d2912015-10-09 13:33:25 +02002215 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002216 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2217 0x1f105);
2218 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2219 0x1001 | ((ctrl->CAS + 8) << 16));
2220 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2221 (slotrank << 24) | 0x60000);
2222 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2223
Patrick Rudolph371d2912015-10-09 13:33:25 +02002224 /* DRAM command MRS
2225 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002226 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2227 0x1f000);
2228 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2229 0xc01 | (ctrl->tMOD << 16));
2230 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2231 (slotrank << 24) | 0x360000);
2232 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2233 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2234 0xc0001);
2235
2236 wait_428c(channel);
2237 }
2238
2239 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2240 ctrl->timings[channel][slotrank].lanes[lane].falling =
2241 48;
2242 ctrl->timings[channel][slotrank].lanes[lane].rising =
2243 48;
2244 }
2245
2246 program_timings(ctrl, channel);
2247
2248 FOR_ALL_POPULATED_RANKS {
2249 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002250 /* DRAM command MRS
2251 * write MR3 MPR enable
2252 * in this mode only RD and RDA are allowed
2253 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002254 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2255 0x1f000);
2256 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2257 0xc01 | (ctrl->tMOD << 16));
2258 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2259 (slotrank << 24) | 0x360004);
2260 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2261
Patrick Rudolph371d2912015-10-09 13:33:25 +02002262 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002263 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2264 0x1f105);
2265 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2266 0x4041003);
2267 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2268 (slotrank << 24) | 0);
2269 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2270
Patrick Rudolph371d2912015-10-09 13:33:25 +02002271 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002272 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2273 0x1f105);
2274 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2275 0x1001 | ((ctrl->CAS + 8) << 16));
2276 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2277 (slotrank << 24) | 0x60000);
2278 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2279
Patrick Rudolph371d2912015-10-09 13:33:25 +02002280 /* DRAM command MRS
2281 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002282 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2283 0x1f000);
2284 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2285 0xc01 | (ctrl->tMOD << 16));
2286
2287 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2288 (slotrank << 24) | 0x360000);
2289 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2290
2291 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2292 0xc0001);
2293 wait_428c(channel);
2294 }
2295 }
2296}
2297
2298static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
2299{
Patrick Rudolph371d2912015-10-09 13:33:25 +02002300 /* enable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002301 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002302 0x80 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002303
2304 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002305 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002306 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
2307 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2308 0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
2309 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2310 8 | (slotrank << 24));
2311 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2312
Patrick Rudolph371d2912015-10-09 13:33:25 +02002313 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002314 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
2315 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2316 0x4000c01 | ((ctrl->CAS + 38) << 16));
2317 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2318 (slotrank << 24) | 4);
2319 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2320
2321 write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
2322 wait_428c(channel);
2323
Patrick Rudolph371d2912015-10-09 13:33:25 +02002324 /* disable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002325 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002326 0x1080 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002327}
2328
2329static void discover_timB(ramctr_timing * ctrl, int channel, int slotrank)
2330{
2331 int timB;
2332 int statistics[NUM_LANES][128];
2333 int lane;
2334
2335 write32(DEFAULT_MCHBAR + 0x3400, 0x108052 | (slotrank << 2));
2336
2337 for (timB = 0; timB < 128; timB++) {
2338 FOR_ALL_LANES {
2339 ctrl->timings[channel][slotrank].lanes[lane].timB = timB;
2340 }
2341 program_timings(ctrl, channel);
2342
2343 test_timB(ctrl, channel, slotrank);
2344
2345 FOR_ALL_LANES {
2346 statistics[lane][timB] =
2347 !((read32
2348 (DEFAULT_MCHBAR + lane_registers[lane] +
2349 channel * 0x100 + 4 + ((timB / 32) & 1) * 4)
2350 >> (timB % 32)) & 1);
2351 printram("Bstat: %d, %d, %d, %x, %x\n",
2352 channel, slotrank, lane, timB,
2353 statistics[lane][timB]);
2354 }
2355 }
2356 FOR_ALL_LANES {
2357 struct run rn = get_longest_zero_run(statistics[lane], 128);
Vladimir Serbinenko3141eac2016-01-29 19:42:02 +01002358 ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002359 if (rn.all)
2360 die("timB discovery failed");
2361 printram("Bval: %d, %d, %d, %x\n", channel, slotrank,
2362 lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
2363 }
2364}
2365
2366static int get_timB_high_adjust(u64 val)
2367{
2368 int i;
2369
2370 /* good */
2371 if (val == 0xffffffffffffffffLL)
2372 return 0;
2373
2374 if (val >= 0xf000000000000000LL) {
2375 /* needs negative adjustment */
2376 for (i = 0; i < 8; i++)
2377 if (val << (8 * (7 - i) + 4))
2378 return -i;
2379 } else {
2380 /* needs positive adjustment */
2381 for (i = 0; i < 8; i++)
2382 if (val >> (8 * (7 - i) + 4))
2383 return i;
2384 }
2385 return 8;
2386}
2387
2388static void adjust_high_timB(ramctr_timing * ctrl)
2389{
2390 int channel, slotrank, lane, old;
2391 write32(DEFAULT_MCHBAR + 0x3400, 0x200);
2392 FOR_ALL_POPULATED_CHANNELS {
2393 fill_pattern1(ctrl, channel);
2394 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 1);
2395 }
2396 FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
2397
2398 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x10001);
2399
2400 wait_428c(channel);
2401
Patrick Rudolph371d2912015-10-09 13:33:25 +02002402 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002403 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2404 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2405 0xc01 | (ctrl->tRCD << 16));
2406 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2407 (slotrank << 24) | 0x60000);
2408 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2409
Patrick Rudolph371d2912015-10-09 13:33:25 +02002410 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002411 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2412 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
2413 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2414 (slotrank << 24) | 0x8);
2415 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2416
Patrick Rudolph371d2912015-10-09 13:33:25 +02002417 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002418 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2419 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
2420 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2421 (slotrank << 24));
2422 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
2423
Patrick Rudolph371d2912015-10-09 13:33:25 +02002424 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002425 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2426 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2427 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2428 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2429 (slotrank << 24) | 0x8);
2430 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2431
2432 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2433
2434 wait_428c(channel);
2435
Patrick Rudolph371d2912015-10-09 13:33:25 +02002436 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002437 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2438 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2439 0xc01 | ((ctrl->tRP) << 16));
2440 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2441 (slotrank << 24) | 0x60400);
2442 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2443
Patrick Rudolph371d2912015-10-09 13:33:25 +02002444 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002445 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2446 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2447 0xc01 | ((ctrl->tRCD) << 16));
2448 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2449 (slotrank << 24) | 0x60000);
2450 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2451
Patrick Rudolph371d2912015-10-09 13:33:25 +02002452 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002453 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
2454 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2455 0x4000c01 |
2456 ((ctrl->tRP +
2457 ctrl->timings[channel][slotrank].val_4024 +
2458 ctrl->timings[channel][slotrank].val_4028) << 16));
2459 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2460 (slotrank << 24) | 0x60008);
2461 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2462
2463 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
2464 wait_428c(channel);
2465 FOR_ALL_LANES {
2466 u64 res =
2467 read32(DEFAULT_MCHBAR + lane_registers[lane] +
2468 0x100 * channel + 4);
2469 res |=
2470 ((u64) read32(DEFAULT_MCHBAR + lane_registers[lane] +
2471 0x100 * channel + 8)) << 32;
2472 old = ctrl->timings[channel][slotrank].lanes[lane].timB;
2473 ctrl->timings[channel][slotrank].lanes[lane].timB +=
2474 get_timB_high_adjust(res) * 64;
2475
2476 printk(BIOS_DEBUG, "High adjust %d:%016llx\n", lane, res);
2477 printram("Bval+: %d, %d, %d, %x -> %x\n", channel,
2478 slotrank, lane, old,
2479 ctrl->timings[channel][slotrank].lanes[lane].
2480 timB);
2481 }
2482 }
2483 write32(DEFAULT_MCHBAR + 0x3400, 0);
2484}
2485
2486static void write_op(ramctr_timing * ctrl, int channel)
2487{
2488 int slotrank;
2489
2490 wait_428c(channel);
2491
2492 /* choose an existing rank. */
2493 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2494
Patrick Rudolph371d2912015-10-09 13:33:25 +02002495 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002496 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2497 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2498
2499 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2500 (slotrank << 24) | 0x60000);
2501
2502 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2503
2504 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2505 wait_428c(channel);
2506}
2507
Patrick Rudolph371d2912015-10-09 13:33:25 +02002508/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
2509 * DDR3 adopted the fly-by topology. The data and strobes signals reach
2510 * the chips at different times with respect to command, address and
2511 * clock signals.
2512 * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
2513 * shift can be introduced.
2514 * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
2515 *
2516 * To find the required phase shift the DRAM is placed in "write leveling" mode.
2517 * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
2518 * sampled value on the data lanes (DQs).
2519 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002520static void write_training(ramctr_timing * ctrl)
2521{
2522 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002523
2524 FOR_ALL_POPULATED_CHANNELS
2525 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
2526 read32(DEFAULT_MCHBAR + 0x4008 +
2527 0x400 * channel) | 0x8000000);
2528
2529 FOR_ALL_POPULATED_CHANNELS {
2530 write_op(ctrl, channel);
2531 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2532 read32(DEFAULT_MCHBAR + 0x4020 +
2533 0x400 * channel) | 0x200000);
2534 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002535
2536 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002537 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2538 FOR_ALL_POPULATED_CHANNELS {
2539 write_op(ctrl, channel);
2540 }
2541
Patrick Rudolph371d2912015-10-09 13:33:25 +02002542 /* enable write leveling on all ranks
2543 * disable all DQ outputs
2544 * only NOP is allowed in this mode */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002545 FOR_ALL_CHANNELS
2546 FOR_ALL_POPULATED_RANKS
2547 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002548 make_mr1(ctrl, slotrank, channel) | 0x1080);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002549
2550 write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
2551
Patrick Rudolph9b515682015-10-09 13:43:51 +02002552 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002553
Patrick Rudolph371d2912015-10-09 13:33:25 +02002554 /* set any valid value for timB, it gets corrected later */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002555 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2556 discover_timB(ctrl, channel, slotrank);
2557
Patrick Rudolph371d2912015-10-09 13:33:25 +02002558 /* disable write leveling on all ranks */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002559 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2560 write_mrreg(ctrl, channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002561 slotrank, 1, make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002562
2563 write32(DEFAULT_MCHBAR + 0x3400, 0);
2564
2565 FOR_ALL_POPULATED_CHANNELS
2566 wait_428c(channel);
2567
Patrick Rudolph371d2912015-10-09 13:33:25 +02002568 /* refresh enable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002569 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
2570
2571 FOR_ALL_POPULATED_CHANNELS {
2572 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2573 ~0x00200000 & read32(DEFAULT_MCHBAR + 0x4020 +
2574 0x400 * channel));
2575 read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
2576 wait_428c(channel);
2577
Patrick Rudolph371d2912015-10-09 13:33:25 +02002578 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002579 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2580 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
2581 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
2582 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2583
2584 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2585 wait_428c(channel);
2586 }
2587
Patrick Rudolph9b515682015-10-09 13:43:51 +02002588 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002589
2590 printram("CPE\n");
2591 precharge(ctrl);
2592 printram("CPF\n");
2593
2594 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2595 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2596 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2597 0);
2598 }
2599
2600 FOR_ALL_POPULATED_CHANNELS {
2601 fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
2602 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2603 }
2604
2605 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2606 discover_timC(ctrl, channel, slotrank);
2607
2608 FOR_ALL_POPULATED_CHANNELS
2609 program_timings(ctrl, channel);
2610
Patrick Rudolph371d2912015-10-09 13:33:25 +02002611 /* measure and adjust timB timings */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002612 adjust_high_timB(ctrl);
2613
2614 FOR_ALL_POPULATED_CHANNELS
2615 program_timings(ctrl, channel);
2616
2617 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2618 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2619 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2620 0);
2621 }
2622}
2623
2624static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
2625{
2626 struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
2627 int timC_delta;
2628 int lanes_ok = 0;
2629 int ctr = 0;
2630 int lane;
2631
2632 for (timC_delta = -5; timC_delta <= 5; timC_delta++) {
2633 FOR_ALL_LANES {
2634 ctrl->timings[channel][slotrank].lanes[lane].timC =
2635 saved_rt.lanes[lane].timC + timC_delta;
2636 }
2637 program_timings(ctrl, channel);
2638 FOR_ALL_LANES {
2639 write32(DEFAULT_MCHBAR + 4 * lane + 0x4f40, 0);
2640 }
2641
2642 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2643
2644 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002645 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002646 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2647 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2648 ((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
2649 | 8 | (ctrl->tRCD << 16));
2650
2651 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2652 (slotrank << 24) | ctr | 0x60000);
2653
2654 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002655 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002656 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
2657 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2658 0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
2659 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2660 (slotrank << 24));
2661 write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
2662 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
2663
Patrick Rudolph371d2912015-10-09 13:33:25 +02002664 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002665 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2666 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2667 0x4001020 | (max(ctrl->tRTP, 8) << 16));
2668 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2669 (slotrank << 24));
2670 write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
2671 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
2672
Patrick Rudolph371d2912015-10-09 13:33:25 +02002673 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002674 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2675 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
2676 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2677 (slotrank << 24) | 0x60400);
2678 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2679
2680 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2681 wait_428c(channel);
2682 FOR_ALL_LANES {
2683 u32 r32 =
2684 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2685 0x400 * channel);
2686
2687 if (r32 == 0)
2688 lanes_ok |= 1 << lane;
2689 }
2690 ctr++;
2691 if (lanes_ok == ((1 << NUM_LANES) - 1))
2692 break;
2693 }
2694
2695 ctrl->timings[channel][slotrank] = saved_rt;
2696
2697 printram("3lanes: %x\n", lanes_ok);
2698 return lanes_ok != ((1 << NUM_LANES) - 1);
2699}
2700
2701#include "raminit_patterns.h"
2702
2703static void fill_pattern5(ramctr_timing * ctrl, int channel, int patno)
2704{
2705 unsigned i, j;
2706 unsigned channel_offset =
2707 get_precedening_channels(ctrl, channel) * 0x40;
2708 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2709
2710 if (patno) {
2711 u8 base8 = 0x80 >> ((patno - 1) % 8);
2712 u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
2713 for (i = 0; i < 32; i++) {
2714 for (j = 0; j < 16; j++) {
2715 u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;
2716 if (invert[patno - 1][i] & (1 << (j / 2)))
2717 val = ~val;
2718 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2719 j * 4), val);
2720 }
2721 }
2722
2723 } else {
2724 for (i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
2725 for (j = 0; j < 16; j++)
2726 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2727 j * 4), pattern[i][j]);
2728 }
2729 sfence();
2730 }
2731}
2732
2733static void reprogram_320c(ramctr_timing * ctrl)
2734{
2735 int channel, slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002736
2737 FOR_ALL_POPULATED_CHANNELS {
2738 wait_428c(channel);
2739
2740 /* choose an existing rank. */
2741 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2742
Patrick Rudolph371d2912015-10-09 13:33:25 +02002743 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002744 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2745 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2746
2747 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2748 (slotrank << 24) | 0x60000);
2749
2750 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2751
2752 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2753 wait_428c(channel);
2754 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2755 read32(DEFAULT_MCHBAR + 0x4020 +
2756 0x400 * channel) | 0x200000);
2757 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002758
2759 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002760 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2761 FOR_ALL_POPULATED_CHANNELS {
2762 wait_428c(channel);
2763
2764 /* choose an existing rank. */
2765 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2766
Patrick Rudolph371d2912015-10-09 13:33:25 +02002767 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002768 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2769 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2770
2771 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2772 (slotrank << 24) | 0x60000);
2773
2774 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2775
2776 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2777 wait_428c(channel);
2778 }
2779
2780 /* jedec reset */
2781 dram_jedecreset(ctrl);
2782 /* mrs commands. */
2783 dram_mrscommands(ctrl);
2784
Patrick Rudolph9b515682015-10-09 13:43:51 +02002785 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002786}
2787
2788#define MIN_C320C_LEN 13
2789
2790static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
2791{
2792 struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
2793 int channel, slotrank;
2794 int c320c;
2795 int stat[NUM_SLOTRANKS][256];
2796
2797 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2798 saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
2799 }
2800
2801 FOR_ALL_POPULATED_CHANNELS {
2802 ctrl->cmd_stretch[channel] = cmd_stretch;
2803 }
2804
2805 FOR_ALL_POPULATED_CHANNELS
2806 MCHBAR32(0x4004 + 0x400 * channel) =
2807 ctrl->tRRD
2808 | (ctrl->tRTP << 4)
2809 | (ctrl->tCKE << 8)
2810 | (ctrl->tWTR << 12)
2811 | (ctrl->tFAW << 16)
2812 | (ctrl->tWR << 24)
2813 | (ctrl->cmd_stretch[channel] << 30);
2814
2815
2816 FOR_ALL_CHANNELS {
2817 int delta = 0;
2818 if (ctrl->cmd_stretch[channel] == 2)
2819 delta = 2;
2820 else if (ctrl->cmd_stretch[channel] == 0)
2821 delta = 4;
2822
2823 FOR_ALL_POPULATED_RANKS {
2824 ctrl->timings[channel][slotrank].val_4024 -= delta;
2825 }
2826 }
2827
2828 FOR_ALL_POPULATED_CHANNELS {
2829 for (c320c = -127; c320c <= 127; c320c++) {
2830 FOR_ALL_POPULATED_RANKS {
2831 ctrl->timings[channel][slotrank].val_320c = c320c;
2832 }
2833 program_timings(ctrl, channel);
2834 reprogram_320c(ctrl);
2835 FOR_ALL_POPULATED_RANKS {
2836 stat[slotrank][c320c + 127] =
2837 test_320c(ctrl, channel, slotrank);
2838 printram("3stat: %d, %d, %d: %d\n",
2839 channel, slotrank, c320c,
2840 stat[slotrank][c320c + 127]);
2841 }
2842 }
2843 FOR_ALL_POPULATED_RANKS {
2844 struct run rn =
2845 get_longest_zero_run(stat[slotrank], 255);
2846 ctrl->timings[channel][slotrank].val_320c =
2847 rn.middle - 127;
2848 printram("3val: %d, %d: %d\n", channel,
2849 slotrank,
2850 ctrl->timings[channel][slotrank].val_320c);
2851 if (rn.all || rn.length < MIN_C320C_LEN) {
2852 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2853 ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
2854 }
2855 return 0;
2856 }
2857 }
2858 }
2859 return 1;
2860}
2861
Patrick Rudolph371d2912015-10-09 13:33:25 +02002862/* Adjust CMD phase shift and try multiple command rates.
2863 * A command rate of 2T doubles the time needed for address and
2864 * command decode. */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002865static void command_training(ramctr_timing * ctrl)
2866{
2867 int channel;
2868
2869 FOR_ALL_POPULATED_CHANNELS {
2870 fill_pattern5(ctrl, channel, 0);
2871 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2872 }
2873
2874 /* try command rate 1T and 2T */
2875 if (!try_cmd_stretch(ctrl, 0) && !try_cmd_stretch(ctrl, 2))
2876 die("c320c discovery failed");
2877
2878 FOR_ALL_POPULATED_CHANNELS {
2879 program_timings(ctrl, channel);
2880 }
2881
2882 reprogram_320c(ctrl);
2883}
2884
2885static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
2886 int *edges)
2887{
2888 int edge;
2889 int statistics[NUM_LANES][MAX_EDGE_TIMING + 1];
2890 int lane;
2891
2892 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
2893 FOR_ALL_LANES {
2894 ctrl->timings[channel][slotrank].lanes[lane].rising =
2895 edge;
2896 ctrl->timings[channel][slotrank].lanes[lane].falling =
2897 edge;
2898 }
2899 printram("edge %02x\n", edge);
2900 program_timings(ctrl, channel);
2901
2902 FOR_ALL_LANES {
2903 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2904 4 * lane, 0);
2905 read32(DEFAULT_MCHBAR + 0x400 * channel + 4 * lane +
2906 0x4140);
2907 }
2908
2909 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002910 /* DRAM command MRS
2911 * write MR3 MPR enable
2912 * in this mode only RD and RDA are allowed
2913 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002914 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
2915 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2916 (0xc01 | (ctrl->tMOD << 16)));
2917 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2918 (slotrank << 24) | 0x360004);
2919 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2920
Patrick Rudolph371d2912015-10-09 13:33:25 +02002921 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002922 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
2923 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
2924 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2925 (slotrank << 24));
2926 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2927
Patrick Rudolph371d2912015-10-09 13:33:25 +02002928 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002929 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2930 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2931 0x1001 | ((ctrl->CAS + 8) << 16));
2932 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2933 (slotrank << 24) | 0x60000);
2934 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2935
Patrick Rudolph371d2912015-10-09 13:33:25 +02002936 /* DRAM command MRS
2937 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002938 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
2939 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2940 (0xc01 | (ctrl->tMOD << 16)));
2941 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2942 (slotrank << 24) | 0x360000);
2943 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2944
2945 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2946
2947 wait_428c(channel);
2948
2949 FOR_ALL_LANES {
2950 statistics[lane][edge] =
2951 read32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2952 lane * 4);
2953 }
2954 }
2955 FOR_ALL_LANES {
2956 struct run rn =
2957 get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
2958 edges[lane] = rn.middle;
2959 if (rn.all)
2960 die("edge discovery failed");
2961 printram("eval %d, %d, %d, %02x\n", channel, slotrank,
2962 lane, edges[lane]);
2963 }
2964}
2965
2966static void discover_edges(ramctr_timing * ctrl)
2967{
2968 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
2969 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
2970 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002971
2972 write32(DEFAULT_MCHBAR + 0x3400, 0);
2973
Patrick Rudolph9b515682015-10-09 13:43:51 +02002974 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002975
2976 FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
2977 write32(DEFAULT_MCHBAR + 4 * lane +
2978 0x400 * channel + 0x4080, 0);
2979 }
2980
2981 FOR_ALL_POPULATED_CHANNELS {
2982 fill_pattern0(ctrl, channel, 0, 0);
2983 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2984 FOR_ALL_LANES {
2985 read32(DEFAULT_MCHBAR + 0x400 * channel +
2986 lane * 4 + 0x4140);
2987 }
2988
2989 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2990 ctrl->timings[channel][slotrank].lanes[lane].falling =
2991 16;
2992 ctrl->timings[channel][slotrank].lanes[lane].rising =
2993 16;
2994 }
2995
2996 program_timings(ctrl, channel);
2997
2998 FOR_ALL_POPULATED_RANKS {
2999 wait_428c(channel);
3000
Patrick Rudolph371d2912015-10-09 13:33:25 +02003001 /* DRAM command MRS
3002 * MR3 enable MPR
3003 * write MR3 MPR enable
3004 * in this mode only RD and RDA are allowed
3005 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003006 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3007 0x1f000);
3008 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3009 0xc01 | (ctrl->tMOD << 16));
3010 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3011 (slotrank << 24) | 0x360004);
3012 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3013
Patrick Rudolph371d2912015-10-09 13:33:25 +02003014 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003015 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3016 0x1f105);
3017 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3018 0x4041003);
3019 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3020 (slotrank << 24) | 0);
3021 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3022
Patrick Rudolph371d2912015-10-09 13:33:25 +02003023 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003024 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3025 0x1f105);
3026 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3027 0x1001 | ((ctrl->CAS + 8) << 16));
3028 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3029 (slotrank << 24) | 0x60000);
3030 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3031
Patrick Rudolph371d2912015-10-09 13:33:25 +02003032 /* DRAM command MRS
3033 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003034 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3035 0x1f000);
3036 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3037 0xc01 | (ctrl->tMOD << 16));
3038 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3039 (slotrank << 24) | 0x360000);
3040 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3041 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3042 0xc0001);
3043
3044 wait_428c(channel);
3045 }
3046
Patrick Rudolph371d2912015-10-09 13:33:25 +02003047 /* XXX: check any measured value ? */
3048
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003049 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3050 ctrl->timings[channel][slotrank].lanes[lane].falling =
3051 48;
3052 ctrl->timings[channel][slotrank].lanes[lane].rising =
3053 48;
3054 }
3055
3056 program_timings(ctrl, channel);
3057
3058 FOR_ALL_POPULATED_RANKS {
3059 wait_428c(channel);
3060
Patrick Rudolph371d2912015-10-09 13:33:25 +02003061 /* DRAM command MRS
3062 * MR3 enable MPR
3063 * write MR3 MPR enable
3064 * in this mode only RD and RDA are allowed
3065 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003066 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3067 0x1f000);
3068 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3069 0xc01 | (ctrl->tMOD << 16));
3070 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3071 (slotrank << 24) | 0x360004);
3072 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3073
Patrick Rudolph371d2912015-10-09 13:33:25 +02003074 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003075 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3076 0x1f105);
3077 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3078 0x4041003);
3079 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3080 (slotrank << 24) | 0);
3081 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3082
Patrick Rudolph371d2912015-10-09 13:33:25 +02003083 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003084 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3085 0x1f105);
3086 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3087 0x1001 | ((ctrl->CAS + 8) << 16));
3088 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3089 (slotrank << 24) | 0x60000);
3090 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3091
Patrick Rudolph371d2912015-10-09 13:33:25 +02003092 /* DRAM command MRS
3093 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003094 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3095 0x1f000);
3096 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3097 0xc01 | (ctrl->tMOD << 16));
3098 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3099 (slotrank << 24) | 0x360000);
3100 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3101
3102 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3103 0xc0001);
3104 wait_428c(channel);
3105 }
3106
Patrick Rudolph371d2912015-10-09 13:33:25 +02003107 /* XXX: check any measured value ? */
3108
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003109 FOR_ALL_LANES {
3110 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
3111 lane * 4,
3112 ~read32(DEFAULT_MCHBAR + 0x4040 +
3113 0x400 * channel + lane * 4) & 0xff);
3114 }
3115
3116 fill_pattern0(ctrl, channel, 0, 0xffffffff);
3117 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3118 }
3119
3120 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3121 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
3122
3123 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3124 discover_edges_real(ctrl, channel, slotrank,
3125 falling_edges[channel][slotrank]);
3126 }
3127
3128 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
3129
3130 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3131 discover_edges_real(ctrl, channel, slotrank,
3132 rising_edges[channel][slotrank]);
3133 }
3134
3135 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3136
3137 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3138 ctrl->timings[channel][slotrank].lanes[lane].falling =
3139 falling_edges[channel][slotrank][lane];
3140 ctrl->timings[channel][slotrank].lanes[lane].rising =
3141 rising_edges[channel][slotrank][lane];
3142 }
3143
3144 FOR_ALL_POPULATED_CHANNELS {
3145 program_timings(ctrl, channel);
3146 }
3147
3148 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3149 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3150 0);
3151 }
3152}
3153
3154static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
3155 int slotrank, int *edges)
3156{
3157 int edge;
3158 u32 raw_statistics[MAX_EDGE_TIMING + 1];
3159 int statistics[MAX_EDGE_TIMING + 1];
3160 const int reg3000b24[] = { 0, 0xc, 0x2c };
3161 int lane, i;
3162 int lower[NUM_LANES];
3163 int upper[NUM_LANES];
3164 int pat;
3165
3166 FOR_ALL_LANES {
3167 lower[lane] = 0;
3168 upper[lane] = MAX_EDGE_TIMING;
3169 }
3170
3171 for (i = 0; i < 3; i++) {
3172 write32(DEFAULT_MCHBAR + 0x3000 + 0x100 * channel,
3173 reg3000b24[i] << 24);
3174 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3175 fill_pattern5(ctrl, channel, pat);
3176 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
3177 printram("patterned\n");
3178 printram("[%x] = 0x%08x\n(%d, %d)\n",
3179 0x3000 + 0x100 * channel, reg3000b24[i] << 24, channel,
3180 slotrank);
3181 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3182 FOR_ALL_LANES {
3183 ctrl->timings[channel][slotrank].lanes[lane].
3184 rising = edge;
3185 ctrl->timings[channel][slotrank].lanes[lane].
3186 falling = edge;
3187 }
3188 program_timings(ctrl, channel);
3189
3190 FOR_ALL_LANES {
3191 write32(DEFAULT_MCHBAR + 0x4340 +
3192 0x400 * channel + 4 * lane, 0);
3193 read32(DEFAULT_MCHBAR + 0x400 * channel +
3194 4 * lane + 0x4140);
3195 }
3196 wait_428c(channel);
3197
Patrick Rudolph371d2912015-10-09 13:33:25 +02003198 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003199 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3200 0x1f006);
3201 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3202 0x4 | (ctrl->tRCD << 16)
3203 | (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) <<
3204 10));
3205 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3206 (slotrank << 24) | 0x60000);
3207 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
3208 0x240);
3209
Patrick Rudolph371d2912015-10-09 13:33:25 +02003210 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003211 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3212 0x1f201);
3213 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3214 0x8005020 | ((ctrl->tWTR + ctrl->CWL + 8) <<
3215 16));
3216 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3217 (slotrank << 24));
3218 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
3219 0x242);
3220
Patrick Rudolph371d2912015-10-09 13:33:25 +02003221 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003222 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3223 0x1f105);
3224 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3225 0x4005020 | (max(ctrl->tRTP, 8) << 16));
3226 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3227 (slotrank << 24));
3228 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
3229 0x242);
3230
Patrick Rudolph371d2912015-10-09 13:33:25 +02003231 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003232 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3233 0x1f002);
3234 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3235 0xc01 | (ctrl->tRP << 16));
3236 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3237 (slotrank << 24) | 0x60400);
3238 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3239
3240 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3241 0xc0001);
3242 wait_428c(channel);
3243 FOR_ALL_LANES {
3244 read32(DEFAULT_MCHBAR + 0x4340 +
3245 0x400 * channel + lane * 4);
3246 }
3247
3248 raw_statistics[edge] =
3249 MCHBAR32(0x436c + 0x400 * channel);
3250 }
3251 FOR_ALL_LANES {
3252 struct run rn;
3253 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++)
3254 statistics[edge] =
3255 ! !(raw_statistics[edge] & (1 << lane));
3256 rn = get_longest_zero_run(statistics,
3257 MAX_EDGE_TIMING + 1);
3258 printram("edges: %d, %d, %d: 0x%x-0x%x-0x%x, 0x%x-0x%x\n",
3259 channel, slotrank, i, rn.start, rn.middle,
3260 rn.end, rn.start + ctrl->edge_offset[i],
3261 rn.end - ctrl->edge_offset[i]);
3262 lower[lane] =
3263 max(rn.start + ctrl->edge_offset[i], lower[lane]);
3264 upper[lane] =
3265 min(rn.end - ctrl->edge_offset[i], upper[lane]);
3266 edges[lane] = (lower[lane] + upper[lane]) / 2;
Patrick Rudolph9733e282015-08-16 17:06:30 +02003267 if (rn.all || (lower[lane] > upper[lane]))
3268 die("edge write discovery failed");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003269
3270 }
3271 }
3272 }
3273
3274 write32(DEFAULT_MCHBAR + 0x3000, 0);
3275 printram("CPA\n");
3276}
3277
3278static void discover_edges_write(ramctr_timing * ctrl)
3279{
3280 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3281 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3282 int channel, slotrank, lane;
3283
3284 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3285 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
3286
3287 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3288 discover_edges_write_real(ctrl, channel, slotrank,
3289 falling_edges[channel][slotrank]);
3290 }
3291
3292 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
3293
3294 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3295 discover_edges_write_real(ctrl, channel, slotrank,
3296 rising_edges[channel][slotrank]);
3297 }
3298
3299 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3300
3301 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3302 ctrl->timings[channel][slotrank].lanes[lane].falling =
3303 falling_edges[channel][slotrank][lane];
3304 ctrl->timings[channel][slotrank].lanes[lane].rising =
3305 rising_edges[channel][slotrank][lane];
3306 }
3307
3308 FOR_ALL_POPULATED_CHANNELS
3309 program_timings(ctrl, channel);
3310
3311 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3312 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3313 0);
3314 }
3315}
3316
3317static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
3318{
3319 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003320 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003321 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
3322 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3323 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD)
3324 << 10) | (ctrl->tRCD << 16) | 4);
3325 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3326 (slotrank << 24) | 0x60000);
3327 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
3328
Patrick Rudolph371d2912015-10-09 13:33:25 +02003329 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003330 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
3331 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3332 0x80011e0 |
3333 ((ctrl->tWTR + ctrl->CWL + 8) << 16));
3334 write32(DEFAULT_MCHBAR + 0x4204 +
3335 0x400 * channel, (slotrank << 24));
3336 write32(DEFAULT_MCHBAR + 0x4214 +
3337 0x400 * channel, 0x242);
3338
Patrick Rudolph371d2912015-10-09 13:33:25 +02003339 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003340 write32(DEFAULT_MCHBAR + 0x4228 +
3341 0x400 * channel, 0x1f105);
3342 write32(DEFAULT_MCHBAR + 0x4238 +
3343 0x400 * channel,
3344 0x40011e0 | (max(ctrl->tRTP, 8) << 16));
3345 write32(DEFAULT_MCHBAR + 0x4208 +
3346 0x400 * channel, (slotrank << 24));
3347 write32(DEFAULT_MCHBAR + 0x4218 +
3348 0x400 * channel, 0x242);
3349
Patrick Rudolph371d2912015-10-09 13:33:25 +02003350 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003351 write32(DEFAULT_MCHBAR + 0x422c +
3352 0x400 * channel, 0x1f002);
3353 write32(DEFAULT_MCHBAR + 0x423c +
3354 0x400 * channel,
3355 0x1001 | (ctrl->tRP << 16));
3356 write32(DEFAULT_MCHBAR + 0x420c +
3357 0x400 * channel,
3358 (slotrank << 24) | 0x60400);
3359 write32(DEFAULT_MCHBAR + 0x421c +
3360 0x400 * channel, 0);
3361
3362 write32(DEFAULT_MCHBAR + 0x4284 +
3363 0x400 * channel, 0xc0001);
3364 wait_428c(channel);
3365}
3366
3367static void discover_timC_write(ramctr_timing * ctrl)
3368{
3369 const u8 rege3c_b24[3] = { 0, 0xf, 0x2f };
3370 int i, pat;
3371
3372 int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3373 int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3374 int channel, slotrank, lane;
3375
3376 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3377 lower[channel][slotrank][lane] = 0;
3378 upper[channel][slotrank][lane] = MAX_TIMC;
3379 }
3380
3381 write32(DEFAULT_MCHBAR + 0x4ea8, 1);
3382
3383 for (i = 0; i < 3; i++)
3384 FOR_ALL_POPULATED_CHANNELS {
3385 write32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100),
3386 (rege3c_b24[i] << 24)
3387 | (read32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100))
3388 & ~0x3f000000));
3389 udelay(2);
3390 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3391 FOR_ALL_POPULATED_RANKS {
3392 int timC;
3393 u32 raw_statistics[MAX_TIMC + 1];
3394 int statistics[MAX_TIMC + 1];
3395
3396 fill_pattern5(ctrl, channel, pat);
3397 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
3398 for (timC = 0; timC < MAX_TIMC + 1; timC++) {
3399 FOR_ALL_LANES
3400 ctrl->timings[channel][slotrank].lanes[lane].timC = timC;
3401 program_timings(ctrl, channel);
3402
3403 test_timC_write (ctrl, channel, slotrank);
3404
3405 raw_statistics[timC] =
3406 MCHBAR32(0x436c + 0x400 * channel);
3407 }
3408 FOR_ALL_LANES {
3409 struct run rn;
3410 for (timC = 0; timC <= MAX_TIMC; timC++)
3411 statistics[timC] =
3412 !!(raw_statistics[timC] &
3413 (1 << lane));
3414 rn = get_longest_zero_run(statistics,
3415 MAX_TIMC + 1);
3416 if (rn.all)
3417 die("timC write discovery failed");
3418 printram("timC: %d, %d, %d: 0x%x-0x%x-0x%x, 0x%x-0x%x\n",
3419 channel, slotrank, i, rn.start,
3420 rn.middle, rn.end,
3421 rn.start + ctrl->timC_offset[i],
3422 rn.end - ctrl->timC_offset[i]);
3423 lower[channel][slotrank][lane] =
3424 max(rn.start + ctrl->timC_offset[i],
3425 lower[channel][slotrank][lane]);
3426 upper[channel][slotrank][lane] =
3427 min(rn.end - ctrl->timC_offset[i],
3428 upper[channel][slotrank][lane]);
3429
3430 }
3431 }
3432 }
3433 }
3434
3435 FOR_ALL_CHANNELS {
3436 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3437 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3438 ~0x3f000000));
3439 udelay(2);
3440 }
3441
3442 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3443
3444 printram("CPB\n");
3445
3446 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3447 printram("timC [%d, %d, %d] = 0x%x\n", channel,
3448 slotrank, lane,
3449 (lower[channel][slotrank][lane] +
3450 upper[channel][slotrank][lane]) / 2);
3451 ctrl->timings[channel][slotrank].lanes[lane].timC =
3452 (lower[channel][slotrank][lane] +
3453 upper[channel][slotrank][lane]) / 2;
3454 }
3455 FOR_ALL_POPULATED_CHANNELS {
3456 program_timings(ctrl, channel);
3457 }
3458}
3459
3460static void normalize_training(ramctr_timing * ctrl)
3461{
3462 int channel, slotrank, lane;
3463 int mat = 0;
3464
3465 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3466 int delta;
3467 FOR_ALL_LANES mat =
3468 max(ctrl->timings[channel][slotrank].lanes[lane].timA, mat);
3469 delta = (mat >> 6) - ctrl->timings[channel][slotrank].val_4028;
3470 ctrl->timings[channel][slotrank].val_4024 += delta;
3471 ctrl->timings[channel][slotrank].val_4028 += delta;
3472 }
3473
3474 FOR_ALL_POPULATED_CHANNELS {
3475 program_timings(ctrl, channel);
3476 }
3477}
3478
3479static void write_controller_mr(ramctr_timing * ctrl)
3480{
3481 int channel, slotrank;
3482
3483 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3484 write32(DEFAULT_MCHBAR + 0x0004 + (channel << 8) +
3485 lane_registers[slotrank], make_mr0(ctrl, slotrank));
3486 write32(DEFAULT_MCHBAR + 0x0008 + (channel << 8) +
Patrick Rudolph7e513d12016-01-10 14:22:34 +01003487 lane_registers[slotrank],
3488 make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003489 }
3490}
3491
3492static void channel_test(ramctr_timing * ctrl)
3493{
3494 int channel, slotrank, lane;
3495
3496 FOR_ALL_POPULATED_CHANNELS
3497 if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000)
3498 die("Mini channel test failed (1)\n");
3499 FOR_ALL_POPULATED_CHANNELS {
3500 fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
3501
3502 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3503 }
3504
3505 for (slotrank = 0; slotrank < 4; slotrank++)
3506 FOR_ALL_CHANNELS
3507 if (ctrl->rankmap[channel] & (1 << slotrank)) {
3508 FOR_ALL_LANES {
3509 write32(DEFAULT_MCHBAR + (0x4f40 + 4 * lane), 0);
3510 write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
3511 }
3512 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003513 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003514 write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
3515 write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
3516 write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
3517 0x00060000 | (slotrank << 24));
3518 write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003519 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003520 write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
3521 write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
3522 write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
3523 0x00000000 | (slotrank << 24));
3524 write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003525 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003526 write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
3527 write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
3528 write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
3529 0x00000000 | (slotrank << 24));
3530 write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003531 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003532 write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
3533 write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
3534 write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),
3535 0x00060400 | (slotrank << 24));
3536 write32(DEFAULT_MCHBAR + 0x421c + (channel << 10), 0x00000240);
3537 write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
3538 wait_428c(channel);
3539 FOR_ALL_LANES
3540 if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane))
3541 die("Mini channel test failed (2)\n");
3542 }
3543}
3544
3545static void set_scrambling_seed(ramctr_timing * ctrl)
3546{
3547 int channel;
3548
3549 /* FIXME: we hardcode seeds. Do we need to use some PRNG for them?
3550 I don't think so. */
3551 static u32 seeds[NUM_CHANNELS][3] = {
3552 {0x00009a36, 0xbafcfdcf, 0x46d1ab68},
3553 {0x00028bfa, 0x53fe4b49, 0x19ed5483}
3554 };
3555 FOR_ALL_POPULATED_CHANNELS {
3556 MCHBAR32(0x4020 + 0x400 * channel) &= ~0x10000000;
3557 write32(DEFAULT_MCHBAR + 0x4034, seeds[channel][0]);
3558 write32(DEFAULT_MCHBAR + 0x403c, seeds[channel][1]);
3559 write32(DEFAULT_MCHBAR + 0x4038, seeds[channel][2]);
3560 }
3561}
3562
3563static void set_4f8c(void)
3564{
3565 struct cpuid_result cpures;
3566 u32 cpu;
3567
3568 cpures = cpuid(0);
3569 cpu = (cpures.eax);
3570 if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
3571 MCHBAR32(0x4f8c) = 0x141D1519;
3572 } else {
3573 MCHBAR32(0x4f8c) = 0x551D1519;
3574 }
3575}
3576
3577static void prepare_training(ramctr_timing * ctrl)
3578{
3579 int channel;
3580
3581 FOR_ALL_POPULATED_CHANNELS {
3582 // Always drive command bus
3583 MCHBAR32(0x4004 + 0x400 * channel) |= 0x20000000;
3584 }
3585
3586 udelay(1);
3587
3588 FOR_ALL_POPULATED_CHANNELS {
3589 wait_428c(channel);
3590 }
3591}
3592
3593static void set_4008c(ramctr_timing * ctrl)
3594{
3595 int channel, slotrank;
3596 u32 reg;
3597 FOR_ALL_POPULATED_CHANNELS {
3598 u32 b20, b4_8_12;
3599 int min_320c = 10000;
3600 int max_320c = -10000;
3601
3602 FOR_ALL_POPULATED_RANKS {
3603 max_320c = max(ctrl->timings[channel][slotrank].val_320c, max_320c);
3604 min_320c = min(ctrl->timings[channel][slotrank].val_320c, min_320c);
3605 }
3606
3607 if (max_320c - min_320c > 51)
3608 b20 = 0;
3609 else
3610 b20 = ctrl->ref_card_offset[channel];
3611
3612 if (ctrl->reg_320c_range_threshold < max_320c - min_320c)
3613 b4_8_12 = 0x3330;
3614 else
3615 b4_8_12 = 0x2220;
3616
3617 reg = read32(DEFAULT_MCHBAR + 0x400c + (channel << 10));
3618 write32(DEFAULT_MCHBAR + 0x400c + (channel << 10),
3619 (reg & 0xFFF0FFFF)
3620 | (ctrl->ref_card_offset[channel] << 16)
3621 | (ctrl->ref_card_offset[channel] << 18));
3622 write32(DEFAULT_MCHBAR + 0x4008 + (channel << 10),
3623 0x0a000000
3624 | (b20 << 20)
3625 | ((ctrl->ref_card_offset[channel] + 2) << 16)
3626 | b4_8_12);
3627 }
3628}
3629
3630static void set_42a0(ramctr_timing * ctrl)
3631{
3632 int channel;
3633 FOR_ALL_POPULATED_CHANNELS {
3634 write32(DEFAULT_MCHBAR + (0x42a0 + 0x400 * channel),
3635 0x00001000 | ctrl->rankmap[channel]);
3636 MCHBAR32(0x4004 + 0x400 * channel) &= ~0x20000000; // OK
3637 }
3638}
3639
3640static int encode_5d10(int ns)
3641{
3642 return (ns + 499) / 500;
3643}
3644
3645/* FIXME: values in this function should be hardware revision-dependent. */
3646static void final_registers(ramctr_timing * ctrl)
3647{
3648 int channel;
3649 int t1_cycles = 0, t1_ns = 0, t2_ns;
3650 int t3_ns;
3651 u32 r32;
3652
3653 write32(DEFAULT_MCHBAR + 0x4cd4, 0x00000046);
3654
3655 write32(DEFAULT_MCHBAR + 0x400c, (read32(DEFAULT_MCHBAR + 0x400c) & 0xFFFFCFFF) | 0x1000); // OK
3656 write32(DEFAULT_MCHBAR + 0x440c, (read32(DEFAULT_MCHBAR + 0x440c) & 0xFFFFCFFF) | 0x1000); // OK
3657 write32(DEFAULT_MCHBAR + 0x4cb0, 0x00000740);
3658 write32(DEFAULT_MCHBAR + 0x4380, 0x00000aaa); // OK
3659 write32(DEFAULT_MCHBAR + 0x4780, 0x00000aaa); // OK
3660 write32(DEFAULT_MCHBAR + 0x4f88, 0x5f7003ff); // OK
3661 write32(DEFAULT_MCHBAR + 0x5064, 0x00073000 | ctrl->reg_5064b0); // OK
3662
3663 FOR_ALL_CHANNELS {
3664 switch (ctrl->rankmap[channel]) {
3665 /* Unpopulated channel. */
3666 case 0:
3667 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0);
3668 break;
3669 /* Only single-ranked dimms. */
3670 case 1:
3671 case 4:
3672 case 5:
3673 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x373131);
3674 break;
3675 /* Dual-ranked dimms present. */
3676 default:
3677 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x9b6ea1);
3678 break;
3679 }
3680 }
3681
3682 write32 (DEFAULT_MCHBAR + 0x5880, 0xca9171e5);
3683 write32 (DEFAULT_MCHBAR + 0x5888,
3684 (read32 (DEFAULT_MCHBAR + 0x5888) & ~0xffffff) | 0xe4d5d0);
3685 write32 (DEFAULT_MCHBAR + 0x58a8, read32 (DEFAULT_MCHBAR + 0x58a8) & ~0x1f);
3686 write32 (DEFAULT_MCHBAR + 0x4294,
3687 (read32 (DEFAULT_MCHBAR + 0x4294) & ~0x30000)
3688 | (1 << 16));
3689 write32 (DEFAULT_MCHBAR + 0x4694,
3690 (read32 (DEFAULT_MCHBAR + 0x4694) & ~0x30000)
3691 | (1 << 16));
3692
3693 MCHBAR32(0x5030) |= 1; // OK
3694 MCHBAR32(0x5030) |= 0x80; // OK
3695 MCHBAR32(0x5f18) = 0xfa; // OK
3696
3697 /* Find a populated channel. */
3698 FOR_ALL_POPULATED_CHANNELS
3699 break;
3700
3701 t1_cycles = ((read32(DEFAULT_MCHBAR + 0x4290 + channel * 0x400) >> 8) & 0xff);
3702 r32 = read32(DEFAULT_MCHBAR + 0x5064);
3703 if (r32 & 0x20000)
3704 t1_cycles += (r32 & 0xfff);
3705 t1_cycles += (read32(DEFAULT_MCHBAR + channel * 0x400 + 0x42a4) & 0xfff);
3706 t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
3707 if (!(r32 & 0x20000))
3708 t1_ns += 500;
3709
3710 t2_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f10) >> 8) & 0xfff);
3711 if ( read32(DEFAULT_MCHBAR + 0x5f00) & 8 )
3712 {
3713 t3_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f20) >> 8) & 0xfff);
3714 t3_ns += 10 * (read32(DEFAULT_MCHBAR + 0x5f18) & 0xff);
3715 }
3716 else
3717 {
3718 t3_ns = 500;
3719 }
3720 printk(BIOS_DEBUG, "t123: %d, %d, %d\n",
3721 t1_ns, t2_ns, t3_ns);
3722 write32 (DEFAULT_MCHBAR + 0x5d10,
3723 ((encode_5d10(t1_ns) + encode_5d10(t2_ns)) << 16)
3724 | (encode_5d10(t1_ns) << 8)
3725 | ((encode_5d10(t3_ns) + encode_5d10(t2_ns) + encode_5d10(t1_ns)) << 24)
3726 | (read32(DEFAULT_MCHBAR + 0x5d10) & 0xC0C0C0C0)
3727 | 0xc);
3728}
3729
3730static void save_timings(ramctr_timing * ctrl)
3731{
3732 struct mrc_data_container *mrcdata;
3733 int output_len = ALIGN(sizeof (*ctrl), 16);
3734
3735 /* Save the MRC S3 restore data to cbmem */
3736 mrcdata = cbmem_add
3737 (CBMEM_ID_MRCDATA,
3738 output_len + sizeof(struct mrc_data_container));
3739
3740 printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
3741 ctrl, mrcdata, output_len);
3742
3743 mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
3744 mrcdata->mrc_data_size = output_len;
3745 mrcdata->reserved = 0;
3746 memcpy(mrcdata->mrc_data, ctrl, sizeof (*ctrl));
3747
3748 /* Zero the unused space in aligned buffer. */
3749 if (output_len > sizeof (*ctrl))
3750 memset(mrcdata->mrc_data+sizeof (*ctrl), 0,
3751 output_len - sizeof (*ctrl));
3752
3753 mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
3754 mrcdata->mrc_data_size);
3755}
3756
3757static void restore_timings(ramctr_timing * ctrl)
3758{
3759 int channel, slotrank, lane;
3760
3761 FOR_ALL_POPULATED_CHANNELS
3762 MCHBAR32(0x4004 + 0x400 * channel) =
3763 ctrl->tRRD
3764 | (ctrl->tRTP << 4)
3765 | (ctrl->tCKE << 8)
3766 | (ctrl->tWTR << 12)
3767 | (ctrl->tFAW << 16)
3768 | (ctrl->tWR << 24)
3769 | (ctrl->cmd_stretch[channel] << 30);
3770
3771 udelay(1);
3772
3773 FOR_ALL_POPULATED_CHANNELS {
3774 wait_428c(channel);
3775 }
3776
3777 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3778 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
3779 + 4 * lane, 0);
3780 }
3781
3782 FOR_ALL_POPULATED_CHANNELS
3783 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
3784 read32(DEFAULT_MCHBAR + 0x4008 +
3785 0x400 * channel) | 0x8000000);
3786
3787 FOR_ALL_POPULATED_CHANNELS {
3788 udelay (1);
3789 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
3790 read32(DEFAULT_MCHBAR + 0x4020 +
3791 0x400 * channel) | 0x200000);
3792 }
3793
3794 printram("CPE\n");
3795
3796 write32(DEFAULT_MCHBAR + 0x3400, 0);
3797 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3798
3799 printram("CP5b\n");
3800
3801 FOR_ALL_POPULATED_CHANNELS {
3802 program_timings(ctrl, channel);
3803 }
3804
3805 u32 reg, addr;
3806
3807 while (!(MCHBAR32(0x5084) & 0x10000)) ;
3808 do {
3809 reg = MCHBAR32(0x428c);
3810 } while ((reg & 0x14) == 0);
3811
3812 // Set state of memory controller
3813 MCHBAR32(0x5030) = 0x116;
3814 MCHBAR32(0x4ea0) = 0;
3815
3816 // Wait 500us
3817 udelay(500);
3818
3819 FOR_ALL_CHANNELS {
3820 // Set valid rank CKE
3821 reg = 0;
3822 reg = (reg & ~0xf) | ctrl->rankmap[channel];
3823 addr = 0x400 * channel + 0x42a0;
3824 MCHBAR32(addr) = reg;
3825
3826 // Wait 10ns for ranks to settle
3827 //udelay(0.01);
3828
3829 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
3830 MCHBAR32(addr) = reg;
3831
3832 // Write reset using a NOP
3833 write_reset(ctrl);
3834 }
3835
3836 /* mrs commands. */
3837 dram_mrscommands(ctrl);
3838
3839 printram("CP5c\n");
3840
3841 write32(DEFAULT_MCHBAR + 0x3000, 0);
3842
3843 FOR_ALL_CHANNELS {
3844 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3845 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3846 ~0x3f000000));
3847 udelay(2);
3848 }
3849
3850 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3851}
3852
3853void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
3854 int s3resume)
3855{
3856 int me_uma_size;
3857 int cbmem_was_inited;
3858
3859 MCHBAR32(0x5f00) |= 1;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003860
Vadim Bendebury7a3f36a2012-04-18 15:47:32 -07003861 report_platform_info();
3862
Stefan Reinauer00636b02012-04-04 00:08:51 +02003863 /* Wait for ME to be ready */
3864 intel_early_me_init();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003865 me_uma_size = intel_early_me_uma_size();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003866
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003867 printk(BIOS_DEBUG, "Starting native Platform init\n");
Stefan Reinauer00636b02012-04-04 00:08:51 +02003868
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003869 u32 reg_5d10;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003870
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003871 wait_txt_clear();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003872
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003873 wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 });
Stefan Reinauer00636b02012-04-04 00:08:51 +02003874
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003875 reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000
3876 if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */
3877 && reg_5d10 && !s3resume) {
3878 write32(DEFAULT_MCHBAR + 0x5d10, 0);
3879 /* Need reset. */
Stefan Reinauer00636b02012-04-04 00:08:51 +02003880 outb(0x6, 0xcf9);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003881
Patrick Georgi546953c2014-11-29 10:38:17 +01003882 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003883 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02003884
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003885 ramctr_timing ctrl;
Vadim Bendebury48a4a7f2012-06-07 18:47:13 -07003886
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003887 memset(&ctrl, 0, sizeof (ctrl));
3888
3889 early_pch_init_native();
3890 early_thermal_init();
3891
3892 ctrl.mobile = mobile;
3893 ctrl.tCK = min_tck;
3894
3895 /* FIXME: for non-S3 we should be able to use timing caching with
3896 proper verification. Right now we use timings only for S3 case.
3897 */
3898 if (s3resume) {
3899 struct mrc_data_container *mrc_cache;
3900
3901 mrc_cache = find_current_mrc_cache();
3902 if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) {
3903 /* Failed S3 resume, reset to come up cleanly */
3904 outb(0x6, 0xcf9);
3905 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003906 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003907 memcpy(&ctrl, mrc_cache->mrc_data, sizeof (ctrl));
Stefan Reinauer00636b02012-04-04 00:08:51 +02003908 }
3909
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003910 if (!s3resume) {
3911 dimm_info info;
Sven Schnelled4ee8082012-07-28 09:28:56 +02003912
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003913 /* Get DDR3 SPD data */
3914 dram_find_spds_ddr3(spds, &info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003915
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003916 /* Find fastest common supported parameters */
3917 dram_find_common_params(&info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003918
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003919 dram_dimm_mapping(&info, &ctrl);
3920 }
3921
3922 /* Set MCU frequency */
3923 dram_freq(&ctrl);
3924
3925 if (!s3resume) {
3926 /* Calculate timings */
3927 dram_timing(&ctrl);
3928 }
3929
3930 /* Set version register */
3931 MCHBAR32(0x5034) = 0xC04EB002;
3932
3933 /* Enable crossover */
3934 dram_xover(&ctrl);
3935
3936 /* Set timing and refresh registers */
3937 dram_timing_regs(&ctrl);
3938
3939 /* Power mode preset */
3940 MCHBAR32(0x4e80) = 0x5500;
3941
3942 /* Set scheduler parameters */
3943 MCHBAR32(0x4c20) = 0x10100005;
3944
3945 /* Set cpu specific register */
3946 set_4f8c();
3947
3948 /* Clear IO reset bit */
3949 MCHBAR32(0x5030) &= ~0x20;
3950
3951 /* Set MAD-DIMM registers */
3952 dram_dimm_set_mapping(&ctrl);
3953 printk(BIOS_DEBUG, "Done dimm mapping\n");
3954
3955 /* Zone config */
3956 dram_zones(&ctrl, 1);
3957
3958 /* Set memory map */
3959 dram_memorymap(&ctrl, me_uma_size);
3960 printk(BIOS_DEBUG, "Done memory map\n");
3961
3962 /* Set IO registers */
3963 dram_ioregs(&ctrl);
3964 printk(BIOS_DEBUG, "Done io registers\n");
3965
3966 udelay(1);
3967
3968 if (s3resume) {
3969 restore_timings(&ctrl);
3970 } else {
3971 /* Do jedec ddr3 reset sequence */
3972 dram_jedecreset(&ctrl);
3973 printk(BIOS_DEBUG, "Done jedec reset\n");
3974
3975 /* MRS commands */
3976 dram_mrscommands(&ctrl);
3977 printk(BIOS_DEBUG, "Done MRS commands\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003978
3979 /* Prepare for memory training */
3980 prepare_training(&ctrl);
3981
3982 read_training(&ctrl);
3983 write_training(&ctrl);
3984
3985 printram("CP5a\n");
3986
3987 discover_edges(&ctrl);
3988
3989 printram("CP5b\n");
3990
3991 command_training(&ctrl);
3992
3993 printram("CP5c\n");
3994
3995 discover_edges_write(&ctrl);
3996
3997 discover_timC_write(&ctrl);
3998
3999 normalize_training(&ctrl);
4000 }
4001
4002 set_4008c(&ctrl);
4003
4004 write_controller_mr(&ctrl);
4005
4006 if (!s3resume) {
4007 channel_test(&ctrl);
4008 }
4009
4010 /* FIXME: should be hardware revision-dependent. */
4011 write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
4012
4013 set_scrambling_seed(&ctrl);
4014
4015 set_42a0(&ctrl);
4016
4017 final_registers(&ctrl);
4018
4019 /* Zone config */
4020 dram_zones(&ctrl, 0);
4021
4022 if (!s3resume)
4023 quick_ram_check();
4024
4025 intel_early_me_status();
4026 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
4027 intel_early_me_status();
4028
Stefan Reinauer00636b02012-04-04 00:08:51 +02004029 report_memory_config();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004030
4031 cbmem_was_inited = !cbmem_recovery(s3resume);
4032 if (!s3resume)
4033 save_timings(&ctrl);
4034 if (s3resume && !cbmem_was_inited) {
4035 /* Failed S3 resume, reset to come up cleanly */
4036 outb(0x6, 0xcf9);
4037 halt();
4038 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02004039}
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004040
4041#define HOST_BRIDGE PCI_DEVFN(0, 0)
4042#define DEFAULT_TCK TCK_800MHZ
4043
4044static unsigned int get_mem_min_tck(void)
4045{
4046 const struct device *dev;
4047 const struct northbridge_intel_sandybridge_config *cfg;
4048
4049 dev = dev_find_slot(0, HOST_BRIDGE);
4050 if (!(dev && dev->chip_info))
4051 return DEFAULT_TCK;
4052
4053 cfg = dev->chip_info;
4054
4055 /* If this is zero, it just means devicetree.cb didn't set it */
4056 if (cfg->max_mem_clock_mhz == 0)
4057 return DEFAULT_TCK;
4058
4059 if (cfg->max_mem_clock_mhz >= 800)
4060 return TCK_800MHZ;
4061 else if (cfg->max_mem_clock_mhz >= 666)
4062 return TCK_666MHZ;
4063 else if (cfg->max_mem_clock_mhz >= 533)
4064 return TCK_533MHZ;
4065 return TCK_400MHZ;
4066}
4067
4068void perform_raminit(int s3resume)
4069{
4070 spd_raw_data spd[4];
4071
4072 post_code(0x3a);
4073
4074 memset (spd, 0, sizeof (spd));
4075 mainboard_get_spd(spd);
4076
4077 timestamp_add_now(TS_BEFORE_INITRAM);
4078
4079 init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume);
4080}