blob: 65282d2848da4d174136ab5b607915c52ad8f2fd [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{
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100287 int dimms = 0, dimms_on_channel;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700288 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
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100298 dimms_on_channel = 0;
299 /* count dimms on channel */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700300 for (slot = 0; slot < NUM_SLOTS; slot++) {
301 spd_slot = 2 * channel + slot;
302 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100303 if (dimm->dimm[channel][slot].dram_type == SPD_MEMORY_TYPE_SDRAM_DDR3)
304 dimms_on_channel++;
305 }
306
307 for (slot = 0; slot < NUM_SLOTS; slot++) {
308 spd_slot = 2 * channel + slot;
309 /* search for XMP profile */
310 spd_xmp_decode_ddr3(&dimm->dimm[channel][slot],
311 spd[spd_slot],
312 DDR3_XMP_PROFILE_1);
313
314 if (dimm->dimm[channel][slot].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) {
315 printram("No valid XMP profile found.\n");
316 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
317 } else if (dimms_on_channel > dimm->dimm[channel][slot].dimms_per_channel) {
318 printram("XMP profile supports %u DIMMs, but %u DIMMs are installed.\n",
319 dimm->dimm[channel][slot].dimms_per_channel,
320 dimms_on_channel);
321 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
322 } else if (dimm->dimm[channel][slot].voltage != 1500) {
323 /* TODO: support other DDR3 voltage than 1500mV */
324 printram("XMP profile's requested %u mV is unsupported.\n",
325 dimm->dimm[channel][slot].voltage);
326 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
327 }
328
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700329 if (dimm->dimm[channel][slot].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) {
330 // set dimm invalid
331 dimm->dimm[channel][slot].ranks = 0;
332 dimm->dimm[channel][slot].size_mb = 0;
333 continue;
334 }
335
336 dram_print_spd_ddr3(&dimm->dimm[channel][slot]);
337 dimms++;
338 ctrl->rank_mirror[channel][slot * 2] = 0;
339 ctrl->rank_mirror[channel][slot * 2 + 1] = dimm->dimm[channel][slot].flags.pins_mirrored;
340 ctrl->channel_size_mb[channel] += dimm->dimm[channel][slot].size_mb;
341
342 ctrl->auto_self_refresh &= dimm->dimm[channel][slot].flags.asr;
343 ctrl->extended_temperature_range &= dimm->dimm[channel][slot].flags.ext_temp_refresh;
344
345 ctrl->rankmap[channel] |= ((1 << dimm->dimm[channel][slot].ranks) - 1) << (2 * slot);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100346 printk(BIOS_DEBUG, "channel[%d] rankmap = 0x%x\n",
347 channel, ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700348 }
349 if ((ctrl->rankmap[channel] & 3) && (ctrl->rankmap[channel] & 0xc)
350 && dimm->dimm[channel][0].reference_card <= 5 && dimm->dimm[channel][1].reference_card <= 5) {
351 const int ref_card_offset_table[6][6] = {
352 { 0, 0, 0, 0, 2, 2, },
353 { 0, 0, 0, 0, 2, 2, },
354 { 0, 0, 0, 0, 2, 2, },
355 { 0, 0, 0, 0, 1, 1, },
356 { 2, 2, 2, 1, 0, 0, },
357 { 2, 2, 2, 1, 0, 0, },
358 };
359 ctrl->ref_card_offset[channel] = ref_card_offset_table[dimm->dimm[channel][0].reference_card]
360 [dimm->dimm[channel][1].reference_card];
361 } else
362 ctrl->ref_card_offset[channel] = 0;
363 }
364
365 if (!dimms)
366 die("No DIMMs were found");
367}
368
369static void dram_find_common_params(const dimm_info * dimms,
370 ramctr_timing * ctrl)
371{
372 size_t valid_dimms;
373 int channel, slot;
374 ctrl->cas_supported = 0xff;
375 valid_dimms = 0;
376 FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) {
377 const dimm_attr *dimm = &dimms->dimm[channel][slot];
378 if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
379 continue;
380 valid_dimms++;
381
382 /* Find all possible CAS combinations */
383 ctrl->cas_supported &= dimm->cas_supported;
384
385 /* Find the smallest common latencies supported by all DIMMs */
386 ctrl->tCK = MAX(ctrl->tCK, dimm->tCK);
387 ctrl->tAA = MAX(ctrl->tAA, dimm->tAA);
388 ctrl->tWR = MAX(ctrl->tWR, dimm->tWR);
389 ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
390 ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
391 ctrl->tRP = MAX(ctrl->tRP, dimm->tRP);
392 ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
393 ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
394 ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
395 ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
396 ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
397 }
398
399 if (!ctrl->cas_supported)
400 die("Unsupported DIMM combination. "
401 "DIMMS do not support common CAS latency");
402 if (!valid_dimms)
403 die("No valid DIMMs found");
404}
405
406static u8 get_CWL(u8 CAS)
407{
408 /* Get CWL based on CAS using the following rule:
409 * _________________________________________
410 * CAS: | 4T | 5T | 6T | 7T | 8T | 9T | 10T | 11T |
411 * CWL: | 5T | 5T | 5T | 6T | 6T | 7T | 7T | 8T |
412 */
413 static const u8 cas_cwl_map[] = { 5, 5, 5, 6, 6, 7, 7, 8 };
414 if (CAS > 11)
415 return 8;
416 return cas_cwl_map[CAS - 4];
417}
418
419/* Frequency multiplier. */
420static u32 get_FRQ(u32 tCK)
421{
422 u32 FRQ;
423 FRQ = 256000 / (tCK * BASEFREQ);
424 if (FRQ > 8)
425 return 8;
426 if (FRQ < 3)
427 return 3;
428 return FRQ;
429}
430
431static u32 get_REFI(u32 tCK)
432{
433 /* Get REFI based on MCU frequency using the following rule:
434 * _________________________________________
435 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
436 * REFI: | 3120 | 4160 | 5200 | 6240 | 7280 | 8320 |
437 */
438 static const u32 frq_refi_map[] =
439 { 3120, 4160, 5200, 6240, 7280, 8320 };
440 return frq_refi_map[get_FRQ(tCK) - 3];
441}
442
443static u8 get_XSOffset(u32 tCK)
444{
445 /* Get XSOffset based on MCU frequency using the following rule:
446 * _________________________
447 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
448 * XSOffset : | 4 | 6 | 7 | 8 | 10 | 11 |
449 */
450 static const u8 frq_xs_map[] = { 4, 6, 7, 8, 10, 11 };
451 return frq_xs_map[get_FRQ(tCK) - 3];
452}
453
454static u8 get_MOD(u32 tCK)
455{
456 /* Get MOD based on MCU frequency using the following rule:
457 * _____________________________
458 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
459 * MOD : | 12 | 12 | 12 | 12 | 15 | 16 |
460 */
461 static const u8 frq_mod_map[] = { 12, 12, 12, 12, 15, 16 };
462 return frq_mod_map[get_FRQ(tCK) - 3];
463}
464
465static u8 get_WLO(u32 tCK)
466{
467 /* Get WLO based on MCU frequency using the following rule:
468 * _______________________
469 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
470 * WLO : | 4 | 5 | 6 | 6 | 8 | 8 |
471 */
472 static const u8 frq_wlo_map[] = { 4, 5, 6, 6, 8, 8 };
473 return frq_wlo_map[get_FRQ(tCK) - 3];
474}
475
476static u8 get_CKE(u32 tCK)
477{
478 /* Get CKE based on MCU frequency using the following rule:
479 * _______________________
480 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
481 * CKE : | 3 | 3 | 4 | 4 | 5 | 6 |
482 */
483 static const u8 frq_cke_map[] = { 3, 3, 4, 4, 5, 6 };
484 return frq_cke_map[get_FRQ(tCK) - 3];
485}
486
487static u8 get_XPDLL(u32 tCK)
488{
489 /* Get XPDLL based on MCU frequency using the following rule:
490 * _____________________________
491 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
492 * XPDLL : | 10 | 13 | 16 | 20 | 23 | 26 |
493 */
494 static const u8 frq_xpdll_map[] = { 10, 13, 16, 20, 23, 26 };
495 return frq_xpdll_map[get_FRQ(tCK) - 3];
496}
497
498static u8 get_XP(u32 tCK)
499{
500 /* Get XP based on MCU frequency using the following rule:
501 * _______________________
502 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
503 * XP : | 3 | 4 | 4 | 5 | 6 | 7 |
504 */
505 static const u8 frq_xp_map[] = { 3, 4, 4, 5, 6, 7 };
506 return frq_xp_map[get_FRQ(tCK) - 3];
507}
508
509static u8 get_AONPD(u32 tCK)
510{
511 /* Get AONPD based on MCU frequency using the following rule:
512 * ________________________
513 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
514 * AONPD : | 4 | 5 | 6 | 8 | 8 | 10 |
515 */
516 static const u8 frq_aonpd_map[] = { 4, 5, 6, 8, 8, 10 };
517 return frq_aonpd_map[get_FRQ(tCK) - 3];
518}
519
520static u32 get_COMP2(u32 tCK)
521{
522 /* Get COMP2 based on MCU frequency using the following rule:
523 * ___________________________________________________________
524 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
525 * COMP : | D6BEDCC | CE7C34C | CA57A4C | C6369CC | C42514C | C21410C |
526 */
527 static const u32 frq_comp2_map[] = { 0xD6BEDCC, 0xCE7C34C, 0xCA57A4C,
528 0xC6369CC, 0xC42514C, 0xC21410C
529 };
530 return frq_comp2_map[get_FRQ(tCK) - 3];
531}
532
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100533static u32 get_XOVER_CLK(u8 rankmap)
534{
535 return rankmap << 24;
536}
537
538static u32 get_XOVER_CMD(u8 rankmap)
539{
540 u32 reg;
541
542 // enable xover cmd
543 reg = 0x4000;
544
545 // enable xover ctl
546 if (rankmap & 0x3)
547 reg |= 0x20000;
548
549 if (rankmap & 0xc)
550 reg |= 0x4000000;
551
552 return reg;
553}
554
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700555static void dram_timing(ramctr_timing * ctrl)
556{
557 u8 val;
558 u32 val32;
559
560 /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure
561 * we cap it if we have faster DIMMs.
562 * Then, align it to the closest JEDEC standard frequency */
563 if (ctrl->tCK <= TCK_1066MHZ) {
564 ctrl->tCK = TCK_1066MHZ;
565 ctrl->edge_offset[0] = 16;
566 ctrl->edge_offset[1] = 7;
567 ctrl->edge_offset[2] = 7;
568 ctrl->timC_offset[0] = 18;
569 ctrl->timC_offset[1] = 7;
570 ctrl->timC_offset[2] = 7;
571 ctrl->reg_c14_offset = 16;
572 ctrl->reg_5064b0 = 0x218;
573 ctrl->reg_320c_range_threshold = 13;
574 } else if (ctrl->tCK <= TCK_933MHZ) {
575 ctrl->tCK = TCK_933MHZ;
576 ctrl->edge_offset[0] = 14;
577 ctrl->edge_offset[1] = 6;
578 ctrl->edge_offset[2] = 6;
579 ctrl->timC_offset[0] = 15;
580 ctrl->timC_offset[1] = 6;
581 ctrl->timC_offset[2] = 6;
582 ctrl->reg_c14_offset = 14;
583 ctrl->reg_5064b0 = 0x1d5;
584 ctrl->reg_320c_range_threshold = 15;
585 } else if (ctrl->tCK <= TCK_800MHZ) {
586 ctrl->tCK = TCK_800MHZ;
587 ctrl->edge_offset[0] = 13;
588 ctrl->edge_offset[1] = 5;
589 ctrl->edge_offset[2] = 5;
590 ctrl->timC_offset[0] = 14;
591 ctrl->timC_offset[1] = 5;
592 ctrl->timC_offset[2] = 5;
593 ctrl->reg_c14_offset = 12;
594 ctrl->reg_5064b0 = 0x193;
595 ctrl->reg_320c_range_threshold = 15;
596 } else if (ctrl->tCK <= TCK_666MHZ) {
597 ctrl->tCK = TCK_666MHZ;
598 ctrl->edge_offset[0] = 10;
599 ctrl->edge_offset[1] = 4;
600 ctrl->edge_offset[2] = 4;
601 ctrl->timC_offset[0] = 11;
602 ctrl->timC_offset[1] = 4;
603 ctrl->timC_offset[2] = 4;
604 ctrl->reg_c14_offset = 10;
605 ctrl->reg_5064b0 = 0x150;
606 ctrl->reg_320c_range_threshold = 16;
607 } else if (ctrl->tCK <= TCK_533MHZ) {
608 ctrl->tCK = TCK_533MHZ;
609 ctrl->edge_offset[0] = 8;
610 ctrl->edge_offset[1] = 3;
611 ctrl->edge_offset[2] = 3;
612 ctrl->timC_offset[0] = 9;
613 ctrl->timC_offset[1] = 3;
614 ctrl->timC_offset[2] = 3;
615 ctrl->reg_c14_offset = 8;
616 ctrl->reg_5064b0 = 0x10d;
617 ctrl->reg_320c_range_threshold = 17;
618 } else {
619 ctrl->tCK = TCK_400MHZ;
620 ctrl->edge_offset[0] = 6;
621 ctrl->edge_offset[1] = 2;
622 ctrl->edge_offset[2] = 2;
623 ctrl->timC_offset[0] = 6;
624 ctrl->timC_offset[1] = 2;
625 ctrl->timC_offset[2] = 2;
626 ctrl->reg_c14_offset = 8;
627 ctrl->reg_5064b0 = 0xcd;
628 ctrl->reg_320c_range_threshold = 17;
629 }
630
631 val32 = (1000 << 8) / ctrl->tCK;
632 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
633
634 /* Find CAS and CWL latencies */
635 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
636 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
637 /* Find lowest supported CAS latency that satisfies the minimum value */
638 while (!((ctrl->cas_supported >> (val - 4)) & 1)
639 && (ctrl->cas_supported >> (val - 4))) {
640 val++;
641 }
642 /* Is CAS supported */
643 if (!(ctrl->cas_supported & (1 << (val - 4))))
644 printk(BIOS_DEBUG, "CAS not supported\n");
645 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
646 ctrl->CAS = val;
647 ctrl->CWL = get_CWL(ctrl->CAS);
648 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
649
650 /* Find tRCD */
651 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
652 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
653
654 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
655 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
656
657 /* Find tRAS */
658 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
659 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
660
661 /* Find tWR */
662 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
663 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
664
665 /* Find tFAW */
666 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
667 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
668
669 /* Find tRRD */
670 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
671 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
672
673 /* Find tRTP */
674 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
675 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
676
677 /* Find tWTR */
678 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
679 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
680
681 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
682 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
683 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
684
685 ctrl->tREFI = get_REFI(ctrl->tCK);
686 ctrl->tMOD = get_MOD(ctrl->tCK);
687 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
688 ctrl->tWLO = get_WLO(ctrl->tCK);
689 ctrl->tCKE = get_CKE(ctrl->tCK);
690 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
691 ctrl->tXP = get_XP(ctrl->tCK);
692 ctrl->tAONPD = get_AONPD(ctrl->tCK);
693}
694
695static void dram_freq(ramctr_timing * ctrl)
696{
697 if (ctrl->tCK > TCK_400MHZ) {
698 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
699 ctrl->tCK = TCK_400MHZ;
700 }
701 while (1) {
702 u8 val2;
703 u32 reg1 = 0;
704
705 /* Step 1 - Set target PCU frequency */
706
707 if (ctrl->tCK <= TCK_1066MHZ) {
708 ctrl->tCK = TCK_1066MHZ;
709 } else if (ctrl->tCK <= TCK_933MHZ) {
710 ctrl->tCK = TCK_933MHZ;
711 } else if (ctrl->tCK <= TCK_800MHZ) {
712 ctrl->tCK = TCK_800MHZ;
713 } else if (ctrl->tCK <= TCK_666MHZ) {
714 ctrl->tCK = TCK_666MHZ;
715 } else if (ctrl->tCK <= TCK_533MHZ) {
716 ctrl->tCK = TCK_533MHZ;
717 } else if (ctrl->tCK <= TCK_400MHZ) {
718 ctrl->tCK = TCK_400MHZ;
719 } else {
720 die ("No lock frequency found");
721 }
722
723 /* Frequency mulitplier. */
724 u32 FRQ = get_FRQ(ctrl->tCK);
725
726 /* Step 2 - Select frequency in the MCU */
727 reg1 = FRQ;
728 reg1 |= 0x80000000; // set running bit
729 MCHBAR32(0x5e00) = reg1;
730 while (reg1 & 0x80000000) {
731 printk(BIOS_DEBUG, " PLL busy...");
732 reg1 = MCHBAR32(0x5e00);
733 }
734 printk(BIOS_DEBUG, "done\n");
735
736 /* Step 3 - Verify lock frequency */
737 reg1 = MCHBAR32(0x5e04);
738 val2 = (u8) reg1;
739 if (val2 >= FRQ) {
740 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
741 (1000 << 8) / ctrl->tCK);
742 return;
743 }
744 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
745 ctrl->tCK++;
746 }
747}
748
749static void dram_xover(ramctr_timing * ctrl)
750{
751 u32 reg;
752 int channel;
753
754 FOR_ALL_CHANNELS {
755 // enable xover clk
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100756 reg = get_XOVER_CLK(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100757 printram("XOVER CLK [%x] = %x\n", channel * 0x100 + 0xc14,
758 reg);
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100759 MCHBAR32(channel * 0x100 + 0xc14) = reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700760
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100761 // enable xover ctl & xover cmd
762 reg = get_XOVER_CMD(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100763 printram("XOVER CMD [%x] = %x\n", 0x100 * channel + 0x320c,
764 reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700765 MCHBAR32(0x100 * channel + 0x320c) = reg;
766 }
767}
768
769static void dram_timing_regs(ramctr_timing * ctrl)
770{
771 u32 reg, addr, val32, cpu, stretch;
772 struct cpuid_result cpures;
773 int channel;
774
775 FOR_ALL_CHANNELS {
776 // DBP
777 reg = 0;
778 reg |= ctrl->tRCD;
779 reg |= (ctrl->tRP << 4);
780 reg |= (ctrl->CAS << 8);
781 reg |= (ctrl->CWL << 12);
782 reg |= (ctrl->tRAS << 16);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100783 printram("DBP [%x] = %x\n", 0x400 * channel + 0x4000, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700784 MCHBAR32(0x400 * channel + 0x4000) = reg;
785
786 // RAP
787 reg = 0;
788 reg |= ctrl->tRRD;
789 reg |= (ctrl->tRTP << 4);
790 reg |= (ctrl->tCKE << 8);
791 reg |= (ctrl->tWTR << 12);
792 reg |= (ctrl->tFAW << 16);
793 reg |= (ctrl->tWR << 24);
794 reg |= (3 << 30);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100795 printram("RAP [%x] = %x\n", 0x400 * channel + 0x4004, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700796 MCHBAR32(0x400 * channel + 0x4004) = reg;
797
798 // OTHP
799 addr = 0x400 * channel + 0x400c;
800 reg = 0;
801 reg |= ctrl->tXPDLL;
802 reg |= (ctrl->tXP << 5);
803 reg |= (ctrl->tAONPD << 8);
804 reg |= 0xa0000;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100805 printram("OTHP [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700806 MCHBAR32(addr) = reg;
807
808 MCHBAR32(0x400 * channel + 0x4014) = 0;
809
810 MCHBAR32(addr) |= 0x00020000;
811
812 // ODT stretch
813 reg = 0;
814
815 cpures = cpuid(0);
816 cpu = cpures.eax;
817 if (IS_IVY_CPU(cpu)
818 || (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_D2(cpu))) {
819 stretch = 2;
820 addr = 0x400 * channel + 0x400c;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100821 printram("ODT stretch [%x] = %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700822 0x400 * channel + 0x400c, reg);
823 reg = MCHBAR32(addr);
824
825 if (((ctrl->rankmap[channel] & 3) == 0)
826 || (ctrl->rankmap[channel] & 0xc) == 0) {
827
828 // Rank 0 - operate on rank 2
829 reg = (reg & ~0xc0000) | (stretch << 18);
830
831 // Rank 2 - operate on rank 0
832 reg = (reg & ~0x30000) | (stretch << 16);
833
Patrick Rudolpha649a542016-01-17 18:32:06 +0100834 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700835 MCHBAR32(addr) = reg;
836 }
837
838 } else if (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_C(cpu)) {
839 stretch = 3;
840 addr = 0x400 * channel + 0x401c;
841 reg = MCHBAR32(addr);
842
843 if (((ctrl->rankmap[channel] & 3) == 0)
844 || (ctrl->rankmap[channel] & 0xc) == 0) {
845
846 // Rank 0 - operate on rank 2
847 reg = (reg & ~0x3000) | (stretch << 12);
848
849 // Rank 2 - operate on rank 0
850 reg = (reg & ~0xc00) | (stretch << 10);
851
Patrick Rudolpha649a542016-01-17 18:32:06 +0100852 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700853 MCHBAR32(addr) = reg;
854 }
855 } else {
856 stretch = 0;
857 }
858
859 // REFI
860 reg = 0;
861 val32 = ctrl->tREFI;
862 reg = (reg & ~0xffff) | val32;
863 val32 = ctrl->tRFC;
864 reg = (reg & ~0x1ff0000) | (val32 << 16);
865 val32 = (u32) (ctrl->tREFI * 9) / 1024;
866 reg = (reg & ~0xfe000000) | (val32 << 25);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100867 printram("REFI [%x] = %x\n", 0x400 * channel + 0x4298,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700868 reg);
869 MCHBAR32(0x400 * channel + 0x4298) = reg;
870
871 MCHBAR32(0x400 * channel + 0x4294) |= 0xff;
872
873 // SRFTP
874 reg = 0;
875 val32 = tDLLK;
876 reg = (reg & ~0xfff) | val32;
877 val32 = ctrl->tXSOffset;
878 reg = (reg & ~0xf000) | (val32 << 12);
879 val32 = tDLLK - ctrl->tXSOffset;
880 reg = (reg & ~0x3ff0000) | (val32 << 16);
881 val32 = ctrl->tMOD - 8;
882 reg = (reg & ~0xf0000000) | (val32 << 28);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100883 printram("SRFTP [%x] = %x\n", 0x400 * channel + 0x42a4,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700884 reg);
885 MCHBAR32(0x400 * channel + 0x42a4) = reg;
886 }
887}
888
889static void dram_dimm_mapping(dimm_info * info, ramctr_timing * ctrl)
890{
891 u32 reg, val32;
892 int channel;
893
894 FOR_ALL_CHANNELS {
895 dimm_attr *dimmA = 0;
896 dimm_attr *dimmB = 0;
897 reg = 0;
898 val32 = 0;
899 if (info->dimm[channel][0].size_mb >=
900 info->dimm[channel][1].size_mb) {
901 // dimm 0 is bigger, set it to dimmA
902 dimmA = &info->dimm[channel][0];
903 dimmB = &info->dimm[channel][1];
904 reg |= (0 << 16);
905 } else {
906 // dimm 1 is bigger, set it to dimmA
907 dimmA = &info->dimm[channel][1];
908 dimmB = &info->dimm[channel][0];
909 reg |= (1 << 16);
910 }
911 // dimmA
912 if (dimmA && (dimmA->ranks > 0)) {
913 val32 = dimmA->size_mb / 256;
914 reg = (reg & ~0xff) | val32;
915 val32 = dimmA->ranks - 1;
916 reg = (reg & ~0x20000) | (val32 << 17);
917 val32 = (dimmA->width / 8) - 1;
918 reg = (reg & ~0x80000) | (val32 << 19);
919 }
920 // dimmB
921 if (dimmB && (dimmB->ranks > 0)) {
922 val32 = dimmB->size_mb / 256;
923 reg = (reg & ~0xff00) | (val32 << 8);
924 val32 = dimmB->ranks - 1;
925 reg = (reg & ~0x40000) | (val32 << 18);
926 val32 = (dimmB->width / 8) - 1;
927 reg = (reg & ~0x100000) | (val32 << 20);
928 }
929 reg = (reg & ~0x200000) | (1 << 21); // rank interleave
930 reg = (reg & ~0x400000) | (1 << 22); // enhanced interleave
931
932 // Save MAD-DIMM register
933 if ((dimmA && (dimmA->ranks > 0))
934 || (dimmB && (dimmB->ranks > 0))) {
935 ctrl->mad_dimm[channel] = reg;
936 } else {
937 ctrl->mad_dimm[channel] = 0;
938 }
939 }
940}
941
942static void dram_dimm_set_mapping(ramctr_timing * ctrl)
943{
944 int channel;
945 FOR_ALL_CHANNELS {
946 MCHBAR32(0x5004 + channel * 4) = ctrl->mad_dimm[channel];
947 }
948}
949
950static void dram_zones(ramctr_timing * ctrl, int training)
951{
952 u32 reg, ch0size, ch1size;
953 u8 val;
954 reg = 0;
955 val = 0;
956 if (training) {
957 ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
958 ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
959 } else {
960 ch0size = ctrl->channel_size_mb[0];
961 ch1size = ctrl->channel_size_mb[1];
962 }
963
964 if (ch0size >= ch1size) {
965 reg = MCHBAR32(0x5014);
966 val = ch1size / 256;
967 reg = (reg & ~0xff000000) | val << 24;
968 reg = (reg & ~0xff0000) | (2 * val) << 16;
969 MCHBAR32(0x5014) = reg;
970 MCHBAR32(0x5000) = 0x24;
971 } else {
972 reg = MCHBAR32(0x5014);
973 val = ch0size / 256;
974 reg = (reg & ~0xff000000) | val << 24;
975 reg = (reg & ~0xff0000) | (2 * val) << 16;
976 MCHBAR32(0x5014) = reg;
977 MCHBAR32(0x5000) = 0x21;
978 }
979}
980
981static void dram_memorymap(ramctr_timing * ctrl, int me_uma_size)
982{
983 u32 reg, val, reclaim;
984 u32 tom, gfxstolen, gttsize;
985 size_t tsegsize, mmiosize, toludbase, touudbase, gfxstolenbase, gttbase,
986 tsegbase, mestolenbase;
987 size_t tsegbasedelta, remapbase, remaplimit;
988 uint16_t ggc;
989
990 mmiosize = 0x400;
991
992 ggc = pci_read_config16(NORTHBRIDGE, GGC);
993 if (!(ggc & 2)) {
994 gfxstolen = ((ggc >> 3) & 0x1f) * 32;
995 gttsize = ((ggc >> 8) & 0x3);
996 } else {
997 gfxstolen = 0;
998 gttsize = 0;
999 }
1000
1001 tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;
1002
1003 tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];
1004
1005 mestolenbase = tom - me_uma_size;
1006
1007 toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize,
1008 tom - me_uma_size);
1009 gfxstolenbase = toludbase - gfxstolen;
1010 gttbase = gfxstolenbase - gttsize;
1011
1012 tsegbase = gttbase - tsegsize;
1013
1014 // Round tsegbase down to nearest address aligned to tsegsize
1015 tsegbasedelta = tsegbase & (tsegsize - 1);
1016 tsegbase &= ~(tsegsize - 1);
1017
1018 gttbase -= tsegbasedelta;
1019 gfxstolenbase -= tsegbasedelta;
1020 toludbase -= tsegbasedelta;
1021
1022 // Test if it is possible to reclaim a hole in the ram addressing
1023 if (tom - me_uma_size > toludbase) {
1024 // Reclaim is possible
1025 reclaim = 1;
1026 remapbase = MAX(4096, tom - me_uma_size);
1027 remaplimit =
1028 remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
1029 touudbase = remaplimit + 1;
1030 } else {
1031 // Reclaim not possible
1032 reclaim = 0;
1033 touudbase = tom - me_uma_size;
1034 }
1035
1036 // Update memory map in pci-e configuration space
Patrick Rudolpha649a542016-01-17 18:32:06 +01001037 printk(BIOS_DEBUG, "Update PCI-E configuration space:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001038
1039 // TOM (top of memory)
1040 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa0);
1041 val = tom & 0xfff;
1042 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001043 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001044 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa0, reg);
1045
1046 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa4);
1047 val = tom & 0xfffff000;
1048 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001049 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001050 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa4, reg);
1051
1052 // TOLUD (top of low used dram)
1053 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xbc);
1054 val = toludbase & 0xfff;
1055 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001056 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xbc, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001057 pcie_write_config32(PCI_DEV(0, 0, 0), 0xbc, reg);
1058
1059 // TOUUD LSB (top of upper usable dram)
1060 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa8);
1061 val = touudbase & 0xfff;
1062 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001063 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001064 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa8, reg);
1065
1066 // TOUUD MSB
1067 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xac);
1068 val = touudbase & 0xfffff000;
1069 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001070 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xac, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001071 pcie_write_config32(PCI_DEV(0, 0, 0), 0xac, reg);
1072
1073 if (reclaim) {
1074 // REMAP BASE
1075 pcie_write_config32(PCI_DEV(0, 0, 0), 0x90, remapbase << 20);
1076 pcie_write_config32(PCI_DEV(0, 0, 0), 0x94, remapbase >> 12);
1077
1078 // REMAP LIMIT
1079 pcie_write_config32(PCI_DEV(0, 0, 0), 0x98, remaplimit << 20);
1080 pcie_write_config32(PCI_DEV(0, 0, 0), 0x9c, remaplimit >> 12);
1081 }
1082 // TSEG
1083 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb8);
1084 val = tsegbase & 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", 0xb8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001087 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb8, reg);
1088
1089 // GFX stolen memory
1090 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb0);
1091 val = gfxstolenbase & 0xfff;
1092 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001093 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001094 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb0, reg);
1095
1096 // GTT stolen memory
1097 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb4);
1098 val = gttbase & 0xfff;
1099 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001100 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001101 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb4, reg);
1102
1103 if (me_uma_size) {
1104 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x7c);
1105 val = (0x80000 - me_uma_size) & 0xfffff000;
1106 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001107 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x7c, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001108 pcie_write_config32(PCI_DEV(0, 0, 0), 0x7c, reg);
1109
1110 // ME base
1111 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x70);
1112 val = mestolenbase & 0xfff;
1113 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001114 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x70, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001115 pcie_write_config32(PCI_DEV(0, 0, 0), 0x70, reg);
1116
1117 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x74);
1118 val = mestolenbase & 0xfffff000;
1119 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001120 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x74, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001121 pcie_write_config32(PCI_DEV(0, 0, 0), 0x74, reg);
1122
1123 // ME mask
1124 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x78);
1125 val = (0x80000 - me_uma_size) & 0xfff;
1126 reg = (reg & ~0xfff00000) | (val << 20);
1127 reg = (reg & ~0x400) | (1 << 10); // set lockbit on ME mem
1128
1129 reg = (reg & ~0x800) | (1 << 11); // set ME memory enable
Patrick Rudolpha649a542016-01-17 18:32:06 +01001130 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x78, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001131 pcie_write_config32(PCI_DEV(0, 0, 0), 0x78, reg);
1132 }
1133}
1134
1135static void dram_ioregs(ramctr_timing * ctrl)
1136{
1137 u32 reg, comp2;
1138
1139 int channel;
1140
1141 // IO clock
1142 FOR_ALL_CHANNELS {
1143 MCHBAR32(0xc00 + 0x100 * channel) = ctrl->rankmap[channel];
1144 }
1145
1146 // IO command
1147 FOR_ALL_CHANNELS {
1148 MCHBAR32(0x3200 + 0x100 * channel) = ctrl->rankmap[channel];
1149 }
1150
1151 // IO control
1152 FOR_ALL_POPULATED_CHANNELS {
1153 program_timings(ctrl, channel);
1154 }
1155
1156 // Rcomp
Patrick Rudolpha649a542016-01-17 18:32:06 +01001157 printram("RCOMP...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001158 reg = 0;
1159 while (reg == 0) {
1160 reg = MCHBAR32(0x5084) & 0x10000;
1161 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001162 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001163
1164 // Set comp2
1165 comp2 = get_COMP2(ctrl->tCK);
1166 MCHBAR32(0x3714) = comp2;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001167 printram("COMP2 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001168
1169 // Set comp1
1170 FOR_ALL_POPULATED_CHANNELS {
1171 reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
1172 reg = (reg & ~0xe00) | (1 << 9); //odt
1173 reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
1174 reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
1175 MCHBAR32(0x1810 + channel * 0x100) = reg;
1176 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001177 printram("COMP1 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001178
Patrick Rudolpha649a542016-01-17 18:32:06 +01001179 printram("FORCE RCOMP and wait 20us...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001180 MCHBAR32(0x5f08) |= 0x100;
1181 udelay(20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001182 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001183}
1184
1185static void wait_428c(int channel)
1186{
1187 while (1) {
1188 if (read32(DEFAULT_MCHBAR + 0x428c + (channel << 10)) & 0x50)
1189 return;
1190 }
1191}
1192
1193static void write_reset(ramctr_timing * ctrl)
1194{
1195 int channel, slotrank;
1196
1197 /* choose a populated channel. */
1198 channel = (ctrl->rankmap[0]) ? 0 : 1;
1199
1200 wait_428c(channel);
1201
1202 /* choose a populated rank. */
1203 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
1204
Patrick Rudolph371d2912015-10-09 13:33:25 +02001205 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001206 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1207 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x80c01);
1208
1209 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1210 (slotrank << 24) | 0x60000);
1211
1212 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1213
1214 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x400001);
1215 wait_428c(channel);
1216}
1217
1218static void dram_jedecreset(ramctr_timing * ctrl)
1219{
1220 u32 reg, addr;
1221 int channel;
1222
1223 while (!(MCHBAR32(0x5084) & 0x10000)) ;
1224 do {
1225 reg = MCHBAR32(0x428c);
1226 } while ((reg & 0x14) == 0);
1227
1228 // Set state of memory controller
1229 reg = 0x112;
1230 MCHBAR32(0x5030) = reg;
1231 MCHBAR32(0x4ea0) = 0;
1232 reg |= 2; //ddr reset
1233 MCHBAR32(0x5030) = reg;
1234
1235 // Assert dimm reset signal
1236 reg = MCHBAR32(0x5030);
1237 reg &= ~0x2;
1238 MCHBAR32(0x5030) = reg;
1239
1240 // Wait 200us
1241 udelay(200);
1242
1243 // Deassert dimm reset signal
1244 MCHBAR32(0x5030) |= 2;
1245
1246 // Wait 500us
1247 udelay(500);
1248
1249 // Enable DCLK
1250 MCHBAR32(0x5030) |= 4;
1251
1252 // XXX Wait 20ns
1253 udelay(1);
1254
1255 FOR_ALL_CHANNELS {
1256 // Set valid rank CKE
1257 reg = 0;
1258 reg = (reg & ~0xf) | ctrl->rankmap[channel];
1259 addr = 0x400 * channel + 0x42a0;
1260 MCHBAR32(addr) = reg;
1261
1262 // Wait 10ns for ranks to settle
1263 //udelay(0.01);
1264
1265 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
1266 MCHBAR32(addr) = reg;
1267
1268 // Write reset using a NOP
1269 write_reset(ctrl);
1270 }
1271}
1272
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001273static odtmap get_ODT(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001274{
1275 /* Get ODT based on rankmap: */
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001276 int dimms_per_ch = (ctrl->rankmap[channel] & 1)
1277 + ((ctrl->rankmap[channel] >> 2) & 1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001278
1279 if (dimms_per_ch == 1) {
1280 return (const odtmap){60, 60};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001281 } else {
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001282 return (const odtmap){120, 30};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001283 }
1284}
1285
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001286static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001287 int reg, u32 val)
1288{
1289 wait_428c(channel);
1290
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001291 if (ctrl->rank_mirror[channel][slotrank]) {
1292 /* DDR3 Rank1 Address mirror
1293 * swap the following pins:
1294 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1 */
1295 reg = ((reg >> 1) & 1) | ((reg << 1) & 2);
1296 val = (val & ~0x1f8) | ((val >> 1) & 0xa8)
1297 | ((val & 0xa8) << 1);
1298 }
1299
Patrick Rudolph371d2912015-10-09 13:33:25 +02001300 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001301 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
1302 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
1303 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1304 (slotrank << 24) | (reg << 20) | val | 0x60000);
1305 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1306
Patrick Rudolph371d2912015-10-09 13:33:25 +02001307 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001308 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
1309 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
1310 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
1311 (slotrank << 24) | (reg << 20) | val | 0x60000);
1312 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1313
Patrick Rudolph371d2912015-10-09 13:33:25 +02001314 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001315 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
1316 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1317 0x1001 | (ctrl->tMOD << 16));
1318 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1319 (slotrank << 24) | (reg << 20) | val | 0x60000);
1320 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1321 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
1322}
1323
1324static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
1325{
1326 u16 mr0reg, mch_cas, mch_wr;
1327 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 +02001328
1329 /* DLL Reset - self clearing - set after CLK frequency has been changed */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001330 mr0reg = 0x100;
1331
1332 // Convert CAS to MCH register friendly
1333 if (ctrl->CAS < 12) {
1334 mch_cas = (u16) ((ctrl->CAS - 4) << 1);
1335 } else {
1336 mch_cas = (u16) (ctrl->CAS - 12);
1337 mch_cas = ((mch_cas << 1) | 0x1);
1338 }
1339
1340 // Convert tWR to MCH register friendly
1341 mch_wr = mch_wr_t[ctrl->tWR - 5];
1342
1343 mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
1344 mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
1345 mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001346
1347 // Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001348 mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
1349 return mr0reg;
1350}
1351
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001352static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001353{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001354 write_mrreg(ctrl, channel, rank, 0,
1355 make_mr0(ctrl, rank));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001356}
1357
1358static u32 encode_odt(u32 odt)
1359{
1360 switch (odt) {
1361 case 30:
1362 return (1 << 9) | (1 << 2); // RZQ/8, RZQ/4
1363 case 60:
1364 return (1 << 2); // RZQ/4
1365 case 120:
1366 return (1 << 6); // RZQ/2
1367 default:
1368 case 0:
1369 return 0;
1370 }
1371}
1372
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001373static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001374{
1375 odtmap odt;
1376 u32 mr1reg;
1377
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001378 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001379 mr1reg = 0x2;
1380
1381 mr1reg |= encode_odt(odt.rttnom);
1382
1383 return mr1reg;
1384}
1385
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001386static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001387{
1388 u16 mr1reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001389
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001390 mr1reg = make_mr1(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001391
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001392 write_mrreg(ctrl, channel, rank, 1, mr1reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001393}
1394
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001395static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001396{
1397 u16 pasr, cwl, mr2reg;
1398 odtmap odt;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001399 int srt;
1400
1401 pasr = 0;
1402 cwl = ctrl->CWL - 5;
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001403 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001404
1405 srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;
1406
1407 mr2reg = 0;
1408 mr2reg = (mr2reg & ~0x7) | pasr;
1409 mr2reg = (mr2reg & ~0x38) | (cwl << 3);
1410 mr2reg = (mr2reg & ~0x40) | (ctrl->auto_self_refresh << 6);
1411 mr2reg = (mr2reg & ~0x80) | (srt << 7);
1412 mr2reg |= (odt.rttwr / 60) << 9;
1413
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001414 write_mrreg(ctrl, channel, rank, 2, mr2reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001415}
1416
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001417static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001418{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001419 write_mrreg(ctrl, channel, rank, 3, 0);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001420}
1421
1422static void dram_mrscommands(ramctr_timing * ctrl)
1423{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001424 u8 slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001425 u32 reg, addr;
1426 int channel;
1427
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001428 FOR_ALL_POPULATED_CHANNELS {
1429 FOR_ALL_POPULATED_RANKS {
1430 // MR2
1431 dram_mr2(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001432
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001433 // MR3
1434 dram_mr3(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001435
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001436 // MR1
1437 dram_mr1(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001438
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001439 // MR0
1440 dram_mr0(ctrl, slotrank, channel);
1441 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001442 }
1443
Patrick Rudolph371d2912015-10-09 13:33:25 +02001444 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001445 write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
1446 write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
1447 write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
1448 write32(DEFAULT_MCHBAR + 0x4e10, 0);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001449
1450 /* DRAM command ZQCL */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001451 write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
1452 write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
1453 write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
1454 write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001455
1456 /* execute command queue on all channels ? */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001457 write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
1458
1459 // Drain
1460 FOR_ALL_CHANNELS {
1461 // Wait for ref drained
1462 wait_428c(channel);
1463 }
1464
1465 // Refresh enable
1466 MCHBAR32(0x5030) |= 8;
1467
1468 FOR_ALL_POPULATED_CHANNELS {
1469 addr = 0x400 * channel + 0x4020;
1470 reg = MCHBAR32(addr);
1471 reg &= ~0x200000;
1472 MCHBAR32(addr) = reg;
1473
1474 wait_428c(channel);
1475
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001476 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001477
1478 // Drain
1479 wait_428c(channel);
1480
Patrick Rudolph371d2912015-10-09 13:33:25 +02001481 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001482 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1483 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
1484 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001485 (slotrank << 24) | 0x60000);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001486 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
1487 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x1);
1488
1489 // Drain
1490 wait_428c(channel);
1491 }
1492}
1493
1494const u32 lane_registers[] = {
1495 0x0000, 0x0200, 0x0400, 0x0600,
1496 0x1000, 0x1200, 0x1400, 0x1600,
1497 0x0800
1498};
1499
1500static void program_timings(ramctr_timing * ctrl, int channel)
1501{
1502 u32 reg32, reg_4024, reg_c14, reg_c18, reg_4028;
1503 int lane;
1504 int slotrank, slot;
1505 int full_shift = 0;
1506 u16 slot320c[NUM_SLOTS];
1507
1508 FOR_ALL_POPULATED_RANKS {
1509 if (full_shift < -ctrl->timings[channel][slotrank].val_320c)
1510 full_shift = -ctrl->timings[channel][slotrank].val_320c;
1511 }
1512
1513 for (slot = 0; slot < NUM_SLOTS; slot++)
1514 switch ((ctrl->rankmap[channel] >> (2 * slot)) & 3) {
1515 case 0:
1516 default:
1517 slot320c[slot] = 0x7f;
1518 break;
1519 case 1:
1520 slot320c[slot] =
1521 ctrl->timings[channel][2 * slot + 0].val_320c +
1522 full_shift;
1523 break;
1524 case 2:
1525 slot320c[slot] =
1526 ctrl->timings[channel][2 * slot + 1].val_320c +
1527 full_shift;
1528 break;
1529 case 3:
1530 slot320c[slot] =
1531 (ctrl->timings[channel][2 * slot].val_320c +
1532 ctrl->timings[channel][2 * slot +
1533 1].val_320c) / 2 +
1534 full_shift;
1535 break;
1536 }
1537
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001538 /* enable CMD XOVER */
1539 reg32 = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001540 reg32 |= ((slot320c[0] & 0x3f) << 6) | ((slot320c[0] & 0x40) << 9);
1541 reg32 |= (slot320c[1] & 0x7f) << 18;
1542 reg32 |= (full_shift & 0x3f) | ((full_shift & 0x40) << 6);
1543
1544 MCHBAR32(0x320c + 0x100 * channel) = reg32;
1545
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001546 /* enable CLK XOVER */
1547 reg_c14 = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001548 reg_c18 = 0;
1549
1550 FOR_ALL_POPULATED_RANKS {
1551 int shift =
1552 ctrl->timings[channel][slotrank].val_320c + full_shift;
1553 int offset_val_c14;
1554 if (shift < 0)
1555 shift = 0;
1556 offset_val_c14 = ctrl->reg_c14_offset + shift;
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001557 /* set CLK phase shift */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001558 reg_c14 |= (offset_val_c14 & 0x3f) << (6 * slotrank);
1559 reg_c18 |= ((offset_val_c14 >> 6) & 1) << slotrank;
1560 }
1561
1562 MCHBAR32(0xc14 + channel * 0x100) = reg_c14;
1563 MCHBAR32(0xc18 + channel * 0x100) = reg_c18;
1564
1565 reg_4028 = MCHBAR32(0x4028 + 0x400 * channel);
1566 reg_4028 &= 0xffff0000;
1567
1568 reg_4024 = 0;
1569
1570 FOR_ALL_POPULATED_RANKS {
1571 int post_timA_min_high = 7, post_timA_max_high = 0;
1572 int pre_timA_min_high = 7, pre_timA_max_high = 0;
1573 int shift_402x = 0;
1574 int shift =
1575 ctrl->timings[channel][slotrank].val_320c + full_shift;
1576
1577 if (shift < 0)
1578 shift = 0;
1579
1580 FOR_ALL_LANES {
1581 if (post_timA_min_high >
1582 ((ctrl->timings[channel][slotrank].lanes[lane].
1583 timA + shift) >> 6))
1584 post_timA_min_high =
1585 ((ctrl->timings[channel][slotrank].
1586 lanes[lane].timA + shift) >> 6);
1587 if (pre_timA_min_high >
1588 (ctrl->timings[channel][slotrank].lanes[lane].
1589 timA >> 6))
1590 pre_timA_min_high =
1591 (ctrl->timings[channel][slotrank].
1592 lanes[lane].timA >> 6);
1593 if (post_timA_max_high <
1594 ((ctrl->timings[channel][slotrank].lanes[lane].
1595 timA + shift) >> 6))
1596 post_timA_max_high =
1597 ((ctrl->timings[channel][slotrank].
1598 lanes[lane].timA + shift) >> 6);
1599 if (pre_timA_max_high <
1600 (ctrl->timings[channel][slotrank].lanes[lane].
1601 timA >> 6))
1602 pre_timA_max_high =
1603 (ctrl->timings[channel][slotrank].
1604 lanes[lane].timA >> 6);
1605 }
1606
1607 if (pre_timA_max_high - pre_timA_min_high <
1608 post_timA_max_high - post_timA_min_high)
1609 shift_402x = +1;
1610 else if (pre_timA_max_high - pre_timA_min_high >
1611 post_timA_max_high - post_timA_min_high)
1612 shift_402x = -1;
1613
1614 reg_4028 |=
1615 (ctrl->timings[channel][slotrank].val_4028 + shift_402x -
1616 post_timA_min_high) << (4 * slotrank);
1617 reg_4024 |=
1618 (ctrl->timings[channel][slotrank].val_4024 +
1619 shift_402x) << (8 * slotrank);
1620
1621 FOR_ALL_LANES {
1622 MCHBAR32(lane_registers[lane] + 0x10 + 0x100 * channel +
1623 4 * slotrank)
1624 =
1625 (((ctrl->timings[channel][slotrank].lanes[lane].
1626 timA + shift) & 0x3f)
1627 |
1628 ((ctrl->timings[channel][slotrank].lanes[lane].
1629 rising + shift) << 8)
1630 |
1631 (((ctrl->timings[channel][slotrank].lanes[lane].
1632 timA + shift -
1633 (post_timA_min_high << 6)) & 0x1c0) << 10)
Patrick Rudolph0188b132016-02-10 19:16:34 +01001634 | ((ctrl->timings[channel][slotrank].lanes[lane].
1635 falling + shift) << 20));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001636
1637 MCHBAR32(lane_registers[lane] + 0x20 + 0x100 * channel +
1638 4 * slotrank)
1639 =
1640 (((ctrl->timings[channel][slotrank].lanes[lane].
1641 timC + shift) & 0x3f)
1642 |
1643 (((ctrl->timings[channel][slotrank].lanes[lane].
1644 timB + shift) & 0x3f) << 8)
1645 |
1646 (((ctrl->timings[channel][slotrank].lanes[lane].
1647 timB + shift) & 0x1c0) << 9)
1648 |
1649 (((ctrl->timings[channel][slotrank].lanes[lane].
1650 timC + shift) & 0x40) << 13));
1651 }
1652 }
1653 MCHBAR32(0x4024 + 0x400 * channel) = reg_4024;
1654 MCHBAR32(0x4028 + 0x400 * channel) = reg_4028;
1655}
1656
1657static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
1658{
1659 wait_428c(channel);
1660
Patrick Rudolph371d2912015-10-09 13:33:25 +02001661 /* DRAM command MRS
1662 * write MR3 MPR enable
1663 * in this mode only RD and RDA are allowed
1664 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001665 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
1666 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1667 (0xc01 | (ctrl->tMOD << 16)));
1668 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1669 (slotrank << 24) | 0x360004);
1670 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1671
Patrick Rudolph371d2912015-10-09 13:33:25 +02001672 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001673 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
1674 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
1675 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
1676 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1677
Patrick Rudolph371d2912015-10-09 13:33:25 +02001678 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001679 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
1680 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1681 0x100f | ((ctrl->CAS + 36) << 16));
1682 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1683 (slotrank << 24) | 0x60000);
1684 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1685
Patrick Rudolph371d2912015-10-09 13:33:25 +02001686 /* DRAM command MRS
1687 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001688 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
1689 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
1690 (0xc01 | (ctrl->tMOD << 16)));
1691 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
1692 (slotrank << 24) | 0x360000);
1693 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
1694
1695 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
1696
1697 wait_428c(channel);
1698}
1699
1700static int does_lane_work(ramctr_timing * ctrl, int channel, int slotrank,
1701 int lane)
1702{
1703 u32 timA = ctrl->timings[channel][slotrank].lanes[lane].timA;
1704 return ((read32
1705 (DEFAULT_MCHBAR + lane_registers[lane] + channel * 0x100 + 4 +
1706 ((timA / 32) & 1) * 4)
1707 >> (timA % 32)) & 1);
1708}
1709
1710struct run {
1711 int middle;
1712 int end;
1713 int start;
1714 int all;
1715 int length;
1716};
1717
1718static struct run get_longest_zero_run(int *seq, int sz)
1719{
1720 int i, ls;
1721 int bl = 0, bs = 0;
1722 struct run ret;
1723
1724 ls = 0;
1725 for (i = 0; i < 2 * sz; i++)
1726 if (seq[i % sz]) {
1727 if (i - ls > bl) {
1728 bl = i - ls;
1729 bs = ls;
1730 }
1731 ls = i + 1;
1732 }
1733 if (bl == 0) {
1734 ret.middle = sz / 2;
1735 ret.start = 0;
1736 ret.end = sz;
1737 ret.all = 1;
1738 return ret;
1739 }
1740
1741 ret.start = bs % sz;
1742 ret.end = (bs + bl - 1) % sz;
1743 ret.middle = (bs + (bl - 1) / 2) % sz;
1744 ret.length = bl;
1745 ret.all = 0;
1746
1747 return ret;
1748}
1749
1750static void discover_timA_coarse(ramctr_timing * ctrl, int channel,
1751 int slotrank, int *upperA)
1752{
1753 int timA;
1754 int statistics[NUM_LANES][128];
1755 int lane;
1756
1757 for (timA = 0; timA < 128; timA++) {
1758 FOR_ALL_LANES {
1759 ctrl->timings[channel][slotrank].lanes[lane].timA = timA;
1760 }
1761 program_timings(ctrl, channel);
1762
1763 test_timA(ctrl, channel, slotrank);
1764
1765 FOR_ALL_LANES {
1766 statistics[lane][timA] =
1767 !does_lane_work(ctrl, channel, slotrank, lane);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001768 printram("Astat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001769 channel, slotrank, lane, timA,
1770 statistics[lane][timA]);
1771 }
1772 }
1773 FOR_ALL_LANES {
1774 struct run rn = get_longest_zero_run(statistics[lane], 128);
1775 ctrl->timings[channel][slotrank].lanes[lane].timA = rn.middle;
1776 upperA[lane] = rn.end;
1777 if (upperA[lane] < rn.middle)
1778 upperA[lane] += 128;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001779 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001780 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001781 printram("Aend: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001782 lane, upperA[lane]);
1783 }
1784}
1785
1786static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
1787 int *upperA)
1788{
1789 int timA_delta;
1790 int statistics[NUM_LANES][51];
1791 int lane, i;
1792
1793 memset(statistics, 0, sizeof(statistics));
1794
1795 for (timA_delta = -25; timA_delta <= 25; timA_delta++) {
1796 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
1797 timA = upperA[lane] + timA_delta + 0x40;
1798 program_timings(ctrl, channel);
1799
1800 for (i = 0; i < 100; i++) {
1801 test_timA(ctrl, channel, slotrank);
1802 FOR_ALL_LANES {
1803 statistics[lane][timA_delta + 25] +=
1804 does_lane_work(ctrl, channel, slotrank,
1805 lane);
1806 }
1807 }
1808 }
1809 FOR_ALL_LANES {
1810 int last_zero, first_all;
1811
1812 for (last_zero = -25; last_zero <= 25; last_zero++)
1813 if (statistics[lane][last_zero + 25])
1814 break;
1815 last_zero--;
1816 for (first_all = -25; first_all <= 25; first_all++)
1817 if (statistics[lane][first_all + 25] == 100)
1818 break;
1819
1820 printram("lane %d: %d, %d\n", lane, last_zero,
1821 first_all);
1822
1823 ctrl->timings[channel][slotrank].lanes[lane].timA =
1824 (last_zero + first_all) / 2 + upperA[lane];
Patrick Rudolpha649a542016-01-17 18:32:06 +01001825 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001826 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1827 }
1828}
1829
1830static void discover_402x(ramctr_timing * ctrl, int channel, int slotrank,
1831 int *upperA)
1832{
1833 int works[NUM_LANES];
1834 int lane;
1835 while (1) {
1836 int all_works = 1, some_works = 0;
1837 program_timings(ctrl, channel);
1838 test_timA(ctrl, channel, slotrank);
1839 FOR_ALL_LANES {
1840 works[lane] =
1841 !does_lane_work(ctrl, channel, slotrank, lane);
1842 if (works[lane])
1843 some_works = 1;
1844 else
1845 all_works = 0;
1846 }
1847 if (all_works)
1848 return;
1849 if (!some_works) {
1850 if (ctrl->timings[channel][slotrank].val_4024 < 2)
1851 die("402x discovery failed");
1852 ctrl->timings[channel][slotrank].val_4024 -= 2;
1853 printram("4024 -= 2;\n");
1854 continue;
1855 }
1856 ctrl->timings[channel][slotrank].val_4028 += 2;
1857 printram("4028 += 2;\n");
1858 if (ctrl->timings[channel][slotrank].val_4028 >= 0x10)
1859 die("402x discovery failed");
1860 FOR_ALL_LANES if (works[lane]) {
1861 ctrl->timings[channel][slotrank].lanes[lane].timA +=
1862 128;
1863 upperA[lane] += 128;
1864 printram("increment %d, %d, %d\n", channel,
1865 slotrank, lane);
1866 }
1867 }
1868}
1869
1870struct timA_minmax {
1871 int timA_min_high, timA_max_high;
1872};
1873
1874static void pre_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1875 struct timA_minmax *mnmx)
1876{
1877 int lane;
1878 mnmx->timA_min_high = 7;
1879 mnmx->timA_max_high = 0;
1880
1881 FOR_ALL_LANES {
1882 if (mnmx->timA_min_high >
1883 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1884 mnmx->timA_min_high =
1885 (ctrl->timings[channel][slotrank].lanes[lane].
1886 timA >> 6);
1887 if (mnmx->timA_max_high <
1888 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1889 mnmx->timA_max_high =
1890 (ctrl->timings[channel][slotrank].lanes[lane].
1891 timA >> 6);
1892 }
1893}
1894
1895static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1896 struct timA_minmax *mnmx)
1897{
1898 struct timA_minmax post;
1899 int shift_402x = 0;
1900
1901 /* Get changed maxima. */
1902 pre_timA_change(ctrl, channel, slotrank, &post);
1903
1904 if (mnmx->timA_max_high - mnmx->timA_min_high <
1905 post.timA_max_high - post.timA_min_high)
1906 shift_402x = +1;
1907 else if (mnmx->timA_max_high - mnmx->timA_min_high >
1908 post.timA_max_high - post.timA_min_high)
1909 shift_402x = -1;
1910 else
1911 shift_402x = 0;
1912
1913 ctrl->timings[channel][slotrank].val_4028 += shift_402x;
1914 ctrl->timings[channel][slotrank].val_4024 += shift_402x;
1915 printram("4024 += %d;\n", shift_402x);
1916 printram("4028 += %d;\n", shift_402x);
1917}
1918
Patrick Rudolph371d2912015-10-09 13:33:25 +02001919/* Compensate the skew between DQS and DQs.
1920 * To ease PCB design a small skew between Data Strobe signals and
1921 * Data Signals is allowed.
1922 * The controller has to measure and compensate this skew for every byte-lane.
1923 * By delaying either all DQs signals or DQS signal, a full phase
1924 * shift can be introduced.
1925 * It is assumed that one byte-lane's DQs signals have the same routing delay.
1926 *
1927 * To measure the actual skew, the DRAM is placed in "read leveling" mode.
1928 * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
1929 * The memory controller iterates over all possible values to do a full phase shift
1930 * and issues read commands.
1931 * With DQS and DQs in phase the data read is expected to alternate on every byte:
1932 * 0xFF 0x00 0xFF ...
1933 * Once the controller has detected this pattern a bit in the result register is
1934 * set for the current phase shift.
1935 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001936static void read_training(ramctr_timing * ctrl)
1937{
1938 int channel, slotrank, lane;
1939
1940 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001941 int all_high, some_high;
1942 int upperA[NUM_LANES];
1943 struct timA_minmax mnmx;
1944
1945 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001946
1947 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001948 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
1949 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1950 0xc01 | (ctrl->tRP << 16));
1951 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1952 (slotrank << 24) | 0x60400);
1953 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1954 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
1955
1956 write32(DEFAULT_MCHBAR + 0x3400, (slotrank << 2) | 0x8001);
1957
1958 ctrl->timings[channel][slotrank].val_4028 = 4;
1959 ctrl->timings[channel][slotrank].val_4024 = 55;
1960 program_timings(ctrl, channel);
1961
1962 discover_timA_coarse(ctrl, channel, slotrank, upperA);
1963
1964 all_high = 1;
1965 some_high = 0;
1966 FOR_ALL_LANES {
1967 if (ctrl->timings[channel][slotrank].lanes[lane].
1968 timA >= 0x40)
1969 some_high = 1;
1970 else
1971 all_high = 0;
1972 }
1973
1974 if (all_high) {
1975 ctrl->timings[channel][slotrank].val_4028--;
1976 printram("4028--;\n");
1977 FOR_ALL_LANES {
1978 ctrl->timings[channel][slotrank].lanes[lane].
1979 timA -= 0x40;
1980 upperA[lane] -= 0x40;
1981
1982 }
1983 } else if (some_high) {
1984 ctrl->timings[channel][slotrank].val_4024++;
1985 ctrl->timings[channel][slotrank].val_4028++;
1986 printram("4024++;\n");
1987 printram("4028++;\n");
1988 }
1989
1990 program_timings(ctrl, channel);
1991
1992 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1993
1994 discover_402x(ctrl, channel, slotrank, upperA);
1995
1996 post_timA_change(ctrl, channel, slotrank, &mnmx);
1997 pre_timA_change(ctrl, channel, slotrank, &mnmx);
1998
1999 discover_timA_fine(ctrl, channel, slotrank, upperA);
2000
2001 post_timA_change(ctrl, channel, slotrank, &mnmx);
2002 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2003
2004 FOR_ALL_LANES {
2005 ctrl->timings[channel][slotrank].lanes[lane].timA -= mnmx.timA_min_high * 0x40;
2006 }
2007 ctrl->timings[channel][slotrank].val_4028 -= mnmx.timA_min_high;
2008 printram("4028 -= %d;\n", mnmx.timA_min_high);
2009
2010 post_timA_change(ctrl, channel, slotrank, &mnmx);
2011
2012 printram("4/8: %d, %d, %x, %x\n", channel, slotrank,
2013 ctrl->timings[channel][slotrank].val_4024,
2014 ctrl->timings[channel][slotrank].val_4028);
2015
Patrick Rudolpha649a542016-01-17 18:32:06 +01002016 printram("final results:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002017 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01002018 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002019 lane,
2020 ctrl->timings[channel][slotrank].lanes[lane].timA);
2021
2022 write32(DEFAULT_MCHBAR + 0x3400, 0);
2023
Patrick Rudolph9b515682015-10-09 13:43:51 +02002024 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002025 }
2026
2027 FOR_ALL_POPULATED_CHANNELS {
2028 program_timings(ctrl, channel);
2029 }
2030 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2031 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
2032 + 4 * lane, 0);
2033 }
2034}
2035
2036static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
2037{
2038 int lane;
2039
2040 FOR_ALL_LANES {
2041 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel + 4 * lane, 0);
2042 read32(DEFAULT_MCHBAR + 0x4140 + 0x400 * channel + 4 * lane);
2043 }
2044
2045 wait_428c(channel);
2046
Patrick Rudolph371d2912015-10-09 13:33:25 +02002047 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002048 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2049 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2050 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
2051 | 4 | (ctrl->tRCD << 16));
2052
2053 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2054 (slotrank << 24) | (6 << 16));
2055
2056 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
2057
Patrick Rudolph371d2912015-10-09 13:33:25 +02002058 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002059 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2060 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
2061 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2062 (slotrank << 24) | 8);
2063 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2064
Patrick Rudolph371d2912015-10-09 13:33:25 +02002065 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002066 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2067 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
2068 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2069 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2070
Patrick Rudolph371d2912015-10-09 13:33:25 +02002071 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002072 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2073 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2074 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2075 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2076 (slotrank << 24) | 8);
2077 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2078
2079 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2080
2081 wait_428c(channel);
2082
Patrick Rudolph371d2912015-10-09 13:33:25 +02002083 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002084 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2085 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2086 0xc01 | (ctrl->tRP << 16));
2087 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2088 (slotrank << 24) | 0x60400);
2089 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2090
Patrick Rudolph371d2912015-10-09 13:33:25 +02002091 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002092 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2093 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2094 (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
2095 | 8 | (ctrl->CAS << 16));
2096
2097 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2098 (slotrank << 24) | 0x60000);
2099
2100 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
2101
Patrick Rudolph371d2912015-10-09 13:33:25 +02002102 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002103 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2104 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2105 0x40011f4 | (max(ctrl->tRTP, 8) << 16));
2106 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2107 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2108
Patrick Rudolph371d2912015-10-09 13:33:25 +02002109 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002110 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2111 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2112 0xc01 | (ctrl->tRP << 16));
2113 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2114 (slotrank << 24) | 0x60400);
2115 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2116 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2117 wait_428c(channel);
2118}
2119
2120static void discover_timC(ramctr_timing * ctrl, int channel, int slotrank)
2121{
2122 int timC;
2123 int statistics[NUM_LANES][MAX_TIMC + 1];
2124 int lane;
2125
2126 wait_428c(channel);
2127
Patrick Rudolph371d2912015-10-09 13:33:25 +02002128 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002129 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2130 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2131 0xc01 | (ctrl->tRP << 16));
2132 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2133 (slotrank << 24) | 0x60400);
2134 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2135 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2136
2137 for (timC = 0; timC <= MAX_TIMC; timC++) {
2138 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
2139 timC = timC;
2140 program_timings(ctrl, channel);
2141
2142 test_timC(ctrl, channel, slotrank);
2143
2144 FOR_ALL_LANES {
2145 statistics[lane][timC] =
2146 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2147 0x400 * channel);
2148 printram("Cstat: %d, %d, %d, %x, %x\n",
2149 channel, slotrank, lane, timC,
2150 statistics[lane][timC]);
2151 }
2152 }
2153 FOR_ALL_LANES {
2154 struct run rn =
2155 get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
2156 ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
2157 if (rn.all)
Patrick Rudolpha649a542016-01-17 18:32:06 +01002158 die("timC discovery failed");
2159 printram("Cval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002160 lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
2161 }
2162}
2163
2164static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
2165{
2166 int channel, ret = 0;
2167 FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
2168 ret++;
2169 return ret;
2170}
2171
2172static void fill_pattern0(ramctr_timing * ctrl, int channel, u32 a, u32 b)
2173{
2174 unsigned j;
2175 unsigned channel_offset =
2176 get_precedening_channels(ctrl, channel) * 0x40;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002177 for (j = 0; j < 16; j++)
2178 write32((void *)(0x04000000 + channel_offset + 4 * j), j & 2 ? b : a);
2179 sfence();
2180}
2181
2182static int num_of_channels(const ramctr_timing * ctrl)
2183{
2184 int ret = 0;
2185 int channel;
2186 FOR_ALL_POPULATED_CHANNELS ret++;
2187 return ret;
2188}
2189
2190static void fill_pattern1(ramctr_timing * ctrl, int channel)
2191{
2192 unsigned j;
2193 unsigned channel_offset =
2194 get_precedening_channels(ctrl, channel) * 0x40;
2195 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2196 for (j = 0; j < 16; j++)
2197 write32((void *)(0x04000000 + channel_offset + j * 4), 0xffffffff);
2198 for (j = 0; j < 16; j++)
2199 write32((void *)(0x04000000 + channel_offset + channel_step + j * 4), 0);
2200 sfence();
2201}
2202
2203static void precharge(ramctr_timing * ctrl)
2204{
2205 int channel, slotrank, lane;
2206
2207 FOR_ALL_POPULATED_CHANNELS {
2208 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2209 ctrl->timings[channel][slotrank].lanes[lane].falling =
2210 16;
2211 ctrl->timings[channel][slotrank].lanes[lane].rising =
2212 16;
Patrick Rudolpha649a542016-01-17 18:32:06 +01002213 }
2214
2215 program_timings(ctrl, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002216
2217 FOR_ALL_POPULATED_RANKS {
2218 wait_428c(channel);
2219
Patrick Rudolph371d2912015-10-09 13:33:25 +02002220 /* DRAM command MRS
2221 * write MR3 MPR enable
2222 * in this mode only RD and RDA are allowed
2223 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002224 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2225 0x1f000);
2226 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2227 0xc01 | (ctrl->tMOD << 16));
2228 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2229 (slotrank << 24) | 0x360004);
2230 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2231
Patrick Rudolph371d2912015-10-09 13:33:25 +02002232 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002233 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2234 0x1f105);
2235 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2236 0x4041003);
2237 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2238 (slotrank << 24) | 0);
2239 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2240
Patrick Rudolph371d2912015-10-09 13:33:25 +02002241 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002242 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2243 0x1f105);
2244 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2245 0x1001 | ((ctrl->CAS + 8) << 16));
2246 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2247 (slotrank << 24) | 0x60000);
2248 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2249
Patrick Rudolph371d2912015-10-09 13:33:25 +02002250 /* DRAM command MRS
2251 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002252 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2253 0x1f000);
2254 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2255 0xc01 | (ctrl->tMOD << 16));
2256 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2257 (slotrank << 24) | 0x360000);
2258 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2259 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2260 0xc0001);
2261
2262 wait_428c(channel);
2263 }
2264
2265 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2266 ctrl->timings[channel][slotrank].lanes[lane].falling =
2267 48;
2268 ctrl->timings[channel][slotrank].lanes[lane].rising =
2269 48;
2270 }
2271
2272 program_timings(ctrl, channel);
2273
2274 FOR_ALL_POPULATED_RANKS {
2275 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002276 /* DRAM command MRS
2277 * write MR3 MPR enable
2278 * in this mode only RD and RDA are allowed
2279 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002280 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2281 0x1f000);
2282 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2283 0xc01 | (ctrl->tMOD << 16));
2284 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2285 (slotrank << 24) | 0x360004);
2286 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2287
Patrick Rudolph371d2912015-10-09 13:33:25 +02002288 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002289 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2290 0x1f105);
2291 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2292 0x4041003);
2293 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2294 (slotrank << 24) | 0);
2295 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2296
Patrick Rudolph371d2912015-10-09 13:33:25 +02002297 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002298 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2299 0x1f105);
2300 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2301 0x1001 | ((ctrl->CAS + 8) << 16));
2302 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2303 (slotrank << 24) | 0x60000);
2304 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2305
Patrick Rudolph371d2912015-10-09 13:33:25 +02002306 /* DRAM command MRS
2307 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002308 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2309 0x1f000);
2310 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2311 0xc01 | (ctrl->tMOD << 16));
2312
2313 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2314 (slotrank << 24) | 0x360000);
2315 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2316
2317 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2318 0xc0001);
2319 wait_428c(channel);
2320 }
2321 }
2322}
2323
2324static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
2325{
Patrick Rudolph371d2912015-10-09 13:33:25 +02002326 /* enable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002327 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002328 0x80 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002329
2330 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002331 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002332 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
2333 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2334 0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
2335 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2336 8 | (slotrank << 24));
2337 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2338
Patrick Rudolph371d2912015-10-09 13:33:25 +02002339 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002340 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
2341 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2342 0x4000c01 | ((ctrl->CAS + 38) << 16));
2343 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2344 (slotrank << 24) | 4);
2345 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2346
2347 write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
2348 wait_428c(channel);
2349
Patrick Rudolph371d2912015-10-09 13:33:25 +02002350 /* disable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002351 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002352 0x1080 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002353}
2354
2355static void discover_timB(ramctr_timing * ctrl, int channel, int slotrank)
2356{
2357 int timB;
2358 int statistics[NUM_LANES][128];
2359 int lane;
2360
2361 write32(DEFAULT_MCHBAR + 0x3400, 0x108052 | (slotrank << 2));
2362
2363 for (timB = 0; timB < 128; timB++) {
2364 FOR_ALL_LANES {
2365 ctrl->timings[channel][slotrank].lanes[lane].timB = timB;
2366 }
2367 program_timings(ctrl, channel);
2368
2369 test_timB(ctrl, channel, slotrank);
2370
2371 FOR_ALL_LANES {
2372 statistics[lane][timB] =
2373 !((read32
2374 (DEFAULT_MCHBAR + lane_registers[lane] +
2375 channel * 0x100 + 4 + ((timB / 32) & 1) * 4)
2376 >> (timB % 32)) & 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002377 printram("Bstat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002378 channel, slotrank, lane, timB,
2379 statistics[lane][timB]);
2380 }
2381 }
2382 FOR_ALL_LANES {
2383 struct run rn = get_longest_zero_run(statistics[lane], 128);
Patrick Rudolphd912f1d2016-02-15 20:07:42 +01002384 /* timC is a direct function of timB's 6 LSBs.
2385 * Some tests increments the value of timB by a small value,
2386 * which might cause the 6bit value to overflow, if it's close
2387 * to 0x3F. Increment the value by a small offset if it's likely
2388 * to overflow, to make sure it won't overflow while running
2389 * tests and bricks the system due to a non matching timC.
2390 *
2391 * TODO: find out why some tests (edge write discovery)
2392 * increment timB. */
2393 if ((rn.start & 0x3F) == 0x3E)
2394 rn.start += 2;
2395 else if ((rn.start & 0x3F) == 0x3F)
2396 rn.start += 1;
Vladimir Serbinenko3141eac2016-01-29 19:42:02 +01002397 ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002398 if (rn.all)
2399 die("timB discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01002400 printram("Bval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002401 lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
2402 }
2403}
2404
2405static int get_timB_high_adjust(u64 val)
2406{
2407 int i;
2408
2409 /* good */
2410 if (val == 0xffffffffffffffffLL)
2411 return 0;
2412
2413 if (val >= 0xf000000000000000LL) {
2414 /* needs negative adjustment */
2415 for (i = 0; i < 8; i++)
2416 if (val << (8 * (7 - i) + 4))
2417 return -i;
2418 } else {
2419 /* needs positive adjustment */
2420 for (i = 0; i < 8; i++)
2421 if (val >> (8 * (7 - i) + 4))
2422 return i;
2423 }
2424 return 8;
2425}
2426
2427static void adjust_high_timB(ramctr_timing * ctrl)
2428{
2429 int channel, slotrank, lane, old;
2430 write32(DEFAULT_MCHBAR + 0x3400, 0x200);
2431 FOR_ALL_POPULATED_CHANNELS {
2432 fill_pattern1(ctrl, channel);
2433 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 1);
2434 }
2435 FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
2436
2437 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x10001);
2438
2439 wait_428c(channel);
2440
Patrick Rudolph371d2912015-10-09 13:33:25 +02002441 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002442 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2443 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2444 0xc01 | (ctrl->tRCD << 16));
2445 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2446 (slotrank << 24) | 0x60000);
2447 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2448
Patrick Rudolph371d2912015-10-09 13:33:25 +02002449 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002450 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2451 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
2452 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2453 (slotrank << 24) | 0x8);
2454 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2455
Patrick Rudolph371d2912015-10-09 13:33:25 +02002456 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002457 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2458 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
2459 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2460 (slotrank << 24));
2461 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
2462
Patrick Rudolph371d2912015-10-09 13:33:25 +02002463 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002464 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2465 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2466 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2467 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2468 (slotrank << 24) | 0x8);
2469 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2470
2471 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2472
2473 wait_428c(channel);
2474
Patrick Rudolph371d2912015-10-09 13:33:25 +02002475 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002476 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2477 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2478 0xc01 | ((ctrl->tRP) << 16));
2479 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2480 (slotrank << 24) | 0x60400);
2481 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2482
Patrick Rudolph371d2912015-10-09 13:33:25 +02002483 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002484 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2485 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2486 0xc01 | ((ctrl->tRCD) << 16));
2487 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2488 (slotrank << 24) | 0x60000);
2489 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2490
Patrick Rudolph371d2912015-10-09 13:33:25 +02002491 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002492 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
2493 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2494 0x4000c01 |
2495 ((ctrl->tRP +
2496 ctrl->timings[channel][slotrank].val_4024 +
2497 ctrl->timings[channel][slotrank].val_4028) << 16));
2498 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2499 (slotrank << 24) | 0x60008);
2500 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2501
2502 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
2503 wait_428c(channel);
2504 FOR_ALL_LANES {
2505 u64 res =
2506 read32(DEFAULT_MCHBAR + lane_registers[lane] +
2507 0x100 * channel + 4);
2508 res |=
2509 ((u64) read32(DEFAULT_MCHBAR + lane_registers[lane] +
2510 0x100 * channel + 8)) << 32;
2511 old = ctrl->timings[channel][slotrank].lanes[lane].timB;
2512 ctrl->timings[channel][slotrank].lanes[lane].timB +=
2513 get_timB_high_adjust(res) * 64;
2514
Patrick Rudolpha649a542016-01-17 18:32:06 +01002515 printram("High adjust %d:%016llx\n", lane, res);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002516 printram("Bval+: %d, %d, %d, %x -> %x\n", channel,
2517 slotrank, lane, old,
2518 ctrl->timings[channel][slotrank].lanes[lane].
2519 timB);
2520 }
2521 }
2522 write32(DEFAULT_MCHBAR + 0x3400, 0);
2523}
2524
2525static void write_op(ramctr_timing * ctrl, int channel)
2526{
2527 int slotrank;
2528
2529 wait_428c(channel);
2530
2531 /* choose an existing rank. */
2532 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2533
Patrick Rudolph371d2912015-10-09 13:33:25 +02002534 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002535 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2536 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2537
2538 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2539 (slotrank << 24) | 0x60000);
2540
2541 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2542
2543 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2544 wait_428c(channel);
2545}
2546
Patrick Rudolph371d2912015-10-09 13:33:25 +02002547/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
2548 * DDR3 adopted the fly-by topology. The data and strobes signals reach
2549 * the chips at different times with respect to command, address and
2550 * clock signals.
2551 * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
2552 * shift can be introduced.
2553 * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
2554 *
2555 * To find the required phase shift the DRAM is placed in "write leveling" mode.
2556 * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
2557 * sampled value on the data lanes (DQs).
2558 */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002559static void write_training(ramctr_timing * ctrl)
2560{
2561 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002562
2563 FOR_ALL_POPULATED_CHANNELS
2564 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
2565 read32(DEFAULT_MCHBAR + 0x4008 +
2566 0x400 * channel) | 0x8000000);
2567
2568 FOR_ALL_POPULATED_CHANNELS {
2569 write_op(ctrl, channel);
2570 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2571 read32(DEFAULT_MCHBAR + 0x4020 +
2572 0x400 * channel) | 0x200000);
2573 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002574
2575 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002576 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2577 FOR_ALL_POPULATED_CHANNELS {
2578 write_op(ctrl, channel);
2579 }
2580
Patrick Rudolph371d2912015-10-09 13:33:25 +02002581 /* enable write leveling on all ranks
2582 * disable all DQ outputs
2583 * only NOP is allowed in this mode */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002584 FOR_ALL_CHANNELS
2585 FOR_ALL_POPULATED_RANKS
2586 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002587 make_mr1(ctrl, slotrank, channel) | 0x1080);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002588
2589 write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
2590
Patrick Rudolph9b515682015-10-09 13:43:51 +02002591 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002592
Patrick Rudolph371d2912015-10-09 13:33:25 +02002593 /* set any valid value for timB, it gets corrected later */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002594 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2595 discover_timB(ctrl, channel, slotrank);
2596
Patrick Rudolph371d2912015-10-09 13:33:25 +02002597 /* disable write leveling on all ranks */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002598 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2599 write_mrreg(ctrl, channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002600 slotrank, 1, make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002601
2602 write32(DEFAULT_MCHBAR + 0x3400, 0);
2603
2604 FOR_ALL_POPULATED_CHANNELS
2605 wait_428c(channel);
2606
Patrick Rudolph371d2912015-10-09 13:33:25 +02002607 /* refresh enable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002608 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
2609
2610 FOR_ALL_POPULATED_CHANNELS {
2611 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2612 ~0x00200000 & read32(DEFAULT_MCHBAR + 0x4020 +
2613 0x400 * channel));
2614 read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
2615 wait_428c(channel);
2616
Patrick Rudolph371d2912015-10-09 13:33:25 +02002617 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002618 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2619 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
2620 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
2621 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2622
2623 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2624 wait_428c(channel);
2625 }
2626
Patrick Rudolph9b515682015-10-09 13:43:51 +02002627 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002628
2629 printram("CPE\n");
2630 precharge(ctrl);
2631 printram("CPF\n");
2632
2633 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2634 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2635 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2636 0);
2637 }
2638
2639 FOR_ALL_POPULATED_CHANNELS {
2640 fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
2641 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2642 }
2643
2644 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2645 discover_timC(ctrl, channel, slotrank);
2646
2647 FOR_ALL_POPULATED_CHANNELS
2648 program_timings(ctrl, channel);
2649
Patrick Rudolph371d2912015-10-09 13:33:25 +02002650 /* measure and adjust timB timings */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002651 adjust_high_timB(ctrl);
2652
2653 FOR_ALL_POPULATED_CHANNELS
2654 program_timings(ctrl, channel);
2655
2656 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2657 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2658 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2659 0);
2660 }
2661}
2662
2663static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
2664{
2665 struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
2666 int timC_delta;
2667 int lanes_ok = 0;
2668 int ctr = 0;
2669 int lane;
2670
2671 for (timC_delta = -5; timC_delta <= 5; timC_delta++) {
2672 FOR_ALL_LANES {
2673 ctrl->timings[channel][slotrank].lanes[lane].timC =
2674 saved_rt.lanes[lane].timC + timC_delta;
2675 }
2676 program_timings(ctrl, channel);
2677 FOR_ALL_LANES {
2678 write32(DEFAULT_MCHBAR + 4 * lane + 0x4f40, 0);
2679 }
2680
2681 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2682
2683 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002684 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002685 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2686 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2687 ((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
2688 | 8 | (ctrl->tRCD << 16));
2689
2690 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2691 (slotrank << 24) | ctr | 0x60000);
2692
2693 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002694 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002695 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
2696 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2697 0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
2698 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2699 (slotrank << 24));
2700 write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
2701 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
2702
Patrick Rudolph371d2912015-10-09 13:33:25 +02002703 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002704 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2705 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2706 0x4001020 | (max(ctrl->tRTP, 8) << 16));
2707 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2708 (slotrank << 24));
2709 write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
2710 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
2711
Patrick Rudolph371d2912015-10-09 13:33:25 +02002712 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002713 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2714 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
2715 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2716 (slotrank << 24) | 0x60400);
2717 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2718
2719 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2720 wait_428c(channel);
2721 FOR_ALL_LANES {
2722 u32 r32 =
2723 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2724 0x400 * channel);
2725
2726 if (r32 == 0)
2727 lanes_ok |= 1 << lane;
2728 }
2729 ctr++;
2730 if (lanes_ok == ((1 << NUM_LANES) - 1))
2731 break;
2732 }
2733
2734 ctrl->timings[channel][slotrank] = saved_rt;
2735
2736 printram("3lanes: %x\n", lanes_ok);
2737 return lanes_ok != ((1 << NUM_LANES) - 1);
2738}
2739
2740#include "raminit_patterns.h"
2741
2742static void fill_pattern5(ramctr_timing * ctrl, int channel, int patno)
2743{
2744 unsigned i, j;
2745 unsigned channel_offset =
2746 get_precedening_channels(ctrl, channel) * 0x40;
2747 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2748
2749 if (patno) {
2750 u8 base8 = 0x80 >> ((patno - 1) % 8);
2751 u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
2752 for (i = 0; i < 32; i++) {
2753 for (j = 0; j < 16; j++) {
2754 u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;
2755 if (invert[patno - 1][i] & (1 << (j / 2)))
2756 val = ~val;
2757 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2758 j * 4), val);
2759 }
2760 }
2761
2762 } else {
2763 for (i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
2764 for (j = 0; j < 16; j++)
2765 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2766 j * 4), pattern[i][j]);
2767 }
2768 sfence();
2769 }
2770}
2771
2772static void reprogram_320c(ramctr_timing * ctrl)
2773{
2774 int channel, slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002775
2776 FOR_ALL_POPULATED_CHANNELS {
2777 wait_428c(channel);
2778
2779 /* choose an existing rank. */
2780 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2781
Patrick Rudolph371d2912015-10-09 13:33:25 +02002782 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002783 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2784 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2785
2786 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2787 (slotrank << 24) | 0x60000);
2788
2789 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2790
2791 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2792 wait_428c(channel);
2793 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2794 read32(DEFAULT_MCHBAR + 0x4020 +
2795 0x400 * channel) | 0x200000);
2796 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002797
2798 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002799 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2800 FOR_ALL_POPULATED_CHANNELS {
2801 wait_428c(channel);
2802
2803 /* choose an existing rank. */
2804 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2805
Patrick Rudolph371d2912015-10-09 13:33:25 +02002806 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002807 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2808 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2809
2810 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2811 (slotrank << 24) | 0x60000);
2812
2813 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2814
2815 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2816 wait_428c(channel);
2817 }
2818
2819 /* jedec reset */
2820 dram_jedecreset(ctrl);
2821 /* mrs commands. */
2822 dram_mrscommands(ctrl);
2823
Patrick Rudolph9b515682015-10-09 13:43:51 +02002824 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002825}
2826
2827#define MIN_C320C_LEN 13
2828
2829static int try_cmd_stretch(ramctr_timing * ctrl, int cmd_stretch)
2830{
2831 struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
2832 int channel, slotrank;
2833 int c320c;
2834 int stat[NUM_SLOTRANKS][256];
2835
2836 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2837 saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
2838 }
2839
2840 FOR_ALL_POPULATED_CHANNELS {
2841 ctrl->cmd_stretch[channel] = cmd_stretch;
2842 }
2843
2844 FOR_ALL_POPULATED_CHANNELS
2845 MCHBAR32(0x4004 + 0x400 * channel) =
2846 ctrl->tRRD
2847 | (ctrl->tRTP << 4)
2848 | (ctrl->tCKE << 8)
2849 | (ctrl->tWTR << 12)
2850 | (ctrl->tFAW << 16)
2851 | (ctrl->tWR << 24)
2852 | (ctrl->cmd_stretch[channel] << 30);
2853
2854
2855 FOR_ALL_CHANNELS {
2856 int delta = 0;
2857 if (ctrl->cmd_stretch[channel] == 2)
2858 delta = 2;
2859 else if (ctrl->cmd_stretch[channel] == 0)
2860 delta = 4;
2861
2862 FOR_ALL_POPULATED_RANKS {
2863 ctrl->timings[channel][slotrank].val_4024 -= delta;
2864 }
2865 }
2866
2867 FOR_ALL_POPULATED_CHANNELS {
2868 for (c320c = -127; c320c <= 127; c320c++) {
2869 FOR_ALL_POPULATED_RANKS {
2870 ctrl->timings[channel][slotrank].val_320c = c320c;
2871 }
2872 program_timings(ctrl, channel);
2873 reprogram_320c(ctrl);
2874 FOR_ALL_POPULATED_RANKS {
2875 stat[slotrank][c320c + 127] =
2876 test_320c(ctrl, channel, slotrank);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002877 printram("3stat: %d, %d, %d: %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002878 channel, slotrank, c320c,
2879 stat[slotrank][c320c + 127]);
2880 }
2881 }
2882 FOR_ALL_POPULATED_RANKS {
2883 struct run rn =
2884 get_longest_zero_run(stat[slotrank], 255);
2885 ctrl->timings[channel][slotrank].val_320c =
2886 rn.middle - 127;
2887 printram("3val: %d, %d: %d\n", channel,
2888 slotrank,
2889 ctrl->timings[channel][slotrank].val_320c);
2890 if (rn.all || rn.length < MIN_C320C_LEN) {
2891 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2892 ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
2893 }
2894 return 0;
2895 }
2896 }
2897 }
2898 return 1;
2899}
2900
Patrick Rudolph371d2912015-10-09 13:33:25 +02002901/* Adjust CMD phase shift and try multiple command rates.
2902 * A command rate of 2T doubles the time needed for address and
2903 * command decode. */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002904static void command_training(ramctr_timing * ctrl)
2905{
2906 int channel;
2907
2908 FOR_ALL_POPULATED_CHANNELS {
2909 fill_pattern5(ctrl, channel, 0);
2910 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2911 }
2912
2913 /* try command rate 1T and 2T */
2914 if (!try_cmd_stretch(ctrl, 0) && !try_cmd_stretch(ctrl, 2))
2915 die("c320c discovery failed");
2916
2917 FOR_ALL_POPULATED_CHANNELS {
2918 program_timings(ctrl, channel);
2919 }
2920
2921 reprogram_320c(ctrl);
2922}
2923
2924static void discover_edges_real(ramctr_timing * ctrl, int channel, int slotrank,
2925 int *edges)
2926{
2927 int edge;
2928 int statistics[NUM_LANES][MAX_EDGE_TIMING + 1];
2929 int lane;
2930
2931 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
2932 FOR_ALL_LANES {
2933 ctrl->timings[channel][slotrank].lanes[lane].rising =
2934 edge;
2935 ctrl->timings[channel][slotrank].lanes[lane].falling =
2936 edge;
2937 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002938 program_timings(ctrl, channel);
2939
2940 FOR_ALL_LANES {
2941 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2942 4 * lane, 0);
2943 read32(DEFAULT_MCHBAR + 0x400 * channel + 4 * lane +
2944 0x4140);
2945 }
2946
2947 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002948 /* DRAM command MRS
2949 * write MR3 MPR enable
2950 * in this mode only RD and RDA are allowed
2951 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002952 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
2953 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2954 (0xc01 | (ctrl->tMOD << 16)));
2955 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2956 (slotrank << 24) | 0x360004);
2957 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2958
Patrick Rudolph371d2912015-10-09 13:33:25 +02002959 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002960 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
2961 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
2962 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2963 (slotrank << 24));
2964 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2965
Patrick Rudolph371d2912015-10-09 13:33:25 +02002966 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002967 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2968 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2969 0x1001 | ((ctrl->CAS + 8) << 16));
2970 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2971 (slotrank << 24) | 0x60000);
2972 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2973
Patrick Rudolph371d2912015-10-09 13:33:25 +02002974 /* DRAM command MRS
2975 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002976 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
2977 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2978 (0xc01 | (ctrl->tMOD << 16)));
2979 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2980 (slotrank << 24) | 0x360000);
2981 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2982
2983 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2984
2985 wait_428c(channel);
2986
2987 FOR_ALL_LANES {
2988 statistics[lane][edge] =
2989 read32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
2990 lane * 4);
2991 }
2992 }
2993 FOR_ALL_LANES {
2994 struct run rn =
2995 get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
2996 edges[lane] = rn.middle;
2997 if (rn.all)
2998 die("edge discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01002999 printram("eval %d, %d, %d: %02x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003000 lane, edges[lane]);
3001 }
3002}
3003
3004static void discover_edges(ramctr_timing * ctrl)
3005{
3006 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3007 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3008 int channel, slotrank, lane;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003009
3010 write32(DEFAULT_MCHBAR + 0x3400, 0);
3011
Patrick Rudolph9b515682015-10-09 13:43:51 +02003012 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003013
3014 FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
3015 write32(DEFAULT_MCHBAR + 4 * lane +
3016 0x400 * channel + 0x4080, 0);
3017 }
3018
3019 FOR_ALL_POPULATED_CHANNELS {
3020 fill_pattern0(ctrl, channel, 0, 0);
3021 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3022 FOR_ALL_LANES {
3023 read32(DEFAULT_MCHBAR + 0x400 * channel +
3024 lane * 4 + 0x4140);
3025 }
3026
3027 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3028 ctrl->timings[channel][slotrank].lanes[lane].falling =
3029 16;
3030 ctrl->timings[channel][slotrank].lanes[lane].rising =
3031 16;
3032 }
3033
3034 program_timings(ctrl, channel);
3035
3036 FOR_ALL_POPULATED_RANKS {
3037 wait_428c(channel);
3038
Patrick Rudolph371d2912015-10-09 13:33:25 +02003039 /* DRAM command MRS
3040 * MR3 enable MPR
3041 * write MR3 MPR enable
3042 * in this mode only RD and RDA are allowed
3043 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003044 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3045 0x1f000);
3046 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3047 0xc01 | (ctrl->tMOD << 16));
3048 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3049 (slotrank << 24) | 0x360004);
3050 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3051
Patrick Rudolph371d2912015-10-09 13:33:25 +02003052 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003053 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3054 0x1f105);
3055 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3056 0x4041003);
3057 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3058 (slotrank << 24) | 0);
3059 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3060
Patrick Rudolph371d2912015-10-09 13:33:25 +02003061 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003062 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3063 0x1f105);
3064 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3065 0x1001 | ((ctrl->CAS + 8) << 16));
3066 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3067 (slotrank << 24) | 0x60000);
3068 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3069
Patrick Rudolph371d2912015-10-09 13:33:25 +02003070 /* DRAM command MRS
3071 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003072 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3073 0x1f000);
3074 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3075 0xc01 | (ctrl->tMOD << 16));
3076 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3077 (slotrank << 24) | 0x360000);
3078 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3079 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3080 0xc0001);
3081
3082 wait_428c(channel);
3083 }
3084
Patrick Rudolph371d2912015-10-09 13:33:25 +02003085 /* XXX: check any measured value ? */
3086
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003087 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3088 ctrl->timings[channel][slotrank].lanes[lane].falling =
3089 48;
3090 ctrl->timings[channel][slotrank].lanes[lane].rising =
3091 48;
3092 }
3093
3094 program_timings(ctrl, channel);
3095
3096 FOR_ALL_POPULATED_RANKS {
3097 wait_428c(channel);
3098
Patrick Rudolph371d2912015-10-09 13:33:25 +02003099 /* DRAM command MRS
3100 * MR3 enable MPR
3101 * write MR3 MPR enable
3102 * in this mode only RD and RDA are allowed
3103 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003104 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3105 0x1f000);
3106 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3107 0xc01 | (ctrl->tMOD << 16));
3108 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3109 (slotrank << 24) | 0x360004);
3110 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3111
Patrick Rudolph371d2912015-10-09 13:33:25 +02003112 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003113 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3114 0x1f105);
3115 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3116 0x4041003);
3117 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3118 (slotrank << 24) | 0);
3119 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3120
Patrick Rudolph371d2912015-10-09 13:33:25 +02003121 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003122 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3123 0x1f105);
3124 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3125 0x1001 | ((ctrl->CAS + 8) << 16));
3126 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3127 (slotrank << 24) | 0x60000);
3128 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3129
Patrick Rudolph371d2912015-10-09 13:33:25 +02003130 /* DRAM command MRS
3131 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003132 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3133 0x1f000);
3134 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3135 0xc01 | (ctrl->tMOD << 16));
3136 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3137 (slotrank << 24) | 0x360000);
3138 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3139
3140 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3141 0xc0001);
3142 wait_428c(channel);
3143 }
3144
Patrick Rudolph371d2912015-10-09 13:33:25 +02003145 /* XXX: check any measured value ? */
3146
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003147 FOR_ALL_LANES {
3148 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
3149 lane * 4,
3150 ~read32(DEFAULT_MCHBAR + 0x4040 +
3151 0x400 * channel + lane * 4) & 0xff);
3152 }
3153
3154 fill_pattern0(ctrl, channel, 0, 0xffffffff);
3155 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3156 }
3157
3158 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3159 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003160 printram("discover falling edges:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003161
3162 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3163 discover_edges_real(ctrl, channel, slotrank,
3164 falling_edges[channel][slotrank]);
3165 }
3166
3167 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003168 printram("discover rising edges:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003169
3170 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3171 discover_edges_real(ctrl, channel, slotrank,
3172 rising_edges[channel][slotrank]);
3173 }
3174
3175 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3176
3177 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3178 ctrl->timings[channel][slotrank].lanes[lane].falling =
3179 falling_edges[channel][slotrank][lane];
3180 ctrl->timings[channel][slotrank].lanes[lane].rising =
3181 rising_edges[channel][slotrank][lane];
3182 }
3183
3184 FOR_ALL_POPULATED_CHANNELS {
3185 program_timings(ctrl, channel);
3186 }
3187
3188 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3189 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3190 0);
3191 }
3192}
3193
3194static void discover_edges_write_real(ramctr_timing * ctrl, int channel,
3195 int slotrank, int *edges)
3196{
3197 int edge;
3198 u32 raw_statistics[MAX_EDGE_TIMING + 1];
3199 int statistics[MAX_EDGE_TIMING + 1];
3200 const int reg3000b24[] = { 0, 0xc, 0x2c };
3201 int lane, i;
3202 int lower[NUM_LANES];
3203 int upper[NUM_LANES];
3204 int pat;
3205
3206 FOR_ALL_LANES {
3207 lower[lane] = 0;
3208 upper[lane] = MAX_EDGE_TIMING;
3209 }
3210
3211 for (i = 0; i < 3; i++) {
3212 write32(DEFAULT_MCHBAR + 0x3000 + 0x100 * channel,
3213 reg3000b24[i] << 24);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003214 printram("[%x] = 0x%08x\n",
3215 0x3000 + 0x100 * channel, reg3000b24[i] << 24);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003216 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3217 fill_pattern5(ctrl, channel, pat);
3218 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003219 printram("using pattern %d\n", pat);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003220 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3221 FOR_ALL_LANES {
3222 ctrl->timings[channel][slotrank].lanes[lane].
3223 rising = edge;
3224 ctrl->timings[channel][slotrank].lanes[lane].
3225 falling = edge;
3226 }
3227 program_timings(ctrl, channel);
3228
3229 FOR_ALL_LANES {
3230 write32(DEFAULT_MCHBAR + 0x4340 +
3231 0x400 * channel + 4 * lane, 0);
3232 read32(DEFAULT_MCHBAR + 0x400 * channel +
3233 4 * lane + 0x4140);
3234 }
3235 wait_428c(channel);
3236
Patrick Rudolph371d2912015-10-09 13:33:25 +02003237 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003238 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3239 0x1f006);
3240 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3241 0x4 | (ctrl->tRCD << 16)
3242 | (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) <<
3243 10));
3244 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3245 (slotrank << 24) | 0x60000);
3246 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
3247 0x240);
3248
Patrick Rudolph371d2912015-10-09 13:33:25 +02003249 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003250 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3251 0x1f201);
3252 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3253 0x8005020 | ((ctrl->tWTR + ctrl->CWL + 8) <<
3254 16));
3255 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3256 (slotrank << 24));
3257 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
3258 0x242);
3259
Patrick Rudolph371d2912015-10-09 13:33:25 +02003260 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003261 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3262 0x1f105);
3263 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3264 0x4005020 | (max(ctrl->tRTP, 8) << 16));
3265 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3266 (slotrank << 24));
3267 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
3268 0x242);
3269
Patrick Rudolph371d2912015-10-09 13:33:25 +02003270 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003271 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3272 0x1f002);
3273 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3274 0xc01 | (ctrl->tRP << 16));
3275 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3276 (slotrank << 24) | 0x60400);
3277 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3278
3279 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3280 0xc0001);
3281 wait_428c(channel);
3282 FOR_ALL_LANES {
3283 read32(DEFAULT_MCHBAR + 0x4340 +
3284 0x400 * channel + lane * 4);
3285 }
3286
3287 raw_statistics[edge] =
3288 MCHBAR32(0x436c + 0x400 * channel);
3289 }
3290 FOR_ALL_LANES {
3291 struct run rn;
3292 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++)
3293 statistics[edge] =
3294 ! !(raw_statistics[edge] & (1 << lane));
3295 rn = get_longest_zero_run(statistics,
3296 MAX_EDGE_TIMING + 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003297 printram("edges: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003298 channel, slotrank, i, rn.start, rn.middle,
3299 rn.end, rn.start + ctrl->edge_offset[i],
3300 rn.end - ctrl->edge_offset[i]);
3301 lower[lane] =
3302 max(rn.start + ctrl->edge_offset[i], lower[lane]);
3303 upper[lane] =
3304 min(rn.end - ctrl->edge_offset[i], upper[lane]);
3305 edges[lane] = (lower[lane] + upper[lane]) / 2;
Patrick Rudolph9733e282015-08-16 17:06:30 +02003306 if (rn.all || (lower[lane] > upper[lane]))
3307 die("edge write discovery failed");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003308
3309 }
3310 }
3311 }
3312
3313 write32(DEFAULT_MCHBAR + 0x3000, 0);
3314 printram("CPA\n");
3315}
3316
3317static void discover_edges_write(ramctr_timing * ctrl)
3318{
3319 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3320 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3321 int channel, slotrank, lane;
3322
3323 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3324 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003325 printram("discover falling edges write:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003326
3327 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3328 discover_edges_write_real(ctrl, channel, slotrank,
3329 falling_edges[channel][slotrank]);
3330 }
3331
3332 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003333 printram("discover rising edges write:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003334
3335 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3336 discover_edges_write_real(ctrl, channel, slotrank,
3337 rising_edges[channel][slotrank]);
3338 }
3339
3340 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3341
3342 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3343 ctrl->timings[channel][slotrank].lanes[lane].falling =
3344 falling_edges[channel][slotrank][lane];
3345 ctrl->timings[channel][slotrank].lanes[lane].rising =
3346 rising_edges[channel][slotrank][lane];
3347 }
3348
3349 FOR_ALL_POPULATED_CHANNELS
3350 program_timings(ctrl, channel);
3351
3352 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3353 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3354 0);
3355 }
3356}
3357
3358static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
3359{
3360 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003361 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003362 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
3363 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3364 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD)
3365 << 10) | (ctrl->tRCD << 16) | 4);
3366 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3367 (slotrank << 24) | 0x60000);
3368 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
3369
Patrick Rudolph371d2912015-10-09 13:33:25 +02003370 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003371 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
3372 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3373 0x80011e0 |
3374 ((ctrl->tWTR + ctrl->CWL + 8) << 16));
3375 write32(DEFAULT_MCHBAR + 0x4204 +
3376 0x400 * channel, (slotrank << 24));
3377 write32(DEFAULT_MCHBAR + 0x4214 +
3378 0x400 * channel, 0x242);
3379
Patrick Rudolph371d2912015-10-09 13:33:25 +02003380 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003381 write32(DEFAULT_MCHBAR + 0x4228 +
3382 0x400 * channel, 0x1f105);
3383 write32(DEFAULT_MCHBAR + 0x4238 +
3384 0x400 * channel,
3385 0x40011e0 | (max(ctrl->tRTP, 8) << 16));
3386 write32(DEFAULT_MCHBAR + 0x4208 +
3387 0x400 * channel, (slotrank << 24));
3388 write32(DEFAULT_MCHBAR + 0x4218 +
3389 0x400 * channel, 0x242);
3390
Patrick Rudolph371d2912015-10-09 13:33:25 +02003391 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003392 write32(DEFAULT_MCHBAR + 0x422c +
3393 0x400 * channel, 0x1f002);
3394 write32(DEFAULT_MCHBAR + 0x423c +
3395 0x400 * channel,
3396 0x1001 | (ctrl->tRP << 16));
3397 write32(DEFAULT_MCHBAR + 0x420c +
3398 0x400 * channel,
3399 (slotrank << 24) | 0x60400);
3400 write32(DEFAULT_MCHBAR + 0x421c +
3401 0x400 * channel, 0);
3402
3403 write32(DEFAULT_MCHBAR + 0x4284 +
3404 0x400 * channel, 0xc0001);
3405 wait_428c(channel);
3406}
3407
3408static void discover_timC_write(ramctr_timing * ctrl)
3409{
3410 const u8 rege3c_b24[3] = { 0, 0xf, 0x2f };
3411 int i, pat;
3412
3413 int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3414 int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3415 int channel, slotrank, lane;
3416
3417 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3418 lower[channel][slotrank][lane] = 0;
3419 upper[channel][slotrank][lane] = MAX_TIMC;
3420 }
3421
3422 write32(DEFAULT_MCHBAR + 0x4ea8, 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003423 printram("discover timC write:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003424
3425 for (i = 0; i < 3; i++)
3426 FOR_ALL_POPULATED_CHANNELS {
3427 write32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100),
3428 (rege3c_b24[i] << 24)
3429 | (read32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100))
3430 & ~0x3f000000));
3431 udelay(2);
3432 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3433 FOR_ALL_POPULATED_RANKS {
3434 int timC;
3435 u32 raw_statistics[MAX_TIMC + 1];
3436 int statistics[MAX_TIMC + 1];
3437
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003438 /* Make sure rn.start < rn.end */
3439 statistics[MAX_TIMC] = 1;
3440
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003441 fill_pattern5(ctrl, channel, pat);
3442 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003443 for (timC = 0; timC < MAX_TIMC; timC++) {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003444 FOR_ALL_LANES
3445 ctrl->timings[channel][slotrank].lanes[lane].timC = timC;
3446 program_timings(ctrl, channel);
3447
3448 test_timC_write (ctrl, channel, slotrank);
3449
3450 raw_statistics[timC] =
3451 MCHBAR32(0x436c + 0x400 * channel);
3452 }
3453 FOR_ALL_LANES {
3454 struct run rn;
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003455 for (timC = 0; timC < MAX_TIMC; timC++)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003456 statistics[timC] =
3457 !!(raw_statistics[timC] &
3458 (1 << lane));
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003459
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003460 rn = get_longest_zero_run(statistics,
3461 MAX_TIMC + 1);
3462 if (rn.all)
3463 die("timC write discovery failed");
Patrick Rudolpha649a542016-01-17 18:32:06 +01003464 printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003465 channel, slotrank, i, rn.start,
3466 rn.middle, rn.end,
3467 rn.start + ctrl->timC_offset[i],
3468 rn.end - ctrl->timC_offset[i]);
3469 lower[channel][slotrank][lane] =
3470 max(rn.start + ctrl->timC_offset[i],
3471 lower[channel][slotrank][lane]);
3472 upper[channel][slotrank][lane] =
3473 min(rn.end - ctrl->timC_offset[i],
3474 upper[channel][slotrank][lane]);
3475
3476 }
3477 }
3478 }
3479 }
3480
3481 FOR_ALL_CHANNELS {
3482 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3483 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3484 ~0x3f000000));
3485 udelay(2);
3486 }
3487
3488 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3489
3490 printram("CPB\n");
3491
3492 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
Patrick Rudolpha649a542016-01-17 18:32:06 +01003493 printram("timC %d, %d, %d: %x\n", channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003494 slotrank, lane,
3495 (lower[channel][slotrank][lane] +
3496 upper[channel][slotrank][lane]) / 2);
3497 ctrl->timings[channel][slotrank].lanes[lane].timC =
3498 (lower[channel][slotrank][lane] +
3499 upper[channel][slotrank][lane]) / 2;
3500 }
3501 FOR_ALL_POPULATED_CHANNELS {
3502 program_timings(ctrl, channel);
3503 }
3504}
3505
3506static void normalize_training(ramctr_timing * ctrl)
3507{
3508 int channel, slotrank, lane;
3509 int mat = 0;
3510
3511 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3512 int delta;
3513 FOR_ALL_LANES mat =
3514 max(ctrl->timings[channel][slotrank].lanes[lane].timA, mat);
3515 delta = (mat >> 6) - ctrl->timings[channel][slotrank].val_4028;
3516 ctrl->timings[channel][slotrank].val_4024 += delta;
3517 ctrl->timings[channel][slotrank].val_4028 += delta;
3518 }
3519
3520 FOR_ALL_POPULATED_CHANNELS {
3521 program_timings(ctrl, channel);
3522 }
3523}
3524
3525static void write_controller_mr(ramctr_timing * ctrl)
3526{
3527 int channel, slotrank;
3528
3529 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3530 write32(DEFAULT_MCHBAR + 0x0004 + (channel << 8) +
3531 lane_registers[slotrank], make_mr0(ctrl, slotrank));
3532 write32(DEFAULT_MCHBAR + 0x0008 + (channel << 8) +
Patrick Rudolph7e513d12016-01-10 14:22:34 +01003533 lane_registers[slotrank],
3534 make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003535 }
3536}
3537
3538static void channel_test(ramctr_timing * ctrl)
3539{
3540 int channel, slotrank, lane;
3541
3542 FOR_ALL_POPULATED_CHANNELS
Patrick Rudolpha649a542016-01-17 18:32:06 +01003543 if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000)
3544 die("Mini channel test failed (1)\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003545 FOR_ALL_POPULATED_CHANNELS {
3546 fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
3547
3548 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3549 }
3550
3551 for (slotrank = 0; slotrank < 4; slotrank++)
3552 FOR_ALL_CHANNELS
3553 if (ctrl->rankmap[channel] & (1 << slotrank)) {
3554 FOR_ALL_LANES {
3555 write32(DEFAULT_MCHBAR + (0x4f40 + 4 * lane), 0);
3556 write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
3557 }
3558 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003559 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003560 write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
3561 write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
3562 write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
3563 0x00060000 | (slotrank << 24));
3564 write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003565 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003566 write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
3567 write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
3568 write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
3569 0x00000000 | (slotrank << 24));
3570 write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003571 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003572 write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
3573 write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
3574 write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
3575 0x00000000 | (slotrank << 24));
3576 write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003577 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003578 write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
3579 write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
3580 write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),
3581 0x00060400 | (slotrank << 24));
3582 write32(DEFAULT_MCHBAR + 0x421c + (channel << 10), 0x00000240);
3583 write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
3584 wait_428c(channel);
3585 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01003586 if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane))
3587 die("Mini channel test failed (2)\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003588 }
3589}
3590
3591static void set_scrambling_seed(ramctr_timing * ctrl)
3592{
3593 int channel;
3594
3595 /* FIXME: we hardcode seeds. Do we need to use some PRNG for them?
3596 I don't think so. */
3597 static u32 seeds[NUM_CHANNELS][3] = {
3598 {0x00009a36, 0xbafcfdcf, 0x46d1ab68},
3599 {0x00028bfa, 0x53fe4b49, 0x19ed5483}
3600 };
3601 FOR_ALL_POPULATED_CHANNELS {
3602 MCHBAR32(0x4020 + 0x400 * channel) &= ~0x10000000;
3603 write32(DEFAULT_MCHBAR + 0x4034, seeds[channel][0]);
3604 write32(DEFAULT_MCHBAR + 0x403c, seeds[channel][1]);
3605 write32(DEFAULT_MCHBAR + 0x4038, seeds[channel][2]);
3606 }
3607}
3608
3609static void set_4f8c(void)
3610{
3611 struct cpuid_result cpures;
3612 u32 cpu;
3613
3614 cpures = cpuid(0);
3615 cpu = (cpures.eax);
3616 if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
3617 MCHBAR32(0x4f8c) = 0x141D1519;
3618 } else {
3619 MCHBAR32(0x4f8c) = 0x551D1519;
3620 }
3621}
3622
3623static void prepare_training(ramctr_timing * ctrl)
3624{
3625 int channel;
3626
3627 FOR_ALL_POPULATED_CHANNELS {
3628 // Always drive command bus
3629 MCHBAR32(0x4004 + 0x400 * channel) |= 0x20000000;
3630 }
3631
3632 udelay(1);
3633
3634 FOR_ALL_POPULATED_CHANNELS {
3635 wait_428c(channel);
3636 }
3637}
3638
3639static void set_4008c(ramctr_timing * ctrl)
3640{
3641 int channel, slotrank;
3642 u32 reg;
3643 FOR_ALL_POPULATED_CHANNELS {
3644 u32 b20, b4_8_12;
3645 int min_320c = 10000;
3646 int max_320c = -10000;
3647
3648 FOR_ALL_POPULATED_RANKS {
3649 max_320c = max(ctrl->timings[channel][slotrank].val_320c, max_320c);
3650 min_320c = min(ctrl->timings[channel][slotrank].val_320c, min_320c);
3651 }
3652
3653 if (max_320c - min_320c > 51)
3654 b20 = 0;
3655 else
3656 b20 = ctrl->ref_card_offset[channel];
3657
3658 if (ctrl->reg_320c_range_threshold < max_320c - min_320c)
3659 b4_8_12 = 0x3330;
3660 else
3661 b4_8_12 = 0x2220;
3662
3663 reg = read32(DEFAULT_MCHBAR + 0x400c + (channel << 10));
3664 write32(DEFAULT_MCHBAR + 0x400c + (channel << 10),
3665 (reg & 0xFFF0FFFF)
3666 | (ctrl->ref_card_offset[channel] << 16)
3667 | (ctrl->ref_card_offset[channel] << 18));
3668 write32(DEFAULT_MCHBAR + 0x4008 + (channel << 10),
3669 0x0a000000
3670 | (b20 << 20)
3671 | ((ctrl->ref_card_offset[channel] + 2) << 16)
3672 | b4_8_12);
3673 }
3674}
3675
3676static void set_42a0(ramctr_timing * ctrl)
3677{
3678 int channel;
3679 FOR_ALL_POPULATED_CHANNELS {
3680 write32(DEFAULT_MCHBAR + (0x42a0 + 0x400 * channel),
3681 0x00001000 | ctrl->rankmap[channel]);
3682 MCHBAR32(0x4004 + 0x400 * channel) &= ~0x20000000; // OK
3683 }
3684}
3685
3686static int encode_5d10(int ns)
3687{
3688 return (ns + 499) / 500;
3689}
3690
3691/* FIXME: values in this function should be hardware revision-dependent. */
3692static void final_registers(ramctr_timing * ctrl)
3693{
3694 int channel;
3695 int t1_cycles = 0, t1_ns = 0, t2_ns;
3696 int t3_ns;
3697 u32 r32;
3698
3699 write32(DEFAULT_MCHBAR + 0x4cd4, 0x00000046);
3700
3701 write32(DEFAULT_MCHBAR + 0x400c, (read32(DEFAULT_MCHBAR + 0x400c) & 0xFFFFCFFF) | 0x1000); // OK
3702 write32(DEFAULT_MCHBAR + 0x440c, (read32(DEFAULT_MCHBAR + 0x440c) & 0xFFFFCFFF) | 0x1000); // OK
3703 write32(DEFAULT_MCHBAR + 0x4cb0, 0x00000740);
3704 write32(DEFAULT_MCHBAR + 0x4380, 0x00000aaa); // OK
3705 write32(DEFAULT_MCHBAR + 0x4780, 0x00000aaa); // OK
3706 write32(DEFAULT_MCHBAR + 0x4f88, 0x5f7003ff); // OK
3707 write32(DEFAULT_MCHBAR + 0x5064, 0x00073000 | ctrl->reg_5064b0); // OK
3708
3709 FOR_ALL_CHANNELS {
3710 switch (ctrl->rankmap[channel]) {
3711 /* Unpopulated channel. */
3712 case 0:
3713 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0);
3714 break;
3715 /* Only single-ranked dimms. */
3716 case 1:
3717 case 4:
3718 case 5:
3719 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x373131);
3720 break;
3721 /* Dual-ranked dimms present. */
3722 default:
3723 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x9b6ea1);
3724 break;
3725 }
3726 }
3727
3728 write32 (DEFAULT_MCHBAR + 0x5880, 0xca9171e5);
3729 write32 (DEFAULT_MCHBAR + 0x5888,
3730 (read32 (DEFAULT_MCHBAR + 0x5888) & ~0xffffff) | 0xe4d5d0);
3731 write32 (DEFAULT_MCHBAR + 0x58a8, read32 (DEFAULT_MCHBAR + 0x58a8) & ~0x1f);
3732 write32 (DEFAULT_MCHBAR + 0x4294,
3733 (read32 (DEFAULT_MCHBAR + 0x4294) & ~0x30000)
3734 | (1 << 16));
3735 write32 (DEFAULT_MCHBAR + 0x4694,
3736 (read32 (DEFAULT_MCHBAR + 0x4694) & ~0x30000)
3737 | (1 << 16));
3738
3739 MCHBAR32(0x5030) |= 1; // OK
3740 MCHBAR32(0x5030) |= 0x80; // OK
3741 MCHBAR32(0x5f18) = 0xfa; // OK
3742
3743 /* Find a populated channel. */
3744 FOR_ALL_POPULATED_CHANNELS
3745 break;
3746
3747 t1_cycles = ((read32(DEFAULT_MCHBAR + 0x4290 + channel * 0x400) >> 8) & 0xff);
3748 r32 = read32(DEFAULT_MCHBAR + 0x5064);
3749 if (r32 & 0x20000)
3750 t1_cycles += (r32 & 0xfff);
3751 t1_cycles += (read32(DEFAULT_MCHBAR + channel * 0x400 + 0x42a4) & 0xfff);
3752 t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
3753 if (!(r32 & 0x20000))
3754 t1_ns += 500;
3755
3756 t2_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f10) >> 8) & 0xfff);
3757 if ( read32(DEFAULT_MCHBAR + 0x5f00) & 8 )
3758 {
3759 t3_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f20) >> 8) & 0xfff);
3760 t3_ns += 10 * (read32(DEFAULT_MCHBAR + 0x5f18) & 0xff);
3761 }
3762 else
3763 {
3764 t3_ns = 500;
3765 }
3766 printk(BIOS_DEBUG, "t123: %d, %d, %d\n",
3767 t1_ns, t2_ns, t3_ns);
3768 write32 (DEFAULT_MCHBAR + 0x5d10,
3769 ((encode_5d10(t1_ns) + encode_5d10(t2_ns)) << 16)
3770 | (encode_5d10(t1_ns) << 8)
3771 | ((encode_5d10(t3_ns) + encode_5d10(t2_ns) + encode_5d10(t1_ns)) << 24)
3772 | (read32(DEFAULT_MCHBAR + 0x5d10) & 0xC0C0C0C0)
3773 | 0xc);
3774}
3775
3776static void save_timings(ramctr_timing * ctrl)
3777{
3778 struct mrc_data_container *mrcdata;
3779 int output_len = ALIGN(sizeof (*ctrl), 16);
3780
3781 /* Save the MRC S3 restore data to cbmem */
3782 mrcdata = cbmem_add
3783 (CBMEM_ID_MRCDATA,
3784 output_len + sizeof(struct mrc_data_container));
3785
3786 printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
3787 ctrl, mrcdata, output_len);
3788
3789 mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
3790 mrcdata->mrc_data_size = output_len;
3791 mrcdata->reserved = 0;
3792 memcpy(mrcdata->mrc_data, ctrl, sizeof (*ctrl));
3793
3794 /* Zero the unused space in aligned buffer. */
3795 if (output_len > sizeof (*ctrl))
3796 memset(mrcdata->mrc_data+sizeof (*ctrl), 0,
3797 output_len - sizeof (*ctrl));
3798
3799 mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
3800 mrcdata->mrc_data_size);
3801}
3802
3803static void restore_timings(ramctr_timing * ctrl)
3804{
3805 int channel, slotrank, lane;
3806
3807 FOR_ALL_POPULATED_CHANNELS
3808 MCHBAR32(0x4004 + 0x400 * channel) =
3809 ctrl->tRRD
3810 | (ctrl->tRTP << 4)
3811 | (ctrl->tCKE << 8)
3812 | (ctrl->tWTR << 12)
3813 | (ctrl->tFAW << 16)
3814 | (ctrl->tWR << 24)
3815 | (ctrl->cmd_stretch[channel] << 30);
3816
3817 udelay(1);
3818
3819 FOR_ALL_POPULATED_CHANNELS {
3820 wait_428c(channel);
3821 }
3822
3823 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3824 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
3825 + 4 * lane, 0);
3826 }
3827
3828 FOR_ALL_POPULATED_CHANNELS
3829 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
3830 read32(DEFAULT_MCHBAR + 0x4008 +
3831 0x400 * channel) | 0x8000000);
3832
3833 FOR_ALL_POPULATED_CHANNELS {
3834 udelay (1);
3835 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
3836 read32(DEFAULT_MCHBAR + 0x4020 +
3837 0x400 * channel) | 0x200000);
3838 }
3839
3840 printram("CPE\n");
3841
3842 write32(DEFAULT_MCHBAR + 0x3400, 0);
3843 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3844
3845 printram("CP5b\n");
3846
3847 FOR_ALL_POPULATED_CHANNELS {
3848 program_timings(ctrl, channel);
3849 }
3850
3851 u32 reg, addr;
3852
3853 while (!(MCHBAR32(0x5084) & 0x10000)) ;
3854 do {
3855 reg = MCHBAR32(0x428c);
3856 } while ((reg & 0x14) == 0);
3857
3858 // Set state of memory controller
3859 MCHBAR32(0x5030) = 0x116;
3860 MCHBAR32(0x4ea0) = 0;
3861
3862 // Wait 500us
3863 udelay(500);
3864
3865 FOR_ALL_CHANNELS {
3866 // Set valid rank CKE
3867 reg = 0;
3868 reg = (reg & ~0xf) | ctrl->rankmap[channel];
3869 addr = 0x400 * channel + 0x42a0;
3870 MCHBAR32(addr) = reg;
3871
3872 // Wait 10ns for ranks to settle
3873 //udelay(0.01);
3874
3875 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
3876 MCHBAR32(addr) = reg;
3877
3878 // Write reset using a NOP
3879 write_reset(ctrl);
3880 }
3881
3882 /* mrs commands. */
3883 dram_mrscommands(ctrl);
3884
3885 printram("CP5c\n");
3886
3887 write32(DEFAULT_MCHBAR + 0x3000, 0);
3888
3889 FOR_ALL_CHANNELS {
3890 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3891 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3892 ~0x3f000000));
3893 udelay(2);
3894 }
3895
3896 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3897}
3898
3899void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
3900 int s3resume)
3901{
3902 int me_uma_size;
3903 int cbmem_was_inited;
3904
3905 MCHBAR32(0x5f00) |= 1;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003906
Vadim Bendebury7a3f36a2012-04-18 15:47:32 -07003907 report_platform_info();
3908
Stefan Reinauer00636b02012-04-04 00:08:51 +02003909 /* Wait for ME to be ready */
3910 intel_early_me_init();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003911 me_uma_size = intel_early_me_uma_size();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003912
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003913 printk(BIOS_DEBUG, "Starting native Platform init\n");
Stefan Reinauer00636b02012-04-04 00:08:51 +02003914
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003915 u32 reg_5d10;
Stefan Reinauer00636b02012-04-04 00:08:51 +02003916
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003917 wait_txt_clear();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003918
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003919 wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 });
Stefan Reinauer00636b02012-04-04 00:08:51 +02003920
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003921 reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000
3922 if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */
3923 && reg_5d10 && !s3resume) {
3924 write32(DEFAULT_MCHBAR + 0x5d10, 0);
3925 /* Need reset. */
Stefan Reinauer00636b02012-04-04 00:08:51 +02003926 outb(0x6, 0xcf9);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003927
Patrick Georgi546953c2014-11-29 10:38:17 +01003928 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003929 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02003930
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003931 ramctr_timing ctrl;
Vadim Bendebury48a4a7f2012-06-07 18:47:13 -07003932
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003933 memset(&ctrl, 0, sizeof (ctrl));
3934
3935 early_pch_init_native();
3936 early_thermal_init();
3937
3938 ctrl.mobile = mobile;
3939 ctrl.tCK = min_tck;
3940
3941 /* FIXME: for non-S3 we should be able to use timing caching with
3942 proper verification. Right now we use timings only for S3 case.
3943 */
3944 if (s3resume) {
3945 struct mrc_data_container *mrc_cache;
3946
3947 mrc_cache = find_current_mrc_cache();
3948 if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) {
3949 /* Failed S3 resume, reset to come up cleanly */
3950 outb(0x6, 0xcf9);
3951 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02003952 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003953 memcpy(&ctrl, mrc_cache->mrc_data, sizeof (ctrl));
Stefan Reinauer00636b02012-04-04 00:08:51 +02003954 }
3955
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003956 if (!s3resume) {
3957 dimm_info info;
Sven Schnelled4ee8082012-07-28 09:28:56 +02003958
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003959 /* Get DDR3 SPD data */
3960 dram_find_spds_ddr3(spds, &info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003961
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003962 /* Find fastest common supported parameters */
3963 dram_find_common_params(&info, &ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02003964
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003965 dram_dimm_mapping(&info, &ctrl);
3966 }
3967
3968 /* Set MCU frequency */
3969 dram_freq(&ctrl);
3970
3971 if (!s3resume) {
3972 /* Calculate timings */
3973 dram_timing(&ctrl);
3974 }
3975
3976 /* Set version register */
3977 MCHBAR32(0x5034) = 0xC04EB002;
3978
3979 /* Enable crossover */
3980 dram_xover(&ctrl);
3981
3982 /* Set timing and refresh registers */
3983 dram_timing_regs(&ctrl);
3984
3985 /* Power mode preset */
3986 MCHBAR32(0x4e80) = 0x5500;
3987
3988 /* Set scheduler parameters */
3989 MCHBAR32(0x4c20) = 0x10100005;
3990
3991 /* Set cpu specific register */
3992 set_4f8c();
3993
3994 /* Clear IO reset bit */
3995 MCHBAR32(0x5030) &= ~0x20;
3996
3997 /* Set MAD-DIMM registers */
3998 dram_dimm_set_mapping(&ctrl);
3999 printk(BIOS_DEBUG, "Done dimm mapping\n");
4000
4001 /* Zone config */
4002 dram_zones(&ctrl, 1);
4003
4004 /* Set memory map */
4005 dram_memorymap(&ctrl, me_uma_size);
4006 printk(BIOS_DEBUG, "Done memory map\n");
4007
4008 /* Set IO registers */
4009 dram_ioregs(&ctrl);
4010 printk(BIOS_DEBUG, "Done io registers\n");
4011
4012 udelay(1);
4013
4014 if (s3resume) {
4015 restore_timings(&ctrl);
4016 } else {
4017 /* Do jedec ddr3 reset sequence */
4018 dram_jedecreset(&ctrl);
4019 printk(BIOS_DEBUG, "Done jedec reset\n");
4020
4021 /* MRS commands */
4022 dram_mrscommands(&ctrl);
4023 printk(BIOS_DEBUG, "Done MRS commands\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004024
4025 /* Prepare for memory training */
4026 prepare_training(&ctrl);
4027
4028 read_training(&ctrl);
4029 write_training(&ctrl);
4030
4031 printram("CP5a\n");
4032
4033 discover_edges(&ctrl);
4034
4035 printram("CP5b\n");
4036
4037 command_training(&ctrl);
4038
4039 printram("CP5c\n");
4040
4041 discover_edges_write(&ctrl);
4042
4043 discover_timC_write(&ctrl);
4044
4045 normalize_training(&ctrl);
4046 }
4047
4048 set_4008c(&ctrl);
4049
4050 write_controller_mr(&ctrl);
4051
4052 if (!s3resume) {
4053 channel_test(&ctrl);
4054 }
4055
4056 /* FIXME: should be hardware revision-dependent. */
4057 write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
4058
4059 set_scrambling_seed(&ctrl);
4060
4061 set_42a0(&ctrl);
4062
4063 final_registers(&ctrl);
4064
4065 /* Zone config */
4066 dram_zones(&ctrl, 0);
4067
4068 if (!s3resume)
4069 quick_ram_check();
4070
4071 intel_early_me_status();
4072 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
4073 intel_early_me_status();
4074
Stefan Reinauer00636b02012-04-04 00:08:51 +02004075 report_memory_config();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004076
4077 cbmem_was_inited = !cbmem_recovery(s3resume);
4078 if (!s3resume)
4079 save_timings(&ctrl);
4080 if (s3resume && !cbmem_was_inited) {
4081 /* Failed S3 resume, reset to come up cleanly */
4082 outb(0x6, 0xcf9);
4083 halt();
4084 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02004085}
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004086
4087#define HOST_BRIDGE PCI_DEVFN(0, 0)
4088#define DEFAULT_TCK TCK_800MHZ
4089
4090static unsigned int get_mem_min_tck(void)
4091{
4092 const struct device *dev;
4093 const struct northbridge_intel_sandybridge_config *cfg;
4094
4095 dev = dev_find_slot(0, HOST_BRIDGE);
4096 if (!(dev && dev->chip_info))
4097 return DEFAULT_TCK;
4098
4099 cfg = dev->chip_info;
4100
4101 /* If this is zero, it just means devicetree.cb didn't set it */
4102 if (cfg->max_mem_clock_mhz == 0)
4103 return DEFAULT_TCK;
4104
4105 if (cfg->max_mem_clock_mhz >= 800)
4106 return TCK_800MHZ;
4107 else if (cfg->max_mem_clock_mhz >= 666)
4108 return TCK_666MHZ;
4109 else if (cfg->max_mem_clock_mhz >= 533)
4110 return TCK_533MHZ;
4111 return TCK_400MHZ;
4112}
4113
4114void perform_raminit(int s3resume)
4115{
4116 spd_raw_data spd[4];
4117
4118 post_code(0x3a);
4119
4120 memset (spd, 0, sizeof (spd));
4121 mainboard_get_spd(spd);
4122
4123 timestamp_add_now(TS_BEFORE_INITRAM);
4124
4125 init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume);
4126}