blob: 59f3b3b834995d6525a2903b63d73d0ec7c83b32 [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);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100318 printk(BIOS_DEBUG, "channel[%d] rankmap = 0x%x\n",
319 channel, ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700320 }
321 if ((ctrl->rankmap[channel] & 3) && (ctrl->rankmap[channel] & 0xc)
322 && dimm->dimm[channel][0].reference_card <= 5 && dimm->dimm[channel][1].reference_card <= 5) {
323 const int ref_card_offset_table[6][6] = {
324 { 0, 0, 0, 0, 2, 2, },
325 { 0, 0, 0, 0, 2, 2, },
326 { 0, 0, 0, 0, 2, 2, },
327 { 0, 0, 0, 0, 1, 1, },
328 { 2, 2, 2, 1, 0, 0, },
329 { 2, 2, 2, 1, 0, 0, },
330 };
331 ctrl->ref_card_offset[channel] = ref_card_offset_table[dimm->dimm[channel][0].reference_card]
332 [dimm->dimm[channel][1].reference_card];
333 } else
334 ctrl->ref_card_offset[channel] = 0;
335 }
336
337 if (!dimms)
338 die("No DIMMs were found");
339}
340
341static void dram_find_common_params(const dimm_info * dimms,
342 ramctr_timing * ctrl)
343{
344 size_t valid_dimms;
345 int channel, slot;
346 ctrl->cas_supported = 0xff;
347 valid_dimms = 0;
348 FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) {
349 const dimm_attr *dimm = &dimms->dimm[channel][slot];
350 if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
351 continue;
352 valid_dimms++;
353
354 /* Find all possible CAS combinations */
355 ctrl->cas_supported &= dimm->cas_supported;
356
357 /* Find the smallest common latencies supported by all DIMMs */
358 ctrl->tCK = MAX(ctrl->tCK, dimm->tCK);
359 ctrl->tAA = MAX(ctrl->tAA, dimm->tAA);
360 ctrl->tWR = MAX(ctrl->tWR, dimm->tWR);
361 ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
362 ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
363 ctrl->tRP = MAX(ctrl->tRP, dimm->tRP);
364 ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
365 ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
366 ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
367 ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
368 ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
369 }
370
371 if (!ctrl->cas_supported)
372 die("Unsupported DIMM combination. "
373 "DIMMS do not support common CAS latency");
374 if (!valid_dimms)
375 die("No valid DIMMs found");
376}
377
378static u8 get_CWL(u8 CAS)
379{
380 /* Get CWL based on CAS using the following rule:
381 * _________________________________________
382 * CAS: | 4T | 5T | 6T | 7T | 8T | 9T | 10T | 11T |
383 * CWL: | 5T | 5T | 5T | 6T | 6T | 7T | 7T | 8T |
384 */
385 static const u8 cas_cwl_map[] = { 5, 5, 5, 6, 6, 7, 7, 8 };
386 if (CAS > 11)
387 return 8;
388 return cas_cwl_map[CAS - 4];
389}
390
391/* Frequency multiplier. */
392static u32 get_FRQ(u32 tCK)
393{
394 u32 FRQ;
395 FRQ = 256000 / (tCK * BASEFREQ);
396 if (FRQ > 8)
397 return 8;
398 if (FRQ < 3)
399 return 3;
400 return FRQ;
401}
402
403static u32 get_REFI(u32 tCK)
404{
405 /* Get REFI based on MCU frequency using the following rule:
406 * _________________________________________
407 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
408 * REFI: | 3120 | 4160 | 5200 | 6240 | 7280 | 8320 |
409 */
410 static const u32 frq_refi_map[] =
411 { 3120, 4160, 5200, 6240, 7280, 8320 };
412 return frq_refi_map[get_FRQ(tCK) - 3];
413}
414
415static u8 get_XSOffset(u32 tCK)
416{
417 /* Get XSOffset based on MCU frequency using the following rule:
418 * _________________________
419 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
420 * XSOffset : | 4 | 6 | 7 | 8 | 10 | 11 |
421 */
422 static const u8 frq_xs_map[] = { 4, 6, 7, 8, 10, 11 };
423 return frq_xs_map[get_FRQ(tCK) - 3];
424}
425
426static u8 get_MOD(u32 tCK)
427{
428 /* Get MOD based on MCU frequency using the following rule:
429 * _____________________________
430 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
431 * MOD : | 12 | 12 | 12 | 12 | 15 | 16 |
432 */
433 static const u8 frq_mod_map[] = { 12, 12, 12, 12, 15, 16 };
434 return frq_mod_map[get_FRQ(tCK) - 3];
435}
436
437static u8 get_WLO(u32 tCK)
438{
439 /* Get WLO based on MCU frequency using the following rule:
440 * _______________________
441 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
442 * WLO : | 4 | 5 | 6 | 6 | 8 | 8 |
443 */
444 static const u8 frq_wlo_map[] = { 4, 5, 6, 6, 8, 8 };
445 return frq_wlo_map[get_FRQ(tCK) - 3];
446}
447
448static u8 get_CKE(u32 tCK)
449{
450 /* Get CKE based on MCU frequency using the following rule:
451 * _______________________
452 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
453 * CKE : | 3 | 3 | 4 | 4 | 5 | 6 |
454 */
455 static const u8 frq_cke_map[] = { 3, 3, 4, 4, 5, 6 };
456 return frq_cke_map[get_FRQ(tCK) - 3];
457}
458
459static u8 get_XPDLL(u32 tCK)
460{
461 /* Get XPDLL based on MCU frequency using the following rule:
462 * _____________________________
463 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
464 * XPDLL : | 10 | 13 | 16 | 20 | 23 | 26 |
465 */
466 static const u8 frq_xpdll_map[] = { 10, 13, 16, 20, 23, 26 };
467 return frq_xpdll_map[get_FRQ(tCK) - 3];
468}
469
470static u8 get_XP(u32 tCK)
471{
472 /* Get XP based on MCU frequency using the following rule:
473 * _______________________
474 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
475 * XP : | 3 | 4 | 4 | 5 | 6 | 7 |
476 */
477 static const u8 frq_xp_map[] = { 3, 4, 4, 5, 6, 7 };
478 return frq_xp_map[get_FRQ(tCK) - 3];
479}
480
481static u8 get_AONPD(u32 tCK)
482{
483 /* Get AONPD based on MCU frequency using the following rule:
484 * ________________________
485 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
486 * AONPD : | 4 | 5 | 6 | 8 | 8 | 10 |
487 */
488 static const u8 frq_aonpd_map[] = { 4, 5, 6, 8, 8, 10 };
489 return frq_aonpd_map[get_FRQ(tCK) - 3];
490}
491
492static u32 get_COMP2(u32 tCK)
493{
494 /* Get COMP2 based on MCU frequency using the following rule:
495 * ___________________________________________________________
496 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
497 * COMP : | D6BEDCC | CE7C34C | CA57A4C | C6369CC | C42514C | C21410C |
498 */
499 static const u32 frq_comp2_map[] = { 0xD6BEDCC, 0xCE7C34C, 0xCA57A4C,
500 0xC6369CC, 0xC42514C, 0xC21410C
501 };
502 return frq_comp2_map[get_FRQ(tCK) - 3];
503}
504
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100505static u32 get_XOVER_CLK(u8 rankmap)
506{
507 return rankmap << 24;
508}
509
510static u32 get_XOVER_CMD(u8 rankmap)
511{
512 u32 reg;
513
514 // enable xover cmd
515 reg = 0x4000;
516
517 // enable xover ctl
518 if (rankmap & 0x3)
519 reg |= 0x20000;
520
521 if (rankmap & 0xc)
522 reg |= 0x4000000;
523
524 return reg;
525}
526
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700527static void dram_timing(ramctr_timing * ctrl)
528{
529 u8 val;
530 u32 val32;
531
532 /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure
533 * we cap it if we have faster DIMMs.
534 * Then, align it to the closest JEDEC standard frequency */
535 if (ctrl->tCK <= TCK_1066MHZ) {
536 ctrl->tCK = TCK_1066MHZ;
537 ctrl->edge_offset[0] = 16;
538 ctrl->edge_offset[1] = 7;
539 ctrl->edge_offset[2] = 7;
540 ctrl->timC_offset[0] = 18;
541 ctrl->timC_offset[1] = 7;
542 ctrl->timC_offset[2] = 7;
543 ctrl->reg_c14_offset = 16;
544 ctrl->reg_5064b0 = 0x218;
545 ctrl->reg_320c_range_threshold = 13;
546 } else if (ctrl->tCK <= TCK_933MHZ) {
547 ctrl->tCK = TCK_933MHZ;
548 ctrl->edge_offset[0] = 14;
549 ctrl->edge_offset[1] = 6;
550 ctrl->edge_offset[2] = 6;
551 ctrl->timC_offset[0] = 15;
552 ctrl->timC_offset[1] = 6;
553 ctrl->timC_offset[2] = 6;
554 ctrl->reg_c14_offset = 14;
555 ctrl->reg_5064b0 = 0x1d5;
556 ctrl->reg_320c_range_threshold = 15;
557 } else if (ctrl->tCK <= TCK_800MHZ) {
558 ctrl->tCK = TCK_800MHZ;
559 ctrl->edge_offset[0] = 13;
560 ctrl->edge_offset[1] = 5;
561 ctrl->edge_offset[2] = 5;
562 ctrl->timC_offset[0] = 14;
563 ctrl->timC_offset[1] = 5;
564 ctrl->timC_offset[2] = 5;
565 ctrl->reg_c14_offset = 12;
566 ctrl->reg_5064b0 = 0x193;
567 ctrl->reg_320c_range_threshold = 15;
568 } else if (ctrl->tCK <= TCK_666MHZ) {
569 ctrl->tCK = TCK_666MHZ;
570 ctrl->edge_offset[0] = 10;
571 ctrl->edge_offset[1] = 4;
572 ctrl->edge_offset[2] = 4;
573 ctrl->timC_offset[0] = 11;
574 ctrl->timC_offset[1] = 4;
575 ctrl->timC_offset[2] = 4;
576 ctrl->reg_c14_offset = 10;
577 ctrl->reg_5064b0 = 0x150;
578 ctrl->reg_320c_range_threshold = 16;
579 } else if (ctrl->tCK <= TCK_533MHZ) {
580 ctrl->tCK = TCK_533MHZ;
581 ctrl->edge_offset[0] = 8;
582 ctrl->edge_offset[1] = 3;
583 ctrl->edge_offset[2] = 3;
584 ctrl->timC_offset[0] = 9;
585 ctrl->timC_offset[1] = 3;
586 ctrl->timC_offset[2] = 3;
587 ctrl->reg_c14_offset = 8;
588 ctrl->reg_5064b0 = 0x10d;
589 ctrl->reg_320c_range_threshold = 17;
590 } else {
591 ctrl->tCK = TCK_400MHZ;
592 ctrl->edge_offset[0] = 6;
593 ctrl->edge_offset[1] = 2;
594 ctrl->edge_offset[2] = 2;
595 ctrl->timC_offset[0] = 6;
596 ctrl->timC_offset[1] = 2;
597 ctrl->timC_offset[2] = 2;
598 ctrl->reg_c14_offset = 8;
599 ctrl->reg_5064b0 = 0xcd;
600 ctrl->reg_320c_range_threshold = 17;
601 }
602
603 val32 = (1000 << 8) / ctrl->tCK;
604 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
605
606 /* Find CAS and CWL latencies */
607 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
608 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
609 /* Find lowest supported CAS latency that satisfies the minimum value */
610 while (!((ctrl->cas_supported >> (val - 4)) & 1)
611 && (ctrl->cas_supported >> (val - 4))) {
612 val++;
613 }
614 /* Is CAS supported */
615 if (!(ctrl->cas_supported & (1 << (val - 4))))
616 printk(BIOS_DEBUG, "CAS not supported\n");
617 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
618 ctrl->CAS = val;
619 ctrl->CWL = get_CWL(ctrl->CAS);
620 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
621
622 /* Find tRCD */
623 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
624 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
625
626 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
627 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
628
629 /* Find tRAS */
630 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
631 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
632
633 /* Find tWR */
634 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
635 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
636
637 /* Find tFAW */
638 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
639 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
640
641 /* Find tRRD */
642 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
643 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
644
645 /* Find tRTP */
646 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
647 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
648
649 /* Find tWTR */
650 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
651 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
652
653 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
654 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
655 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
656
657 ctrl->tREFI = get_REFI(ctrl->tCK);
658 ctrl->tMOD = get_MOD(ctrl->tCK);
659 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
660 ctrl->tWLO = get_WLO(ctrl->tCK);
661 ctrl->tCKE = get_CKE(ctrl->tCK);
662 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
663 ctrl->tXP = get_XP(ctrl->tCK);
664 ctrl->tAONPD = get_AONPD(ctrl->tCK);
665}
666
667static void dram_freq(ramctr_timing * ctrl)
668{
669 if (ctrl->tCK > TCK_400MHZ) {
670 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
671 ctrl->tCK = TCK_400MHZ;
672 }
673 while (1) {
674 u8 val2;
675 u32 reg1 = 0;
676
677 /* Step 1 - Set target PCU frequency */
678
679 if (ctrl->tCK <= TCK_1066MHZ) {
680 ctrl->tCK = TCK_1066MHZ;
681 } else if (ctrl->tCK <= TCK_933MHZ) {
682 ctrl->tCK = TCK_933MHZ;
683 } else if (ctrl->tCK <= TCK_800MHZ) {
684 ctrl->tCK = TCK_800MHZ;
685 } else if (ctrl->tCK <= TCK_666MHZ) {
686 ctrl->tCK = TCK_666MHZ;
687 } else if (ctrl->tCK <= TCK_533MHZ) {
688 ctrl->tCK = TCK_533MHZ;
689 } else if (ctrl->tCK <= TCK_400MHZ) {
690 ctrl->tCK = TCK_400MHZ;
691 } else {
692 die ("No lock frequency found");
693 }
694
695 /* Frequency mulitplier. */
696 u32 FRQ = get_FRQ(ctrl->tCK);
697
698 /* Step 2 - Select frequency in the MCU */
699 reg1 = FRQ;
700 reg1 |= 0x80000000; // set running bit
701 MCHBAR32(0x5e00) = reg1;
702 while (reg1 & 0x80000000) {
703 printk(BIOS_DEBUG, " PLL busy...");
704 reg1 = MCHBAR32(0x5e00);
705 }
706 printk(BIOS_DEBUG, "done\n");
707
708 /* Step 3 - Verify lock frequency */
709 reg1 = MCHBAR32(0x5e04);
710 val2 = (u8) reg1;
711 if (val2 >= FRQ) {
712 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
713 (1000 << 8) / ctrl->tCK);
714 return;
715 }
716 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
717 ctrl->tCK++;
718 }
719}
720
721static void dram_xover(ramctr_timing * ctrl)
722{
723 u32 reg;
724 int channel;
725
726 FOR_ALL_CHANNELS {
727 // enable xover clk
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100728 reg = get_XOVER_CLK(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100729 printram("XOVER CLK [%x] = %x\n", channel * 0x100 + 0xc14,
730 reg);
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100731 MCHBAR32(channel * 0x100 + 0xc14) = reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700732
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100733 // enable xover ctl & xover cmd
734 reg = get_XOVER_CMD(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100735 printram("XOVER CMD [%x] = %x\n", 0x100 * channel + 0x320c,
736 reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700737 MCHBAR32(0x100 * channel + 0x320c) = reg;
738 }
739}
740
741static void dram_timing_regs(ramctr_timing * ctrl)
742{
743 u32 reg, addr, val32, cpu, stretch;
744 struct cpuid_result cpures;
745 int channel;
746
747 FOR_ALL_CHANNELS {
748 // DBP
749 reg = 0;
750 reg |= ctrl->tRCD;
751 reg |= (ctrl->tRP << 4);
752 reg |= (ctrl->CAS << 8);
753 reg |= (ctrl->CWL << 12);
754 reg |= (ctrl->tRAS << 16);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100755 printram("DBP [%x] = %x\n", 0x400 * channel + 0x4000, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700756 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100767 printram("RAP [%x] = %x\n", 0x400 * channel + 0x4004, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700768 MCHBAR32(0x400 * channel + 0x4004) = reg;
769
770 // OTHP
771 addr = 0x400 * channel + 0x400c;
772 reg = 0;
773 reg |= ctrl->tXPDLL;
774 reg |= (ctrl->tXP << 5);
775 reg |= (ctrl->tAONPD << 8);
776 reg |= 0xa0000;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100777 printram("OTHP [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700778 MCHBAR32(addr) = reg;
779
780 MCHBAR32(0x400 * channel + 0x4014) = 0;
781
782 MCHBAR32(addr) |= 0x00020000;
783
784 // ODT stretch
785 reg = 0;
786
787 cpures = cpuid(0);
788 cpu = cpures.eax;
789 if (IS_IVY_CPU(cpu)
790 || (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_D2(cpu))) {
791 stretch = 2;
792 addr = 0x400 * channel + 0x400c;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100793 printram("ODT stretch [%x] = %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700794 0x400 * channel + 0x400c, reg);
795 reg = MCHBAR32(addr);
796
797 if (((ctrl->rankmap[channel] & 3) == 0)
798 || (ctrl->rankmap[channel] & 0xc) == 0) {
799
800 // Rank 0 - operate on rank 2
801 reg = (reg & ~0xc0000) | (stretch << 18);
802
803 // Rank 2 - operate on rank 0
804 reg = (reg & ~0x30000) | (stretch << 16);
805
Patrick Rudolpha649a542016-01-17 18:32:06 +0100806 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700807 MCHBAR32(addr) = reg;
808 }
809
810 } else if (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_C(cpu)) {
811 stretch = 3;
812 addr = 0x400 * channel + 0x401c;
813 reg = MCHBAR32(addr);
814
815 if (((ctrl->rankmap[channel] & 3) == 0)
816 || (ctrl->rankmap[channel] & 0xc) == 0) {
817
818 // Rank 0 - operate on rank 2
819 reg = (reg & ~0x3000) | (stretch << 12);
820
821 // Rank 2 - operate on rank 0
822 reg = (reg & ~0xc00) | (stretch << 10);
823
Patrick Rudolpha649a542016-01-17 18:32:06 +0100824 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700825 MCHBAR32(addr) = reg;
826 }
827 } else {
828 stretch = 0;
829 }
830
831 // REFI
832 reg = 0;
833 val32 = ctrl->tREFI;
834 reg = (reg & ~0xffff) | val32;
835 val32 = ctrl->tRFC;
836 reg = (reg & ~0x1ff0000) | (val32 << 16);
837 val32 = (u32) (ctrl->tREFI * 9) / 1024;
838 reg = (reg & ~0xfe000000) | (val32 << 25);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100839 printram("REFI [%x] = %x\n", 0x400 * channel + 0x4298,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700840 reg);
841 MCHBAR32(0x400 * channel + 0x4298) = reg;
842
843 MCHBAR32(0x400 * channel + 0x4294) |= 0xff;
844
845 // SRFTP
846 reg = 0;
847 val32 = tDLLK;
848 reg = (reg & ~0xfff) | val32;
849 val32 = ctrl->tXSOffset;
850 reg = (reg & ~0xf000) | (val32 << 12);
851 val32 = tDLLK - ctrl->tXSOffset;
852 reg = (reg & ~0x3ff0000) | (val32 << 16);
853 val32 = ctrl->tMOD - 8;
854 reg = (reg & ~0xf0000000) | (val32 << 28);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100855 printram("SRFTP [%x] = %x\n", 0x400 * channel + 0x42a4,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700856 reg);
857 MCHBAR32(0x400 * channel + 0x42a4) = reg;
858 }
859}
860
861static void dram_dimm_mapping(dimm_info * info, ramctr_timing * ctrl)
862{
863 u32 reg, val32;
864 int channel;
865
866 FOR_ALL_CHANNELS {
867 dimm_attr *dimmA = 0;
868 dimm_attr *dimmB = 0;
869 reg = 0;
870 val32 = 0;
871 if (info->dimm[channel][0].size_mb >=
872 info->dimm[channel][1].size_mb) {
873 // dimm 0 is bigger, set it to dimmA
874 dimmA = &info->dimm[channel][0];
875 dimmB = &info->dimm[channel][1];
876 reg |= (0 << 16);
877 } else {
878 // dimm 1 is bigger, set it to dimmA
879 dimmA = &info->dimm[channel][1];
880 dimmB = &info->dimm[channel][0];
881 reg |= (1 << 16);
882 }
883 // dimmA
884 if (dimmA && (dimmA->ranks > 0)) {
885 val32 = dimmA->size_mb / 256;
886 reg = (reg & ~0xff) | val32;
887 val32 = dimmA->ranks - 1;
888 reg = (reg & ~0x20000) | (val32 << 17);
889 val32 = (dimmA->width / 8) - 1;
890 reg = (reg & ~0x80000) | (val32 << 19);
891 }
892 // dimmB
893 if (dimmB && (dimmB->ranks > 0)) {
894 val32 = dimmB->size_mb / 256;
895 reg = (reg & ~0xff00) | (val32 << 8);
896 val32 = dimmB->ranks - 1;
897 reg = (reg & ~0x40000) | (val32 << 18);
898 val32 = (dimmB->width / 8) - 1;
899 reg = (reg & ~0x100000) | (val32 << 20);
900 }
901 reg = (reg & ~0x200000) | (1 << 21); // rank interleave
902 reg = (reg & ~0x400000) | (1 << 22); // enhanced interleave
903
904 // Save MAD-DIMM register
905 if ((dimmA && (dimmA->ranks > 0))
906 || (dimmB && (dimmB->ranks > 0))) {
907 ctrl->mad_dimm[channel] = reg;
908 } else {
909 ctrl->mad_dimm[channel] = 0;
910 }
911 }
912}
913
914static void dram_dimm_set_mapping(ramctr_timing * ctrl)
915{
916 int channel;
917 FOR_ALL_CHANNELS {
918 MCHBAR32(0x5004 + channel * 4) = ctrl->mad_dimm[channel];
919 }
920}
921
922static void dram_zones(ramctr_timing * ctrl, int training)
923{
924 u32 reg, ch0size, ch1size;
925 u8 val;
926 reg = 0;
927 val = 0;
928 if (training) {
929 ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
930 ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
931 } else {
932 ch0size = ctrl->channel_size_mb[0];
933 ch1size = ctrl->channel_size_mb[1];
934 }
935
936 if (ch0size >= ch1size) {
937 reg = MCHBAR32(0x5014);
938 val = ch1size / 256;
939 reg = (reg & ~0xff000000) | val << 24;
940 reg = (reg & ~0xff0000) | (2 * val) << 16;
941 MCHBAR32(0x5014) = reg;
942 MCHBAR32(0x5000) = 0x24;
943 } else {
944 reg = MCHBAR32(0x5014);
945 val = ch0size / 256;
946 reg = (reg & ~0xff000000) | val << 24;
947 reg = (reg & ~0xff0000) | (2 * val) << 16;
948 MCHBAR32(0x5014) = reg;
949 MCHBAR32(0x5000) = 0x21;
950 }
951}
952
953static void dram_memorymap(ramctr_timing * ctrl, int me_uma_size)
954{
955 u32 reg, val, reclaim;
956 u32 tom, gfxstolen, gttsize;
957 size_t tsegsize, mmiosize, toludbase, touudbase, gfxstolenbase, gttbase,
958 tsegbase, mestolenbase;
959 size_t tsegbasedelta, remapbase, remaplimit;
960 uint16_t ggc;
961
962 mmiosize = 0x400;
963
964 ggc = pci_read_config16(NORTHBRIDGE, GGC);
965 if (!(ggc & 2)) {
966 gfxstolen = ((ggc >> 3) & 0x1f) * 32;
967 gttsize = ((ggc >> 8) & 0x3);
968 } else {
969 gfxstolen = 0;
970 gttsize = 0;
971 }
972
973 tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;
974
975 tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];
976
977 mestolenbase = tom - me_uma_size;
978
979 toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize,
980 tom - me_uma_size);
981 gfxstolenbase = toludbase - gfxstolen;
982 gttbase = gfxstolenbase - gttsize;
983
984 tsegbase = gttbase - tsegsize;
985
986 // Round tsegbase down to nearest address aligned to tsegsize
987 tsegbasedelta = tsegbase & (tsegsize - 1);
988 tsegbase &= ~(tsegsize - 1);
989
990 gttbase -= tsegbasedelta;
991 gfxstolenbase -= tsegbasedelta;
992 toludbase -= tsegbasedelta;
993
994 // Test if it is possible to reclaim a hole in the ram addressing
995 if (tom - me_uma_size > toludbase) {
996 // Reclaim is possible
997 reclaim = 1;
998 remapbase = MAX(4096, tom - me_uma_size);
999 remaplimit =
1000 remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
1001 touudbase = remaplimit + 1;
1002 } else {
1003 // Reclaim not possible
1004 reclaim = 0;
1005 touudbase = tom - me_uma_size;
1006 }
1007
1008 // Update memory map in pci-e configuration space
Patrick Rudolpha649a542016-01-17 18:32:06 +01001009 printk(BIOS_DEBUG, "Update PCI-E configuration space:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001010
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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001015 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001016 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001021 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001022 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001028 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xbc, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001029 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001035 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001036 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001042 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xac, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001043 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001058 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001059 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001065 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001066 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001072 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001073 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001079 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x7c, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001080 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001086 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x70, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001087 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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001092 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x74, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001093 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
Patrick Rudolpha649a542016-01-17 18:32:06 +01001102 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x78, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001103 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
Patrick Rudolpha649a542016-01-17 18:32:06 +01001129 printram("RCOMP...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001130 reg = 0;
1131 while (reg == 0) {
1132 reg = MCHBAR32(0x5084) & 0x10000;
1133 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001134 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001135
1136 // Set comp2
1137 comp2 = get_COMP2(ctrl->tCK);
1138 MCHBAR32(0x3714) = comp2;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001139 printram("COMP2 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001140
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 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001149 printram("COMP1 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001150
Patrick Rudolpha649a542016-01-17 18:32:06 +01001151 printram("FORCE RCOMP and wait 20us...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001152 MCHBAR32(0x5f08) |= 0x100;
1153 udelay(20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001154 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001155}
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
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001263 if (ctrl->rank_mirror[channel][slotrank]) {
1264 /* DDR3 Rank1 Address mirror
1265 * swap the following pins:
1266 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1 */
1267 reg = ((reg >> 1) & 1) | ((reg << 1) & 2);
1268 val = (val & ~0x1f8) | ((val >> 1) & 0xa8)
1269 | ((val & 0xa8) << 1);
1270 }
1271
Patrick Rudolph371d2912015-10-09 13:33:25 +02001272 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001273 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
1274 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
1275 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1276 (slotrank << 24) | (reg << 20) | val | 0x60000);
1277 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1278
Patrick Rudolph371d2912015-10-09 13:33:25 +02001279 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001280 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
1281 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
1282 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
1283 (slotrank << 24) | (reg << 20) | val | 0x60000);
1284 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1285
Patrick Rudolph371d2912015-10-09 13:33:25 +02001286 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001287 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
1288 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1289 0x1001 | (ctrl->tMOD << 16));
1290 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1291 (slotrank << 24) | (reg << 20) | val | 0x60000);
1292 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1293 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
1294}
1295
1296static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
1297{
1298 u16 mr0reg, mch_cas, mch_wr;
1299 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 +02001300
1301 /* DLL Reset - self clearing - set after CLK frequency has been changed */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001302 mr0reg = 0x100;
1303
1304 // Convert CAS to MCH register friendly
1305 if (ctrl->CAS < 12) {
1306 mch_cas = (u16) ((ctrl->CAS - 4) << 1);
1307 } else {
1308 mch_cas = (u16) (ctrl->CAS - 12);
1309 mch_cas = ((mch_cas << 1) | 0x1);
1310 }
1311
1312 // Convert tWR to MCH register friendly
1313 mch_wr = mch_wr_t[ctrl->tWR - 5];
1314
1315 mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
1316 mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
1317 mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001318
1319 // Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001320 mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
1321 return mr0reg;
1322}
1323
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001324static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001325{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001326 write_mrreg(ctrl, channel, rank, 0,
1327 make_mr0(ctrl, rank));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001328}
1329
1330static u32 encode_odt(u32 odt)
1331{
1332 switch (odt) {
1333 case 30:
1334 return (1 << 9) | (1 << 2); // RZQ/8, RZQ/4
1335 case 60:
1336 return (1 << 2); // RZQ/4
1337 case 120:
1338 return (1 << 6); // RZQ/2
1339 default:
1340 case 0:
1341 return 0;
1342 }
1343}
1344
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001345static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001346{
1347 odtmap odt;
1348 u32 mr1reg;
1349
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001350 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001351 mr1reg = 0x2;
1352
1353 mr1reg |= encode_odt(odt.rttnom);
1354
1355 return mr1reg;
1356}
1357
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001358static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001359{
1360 u16 mr1reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001361
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001362 mr1reg = make_mr1(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001363
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001364 write_mrreg(ctrl, channel, rank, 1, mr1reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001365}
1366
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001367static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001368{
1369 u16 pasr, cwl, mr2reg;
1370 odtmap odt;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001371 int srt;
1372
1373 pasr = 0;
1374 cwl = ctrl->CWL - 5;
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001375 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001376
1377 srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;
1378
1379 mr2reg = 0;
1380 mr2reg = (mr2reg & ~0x7) | pasr;
1381 mr2reg = (mr2reg & ~0x38) | (cwl << 3);
1382 mr2reg = (mr2reg & ~0x40) | (ctrl->auto_self_refresh << 6);
1383 mr2reg = (mr2reg & ~0x80) | (srt << 7);
1384 mr2reg |= (odt.rttwr / 60) << 9;
1385
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001386 write_mrreg(ctrl, channel, rank, 2, mr2reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001387}
1388
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001389static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001390{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001391 write_mrreg(ctrl, channel, rank, 3, 0);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001392}
1393
1394static void dram_mrscommands(ramctr_timing * ctrl)
1395{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001396 u8 slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001397 u32 reg, addr;
1398 int channel;
1399
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001400 FOR_ALL_POPULATED_CHANNELS {
1401 FOR_ALL_POPULATED_RANKS {
1402 // MR2
1403 dram_mr2(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001404
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001405 // MR3
1406 dram_mr3(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001407
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001408 // MR1
1409 dram_mr1(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001410
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001411 // MR0
1412 dram_mr0(ctrl, slotrank, channel);
1413 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001414 }
1415
Patrick Rudolph371d2912015-10-09 13:33:25 +02001416 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001417 write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
1418 write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
1419 write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
1420 write32(DEFAULT_MCHBAR + 0x4e10, 0);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001421
1422 /* DRAM command ZQCL */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001423 write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
1424 write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
1425 write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
1426 write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001427
1428 /* execute command queue on all channels ? */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001429 write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
1430
1431 // Drain
1432 FOR_ALL_CHANNELS {
1433 // Wait for ref drained
1434 wait_428c(channel);
1435 }
1436
1437 // Refresh enable
1438 MCHBAR32(0x5030) |= 8;
1439
1440 FOR_ALL_POPULATED_CHANNELS {
1441 addr = 0x400 * channel + 0x4020;
1442 reg = MCHBAR32(addr);
1443 reg &= ~0x200000;
1444 MCHBAR32(addr) = reg;
1445
1446 wait_428c(channel);
1447
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001448 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001449
1450 // Drain
1451 wait_428c(channel);
1452
Patrick Rudolph371d2912015-10-09 13:33:25 +02001453 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001454 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1455 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
1456 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001457 (slotrank << 24) | 0x60000);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001458 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
1459 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x1);
1460
1461 // Drain
1462 wait_428c(channel);
1463 }
1464}
1465
1466const u32 lane_registers[] = {
1467 0x0000, 0x0200, 0x0400, 0x0600,
1468 0x1000, 0x1200, 0x1400, 0x1600,
1469 0x0800
1470};
1471
1472static void program_timings(ramctr_timing * ctrl, int channel)
1473{
1474 u32 reg32, reg_4024, reg_c14, reg_c18, reg_4028;
1475 int lane;
1476 int slotrank, slot;
1477 int full_shift = 0;
1478 u16 slot320c[NUM_SLOTS];
1479
1480 FOR_ALL_POPULATED_RANKS {
1481 if (full_shift < -ctrl->timings[channel][slotrank].val_320c)
1482 full_shift = -ctrl->timings[channel][slotrank].val_320c;
1483 }
1484
1485 for (slot = 0; slot < NUM_SLOTS; slot++)
1486 switch ((ctrl->rankmap[channel] >> (2 * slot)) & 3) {
1487 case 0:
1488 default:
1489 slot320c[slot] = 0x7f;
1490 break;
1491 case 1:
1492 slot320c[slot] =
1493 ctrl->timings[channel][2 * slot + 0].val_320c +
1494 full_shift;
1495 break;
1496 case 2:
1497 slot320c[slot] =
1498 ctrl->timings[channel][2 * slot + 1].val_320c +
1499 full_shift;
1500 break;
1501 case 3:
1502 slot320c[slot] =
1503 (ctrl->timings[channel][2 * slot].val_320c +
1504 ctrl->timings[channel][2 * slot +
1505 1].val_320c) / 2 +
1506 full_shift;
1507 break;
1508 }
1509
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001510 /* enable CMD XOVER */
1511 reg32 = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001512 reg32 |= ((slot320c[0] & 0x3f) << 6) | ((slot320c[0] & 0x40) << 9);
1513 reg32 |= (slot320c[1] & 0x7f) << 18;
1514 reg32 |= (full_shift & 0x3f) | ((full_shift & 0x40) << 6);
1515
1516 MCHBAR32(0x320c + 0x100 * channel) = reg32;
1517
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001518 /* enable CLK XOVER */
1519 reg_c14 = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001520 reg_c18 = 0;
1521
1522 FOR_ALL_POPULATED_RANKS {
1523 int shift =
1524 ctrl->timings[channel][slotrank].val_320c + full_shift;
1525 int offset_val_c14;
1526 if (shift < 0)
1527 shift = 0;
1528 offset_val_c14 = ctrl->reg_c14_offset + shift;
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001529 /* set CLK phase shift */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001530 reg_c14 |= (offset_val_c14 & 0x3f) << (6 * slotrank);
1531 reg_c18 |= ((offset_val_c14 >> 6) & 1) << slotrank;
1532 }
1533
1534 MCHBAR32(0xc14 + channel * 0x100) = reg_c14;
1535 MCHBAR32(0xc18 + channel * 0x100) = reg_c18;
1536
1537 reg_4028 = MCHBAR32(0x4028 + 0x400 * channel);
1538 reg_4028 &= 0xffff0000;
1539
1540 reg_4024 = 0;
1541
1542 FOR_ALL_POPULATED_RANKS {
1543 int post_timA_min_high = 7, post_timA_max_high = 0;
1544 int pre_timA_min_high = 7, pre_timA_max_high = 0;
1545 int shift_402x = 0;
1546 int shift =
1547 ctrl->timings[channel][slotrank].val_320c + full_shift;
1548
1549 if (shift < 0)
1550 shift = 0;
1551
1552 FOR_ALL_LANES {
1553 if (post_timA_min_high >
1554 ((ctrl->timings[channel][slotrank].lanes[lane].
1555 timA + shift) >> 6))
1556 post_timA_min_high =
1557 ((ctrl->timings[channel][slotrank].
1558 lanes[lane].timA + shift) >> 6);
1559 if (pre_timA_min_high >
1560 (ctrl->timings[channel][slotrank].lanes[lane].
1561 timA >> 6))
1562 pre_timA_min_high =
1563 (ctrl->timings[channel][slotrank].
1564 lanes[lane].timA >> 6);
1565 if (post_timA_max_high <
1566 ((ctrl->timings[channel][slotrank].lanes[lane].
1567 timA + shift) >> 6))
1568 post_timA_max_high =
1569 ((ctrl->timings[channel][slotrank].
1570 lanes[lane].timA + shift) >> 6);
1571 if (pre_timA_max_high <
1572 (ctrl->timings[channel][slotrank].lanes[lane].
1573 timA >> 6))
1574 pre_timA_max_high =
1575 (ctrl->timings[channel][slotrank].
1576 lanes[lane].timA >> 6);
1577 }
1578
1579 if (pre_timA_max_high - pre_timA_min_high <
1580 post_timA_max_high - post_timA_min_high)
1581 shift_402x = +1;
1582 else if (pre_timA_max_high - pre_timA_min_high >
1583 post_timA_max_high - post_timA_min_high)
1584 shift_402x = -1;
1585
1586 reg_4028 |=
1587 (ctrl->timings[channel][slotrank].val_4028 + shift_402x -
1588 post_timA_min_high) << (4 * slotrank);
1589 reg_4024 |=
1590 (ctrl->timings[channel][slotrank].val_4024 +
1591 shift_402x) << (8 * slotrank);
1592
1593 FOR_ALL_LANES {
1594 MCHBAR32(lane_registers[lane] + 0x10 + 0x100 * channel +
1595 4 * slotrank)
1596 =
1597 (((ctrl->timings[channel][slotrank].lanes[lane].
1598 timA + shift) & 0x3f)
1599 |
1600 ((ctrl->timings[channel][slotrank].lanes[lane].
1601 rising + shift) << 8)
1602 |
1603 (((ctrl->timings[channel][slotrank].lanes[lane].
1604 timA + shift -
1605 (post_timA_min_high << 6)) & 0x1c0) << 10)
Patrick Rudolph0188b132016-02-10 19:16:34 +01001606 | ((ctrl->timings[channel][slotrank].lanes[lane].
1607 falling + shift) << 20));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001608
1609 MCHBAR32(lane_registers[lane] + 0x20 + 0x100 * channel +
1610 4 * slotrank)
1611 =
1612 (((ctrl->timings[channel][slotrank].lanes[lane].
1613 timC + shift) & 0x3f)
1614 |
1615 (((ctrl->timings[channel][slotrank].lanes[lane].
1616 timB + shift) & 0x3f) << 8)
1617 |
1618 (((ctrl->timings[channel][slotrank].lanes[lane].
1619 timB + shift) & 0x1c0) << 9)
1620 |
1621 (((ctrl->timings[channel][slotrank].lanes[lane].
1622 timC + shift) & 0x40) << 13));
1623 }
1624 }
1625 MCHBAR32(0x4024 + 0x400 * channel) = reg_4024;
1626 MCHBAR32(0x4028 + 0x400 * channel) = reg_4028;
1627}
1628
1629static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
1630{
1631 wait_428c(channel);
1632
Patrick Rudolph371d2912015-10-09 13:33:25 +02001633 /* DRAM command MRS
1634 * write MR3 MPR enable
1635 * in this mode only RD and RDA are allowed
1636 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001637 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
1638 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1639 (0xc01 | (ctrl->tMOD << 16)));
1640 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1641 (slotrank << 24) | 0x360004);
1642 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1643
Patrick Rudolph371d2912015-10-09 13:33:25 +02001644 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001645 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
1646 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
1647 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
1648 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1649
Patrick Rudolph371d2912015-10-09 13:33:25 +02001650 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001651 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
1652 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1653 0x100f | ((ctrl->CAS + 36) << 16));
1654 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1655 (slotrank << 24) | 0x60000);
1656 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1657
Patrick Rudolph371d2912015-10-09 13:33:25 +02001658 /* DRAM command MRS
1659 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001660 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
1661 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
1662 (0xc01 | (ctrl->tMOD << 16)));
1663 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
1664 (slotrank << 24) | 0x360000);
1665 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
1666
1667 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
1668
1669 wait_428c(channel);
1670}
1671
1672static int does_lane_work(ramctr_timing * ctrl, int channel, int slotrank,
1673 int lane)
1674{
1675 u32 timA = ctrl->timings[channel][slotrank].lanes[lane].timA;
1676 return ((read32
1677 (DEFAULT_MCHBAR + lane_registers[lane] + channel * 0x100 + 4 +
1678 ((timA / 32) & 1) * 4)
1679 >> (timA % 32)) & 1);
1680}
1681
1682struct run {
1683 int middle;
1684 int end;
1685 int start;
1686 int all;
1687 int length;
1688};
1689
1690static struct run get_longest_zero_run(int *seq, int sz)
1691{
1692 int i, ls;
1693 int bl = 0, bs = 0;
1694 struct run ret;
1695
1696 ls = 0;
1697 for (i = 0; i < 2 * sz; i++)
1698 if (seq[i % sz]) {
1699 if (i - ls > bl) {
1700 bl = i - ls;
1701 bs = ls;
1702 }
1703 ls = i + 1;
1704 }
1705 if (bl == 0) {
1706 ret.middle = sz / 2;
1707 ret.start = 0;
1708 ret.end = sz;
1709 ret.all = 1;
1710 return ret;
1711 }
1712
1713 ret.start = bs % sz;
1714 ret.end = (bs + bl - 1) % sz;
1715 ret.middle = (bs + (bl - 1) / 2) % sz;
1716 ret.length = bl;
1717 ret.all = 0;
1718
1719 return ret;
1720}
1721
1722static void discover_timA_coarse(ramctr_timing * ctrl, int channel,
1723 int slotrank, int *upperA)
1724{
1725 int timA;
1726 int statistics[NUM_LANES][128];
1727 int lane;
1728
1729 for (timA = 0; timA < 128; timA++) {
1730 FOR_ALL_LANES {
1731 ctrl->timings[channel][slotrank].lanes[lane].timA = timA;
1732 }
1733 program_timings(ctrl, channel);
1734
1735 test_timA(ctrl, channel, slotrank);
1736
1737 FOR_ALL_LANES {
1738 statistics[lane][timA] =
1739 !does_lane_work(ctrl, channel, slotrank, lane);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001740 printram("Astat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001741 channel, slotrank, lane, timA,
1742 statistics[lane][timA]);
1743 }
1744 }
1745 FOR_ALL_LANES {
1746 struct run rn = get_longest_zero_run(statistics[lane], 128);
1747 ctrl->timings[channel][slotrank].lanes[lane].timA = rn.middle;
1748 upperA[lane] = rn.end;
1749 if (upperA[lane] < rn.middle)
1750 upperA[lane] += 128;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001751 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001752 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001753 printram("Aend: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001754 lane, upperA[lane]);
1755 }
1756}
1757
1758static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
1759 int *upperA)
1760{
1761 int timA_delta;
1762 int statistics[NUM_LANES][51];
1763 int lane, i;
1764
1765 memset(statistics, 0, sizeof(statistics));
1766
1767 for (timA_delta = -25; timA_delta <= 25; timA_delta++) {
1768 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
1769 timA = upperA[lane] + timA_delta + 0x40;
1770 program_timings(ctrl, channel);
1771
1772 for (i = 0; i < 100; i++) {
1773 test_timA(ctrl, channel, slotrank);
1774 FOR_ALL_LANES {
1775 statistics[lane][timA_delta + 25] +=
1776 does_lane_work(ctrl, channel, slotrank,
1777 lane);
1778 }
1779 }
1780 }
1781 FOR_ALL_LANES {
1782 int last_zero, first_all;
1783
1784 for (last_zero = -25; last_zero <= 25; last_zero++)
1785 if (statistics[lane][last_zero + 25])
1786 break;
1787 last_zero--;
1788 for (first_all = -25; first_all <= 25; first_all++)
1789 if (statistics[lane][first_all + 25] == 100)
1790 break;
1791
1792 printram("lane %d: %d, %d\n", lane, last_zero,
1793 first_all);
1794
1795 ctrl->timings[channel][slotrank].lanes[lane].timA =
1796 (last_zero + first_all) / 2 + upperA[lane];
Patrick Rudolpha649a542016-01-17 18:32:06 +01001797 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001798 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1799 }
1800}
1801
1802static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
1803 int *upperA)
1804{
1805 int works[NUM_LANES];
1806 int lane;
1807 while (1) {
1808 int all_works = 1, some_works = 0;
1809 program_timings(ctrl, channel);
1810 test_timA(ctrl, channel, slotrank);
1811 FOR_ALL_LANES {
1812 works[lane] =
1813 !does_lane_work(ctrl, channel, slotrank, lane);
1814 if (works[lane])
1815 some_works = 1;
1816 else
1817 all_works = 0;
1818 }
1819 if (all_works)
1820 return;
1821 if (!some_works) {
1822 if (ctrl->timings[channel][slotrank].val_4024 < 2)
1823 die("402x discovery failed");
1824 ctrl->timings[channel][slotrank].val_4024 -= 2;
1825 printram("4024 -= 2;\n");
1826 continue;
1827 }
1828 ctrl->timings[channel][slotrank].val_4028 += 2;
1829 printram("4028 += 2;\n");
1830 if (ctrl->timings[channel][slotrank].val_4028 >= 0x10)
1831 die("402x discovery failed");
1832 FOR_ALL_LANES if (works[lane]) {
1833 ctrl->timings[channel][slotrank].lanes[lane].timA +=
1834 128;
1835 upperA[lane] += 128;
1836 printram("increment %d, %d, %d\n", channel,
1837 slotrank, lane);
1838 }
1839 }
1840}
1841
1842struct timA_minmax {
1843 int timA_min_high, timA_max_high;
1844};
1845
1846static void pre_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1847 struct timA_minmax *mnmx)
1848{
1849 int lane;
1850 mnmx->timA_min_high = 7;
1851 mnmx->timA_max_high = 0;
1852
1853 FOR_ALL_LANES {
1854 if (mnmx->timA_min_high >
1855 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1856 mnmx->timA_min_high =
1857 (ctrl->timings[channel][slotrank].lanes[lane].
1858 timA >> 6);
1859 if (mnmx->timA_max_high <
1860 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1861 mnmx->timA_max_high =
1862 (ctrl->timings[channel][slotrank].lanes[lane].
1863 timA >> 6);
1864 }
1865}
1866
1867static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1868 struct timA_minmax *mnmx)
1869{
1870 struct timA_minmax post;
1871 int shift_402x = 0;
1872
1873 /* Get changed maxima. */
1874 pre_timA_change(ctrl, channel, slotrank, &post);
1875
1876 if (mnmx->timA_max_high - mnmx->timA_min_high <
1877 post.timA_max_high - post.timA_min_high)
1878 shift_402x = +1;
1879 else if (mnmx->timA_max_high - mnmx->timA_min_high >
1880 post.timA_max_high - post.timA_min_high)
1881 shift_402x = -1;
1882 else
1883 shift_402x = 0;
1884
1885 ctrl->timings[channel][slotrank].val_4028 += shift_402x;
1886 ctrl->timings[channel][slotrank].val_4024 += shift_402x;
1887 printram("4024 += %d;\n", shift_402x);
1888 printram("4028 += %d;\n", shift_402x);
1889}
1890
Patrick Rudolph371d2912015-10-09 13:33:25 +02001891/* Compensate the skew between DQS and DQs.
1892 * To ease PCB design a small skew between Data Strobe signals and
1893 * Data Signals is allowed.
1894 * The controller has to measure and compensate this skew for every byte-lane.
1895 * By delaying either all DQs signals or DQS signal, a full phase
1896 * shift can be introduced.
1897 * It is assumed that one byte-lane's DQs signals have the same routing delay.
1898 *
1899 * To measure the actual skew, the DRAM is placed in "read leveling" mode.
1900 * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
1901 * The memory controller iterates over all possible values to do a full phase shift
1902 * and issues read commands.
1903 * With DQS and DQs in phase the data read is expected to alternate on every byte:
1904 * 0xFF 0x00 0xFF ...
1905 * Once the controller has detected this pattern a bit in the result register is
1906 * set for the current phase shift.
1907 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001908static void read_training(ramctr_timing * ctrl)
1909{
1910 int channel, slotrank, lane;
1911
1912 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001913 int all_high, some_high;
1914 int upperA[NUM_LANES];
1915 struct timA_minmax mnmx;
1916
1917 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001918
1919 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001920 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
1921 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1922 0xc01 | (ctrl->tRP << 16));
1923 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1924 (slotrank << 24) | 0x60400);
1925 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1926 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
1927
1928 write32(DEFAULT_MCHBAR + 0x3400, (slotrank << 2) | 0x8001);
1929
1930 ctrl->timings[channel][slotrank].val_4028 = 4;
1931 ctrl->timings[channel][slotrank].val_4024 = 55;
1932 program_timings(ctrl, channel);
1933
1934 discover_timA_coarse(ctrl, channel, slotrank, upperA);
1935
1936 all_high = 1;
1937 some_high = 0;
1938 FOR_ALL_LANES {
1939 if (ctrl->timings[channel][slotrank].lanes[lane].
1940 timA >= 0x40)
1941 some_high = 1;
1942 else
1943 all_high = 0;
1944 }
1945
1946 if (all_high) {
1947 ctrl->timings[channel][slotrank].val_4028--;
1948 printram("4028--;\n");
1949 FOR_ALL_LANES {
1950 ctrl->timings[channel][slotrank].lanes[lane].
1951 timA -= 0x40;
1952 upperA[lane] -= 0x40;
1953
1954 }
1955 } else if (some_high) {
1956 ctrl->timings[channel][slotrank].val_4024++;
1957 ctrl->timings[channel][slotrank].val_4028++;
1958 printram("4024++;\n");
1959 printram("4028++;\n");
1960 }
1961
1962 program_timings(ctrl, channel);
1963
1964 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1965
1966 discover_402x(ctrl, channel, slotrank, upperA);
1967
1968 post_timA_change(ctrl, channel, slotrank, &mnmx);
1969 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1970
1971 discover_timA_fine(ctrl, channel, slotrank, upperA);
1972
1973 post_timA_change(ctrl, channel, slotrank, &mnmx);
1974 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1975
1976 FOR_ALL_LANES {
1977 ctrl->timings[channel][slotrank].lanes[lane].timA -= mnmx.timA_min_high * 0x40;
1978 }
1979 ctrl->timings[channel][slotrank].val_4028 -= mnmx.timA_min_high;
1980 printram("4028 -= %d;\n", mnmx.timA_min_high);
1981
1982 post_timA_change(ctrl, channel, slotrank, &mnmx);
1983
1984 printram("4/8: %d, %d, %x, %x\n", channel, slotrank,
1985 ctrl->timings[channel][slotrank].val_4024,
1986 ctrl->timings[channel][slotrank].val_4028);
1987
Patrick Rudolpha649a542016-01-17 18:32:06 +01001988 printram("final results:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001989 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01001990 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001991 lane,
1992 ctrl->timings[channel][slotrank].lanes[lane].timA);
1993
1994 write32(DEFAULT_MCHBAR + 0x3400, 0);
1995
Patrick Rudolph9b515682015-10-09 13:43:51 +02001996 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001997 }
1998
1999 FOR_ALL_POPULATED_CHANNELS {
2000 program_timings(ctrl, channel);
2001 }
2002 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2003 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
2004 + 4 * lane, 0);
2005 }
2006}
2007
2008static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
2009{
2010 int lane;
2011
2012 FOR_ALL_LANES {
2013 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel + 4 * lane, 0);
2014 read32(DEFAULT_MCHBAR + 0x4140 + 0x400 * channel + 4 * lane);
2015 }
2016
2017 wait_428c(channel);
2018
Patrick Rudolph371d2912015-10-09 13:33:25 +02002019 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002020 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2021 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2022 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
2023 | 4 | (ctrl->tRCD << 16));
2024
2025 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2026 (slotrank << 24) | (6 << 16));
2027
2028 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
2029
Patrick Rudolph371d2912015-10-09 13:33:25 +02002030 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002031 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2032 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
2033 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2034 (slotrank << 24) | 8);
2035 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2036
Patrick Rudolph371d2912015-10-09 13:33:25 +02002037 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002038 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2039 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
2040 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2041 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2042
Patrick Rudolph371d2912015-10-09 13:33:25 +02002043 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002044 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2045 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2046 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2047 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2048 (slotrank << 24) | 8);
2049 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2050
2051 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2052
2053 wait_428c(channel);
2054
Patrick Rudolph371d2912015-10-09 13:33:25 +02002055 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002056 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2057 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2058 0xc01 | (ctrl->tRP << 16));
2059 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2060 (slotrank << 24) | 0x60400);
2061 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2062
Patrick Rudolph371d2912015-10-09 13:33:25 +02002063 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002064 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2065 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2066 (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
2067 | 8 | (ctrl->CAS << 16));
2068
2069 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2070 (slotrank << 24) | 0x60000);
2071
2072 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
2073
Patrick Rudolph371d2912015-10-09 13:33:25 +02002074 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002075 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2076 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2077 0x40011f4 | (max(ctrl->tRTP, 8) << 16));
2078 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2079 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2080
Patrick Rudolph371d2912015-10-09 13:33:25 +02002081 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002082 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2083 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2084 0xc01 | (ctrl->tRP << 16));
2085 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2086 (slotrank << 24) | 0x60400);
2087 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2088 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2089 wait_428c(channel);
2090}
2091
2092static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
2093{
2094 int timC;
2095 int statistics[NUM_LANES][MAX_TIMC + 1];
2096 int lane;
2097
2098 wait_428c(channel);
2099
Patrick Rudolph371d2912015-10-09 13:33:25 +02002100 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002101 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2102 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2103 0xc01 | (ctrl->tRP << 16));
2104 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2105 (slotrank << 24) | 0x60400);
2106 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2107 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2108
2109 for (timC = 0; timC <= MAX_TIMC; timC++) {
2110 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
2111 timC = timC;
2112 program_timings(ctrl, channel);
2113
2114 test_timC(ctrl, channel, slotrank);
2115
2116 FOR_ALL_LANES {
2117 statistics[lane][timC] =
2118 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2119 0x400 * channel);
2120 printram("Cstat: %d, %d, %d, %x, %x\n",
2121 channel, slotrank, lane, timC,
2122 statistics[lane][timC]);
2123 }
2124 }
2125 FOR_ALL_LANES {
2126 struct run rn =
2127 get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
2128 ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
2129 if (rn.all)
Patrick Rudolpha649a542016-01-17 18:32:06 +01002130 die("timC discovery failed");
2131 printram("Cval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002132 lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
2133 }
2134}
2135
2136static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
2137{
2138 int channel, ret = 0;
2139 FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
2140 ret++;
2141 return ret;
2142}
2143
2144static void fill_pattern0(ramctr_timing * ctrl, int channel, u32 a, u32 b)
2145{
2146 unsigned j;
2147 unsigned channel_offset =
2148 get_precedening_channels(ctrl, channel) * 0x40;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002149 for (j = 0; j < 16; j++)
2150 write32((void *)(0x04000000 + channel_offset + 4 * j), j & 2 ? b : a);
2151 sfence();
2152}
2153
2154static int num_of_channels(const ramctr_timing * ctrl)
2155{
2156 int ret = 0;
2157 int channel;
2158 FOR_ALL_POPULATED_CHANNELS ret++;
2159 return ret;
2160}
2161
2162static void fill_pattern1(ramctr_timing * ctrl, int channel)
2163{
2164 unsigned j;
2165 unsigned channel_offset =
2166 get_precedening_channels(ctrl, channel) * 0x40;
2167 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2168 for (j = 0; j < 16; j++)
2169 write32((void *)(0x04000000 + channel_offset + j * 4), 0xffffffff);
2170 for (j = 0; j < 16; j++)
2171 write32((void *)(0x04000000 + channel_offset + channel_step + j * 4), 0);
2172 sfence();
2173}
2174
2175static void precharge(ramctr_timing * ctrl)
2176{
2177 int channel, slotrank, lane;
2178
2179 FOR_ALL_POPULATED_CHANNELS {
2180 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2181 ctrl->timings[channel][slotrank].lanes[lane].falling =
2182 16;
2183 ctrl->timings[channel][slotrank].lanes[lane].rising =
2184 16;
Patrick Rudolpha649a542016-01-17 18:32:06 +01002185 }
2186
2187 program_timings(ctrl, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002188
2189 FOR_ALL_POPULATED_RANKS {
2190 wait_428c(channel);
2191
Patrick Rudolph371d2912015-10-09 13:33:25 +02002192 /* DRAM command MRS
2193 * write MR3 MPR enable
2194 * in this mode only RD and RDA are allowed
2195 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002196 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2197 0x1f000);
2198 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2199 0xc01 | (ctrl->tMOD << 16));
2200 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2201 (slotrank << 24) | 0x360004);
2202 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2203
Patrick Rudolph371d2912015-10-09 13:33:25 +02002204 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002205 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2206 0x1f105);
2207 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2208 0x4041003);
2209 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2210 (slotrank << 24) | 0);
2211 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2212
Patrick Rudolph371d2912015-10-09 13:33:25 +02002213 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002214 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2215 0x1f105);
2216 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2217 0x1001 | ((ctrl->CAS + 8) << 16));
2218 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2219 (slotrank << 24) | 0x60000);
2220 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2221
Patrick Rudolph371d2912015-10-09 13:33:25 +02002222 /* DRAM command MRS
2223 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002224 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2225 0x1f000);
2226 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2227 0xc01 | (ctrl->tMOD << 16));
2228 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2229 (slotrank << 24) | 0x360000);
2230 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2231 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2232 0xc0001);
2233
2234 wait_428c(channel);
2235 }
2236
2237 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2238 ctrl->timings[channel][slotrank].lanes[lane].falling =
2239 48;
2240 ctrl->timings[channel][slotrank].lanes[lane].rising =
2241 48;
2242 }
2243
2244 program_timings(ctrl, channel);
2245
2246 FOR_ALL_POPULATED_RANKS {
2247 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002248 /* DRAM command MRS
2249 * write MR3 MPR enable
2250 * in this mode only RD and RDA are allowed
2251 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002252 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2253 0x1f000);
2254 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2255 0xc01 | (ctrl->tMOD << 16));
2256 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2257 (slotrank << 24) | 0x360004);
2258 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2259
Patrick Rudolph371d2912015-10-09 13:33:25 +02002260 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002261 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2262 0x1f105);
2263 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2264 0x4041003);
2265 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2266 (slotrank << 24) | 0);
2267 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2268
Patrick Rudolph371d2912015-10-09 13:33:25 +02002269 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002270 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2271 0x1f105);
2272 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2273 0x1001 | ((ctrl->CAS + 8) << 16));
2274 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2275 (slotrank << 24) | 0x60000);
2276 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2277
Patrick Rudolph371d2912015-10-09 13:33:25 +02002278 /* DRAM command MRS
2279 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002280 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2281 0x1f000);
2282 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2283 0xc01 | (ctrl->tMOD << 16));
2284
2285 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2286 (slotrank << 24) | 0x360000);
2287 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2288
2289 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2290 0xc0001);
2291 wait_428c(channel);
2292 }
2293 }
2294}
2295
2296static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
2297{
Patrick Rudolph371d2912015-10-09 13:33:25 +02002298 /* enable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002299 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002300 0x80 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002301
2302 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002303 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002304 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
2305 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2306 0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
2307 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2308 8 | (slotrank << 24));
2309 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2310
Patrick Rudolph371d2912015-10-09 13:33:25 +02002311 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002312 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
2313 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2314 0x4000c01 | ((ctrl->CAS + 38) << 16));
2315 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2316 (slotrank << 24) | 4);
2317 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2318
2319 write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
2320 wait_428c(channel);
2321
Patrick Rudolph371d2912015-10-09 13:33:25 +02002322 /* disable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002323 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002324 0x1080 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002325}
2326
2327static void discover_timB(ramctr_timing * ctrl, int channel, int slotrank)
2328{
2329 int timB;
2330 int statistics[NUM_LANES][128];
2331 int lane;
2332
2333 write32(DEFAULT_MCHBAR + 0x3400, 0x108052 | (slotrank << 2));
2334
2335 for (timB = 0; timB < 128; timB++) {
2336 FOR_ALL_LANES {
2337 ctrl->timings[channel][slotrank].lanes[lane].timB = timB;
2338 }
2339 program_timings(ctrl, channel);
2340
2341 test_timB(ctrl, channel, slotrank);
2342
2343 FOR_ALL_LANES {
2344 statistics[lane][timB] =
2345 !((read32
2346 (DEFAULT_MCHBAR + lane_registers[lane] +
2347 channel * 0x100 + 4 + ((timB / 32) & 1) * 4)
2348 >> (timB % 32)) & 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002349 printram("Bstat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002350 channel, slotrank, lane, timB,
2351 statistics[lane][timB]);
2352 }
2353 }
2354 FOR_ALL_LANES {
2355 struct run rn = get_longest_zero_run(statistics[lane], 128);
Vladimir Serbinenko3141eac2016-01-29 19:42:02 +01002356 ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002357 if (rn.all)
2358 die("timB discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01002359 printram("Bval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002360 lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
2361 }
2362}
2363
2364static int get_timB_high_adjust(u64 val)
2365{
2366 int i;
2367
2368 /* good */
2369 if (val == 0xffffffffffffffffLL)
2370 return 0;
2371
2372 if (val >= 0xf000000000000000LL) {
2373 /* needs negative adjustment */
2374 for (i = 0; i < 8; i++)
2375 if (val << (8 * (7 - i) + 4))
2376 return -i;
2377 } else {
2378 /* needs positive adjustment */
2379 for (i = 0; i < 8; i++)
2380 if (val >> (8 * (7 - i) + 4))
2381 return i;
2382 }
2383 return 8;
2384}
2385
2386static void adjust_high_timB(ramctr_timing * ctrl)
2387{
2388 int channel, slotrank, lane, old;
2389 write32(DEFAULT_MCHBAR + 0x3400, 0x200);
2390 FOR_ALL_POPULATED_CHANNELS {
2391 fill_pattern1(ctrl, channel);
2392 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 1);
2393 }
2394 FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
2395
2396 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x10001);
2397
2398 wait_428c(channel);
2399
Patrick Rudolph371d2912015-10-09 13:33:25 +02002400 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002401 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2402 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2403 0xc01 | (ctrl->tRCD << 16));
2404 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2405 (slotrank << 24) | 0x60000);
2406 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2407
Patrick Rudolph371d2912015-10-09 13:33:25 +02002408 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002409 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2410 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
2411 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2412 (slotrank << 24) | 0x8);
2413 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2414
Patrick Rudolph371d2912015-10-09 13:33:25 +02002415 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002416 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2417 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
2418 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2419 (slotrank << 24));
2420 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
2421
Patrick Rudolph371d2912015-10-09 13:33:25 +02002422 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002423 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2424 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2425 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2426 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2427 (slotrank << 24) | 0x8);
2428 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2429
2430 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2431
2432 wait_428c(channel);
2433
Patrick Rudolph371d2912015-10-09 13:33:25 +02002434 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002435 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2436 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2437 0xc01 | ((ctrl->tRP) << 16));
2438 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2439 (slotrank << 24) | 0x60400);
2440 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2441
Patrick Rudolph371d2912015-10-09 13:33:25 +02002442 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002443 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2444 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2445 0xc01 | ((ctrl->tRCD) << 16));
2446 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2447 (slotrank << 24) | 0x60000);
2448 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2449
Patrick Rudolph371d2912015-10-09 13:33:25 +02002450 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002451 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
2452 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2453 0x4000c01 |
2454 ((ctrl->tRP +
2455 ctrl->timings[channel][slotrank].val_4024 +
2456 ctrl->timings[channel][slotrank].val_4028) << 16));
2457 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2458 (slotrank << 24) | 0x60008);
2459 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2460
2461 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
2462 wait_428c(channel);
2463 FOR_ALL_LANES {
2464 u64 res =
2465 read32(DEFAULT_MCHBAR + lane_registers[lane] +
2466 0x100 * channel + 4);
2467 res |=
2468 ((u64) read32(DEFAULT_MCHBAR + lane_registers[lane] +
2469 0x100 * channel + 8)) << 32;
2470 old = ctrl->timings[channel][slotrank].lanes[lane].timB;
2471 ctrl->timings[channel][slotrank].lanes[lane].timB +=
2472 get_timB_high_adjust(res) * 64;
2473
Patrick Rudolpha649a542016-01-17 18:32:06 +01002474 printram("High adjust %d:%016llx\n", lane, res);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002475 printram("Bval+: %d, %d, %d, %x -> %x\n", channel,
2476 slotrank, lane, old,
2477 ctrl->timings[channel][slotrank].lanes[lane].
2478 timB);
2479 }
2480 }
2481 write32(DEFAULT_MCHBAR + 0x3400, 0);
2482}
2483
2484static void write_op(ramctr_timing * ctrl, int channel)
2485{
2486 int slotrank;
2487
2488 wait_428c(channel);
2489
2490 /* choose an existing rank. */
2491 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2492
Patrick Rudolph371d2912015-10-09 13:33:25 +02002493 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002494 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2495 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2496
2497 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2498 (slotrank << 24) | 0x60000);
2499
2500 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2501
2502 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2503 wait_428c(channel);
2504}
2505
Patrick Rudolph371d2912015-10-09 13:33:25 +02002506/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
2507 * DDR3 adopted the fly-by topology. The data and strobes signals reach
2508 * the chips at different times with respect to command, address and
2509 * clock signals.
2510 * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
2511 * shift can be introduced.
2512 * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
2513 *
2514 * To find the required phase shift the DRAM is placed in "write leveling" mode.
2515 * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
2516 * sampled value on the data lanes (DQs).
2517 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002518static void write_training(ramctr_timing * ctrl)
2519{
2520 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002521
2522 FOR_ALL_POPULATED_CHANNELS
2523 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
2524 read32(DEFAULT_MCHBAR + 0x4008 +
2525 0x400 * channel) | 0x8000000);
2526
2527 FOR_ALL_POPULATED_CHANNELS {
2528 write_op(ctrl, channel);
2529 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2530 read32(DEFAULT_MCHBAR + 0x4020 +
2531 0x400 * channel) | 0x200000);
2532 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002533
2534 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002535 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2536 FOR_ALL_POPULATED_CHANNELS {
2537 write_op(ctrl, channel);
2538 }
2539
Patrick Rudolph371d2912015-10-09 13:33:25 +02002540 /* enable write leveling on all ranks
2541 * disable all DQ outputs
2542 * only NOP is allowed in this mode */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002543 FOR_ALL_CHANNELS
2544 FOR_ALL_POPULATED_RANKS
2545 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002546 make_mr1(ctrl, slotrank, channel) | 0x1080);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002547
2548 write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
2549
Patrick Rudolph9b515682015-10-09 13:43:51 +02002550 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002551
Patrick Rudolph371d2912015-10-09 13:33:25 +02002552 /* set any valid value for timB, it gets corrected later */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002553 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2554 discover_timB(ctrl, channel, slotrank);
2555
Patrick Rudolph371d2912015-10-09 13:33:25 +02002556 /* disable write leveling on all ranks */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002557 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2558 write_mrreg(ctrl, channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002559 slotrank, 1, make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002560
2561 write32(DEFAULT_MCHBAR + 0x3400, 0);
2562
2563 FOR_ALL_POPULATED_CHANNELS
2564 wait_428c(channel);
2565
Patrick Rudolph371d2912015-10-09 13:33:25 +02002566 /* refresh enable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002567 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
2568
2569 FOR_ALL_POPULATED_CHANNELS {
2570 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2571 ~0x00200000 & read32(DEFAULT_MCHBAR + 0x4020 +
2572 0x400 * channel));
2573 read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
2574 wait_428c(channel);
2575
Patrick Rudolph371d2912015-10-09 13:33:25 +02002576 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002577 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2578 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
2579 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
2580 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2581
2582 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2583 wait_428c(channel);
2584 }
2585
Patrick Rudolph9b515682015-10-09 13:43:51 +02002586 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002587
2588 printram("CPE\n");
2589 precharge(ctrl);
2590 printram("CPF\n");
2591
2592 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2593 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2594 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2595 0);
2596 }
2597
2598 FOR_ALL_POPULATED_CHANNELS {
2599 fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
2600 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2601 }
2602
2603 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2604 discover_timC(ctrl, channel, slotrank);
2605
2606 FOR_ALL_POPULATED_CHANNELS
2607 program_timings(ctrl, channel);
2608
Patrick Rudolph371d2912015-10-09 13:33:25 +02002609 /* measure and adjust timB timings */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002610 adjust_high_timB(ctrl);
2611
2612 FOR_ALL_POPULATED_CHANNELS
2613 program_timings(ctrl, channel);
2614
2615 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2616 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2617 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2618 0);
2619 }
2620}
2621
2622static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
2623{
2624 struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
2625 int timC_delta;
2626 int lanes_ok = 0;
2627 int ctr = 0;
2628 int lane;
2629
2630 for (timC_delta = -5; timC_delta <= 5; timC_delta++) {
2631 FOR_ALL_LANES {
2632 ctrl->timings[channel][slotrank].lanes[lane].timC =
2633 saved_rt.lanes[lane].timC + timC_delta;
2634 }
2635 program_timings(ctrl, channel);
2636 FOR_ALL_LANES {
2637 write32(DEFAULT_MCHBAR + 4 * lane + 0x4f40, 0);
2638 }
2639
2640 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2641
2642 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002643 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002644 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2645 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2646 ((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
2647 | 8 | (ctrl->tRCD << 16));
2648
2649 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2650 (slotrank << 24) | ctr | 0x60000);
2651
2652 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002653 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002654 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
2655 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2656 0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
2657 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2658 (slotrank << 24));
2659 write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
2660 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
2661
Patrick Rudolph371d2912015-10-09 13:33:25 +02002662 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002663 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2664 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2665 0x4001020 | (max(ctrl->tRTP, 8) << 16));
2666 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2667 (slotrank << 24));
2668 write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
2669 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
2670
Patrick Rudolph371d2912015-10-09 13:33:25 +02002671 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002672 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2673 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
2674 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2675 (slotrank << 24) | 0x60400);
2676 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2677
2678 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2679 wait_428c(channel);
2680 FOR_ALL_LANES {
2681 u32 r32 =
2682 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2683 0x400 * channel);
2684
2685 if (r32 == 0)
2686 lanes_ok |= 1 << lane;
2687 }
2688 ctr++;
2689 if (lanes_ok == ((1 << NUM_LANES) - 1))
2690 break;
2691 }
2692
2693 ctrl->timings[channel][slotrank] = saved_rt;
2694
2695 printram("3lanes: %x\n", lanes_ok);
2696 return lanes_ok != ((1 << NUM_LANES) - 1);
2697}
2698
2699#include "raminit_patterns.h"
2700
2701static void fill_pattern5(ramctr_timing * ctrl, int channel, int patno)
2702{
2703 unsigned i, j;
2704 unsigned channel_offset =
2705 get_precedening_channels(ctrl, channel) * 0x40;
2706 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2707
2708 if (patno) {
2709 u8 base8 = 0x80 >> ((patno - 1) % 8);
2710 u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
2711 for (i = 0; i < 32; i++) {
2712 for (j = 0; j < 16; j++) {
2713 u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;
2714 if (invert[patno - 1][i] & (1 << (j / 2)))
2715 val = ~val;
2716 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2717 j * 4), val);
2718 }
2719 }
2720
2721 } else {
2722 for (i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
2723 for (j = 0; j < 16; j++)
2724 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2725 j * 4), pattern[i][j]);
2726 }
2727 sfence();
2728 }
2729}
2730
2731static void reprogram_320c(ramctr_timing * ctrl)
2732{
2733 int channel, slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002734
2735 FOR_ALL_POPULATED_CHANNELS {
2736 wait_428c(channel);
2737
2738 /* choose an existing rank. */
2739 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2740
Patrick Rudolph371d2912015-10-09 13:33:25 +02002741 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002742 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2743 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2744
2745 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2746 (slotrank << 24) | 0x60000);
2747
2748 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2749
2750 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2751 wait_428c(channel);
2752 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2753 read32(DEFAULT_MCHBAR + 0x4020 +
2754 0x400 * channel) | 0x200000);
2755 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002756
2757 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002758 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2759 FOR_ALL_POPULATED_CHANNELS {
2760 wait_428c(channel);
2761
2762 /* choose an existing rank. */
2763 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2764
Patrick Rudolph371d2912015-10-09 13:33:25 +02002765 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002766 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2767 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2768
2769 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2770 (slotrank << 24) | 0x60000);
2771
2772 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2773
2774 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2775 wait_428c(channel);
2776 }
2777
2778 /* jedec reset */
2779 dram_jedecreset(ctrl);
2780 /* mrs commands. */
2781 dram_mrscommands(ctrl);
2782
Patrick Rudolph9b515682015-10-09 13:43:51 +02002783 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002784}
2785
2786#define MIN_C320C_LEN 13
2787
2788static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
2789{
2790 struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
2791 int channel, slotrank;
2792 int c320c;
2793 int stat[NUM_SLOTRANKS][256];
2794
2795 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2796 saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
2797 }
2798
2799 FOR_ALL_POPULATED_CHANNELS {
2800 ctrl->cmd_stretch[channel] = cmd_stretch;
2801 }
2802
2803 FOR_ALL_POPULATED_CHANNELS
2804 MCHBAR32(0x4004 + 0x400 * channel) =
2805 ctrl->tRRD
2806 | (ctrl->tRTP << 4)
2807 | (ctrl->tCKE << 8)
2808 | (ctrl->tWTR << 12)
2809 | (ctrl->tFAW << 16)
2810 | (ctrl->tWR << 24)
2811 | (ctrl->cmd_stretch[channel] << 30);
2812
2813
2814 FOR_ALL_CHANNELS {
2815 int delta = 0;
2816 if (ctrl->cmd_stretch[channel] == 2)
2817 delta = 2;
2818 else if (ctrl->cmd_stretch[channel] == 0)
2819 delta = 4;
2820
2821 FOR_ALL_POPULATED_RANKS {
2822 ctrl->timings[channel][slotrank].val_4024 -= delta;
2823 }
2824 }
2825
2826 FOR_ALL_POPULATED_CHANNELS {
2827 for (c320c = -127; c320c <= 127; c320c++) {
2828 FOR_ALL_POPULATED_RANKS {
2829 ctrl->timings[channel][slotrank].val_320c = c320c;
2830 }
2831 program_timings(ctrl, channel);
2832 reprogram_320c(ctrl);
2833 FOR_ALL_POPULATED_RANKS {
2834 stat[slotrank][c320c + 127] =
2835 test_320c(ctrl, channel, slotrank);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002836 printram("3stat: %d, %d, %d: %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002837 channel, slotrank, c320c,
2838 stat[slotrank][c320c + 127]);
2839 }
2840 }
2841 FOR_ALL_POPULATED_RANKS {
2842 struct run rn =
2843 get_longest_zero_run(stat[slotrank], 255);
2844 ctrl->timings[channel][slotrank].val_320c =
2845 rn.middle - 127;
2846 printram("3val: %d, %d: %d\n", channel,
2847 slotrank,
2848 ctrl->timings[channel][slotrank].val_320c);
2849 if (rn.all || rn.length < MIN_C320C_LEN) {
2850 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2851 ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
2852 }
2853 return 0;
2854 }
2855 }
2856 }
2857 return 1;
2858}
2859
Patrick Rudolph371d2912015-10-09 13:33:25 +02002860/* Adjust CMD phase shift and try multiple command rates.
2861 * A command rate of 2T doubles the time needed for address and
2862 * command decode. */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002863static void command_training(ramctr_timing * ctrl)
2864{
2865 int channel;
2866
2867 FOR_ALL_POPULATED_CHANNELS {
2868 fill_pattern5(ctrl, channel, 0);
2869 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2870 }
2871
2872 /* try command rate 1T and 2T */
2873 if (!try_cmd_stretch(ctrl, 0) && !try_cmd_stretch(ctrl, 2))
2874 die("c320c discovery failed");
2875
2876 FOR_ALL_POPULATED_CHANNELS {
2877 program_timings(ctrl, channel);
2878 }
2879
2880 reprogram_320c(ctrl);
2881}
2882
2883static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
2884 int *edges)
2885{
2886 int edge;
2887 int statistics[NUM_LANES][MAX_EDGE_TIMING + 1];
2888 int lane;
2889
2890 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
2891 FOR_ALL_LANES {
2892 ctrl->timings[channel][slotrank].lanes[lane].rising =
2893 edge;
2894 ctrl->timings[channel][slotrank].lanes[lane].falling =
2895 edge;
2896 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002897 program_timings(ctrl, channel);
2898
2899 FOR_ALL_LANES {
2900 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2901 4 * lane, 0);
2902 read32(DEFAULT_MCHBAR + 0x400 * channel + 4 * lane +
2903 0x4140);
2904 }
2905
2906 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002907 /* DRAM command MRS
2908 * write MR3 MPR enable
2909 * in this mode only RD and RDA are allowed
2910 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002911 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
2912 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2913 (0xc01 | (ctrl->tMOD << 16)));
2914 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2915 (slotrank << 24) | 0x360004);
2916 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2917
Patrick Rudolph371d2912015-10-09 13:33:25 +02002918 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002919 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
2920 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
2921 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2922 (slotrank << 24));
2923 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2924
Patrick Rudolph371d2912015-10-09 13:33:25 +02002925 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002926 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2927 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2928 0x1001 | ((ctrl->CAS + 8) << 16));
2929 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2930 (slotrank << 24) | 0x60000);
2931 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2932
Patrick Rudolph371d2912015-10-09 13:33:25 +02002933 /* DRAM command MRS
2934 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002935 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
2936 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2937 (0xc01 | (ctrl->tMOD << 16)));
2938 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2939 (slotrank << 24) | 0x360000);
2940 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2941
2942 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2943
2944 wait_428c(channel);
2945
2946 FOR_ALL_LANES {
2947 statistics[lane][edge] =
2948 read32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2949 lane * 4);
2950 }
2951 }
2952 FOR_ALL_LANES {
2953 struct run rn =
2954 get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
2955 edges[lane] = rn.middle;
2956 if (rn.all)
2957 die("edge discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01002958 printram("eval %d, %d, %d: %02x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002959 lane, edges[lane]);
2960 }
2961}
2962
2963static void discover_edges(ramctr_timing * ctrl)
2964{
2965 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
2966 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
2967 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002968
2969 write32(DEFAULT_MCHBAR + 0x3400, 0);
2970
Patrick Rudolph9b515682015-10-09 13:43:51 +02002971 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002972
2973 FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
2974 write32(DEFAULT_MCHBAR + 4 * lane +
2975 0x400 * channel + 0x4080, 0);
2976 }
2977
2978 FOR_ALL_POPULATED_CHANNELS {
2979 fill_pattern0(ctrl, channel, 0, 0);
2980 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2981 FOR_ALL_LANES {
2982 read32(DEFAULT_MCHBAR + 0x400 * channel +
2983 lane * 4 + 0x4140);
2984 }
2985
2986 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2987 ctrl->timings[channel][slotrank].lanes[lane].falling =
2988 16;
2989 ctrl->timings[channel][slotrank].lanes[lane].rising =
2990 16;
2991 }
2992
2993 program_timings(ctrl, channel);
2994
2995 FOR_ALL_POPULATED_RANKS {
2996 wait_428c(channel);
2997
Patrick Rudolph371d2912015-10-09 13:33:25 +02002998 /* DRAM command MRS
2999 * MR3 enable MPR
3000 * write MR3 MPR enable
3001 * in this mode only RD and RDA are allowed
3002 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003003 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3004 0x1f000);
3005 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3006 0xc01 | (ctrl->tMOD << 16));
3007 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3008 (slotrank << 24) | 0x360004);
3009 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3010
Patrick Rudolph371d2912015-10-09 13:33:25 +02003011 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003012 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3013 0x1f105);
3014 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3015 0x4041003);
3016 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3017 (slotrank << 24) | 0);
3018 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3019
Patrick Rudolph371d2912015-10-09 13:33:25 +02003020 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003021 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3022 0x1f105);
3023 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3024 0x1001 | ((ctrl->CAS + 8) << 16));
3025 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3026 (slotrank << 24) | 0x60000);
3027 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3028
Patrick Rudolph371d2912015-10-09 13:33:25 +02003029 /* DRAM command MRS
3030 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003031 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3032 0x1f000);
3033 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3034 0xc01 | (ctrl->tMOD << 16));
3035 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3036 (slotrank << 24) | 0x360000);
3037 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3038 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3039 0xc0001);
3040
3041 wait_428c(channel);
3042 }
3043
Patrick Rudolph371d2912015-10-09 13:33:25 +02003044 /* XXX: check any measured value ? */
3045
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003046 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3047 ctrl->timings[channel][slotrank].lanes[lane].falling =
3048 48;
3049 ctrl->timings[channel][slotrank].lanes[lane].rising =
3050 48;
3051 }
3052
3053 program_timings(ctrl, channel);
3054
3055 FOR_ALL_POPULATED_RANKS {
3056 wait_428c(channel);
3057
Patrick Rudolph371d2912015-10-09 13:33:25 +02003058 /* DRAM command MRS
3059 * MR3 enable MPR
3060 * write MR3 MPR enable
3061 * in this mode only RD and RDA are allowed
3062 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003063 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3064 0x1f000);
3065 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3066 0xc01 | (ctrl->tMOD << 16));
3067 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3068 (slotrank << 24) | 0x360004);
3069 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3070
Patrick Rudolph371d2912015-10-09 13:33:25 +02003071 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003072 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3073 0x1f105);
3074 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3075 0x4041003);
3076 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3077 (slotrank << 24) | 0);
3078 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3079
Patrick Rudolph371d2912015-10-09 13:33:25 +02003080 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003081 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3082 0x1f105);
3083 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3084 0x1001 | ((ctrl->CAS + 8) << 16));
3085 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3086 (slotrank << 24) | 0x60000);
3087 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3088
Patrick Rudolph371d2912015-10-09 13:33:25 +02003089 /* DRAM command MRS
3090 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003091 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3092 0x1f000);
3093 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3094 0xc01 | (ctrl->tMOD << 16));
3095 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3096 (slotrank << 24) | 0x360000);
3097 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3098
3099 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3100 0xc0001);
3101 wait_428c(channel);
3102 }
3103
Patrick Rudolph371d2912015-10-09 13:33:25 +02003104 /* XXX: check any measured value ? */
3105
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003106 FOR_ALL_LANES {
3107 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
3108 lane * 4,
3109 ~read32(DEFAULT_MCHBAR + 0x4040 +
3110 0x400 * channel + lane * 4) & 0xff);
3111 }
3112
3113 fill_pattern0(ctrl, channel, 0, 0xffffffff);
3114 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3115 }
3116
3117 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3118 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003119 printram("discover falling edges:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003120
3121 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3122 discover_edges_real(ctrl, channel, slotrank,
3123 falling_edges[channel][slotrank]);
3124 }
3125
3126 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003127 printram("discover rising edges:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003128
3129 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3130 discover_edges_real(ctrl, channel, slotrank,
3131 rising_edges[channel][slotrank]);
3132 }
3133
3134 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3135
3136 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3137 ctrl->timings[channel][slotrank].lanes[lane].falling =
3138 falling_edges[channel][slotrank][lane];
3139 ctrl->timings[channel][slotrank].lanes[lane].rising =
3140 rising_edges[channel][slotrank][lane];
3141 }
3142
3143 FOR_ALL_POPULATED_CHANNELS {
3144 program_timings(ctrl, channel);
3145 }
3146
3147 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3148 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3149 0);
3150 }
3151}
3152
3153static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
3154 int slotrank, int *edges)
3155{
3156 int edge;
3157 u32 raw_statistics[MAX_EDGE_TIMING + 1];
3158 int statistics[MAX_EDGE_TIMING + 1];
3159 const int reg3000b24[] = { 0, 0xc, 0x2c };
3160 int lane, i;
3161 int lower[NUM_LANES];
3162 int upper[NUM_LANES];
3163 int pat;
3164
3165 FOR_ALL_LANES {
3166 lower[lane] = 0;
3167 upper[lane] = MAX_EDGE_TIMING;
3168 }
3169
3170 for (i = 0; i < 3; i++) {
3171 write32(DEFAULT_MCHBAR + 0x3000 + 0x100 * channel,
3172 reg3000b24[i] << 24);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003173 printram("[%x] = 0x%08x\n",
3174 0x3000 + 0x100 * channel, reg3000b24[i] << 24);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003175 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3176 fill_pattern5(ctrl, channel, pat);
3177 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003178 printram("using pattern %d\n", pat);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003179 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3180 FOR_ALL_LANES {
3181 ctrl->timings[channel][slotrank].lanes[lane].
3182 rising = edge;
3183 ctrl->timings[channel][slotrank].lanes[lane].
3184 falling = edge;
3185 }
3186 program_timings(ctrl, channel);
3187
3188 FOR_ALL_LANES {
3189 write32(DEFAULT_MCHBAR + 0x4340 +
3190 0x400 * channel + 4 * lane, 0);
3191 read32(DEFAULT_MCHBAR + 0x400 * channel +
3192 4 * lane + 0x4140);
3193 }
3194 wait_428c(channel);
3195
Patrick Rudolph371d2912015-10-09 13:33:25 +02003196 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003197 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3198 0x1f006);
3199 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3200 0x4 | (ctrl->tRCD << 16)
3201 | (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) <<
3202 10));
3203 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3204 (slotrank << 24) | 0x60000);
3205 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
3206 0x240);
3207
Patrick Rudolph371d2912015-10-09 13:33:25 +02003208 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003209 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3210 0x1f201);
3211 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3212 0x8005020 | ((ctrl->tWTR + ctrl->CWL + 8) <<
3213 16));
3214 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3215 (slotrank << 24));
3216 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
3217 0x242);
3218
Patrick Rudolph371d2912015-10-09 13:33:25 +02003219 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003220 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3221 0x1f105);
3222 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3223 0x4005020 | (max(ctrl->tRTP, 8) << 16));
3224 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3225 (slotrank << 24));
3226 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
3227 0x242);
3228
Patrick Rudolph371d2912015-10-09 13:33:25 +02003229 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003230 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3231 0x1f002);
3232 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3233 0xc01 | (ctrl->tRP << 16));
3234 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3235 (slotrank << 24) | 0x60400);
3236 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3237
3238 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3239 0xc0001);
3240 wait_428c(channel);
3241 FOR_ALL_LANES {
3242 read32(DEFAULT_MCHBAR + 0x4340 +
3243 0x400 * channel + lane * 4);
3244 }
3245
3246 raw_statistics[edge] =
3247 MCHBAR32(0x436c + 0x400 * channel);
3248 }
3249 FOR_ALL_LANES {
3250 struct run rn;
3251 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++)
3252 statistics[edge] =
3253 ! !(raw_statistics[edge] & (1 << lane));
3254 rn = get_longest_zero_run(statistics,
3255 MAX_EDGE_TIMING + 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003256 printram("edges: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003257 channel, slotrank, i, rn.start, rn.middle,
3258 rn.end, rn.start + ctrl->edge_offset[i],
3259 rn.end - ctrl->edge_offset[i]);
3260 lower[lane] =
3261 max(rn.start + ctrl->edge_offset[i], lower[lane]);
3262 upper[lane] =
3263 min(rn.end - ctrl->edge_offset[i], upper[lane]);
3264 edges[lane] = (lower[lane] + upper[lane]) / 2;
Patrick Rudolph9733e282015-08-16 17:06:30 +02003265 if (rn.all || (lower[lane] > upper[lane]))
3266 die("edge write discovery failed");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003267
3268 }
3269 }
3270 }
3271
3272 write32(DEFAULT_MCHBAR + 0x3000, 0);
3273 printram("CPA\n");
3274}
3275
3276static void discover_edges_write(ramctr_timing * ctrl)
3277{
3278 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3279 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3280 int channel, slotrank, lane;
3281
3282 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3283 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003284 printram("discover falling edges write:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003285
3286 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3287 discover_edges_write_real(ctrl, channel, slotrank,
3288 falling_edges[channel][slotrank]);
3289 }
3290
3291 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003292 printram("discover rising edges write:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003293
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);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003382 printram("discover timC write:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003383
3384 for (i = 0; i < 3; i++)
3385 FOR_ALL_POPULATED_CHANNELS {
3386 write32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100),
3387 (rege3c_b24[i] << 24)
3388 | (read32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100))
3389 & ~0x3f000000));
3390 udelay(2);
3391 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3392 FOR_ALL_POPULATED_RANKS {
3393 int timC;
3394 u32 raw_statistics[MAX_TIMC + 1];
3395 int statistics[MAX_TIMC + 1];
3396
3397 fill_pattern5(ctrl, channel, pat);
3398 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
3399 for (timC = 0; timC < MAX_TIMC + 1; timC++) {
3400 FOR_ALL_LANES
3401 ctrl->timings[channel][slotrank].lanes[lane].timC = timC;
3402 program_timings(ctrl, channel);
3403
3404 test_timC_write (ctrl, channel, slotrank);
3405
3406 raw_statistics[timC] =
3407 MCHBAR32(0x436c + 0x400 * channel);
3408 }
3409 FOR_ALL_LANES {
3410 struct run rn;
3411 for (timC = 0; timC <= MAX_TIMC; timC++)
3412 statistics[timC] =
3413 !!(raw_statistics[timC] &
3414 (1 << lane));
3415 rn = get_longest_zero_run(statistics,
3416 MAX_TIMC + 1);
3417 if (rn.all)
3418 die("timC write discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01003419 printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003420 channel, slotrank, i, rn.start,
3421 rn.middle, rn.end,
3422 rn.start + ctrl->timC_offset[i],
3423 rn.end - ctrl->timC_offset[i]);
3424 lower[channel][slotrank][lane] =
3425 max(rn.start + ctrl->timC_offset[i],
3426 lower[channel][slotrank][lane]);
3427 upper[channel][slotrank][lane] =
3428 min(rn.end - ctrl->timC_offset[i],
3429 upper[channel][slotrank][lane]);
3430
3431 }
3432 }
3433 }
3434 }
3435
3436 FOR_ALL_CHANNELS {
3437 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3438 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3439 ~0x3f000000));
3440 udelay(2);
3441 }
3442
3443 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3444
3445 printram("CPB\n");
3446
3447 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
Patrick Rudolpha649a542016-01-17 18:32:06 +01003448 printram("timC %d, %d, %d: %x\n", channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003449 slotrank, lane,
3450 (lower[channel][slotrank][lane] +
3451 upper[channel][slotrank][lane]) / 2);
3452 ctrl->timings[channel][slotrank].lanes[lane].timC =
3453 (lower[channel][slotrank][lane] +
3454 upper[channel][slotrank][lane]) / 2;
3455 }
3456 FOR_ALL_POPULATED_CHANNELS {
3457 program_timings(ctrl, channel);
3458 }
3459}
3460
3461static void normalize_training(ramctr_timing * ctrl)
3462{
3463 int channel, slotrank, lane;
3464 int mat = 0;
3465
3466 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3467 int delta;
3468 FOR_ALL_LANES mat =
3469 max(ctrl->timings[channel][slotrank].lanes[lane].timA, mat);
3470 delta = (mat >> 6) - ctrl->timings[channel][slotrank].val_4028;
3471 ctrl->timings[channel][slotrank].val_4024 += delta;
3472 ctrl->timings[channel][slotrank].val_4028 += delta;
3473 }
3474
3475 FOR_ALL_POPULATED_CHANNELS {
3476 program_timings(ctrl, channel);
3477 }
3478}
3479
3480static void write_controller_mr(ramctr_timing * ctrl)
3481{
3482 int channel, slotrank;
3483
3484 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3485 write32(DEFAULT_MCHBAR + 0x0004 + (channel << 8) +
3486 lane_registers[slotrank], make_mr0(ctrl, slotrank));
3487 write32(DEFAULT_MCHBAR + 0x0008 + (channel << 8) +
Patrick Rudolph7e513d12016-01-10 14:22:34 +01003488 lane_registers[slotrank],
3489 make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003490 }
3491}
3492
3493static void channel_test(ramctr_timing * ctrl)
3494{
3495 int channel, slotrank, lane;
3496
3497 FOR_ALL_POPULATED_CHANNELS
Patrick Rudolpha649a542016-01-17 18:32:06 +01003498 if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000)
3499 die("Mini channel test failed (1)\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003500 FOR_ALL_POPULATED_CHANNELS {
3501 fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
3502
3503 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3504 }
3505
3506 for (slotrank = 0; slotrank < 4; slotrank++)
3507 FOR_ALL_CHANNELS
3508 if (ctrl->rankmap[channel] & (1 << slotrank)) {
3509 FOR_ALL_LANES {
3510 write32(DEFAULT_MCHBAR + (0x4f40 + 4 * lane), 0);
3511 write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
3512 }
3513 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003514 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003515 write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
3516 write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
3517 write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
3518 0x00060000 | (slotrank << 24));
3519 write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003520 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003521 write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
3522 write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
3523 write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
3524 0x00000000 | (slotrank << 24));
3525 write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003526 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003527 write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
3528 write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
3529 write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
3530 0x00000000 | (slotrank << 24));
3531 write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003532 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003533 write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
3534 write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
3535 write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),
3536 0x00060400 | (slotrank << 24));
3537 write32(DEFAULT_MCHBAR + 0x421c + (channel << 10), 0x00000240);
3538 write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
3539 wait_428c(channel);
3540 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01003541 if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane))
3542 die("Mini channel test failed (2)\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003543 }
3544}
3545
3546static void set_scrambling_seed(ramctr_timing * ctrl)
3547{
3548 int channel;
3549
3550 /* FIXME: we hardcode seeds. Do we need to use some PRNG for them?
3551 I don't think so. */
3552 static u32 seeds[NUM_CHANNELS][3] = {
3553 {0x00009a36, 0xbafcfdcf, 0x46d1ab68},
3554 {0x00028bfa, 0x53fe4b49, 0x19ed5483}
3555 };
3556 FOR_ALL_POPULATED_CHANNELS {
3557 MCHBAR32(0x4020 + 0x400 * channel) &= ~0x10000000;
3558 write32(DEFAULT_MCHBAR + 0x4034, seeds[channel][0]);
3559 write32(DEFAULT_MCHBAR + 0x403c, seeds[channel][1]);
3560 write32(DEFAULT_MCHBAR + 0x4038, seeds[channel][2]);
3561 }
3562}
3563
3564static void set_4f8c(void)
3565{
3566 struct cpuid_result cpures;
3567 u32 cpu;
3568
3569 cpures = cpuid(0);
3570 cpu = (cpures.eax);
3571 if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
3572 MCHBAR32(0x4f8c) = 0x141D1519;
3573 } else {
3574 MCHBAR32(0x4f8c) = 0x551D1519;
3575 }
3576}
3577
3578static void prepare_training(ramctr_timing * ctrl)
3579{
3580 int channel;
3581
3582 FOR_ALL_POPULATED_CHANNELS {
3583 // Always drive command bus
3584 MCHBAR32(0x4004 + 0x400 * channel) |= 0x20000000;
3585 }
3586
3587 udelay(1);
3588
3589 FOR_ALL_POPULATED_CHANNELS {
3590 wait_428c(channel);
3591 }
3592}
3593
3594static void set_4008c(ramctr_timing * ctrl)
3595{
3596 int channel, slotrank;
3597 u32 reg;
3598 FOR_ALL_POPULATED_CHANNELS {
3599 u32 b20, b4_8_12;
3600 int min_320c = 10000;
3601 int max_320c = -10000;
3602
3603 FOR_ALL_POPULATED_RANKS {
3604 max_320c = max(ctrl->timings[channel][slotrank].val_320c, max_320c);
3605 min_320c = min(ctrl->timings[channel][slotrank].val_320c, min_320c);
3606 }
3607
3608 if (max_320c - min_320c > 51)
3609 b20 = 0;
3610 else
3611 b20 = ctrl->ref_card_offset[channel];
3612
3613 if (ctrl->reg_320c_range_threshold < max_320c - min_320c)
3614 b4_8_12 = 0x3330;
3615 else
3616 b4_8_12 = 0x2220;
3617
3618 reg = read32(DEFAULT_MCHBAR + 0x400c + (channel << 10));
3619 write32(DEFAULT_MCHBAR + 0x400c + (channel << 10),
3620 (reg & 0xFFF0FFFF)
3621 | (ctrl->ref_card_offset[channel] << 16)
3622 | (ctrl->ref_card_offset[channel] << 18));
3623 write32(DEFAULT_MCHBAR + 0x4008 + (channel << 10),
3624 0x0a000000
3625 | (b20 << 20)
3626 | ((ctrl->ref_card_offset[channel] + 2) << 16)
3627 | b4_8_12);
3628 }
3629}
3630
3631static void set_42a0(ramctr_timing * ctrl)
3632{
3633 int channel;
3634 FOR_ALL_POPULATED_CHANNELS {
3635 write32(DEFAULT_MCHBAR + (0x42a0 + 0x400 * channel),
3636 0x00001000 | ctrl->rankmap[channel]);
3637 MCHBAR32(0x4004 + 0x400 * channel) &= ~0x20000000; // OK
3638 }
3639}
3640
3641static int encode_5d10(int ns)
3642{
3643 return (ns + 499) / 500;
3644}
3645
3646/* FIXME: values in this function should be hardware revision-dependent. */
3647static void final_registers(ramctr_timing * ctrl)
3648{
3649 int channel;
3650 int t1_cycles = 0, t1_ns = 0, t2_ns;
3651 int t3_ns;
3652 u32 r32;
3653
3654 write32(DEFAULT_MCHBAR + 0x4cd4, 0x00000046);
3655
3656 write32(DEFAULT_MCHBAR + 0x400c, (read32(DEFAULT_MCHBAR + 0x400c) & 0xFFFFCFFF) | 0x1000); // OK
3657 write32(DEFAULT_MCHBAR + 0x440c, (read32(DEFAULT_MCHBAR + 0x440c) & 0xFFFFCFFF) | 0x1000); // OK
3658 write32(DEFAULT_MCHBAR + 0x4cb0, 0x00000740);
3659 write32(DEFAULT_MCHBAR + 0x4380, 0x00000aaa); // OK
3660 write32(DEFAULT_MCHBAR + 0x4780, 0x00000aaa); // OK
3661 write32(DEFAULT_MCHBAR + 0x4f88, 0x5f7003ff); // OK
3662 write32(DEFAULT_MCHBAR + 0x5064, 0x00073000 | ctrl->reg_5064b0); // OK
3663
3664 FOR_ALL_CHANNELS {
3665 switch (ctrl->rankmap[channel]) {
3666 /* Unpopulated channel. */
3667 case 0:
3668 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0);
3669 break;
3670 /* Only single-ranked dimms. */
3671 case 1:
3672 case 4:
3673 case 5:
3674 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x373131);
3675 break;
3676 /* Dual-ranked dimms present. */
3677 default:
3678 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x9b6ea1);
3679 break;
3680 }
3681 }
3682
3683 write32 (DEFAULT_MCHBAR + 0x5880, 0xca9171e5);
3684 write32 (DEFAULT_MCHBAR + 0x5888,
3685 (read32 (DEFAULT_MCHBAR + 0x5888) & ~0xffffff) | 0xe4d5d0);
3686 write32 (DEFAULT_MCHBAR + 0x58a8, read32 (DEFAULT_MCHBAR + 0x58a8) & ~0x1f);
3687 write32 (DEFAULT_MCHBAR + 0x4294,
3688 (read32 (DEFAULT_MCHBAR + 0x4294) & ~0x30000)
3689 | (1 << 16));
3690 write32 (DEFAULT_MCHBAR + 0x4694,
3691 (read32 (DEFAULT_MCHBAR + 0x4694) & ~0x30000)
3692 | (1 << 16));
3693
3694 MCHBAR32(0x5030) |= 1; // OK
3695 MCHBAR32(0x5030) |= 0x80; // OK
3696 MCHBAR32(0x5f18) = 0xfa; // OK
3697
3698 /* Find a populated channel. */
3699 FOR_ALL_POPULATED_CHANNELS
3700 break;
3701
3702 t1_cycles = ((read32(DEFAULT_MCHBAR + 0x4290 + channel * 0x400) >> 8) & 0xff);
3703 r32 = read32(DEFAULT_MCHBAR + 0x5064);
3704 if (r32 & 0x20000)
3705 t1_cycles += (r32 & 0xfff);
3706 t1_cycles += (read32(DEFAULT_MCHBAR + channel * 0x400 + 0x42a4) & 0xfff);
3707 t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
3708 if (!(r32 & 0x20000))
3709 t1_ns += 500;
3710
3711 t2_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f10) >> 8) & 0xfff);
3712 if ( read32(DEFAULT_MCHBAR + 0x5f00) & 8 )
3713 {
3714 t3_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f20) >> 8) & 0xfff);
3715 t3_ns += 10 * (read32(DEFAULT_MCHBAR + 0x5f18) & 0xff);
3716 }
3717 else
3718 {
3719 t3_ns = 500;
3720 }
3721 printk(BIOS_DEBUG, "t123: %d, %d, %d\n",
3722 t1_ns, t2_ns, t3_ns);
3723 write32 (DEFAULT_MCHBAR + 0x5d10,
3724 ((encode_5d10(t1_ns) + encode_5d10(t2_ns)) << 16)
3725 | (encode_5d10(t1_ns) << 8)
3726 | ((encode_5d10(t3_ns) + encode_5d10(t2_ns) + encode_5d10(t1_ns)) << 24)
3727 | (read32(DEFAULT_MCHBAR + 0x5d10) & 0xC0C0C0C0)
3728 | 0xc);
3729}
3730
3731static void save_timings(ramctr_timing * ctrl)
3732{
3733 struct mrc_data_container *mrcdata;
3734 int output_len = ALIGN(sizeof (*ctrl), 16);
3735
3736 /* Save the MRC S3 restore data to cbmem */
3737 mrcdata = cbmem_add
3738 (CBMEM_ID_MRCDATA,
3739 output_len + sizeof(struct mrc_data_container));
3740
3741 printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
3742 ctrl, mrcdata, output_len);
3743
3744 mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
3745 mrcdata->mrc_data_size = output_len;
3746 mrcdata->reserved = 0;
3747 memcpy(mrcdata->mrc_data, ctrl, sizeof (*ctrl));
3748
3749 /* Zero the unused space in aligned buffer. */
3750 if (output_len > sizeof (*ctrl))
3751 memset(mrcdata->mrc_data+sizeof (*ctrl), 0,
3752 output_len - sizeof (*ctrl));
3753
3754 mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
3755 mrcdata->mrc_data_size);
3756}
3757
3758static void restore_timings(ramctr_timing * ctrl)
3759{
3760 int channel, slotrank, lane;
3761
3762 FOR_ALL_POPULATED_CHANNELS
3763 MCHBAR32(0x4004 + 0x400 * channel) =
3764 ctrl->tRRD
3765 | (ctrl->tRTP << 4)
3766 | (ctrl->tCKE << 8)
3767 | (ctrl->tWTR << 12)
3768 | (ctrl->tFAW << 16)
3769 | (ctrl->tWR << 24)
3770 | (ctrl->cmd_stretch[channel] << 30);
3771
3772 udelay(1);
3773
3774 FOR_ALL_POPULATED_CHANNELS {
3775 wait_428c(channel);
3776 }
3777
3778 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3779 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
3780 + 4 * lane, 0);
3781 }
3782
3783 FOR_ALL_POPULATED_CHANNELS
3784 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
3785 read32(DEFAULT_MCHBAR + 0x4008 +
3786 0x400 * channel) | 0x8000000);
3787
3788 FOR_ALL_POPULATED_CHANNELS {
3789 udelay (1);
3790 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
3791 read32(DEFAULT_MCHBAR + 0x4020 +
3792 0x400 * channel) | 0x200000);
3793 }
3794
3795 printram("CPE\n");
3796
3797 write32(DEFAULT_MCHBAR + 0x3400, 0);
3798 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3799
3800 printram("CP5b\n");
3801
3802 FOR_ALL_POPULATED_CHANNELS {
3803 program_timings(ctrl, channel);
3804 }
3805
3806 u32 reg, addr;
3807
3808 while (!(MCHBAR32(0x5084) & 0x10000)) ;
3809 do {
3810 reg = MCHBAR32(0x428c);
3811 } while ((reg & 0x14) == 0);
3812
3813 // Set state of memory controller
3814 MCHBAR32(0x5030) = 0x116;
3815 MCHBAR32(0x4ea0) = 0;
3816
3817 // Wait 500us
3818 udelay(500);
3819
3820 FOR_ALL_CHANNELS {
3821 // Set valid rank CKE
3822 reg = 0;
3823 reg = (reg & ~0xf) | ctrl->rankmap[channel];
3824 addr = 0x400 * channel + 0x42a0;
3825 MCHBAR32(addr) = reg;
3826
3827 // Wait 10ns for ranks to settle
3828 //udelay(0.01);
3829
3830 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
3831 MCHBAR32(addr) = reg;
3832
3833 // Write reset using a NOP
3834 write_reset(ctrl);
3835 }
3836
3837 /* mrs commands. */
3838 dram_mrscommands(ctrl);
3839
3840 printram("CP5c\n");
3841
3842 write32(DEFAULT_MCHBAR + 0x3000, 0);
3843
3844 FOR_ALL_CHANNELS {
3845 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3846 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3847 ~0x3f000000));
3848 udelay(2);
3849 }
3850
3851 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3852}
3853
3854void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
3855 int s3resume)
3856{
3857 int me_uma_size;
3858 int cbmem_was_inited;
3859
3860 MCHBAR32(0x5f00) |= 1;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003861
Vadim Bendebury7a3f36a2012-04-18 15:47:32 -07003862 report_platform_info();
3863
Stefan Reinauer00636b02012-04-04 00:08:51 +02003864 /* Wait for ME to be ready */
3865 intel_early_me_init();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003866 me_uma_size = intel_early_me_uma_size();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003867
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003868 printk(BIOS_DEBUG, "Starting native Platform init\n");
Stefan Reinauer00636b02012-04-04 00:08:51 +02003869
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003870 u32 reg_5d10;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003871
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003872 wait_txt_clear();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003873
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003874 wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 });
Stefan Reinauer00636b02012-04-04 00:08:51 +02003875
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003876 reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000
3877 if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */
3878 && reg_5d10 && !s3resume) {
3879 write32(DEFAULT_MCHBAR + 0x5d10, 0);
3880 /* Need reset. */
Stefan Reinauer00636b02012-04-04 00:08:51 +02003881 outb(0x6, 0xcf9);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003882
Patrick Georgi546953c2014-11-29 10:38:17 +01003883 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003884 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02003885
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003886 ramctr_timing ctrl;
Vadim Bendebury48a4a7f2012-06-07 18:47:13 -07003887
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003888 memset(&ctrl, 0, sizeof (ctrl));
3889
3890 early_pch_init_native();
3891 early_thermal_init();
3892
3893 ctrl.mobile = mobile;
3894 ctrl.tCK = min_tck;
3895
3896 /* FIXME: for non-S3 we should be able to use timing caching with
3897 proper verification. Right now we use timings only for S3 case.
3898 */
3899 if (s3resume) {
3900 struct mrc_data_container *mrc_cache;
3901
3902 mrc_cache = find_current_mrc_cache();
3903 if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) {
3904 /* Failed S3 resume, reset to come up cleanly */
3905 outb(0x6, 0xcf9);
3906 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003907 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003908 memcpy(&ctrl, mrc_cache->mrc_data, sizeof (ctrl));
Stefan Reinauer00636b02012-04-04 00:08:51 +02003909 }
3910
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003911 if (!s3resume) {
3912 dimm_info info;
Sven Schnelled4ee8082012-07-28 09:28:56 +02003913
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003914 /* Get DDR3 SPD data */
3915 dram_find_spds_ddr3(spds, &info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003916
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003917 /* Find fastest common supported parameters */
3918 dram_find_common_params(&info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003919
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003920 dram_dimm_mapping(&info, &ctrl);
3921 }
3922
3923 /* Set MCU frequency */
3924 dram_freq(&ctrl);
3925
3926 if (!s3resume) {
3927 /* Calculate timings */
3928 dram_timing(&ctrl);
3929 }
3930
3931 /* Set version register */
3932 MCHBAR32(0x5034) = 0xC04EB002;
3933
3934 /* Enable crossover */
3935 dram_xover(&ctrl);
3936
3937 /* Set timing and refresh registers */
3938 dram_timing_regs(&ctrl);
3939
3940 /* Power mode preset */
3941 MCHBAR32(0x4e80) = 0x5500;
3942
3943 /* Set scheduler parameters */
3944 MCHBAR32(0x4c20) = 0x10100005;
3945
3946 /* Set cpu specific register */
3947 set_4f8c();
3948
3949 /* Clear IO reset bit */
3950 MCHBAR32(0x5030) &= ~0x20;
3951
3952 /* Set MAD-DIMM registers */
3953 dram_dimm_set_mapping(&ctrl);
3954 printk(BIOS_DEBUG, "Done dimm mapping\n");
3955
3956 /* Zone config */
3957 dram_zones(&ctrl, 1);
3958
3959 /* Set memory map */
3960 dram_memorymap(&ctrl, me_uma_size);
3961 printk(BIOS_DEBUG, "Done memory map\n");
3962
3963 /* Set IO registers */
3964 dram_ioregs(&ctrl);
3965 printk(BIOS_DEBUG, "Done io registers\n");
3966
3967 udelay(1);
3968
3969 if (s3resume) {
3970 restore_timings(&ctrl);
3971 } else {
3972 /* Do jedec ddr3 reset sequence */
3973 dram_jedecreset(&ctrl);
3974 printk(BIOS_DEBUG, "Done jedec reset\n");
3975
3976 /* MRS commands */
3977 dram_mrscommands(&ctrl);
3978 printk(BIOS_DEBUG, "Done MRS commands\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003979
3980 /* Prepare for memory training */
3981 prepare_training(&ctrl);
3982
3983 read_training(&ctrl);
3984 write_training(&ctrl);
3985
3986 printram("CP5a\n");
3987
3988 discover_edges(&ctrl);
3989
3990 printram("CP5b\n");
3991
3992 command_training(&ctrl);
3993
3994 printram("CP5c\n");
3995
3996 discover_edges_write(&ctrl);
3997
3998 discover_timC_write(&ctrl);
3999
4000 normalize_training(&ctrl);
4001 }
4002
4003 set_4008c(&ctrl);
4004
4005 write_controller_mr(&ctrl);
4006
4007 if (!s3resume) {
4008 channel_test(&ctrl);
4009 }
4010
4011 /* FIXME: should be hardware revision-dependent. */
4012 write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
4013
4014 set_scrambling_seed(&ctrl);
4015
4016 set_42a0(&ctrl);
4017
4018 final_registers(&ctrl);
4019
4020 /* Zone config */
4021 dram_zones(&ctrl, 0);
4022
4023 if (!s3resume)
4024 quick_ram_check();
4025
4026 intel_early_me_status();
4027 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
4028 intel_early_me_status();
4029
Stefan Reinauer00636b02012-04-04 00:08:51 +02004030 report_memory_config();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004031
4032 cbmem_was_inited = !cbmem_recovery(s3resume);
4033 if (!s3resume)
4034 save_timings(&ctrl);
4035 if (s3resume && !cbmem_was_inited) {
4036 /* Failed S3 resume, reset to come up cleanly */
4037 outb(0x6, 0xcf9);
4038 halt();
4039 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02004040}
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004041
4042#define HOST_BRIDGE PCI_DEVFN(0, 0)
4043#define DEFAULT_TCK TCK_800MHZ
4044
4045static unsigned int get_mem_min_tck(void)
4046{
4047 const struct device *dev;
4048 const struct northbridge_intel_sandybridge_config *cfg;
4049
4050 dev = dev_find_slot(0, HOST_BRIDGE);
4051 if (!(dev && dev->chip_info))
4052 return DEFAULT_TCK;
4053
4054 cfg = dev->chip_info;
4055
4056 /* If this is zero, it just means devicetree.cb didn't set it */
4057 if (cfg->max_mem_clock_mhz == 0)
4058 return DEFAULT_TCK;
4059
4060 if (cfg->max_mem_clock_mhz >= 800)
4061 return TCK_800MHZ;
4062 else if (cfg->max_mem_clock_mhz >= 666)
4063 return TCK_666MHZ;
4064 else if (cfg->max_mem_clock_mhz >= 533)
4065 return TCK_533MHZ;
4066 return TCK_400MHZ;
4067}
4068
4069void perform_raminit(int s3resume)
4070{
4071 spd_raw_data spd[4];
4072
4073 post_code(0x3a);
4074
4075 memset (spd, 0, sizeof (spd));
4076 mainboard_get_spd(spd);
4077
4078 timestamp_add_now(TS_BEFORE_INITRAM);
4079
4080 init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume);
4081}