blob: 421763c2ba5eda0b63247b8f13b5afc718078813 [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>
Alexander Couzens81c5c762016-03-09 03:13:45 +010029#include <northbridge/intel/common/mrc_cache.h>
Duncan Laurie7b508dd2012-04-09 12:30:43 -070030#include <device/pci_def.h>
Patrick Rudolphb97009e2016-02-28 15:24:04 +010031#include <memory_info.h>
32#include <smbios.h>
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070033#include "raminit_native.h"
Stefan Reinauer00636b02012-04-04 00:08:51 +020034#include "sandybridge.h"
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070035#include <delay.h>
36#include <lib.h>
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +010037#include <device/device.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020038
39/* Management Engine is in the southbridge */
40#include "southbridge/intel/bd82x6x/me.h"
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070041/* For SPD. */
42#include "southbridge/intel/bd82x6x/smbus.h"
43#include "arch/cpu.h"
44#include "cpu/x86/msr.h"
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +010045#include <northbridge/intel/sandybridge/chip.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020046
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070047/* FIXME: no ECC support. */
48/* FIXME: no support for 3-channel chipsets. */
Stefan Reinauer00636b02012-04-04 00:08:51 +020049
Patrick Rudolph371d2912015-10-09 13:33:25 +020050/*
51 * Register description:
52 * Intel provides a command queue of depth four.
53 * Every command is configured by using multiple registers.
54 * On executing the command queue you have to provide the depth used.
55 *
56 * Known registers:
57 * Channel X = [0, 1]
58 * Command queue index Y = [0, 1, 2, 3]
59 *
60 * DEFAULT_MCHBAR + 0x4220 + 0x400 * X + 4 * Y: command io register
61 * Controls the DRAM command signals
62 * Bit 0: !RAS
63 * Bit 1: !CAS
64 * Bit 2: !WE
65 *
66 * DEFAULT_MCHBAR + 0x4200 + 0x400 * X + 4 * Y: addr bankslot io register
67 * Controls the address, bank address and slotrank signals
68 * Bit 0-15 : Address
69 * Bit 20-22: Bank Address
70 * Bit 24-25: slotrank
71 *
72 * DEFAULT_MCHBAR + 0x4230 + 0x400 * X + 4 * Y: idle register
73 * Controls the idle time after issuing this DRAM command
74 * Bit 16-32: number of clock-cylces to idle
75 *
76 * DEFAULT_MCHBAR + 0x4284 + 0x400 * channel: execute command queue
77 * Starts to execute all queued commands
78 * Bit 0 : start DRAM command execution
79 * Bit 16-20: (number of queued commands - 1) * 4
80 */
81
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070082#define BASEFREQ 133
83#define tDLLK 512
Stefan Reinauer00636b02012-04-04 00:08:51 +020084
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070085#define IS_SANDY_CPU(x) ((x & 0xffff0) == 0x206a0)
86#define IS_SANDY_CPU_C(x) ((x & 0xf) == 4)
87#define IS_SANDY_CPU_D0(x) ((x & 0xf) == 5)
88#define IS_SANDY_CPU_D1(x) ((x & 0xf) == 6)
89#define IS_SANDY_CPU_D2(x) ((x & 0xf) == 7)
Stefan Reinauer00636b02012-04-04 00:08:51 +020090
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070091#define IS_IVY_CPU(x) ((x & 0xffff0) == 0x306a0)
92#define IS_IVY_CPU_C(x) ((x & 0xf) == 4)
93#define IS_IVY_CPU_K(x) ((x & 0xf) == 5)
94#define IS_IVY_CPU_D(x) ((x & 0xf) == 6)
95#define IS_IVY_CPU_E(x) ((x & 0xf) >= 8)
Stefan Reinauer00636b02012-04-04 00:08:51 +020096
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -070097#define NUM_CHANNELS 2
98#define NUM_SLOTRANKS 4
99#define NUM_SLOTS 2
100#define NUM_LANES 8
Stefan Reinauer00636b02012-04-04 00:08:51 +0200101
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700102/* FIXME: Vendor BIOS uses 64 but our algorithms are less
103 performant and even 1 seems to be enough in practice. */
104#define NUM_PATTERNS 4
Stefan Reinauer00636b02012-04-04 00:08:51 +0200105
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700106typedef struct odtmap_st {
107 u16 rttwr;
108 u16 rttnom;
109} odtmap;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200110
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700111typedef struct dimm_info_st {
112 dimm_attr dimm[NUM_CHANNELS][NUM_SLOTS];
113} dimm_info;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200114
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700115struct ram_rank_timings {
116 /* Register 4024. One byte per slotrank. */
117 u8 val_4024;
118 /* Register 4028. One nibble per slotrank. */
119 u8 val_4028;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200120
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700121 int val_320c;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200122
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700123 struct ram_lane_timings {
124 /* lane register offset 0x10. */
125 u16 timA; /* bits 0 - 5, bits 16 - 18 */
126 u8 rising; /* bits 8 - 14 */
127 u8 falling; /* bits 20 - 26. */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200128
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700129 /* lane register offset 0x20. */
130 int timC; /* bit 0 - 5, 19. */
131 u16 timB; /* bits 8 - 13, 15 - 17. */
132 } lanes[NUM_LANES];
133};
Stefan Reinauer00636b02012-04-04 00:08:51 +0200134
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700135struct ramctr_timing_st;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200136
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700137typedef struct ramctr_timing_st {
Patrick Rudolph56abd4d2016-03-13 11:07:45 +0100138 u16 spd_crc[NUM_CHANNELS][NUM_SLOTS];
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700139 int mobile;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200140
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700141 u16 cas_supported;
142 /* tLatencies are in units of ns, scaled by x256 */
143 u32 tCK;
144 u32 tAA;
145 u32 tWR;
146 u32 tRCD;
147 u32 tRRD;
148 u32 tRP;
149 u32 tRAS;
150 u32 tRFC;
151 u32 tWTR;
152 u32 tRTP;
153 u32 tFAW;
154 /* Latencies in terms of clock cycles
155 * They are saved separately as they are needed for DRAM MRS commands*/
156 u8 CAS; /* CAS read latency */
157 u8 CWL; /* CAS write latency */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200158
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700159 u32 tREFI;
160 u32 tMOD;
161 u32 tXSOffset;
162 u32 tWLO;
163 u32 tCKE;
164 u32 tXPDLL;
165 u32 tXP;
166 u32 tAONPD;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200167
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700168 u16 reg_5064b0; /* bits 0-11. */
Stefan Reinauer00636b02012-04-04 00:08:51 +0200169
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700170 u8 rankmap[NUM_CHANNELS];
171 int ref_card_offset[NUM_CHANNELS];
172 u32 mad_dimm[NUM_CHANNELS];
173 int channel_size_mb[NUM_CHANNELS];
174 u32 cmd_stretch[NUM_CHANNELS];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200175
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700176 int reg_c14_offset;
177 int reg_320c_range_threshold;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200178
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700179 int edge_offset[3];
180 int timC_offset[3];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200181
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700182 int extended_temperature_range;
183 int auto_self_refresh;
Stefan Reinauer00636b02012-04-04 00:08:51 +0200184
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700185 int rank_mirror[NUM_CHANNELS][NUM_SLOTRANKS];
186
187 struct ram_rank_timings timings[NUM_CHANNELS][NUM_SLOTRANKS];
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100188
189 dimm_info info;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700190} ramctr_timing;
191
192#define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0)
193#define NORTHBRIDGE PCI_DEV(0, 0x0, 0)
194#define FOR_ALL_LANES for (lane = 0; lane < NUM_LANES; lane++)
195#define FOR_ALL_CHANNELS for (channel = 0; channel < NUM_CHANNELS; channel++)
196#define FOR_ALL_POPULATED_RANKS for (slotrank = 0; slotrank < NUM_SLOTRANKS; slotrank++) if (ctrl->rankmap[channel] & (1 << slotrank))
197#define FOR_ALL_POPULATED_CHANNELS for (channel = 0; channel < NUM_CHANNELS; channel++) if (ctrl->rankmap[channel])
198#define MAX_EDGE_TIMING 71
199#define MAX_TIMC 127
200#define MAX_TIMB 511
201#define MAX_TIMA 127
202
Patrick Rudolph24a845b2016-03-25 18:19:47 +0100203#define MAKE_ERR ((channel<<16)|(slotrank<<8)|1)
Patrick Rudolph2ccb74b2016-03-26 12:16:29 +0100204#define GET_ERR_CHANNEL(x) (x>>16)
Patrick Rudolph24a845b2016-03-25 18:19:47 +0100205
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700206static void program_timings(ramctr_timing * ctrl, int channel);
Patrick Rudolph266a1f72016-06-09 18:13:34 +0200207static unsigned int get_mmio_size(void);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700208
209static const char *ecc_decoder[] = {
Stefan Reinauer00636b02012-04-04 00:08:51 +0200210 "inactive",
211 "active on IO",
212 "disabled on IO",
213 "active"
214};
215
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700216static void wait_txt_clear(void)
217{
218 struct cpuid_result cp;
219
220 cp = cpuid_ext(0x1, 0x0);
221 /* Check if TXT is supported? */
222 if (!(cp.ecx & 0x40))
223 return;
224 /* Some TXT public bit. */
225 if (!(read32((void *)0xfed30010) & 1))
226 return;
227 /* Wait for TXT clear. */
228 while (!(read8((void *)0xfed40000) & (1 << 7))) ;
229}
230
231static void sfence(void)
232{
233 asm volatile ("sfence");
234}
235
Patrick Rudolph9b515682015-10-09 13:43:51 +0200236static void toggle_io_reset(void) {
237 /* toggle IO reset bit */
238 u32 r32 = read32(DEFAULT_MCHBAR + 0x5030);
239 write32(DEFAULT_MCHBAR + 0x5030, r32 | 0x20);
240 udelay(1);
241 write32(DEFAULT_MCHBAR + 0x5030, r32 & ~0x20);
242 udelay(1);
243}
244
Stefan Reinauer00636b02012-04-04 00:08:51 +0200245/*
Patrick Rudolph2ccb74b2016-03-26 12:16:29 +0100246 * Disable a channel in ramctr_timing.
247 */
248static void disable_channel(ramctr_timing *ctrl, int channel) {
249 ctrl->rankmap[channel] = 0;
250 memset(&ctrl->rank_mirror[channel][0], 0, sizeof(ctrl->rank_mirror[0]));
251 ctrl->channel_size_mb[channel] = 0;
252 ctrl->cmd_stretch[channel] = 0;
253 ctrl->mad_dimm[channel] = 0;
254 memset(&ctrl->timings[channel][0], 0, sizeof(ctrl->timings[0]));
255}
256
257/*
Patrick Rudolphb97009e2016-02-28 15:24:04 +0100258 * Fill cbmem with information for SMBIOS type 17.
259 */
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100260static void fill_smbios17(ramctr_timing *ctrl)
Patrick Rudolphb97009e2016-02-28 15:24:04 +0100261{
262 struct memory_info *mem_info;
263 int channel, slot;
264 struct dimm_info *dimm;
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100265 uint16_t ddr_freq;
266 dimm_info *info = &ctrl->info;
267
268 ddr_freq = (1000 << 8) / ctrl->tCK;
Patrick Rudolphb97009e2016-02-28 15:24:04 +0100269
270 /*
271 * Allocate CBMEM area for DIMM information used to populate SMBIOS
272 * table 17
273 */
274 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
275 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
276 if (!mem_info)
277 return;
278
279 memset(mem_info, 0, sizeof(*mem_info));
280
281 FOR_ALL_CHANNELS for(slot = 0; slot < NUM_SLOTS; slot++) {
282 dimm = &mem_info->dimm[mem_info->dimm_cnt];
283 if (info->dimm[channel][slot].size_mb) {
284 dimm->ddr_type = MEMORY_TYPE_DDR3;
285 dimm->ddr_frequency = ddr_freq;
286 dimm->dimm_size = info->dimm[channel][slot].size_mb;
287 dimm->channel_num = channel;
288 dimm->rank_per_dimm = info->dimm[channel][slot].ranks;
289 dimm->dimm_num = slot;
290 memcpy(dimm->module_part_number,
291 info->dimm[channel][slot].part_number, 16);
292 dimm->mod_id = info->dimm[channel][slot].manufacturer_id;
293 dimm->mod_type = info->dimm[channel][slot].dimm_type;
294 dimm->bus_width = info->dimm[channel][slot].width;
295 mem_info->dimm_cnt++;
296 }
297 }
298}
299
300/*
Stefan Reinauer00636b02012-04-04 00:08:51 +0200301 * Dump in the log memory controller configuration as read from the memory
302 * controller registers.
303 */
304static void report_memory_config(void)
305{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700306 u32 addr_decoder_common, addr_decode_ch[NUM_CHANNELS];
Stefan Reinauer00636b02012-04-04 00:08:51 +0200307 int i;
308
309 addr_decoder_common = MCHBAR32(0x5000);
310 addr_decode_ch[0] = MCHBAR32(0x5004);
311 addr_decode_ch[1] = MCHBAR32(0x5008);
312
313 printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700314 (MCHBAR32(0x5e04) * 13333 * 2 + 50) / 100);
Stefan Reinauer00636b02012-04-04 00:08:51 +0200315 printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700316 addr_decoder_common & 3, (addr_decoder_common >> 2) & 3,
Stefan Reinauer00636b02012-04-04 00:08:51 +0200317 (addr_decoder_common >> 4) & 3);
318
319 for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
320 u32 ch_conf = addr_decode_ch[i];
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700321 printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i,
322 ch_conf);
Stefan Reinauer00636b02012-04-04 00:08:51 +0200323 printk(BIOS_DEBUG, " ECC %s\n",
324 ecc_decoder[(ch_conf >> 24) & 3]);
325 printk(BIOS_DEBUG, " enhanced interleave mode %s\n",
326 ((ch_conf >> 22) & 1) ? "on" : "off");
327 printk(BIOS_DEBUG, " rank interleave %s\n",
328 ((ch_conf >> 21) & 1) ? "on" : "off");
329 printk(BIOS_DEBUG, " DIMMA %d MB width x%d %s rank%s\n",
330 ((ch_conf >> 0) & 0xff) * 256,
331 ((ch_conf >> 19) & 1) ? 16 : 8,
332 ((ch_conf >> 17) & 1) ? "dual" : "single",
333 ((ch_conf >> 16) & 1) ? "" : ", selected");
334 printk(BIOS_DEBUG, " DIMMB %d MB width x%d %s rank%s\n",
335 ((ch_conf >> 8) & 0xff) * 256,
336 ((ch_conf >> 20) & 1) ? 16 : 8,
337 ((ch_conf >> 18) & 1) ? "dual" : "single",
338 ((ch_conf >> 16) & 1) ? ", selected" : "");
339 }
340}
341
Patrick Rudolph56abd4d2016-03-13 11:07:45 +0100342/*
343 * Return CRC16 match for all SPDs.
344 */
345static int verify_crc16_spds_ddr3(spd_raw_data *spd, ramctr_timing *ctrl)
346{
347 int channel, slot, spd_slot;
348 int match = 1;
349
350 FOR_ALL_CHANNELS {
351 for (slot = 0; slot < NUM_SLOTS; slot++) {
352 spd_slot = 2 * channel + slot;
353 match &= ctrl->spd_crc[channel][slot] ==
354 spd_ddr3_calc_crc(spd[spd_slot], sizeof(spd_raw_data));
355 }
356 }
357 return match;
358}
359
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700360void read_spd(spd_raw_data * spd, u8 addr)
Stefan Reinauer00636b02012-04-04 00:08:51 +0200361{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700362 int j;
363 for (j = 0; j < 256; j++)
364 (*spd)[j] = do_smbus_read_byte(SMBUS_IO_BASE, addr, j);
365}
366
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100367static void dram_find_spds_ddr3(spd_raw_data *spd, ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700368{
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100369 int dimms = 0, dimms_on_channel;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700370 int channel, slot, spd_slot;
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100371 dimm_info *dimm = &ctrl->info;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700372
373 memset (ctrl->rankmap, 0, sizeof (ctrl->rankmap));
374
375 ctrl->extended_temperature_range = 1;
376 ctrl->auto_self_refresh = 1;
377
378 FOR_ALL_CHANNELS {
379 ctrl->channel_size_mb[channel] = 0;
380
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100381 dimms_on_channel = 0;
382 /* count dimms on channel */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700383 for (slot = 0; slot < NUM_SLOTS; slot++) {
384 spd_slot = 2 * channel + slot;
385 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100386 if (dimm->dimm[channel][slot].dram_type == SPD_MEMORY_TYPE_SDRAM_DDR3)
387 dimms_on_channel++;
388 }
389
390 for (slot = 0; slot < NUM_SLOTS; slot++) {
391 spd_slot = 2 * channel + slot;
392 /* search for XMP profile */
393 spd_xmp_decode_ddr3(&dimm->dimm[channel][slot],
394 spd[spd_slot],
395 DDR3_XMP_PROFILE_1);
396
397 if (dimm->dimm[channel][slot].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) {
398 printram("No valid XMP profile found.\n");
399 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
400 } else if (dimms_on_channel > dimm->dimm[channel][slot].dimms_per_channel) {
401 printram("XMP profile supports %u DIMMs, but %u DIMMs are installed.\n",
402 dimm->dimm[channel][slot].dimms_per_channel,
403 dimms_on_channel);
404 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
405 } else if (dimm->dimm[channel][slot].voltage != 1500) {
406 /* TODO: support other DDR3 voltage than 1500mV */
407 printram("XMP profile's requested %u mV is unsupported.\n",
408 dimm->dimm[channel][slot].voltage);
409 spd_decode_ddr3(&dimm->dimm[channel][slot], spd[spd_slot]);
410 }
411
Patrick Rudolph56abd4d2016-03-13 11:07:45 +0100412 /* fill in CRC16 for MRC cache */
413 ctrl->spd_crc[channel][slot] =
414 spd_ddr3_calc_crc(spd[spd_slot], sizeof(spd_raw_data));
415
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700416 if (dimm->dimm[channel][slot].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) {
417 // set dimm invalid
418 dimm->dimm[channel][slot].ranks = 0;
419 dimm->dimm[channel][slot].size_mb = 0;
420 continue;
421 }
422
423 dram_print_spd_ddr3(&dimm->dimm[channel][slot]);
424 dimms++;
425 ctrl->rank_mirror[channel][slot * 2] = 0;
426 ctrl->rank_mirror[channel][slot * 2 + 1] = dimm->dimm[channel][slot].flags.pins_mirrored;
427 ctrl->channel_size_mb[channel] += dimm->dimm[channel][slot].size_mb;
428
429 ctrl->auto_self_refresh &= dimm->dimm[channel][slot].flags.asr;
430 ctrl->extended_temperature_range &= dimm->dimm[channel][slot].flags.ext_temp_refresh;
431
432 ctrl->rankmap[channel] |= ((1 << dimm->dimm[channel][slot].ranks) - 1) << (2 * slot);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100433 printk(BIOS_DEBUG, "channel[%d] rankmap = 0x%x\n",
434 channel, ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700435 }
436 if ((ctrl->rankmap[channel] & 3) && (ctrl->rankmap[channel] & 0xc)
437 && dimm->dimm[channel][0].reference_card <= 5 && dimm->dimm[channel][1].reference_card <= 5) {
438 const int ref_card_offset_table[6][6] = {
439 { 0, 0, 0, 0, 2, 2, },
440 { 0, 0, 0, 0, 2, 2, },
441 { 0, 0, 0, 0, 2, 2, },
442 { 0, 0, 0, 0, 1, 1, },
443 { 2, 2, 2, 1, 0, 0, },
444 { 2, 2, 2, 1, 0, 0, },
445 };
446 ctrl->ref_card_offset[channel] = ref_card_offset_table[dimm->dimm[channel][0].reference_card]
447 [dimm->dimm[channel][1].reference_card];
448 } else
449 ctrl->ref_card_offset[channel] = 0;
450 }
451
452 if (!dimms)
453 die("No DIMMs were found");
454}
455
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100456static void dram_find_common_params(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700457{
458 size_t valid_dimms;
459 int channel, slot;
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100460 dimm_info *dimms = &ctrl->info;
461
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700462 ctrl->cas_supported = 0xff;
463 valid_dimms = 0;
464 FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) {
465 const dimm_attr *dimm = &dimms->dimm[channel][slot];
466 if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
467 continue;
468 valid_dimms++;
469
470 /* Find all possible CAS combinations */
471 ctrl->cas_supported &= dimm->cas_supported;
472
473 /* Find the smallest common latencies supported by all DIMMs */
474 ctrl->tCK = MAX(ctrl->tCK, dimm->tCK);
475 ctrl->tAA = MAX(ctrl->tAA, dimm->tAA);
476 ctrl->tWR = MAX(ctrl->tWR, dimm->tWR);
477 ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
478 ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
479 ctrl->tRP = MAX(ctrl->tRP, dimm->tRP);
480 ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
481 ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
482 ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
483 ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
484 ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
485 }
486
487 if (!ctrl->cas_supported)
488 die("Unsupported DIMM combination. "
489 "DIMMS do not support common CAS latency");
490 if (!valid_dimms)
491 die("No valid DIMMs found");
492}
493
494static u8 get_CWL(u8 CAS)
495{
496 /* Get CWL based on CAS using the following rule:
497 * _________________________________________
498 * CAS: | 4T | 5T | 6T | 7T | 8T | 9T | 10T | 11T |
499 * CWL: | 5T | 5T | 5T | 6T | 6T | 7T | 7T | 8T |
500 */
501 static const u8 cas_cwl_map[] = { 5, 5, 5, 6, 6, 7, 7, 8 };
502 if (CAS > 11)
503 return 8;
504 return cas_cwl_map[CAS - 4];
505}
506
507/* Frequency multiplier. */
508static u32 get_FRQ(u32 tCK)
509{
510 u32 FRQ;
511 FRQ = 256000 / (tCK * BASEFREQ);
512 if (FRQ > 8)
513 return 8;
514 if (FRQ < 3)
515 return 3;
516 return FRQ;
517}
518
519static u32 get_REFI(u32 tCK)
520{
521 /* Get REFI based on MCU frequency using the following rule:
522 * _________________________________________
523 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
524 * REFI: | 3120 | 4160 | 5200 | 6240 | 7280 | 8320 |
525 */
526 static const u32 frq_refi_map[] =
527 { 3120, 4160, 5200, 6240, 7280, 8320 };
528 return frq_refi_map[get_FRQ(tCK) - 3];
529}
530
531static u8 get_XSOffset(u32 tCK)
532{
533 /* Get XSOffset based on MCU frequency using the following rule:
534 * _________________________
535 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
536 * XSOffset : | 4 | 6 | 7 | 8 | 10 | 11 |
537 */
538 static const u8 frq_xs_map[] = { 4, 6, 7, 8, 10, 11 };
539 return frq_xs_map[get_FRQ(tCK) - 3];
540}
541
542static u8 get_MOD(u32 tCK)
543{
544 /* Get MOD based on MCU frequency using the following rule:
545 * _____________________________
546 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
547 * MOD : | 12 | 12 | 12 | 12 | 15 | 16 |
548 */
549 static const u8 frq_mod_map[] = { 12, 12, 12, 12, 15, 16 };
550 return frq_mod_map[get_FRQ(tCK) - 3];
551}
552
553static u8 get_WLO(u32 tCK)
554{
555 /* Get WLO based on MCU frequency using the following rule:
556 * _______________________
557 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
558 * WLO : | 4 | 5 | 6 | 6 | 8 | 8 |
559 */
560 static const u8 frq_wlo_map[] = { 4, 5, 6, 6, 8, 8 };
561 return frq_wlo_map[get_FRQ(tCK) - 3];
562}
563
564static u8 get_CKE(u32 tCK)
565{
566 /* Get CKE based on MCU frequency using the following rule:
567 * _______________________
568 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
569 * CKE : | 3 | 3 | 4 | 4 | 5 | 6 |
570 */
571 static const u8 frq_cke_map[] = { 3, 3, 4, 4, 5, 6 };
572 return frq_cke_map[get_FRQ(tCK) - 3];
573}
574
575static u8 get_XPDLL(u32 tCK)
576{
577 /* Get XPDLL based on MCU frequency using the following rule:
578 * _____________________________
579 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
580 * XPDLL : | 10 | 13 | 16 | 20 | 23 | 26 |
581 */
582 static const u8 frq_xpdll_map[] = { 10, 13, 16, 20, 23, 26 };
583 return frq_xpdll_map[get_FRQ(tCK) - 3];
584}
585
586static u8 get_XP(u32 tCK)
587{
588 /* Get XP based on MCU frequency using the following rule:
589 * _______________________
590 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
591 * XP : | 3 | 4 | 4 | 5 | 6 | 7 |
592 */
593 static const u8 frq_xp_map[] = { 3, 4, 4, 5, 6, 7 };
594 return frq_xp_map[get_FRQ(tCK) - 3];
595}
596
597static u8 get_AONPD(u32 tCK)
598{
599 /* Get AONPD based on MCU frequency using the following rule:
600 * ________________________
601 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
602 * AONPD : | 4 | 5 | 6 | 8 | 8 | 10 |
603 */
604 static const u8 frq_aonpd_map[] = { 4, 5, 6, 8, 8, 10 };
605 return frq_aonpd_map[get_FRQ(tCK) - 3];
606}
607
608static u32 get_COMP2(u32 tCK)
609{
610 /* Get COMP2 based on MCU frequency using the following rule:
611 * ___________________________________________________________
612 * FRQ : | 3 | 4 | 5 | 6 | 7 | 8 |
613 * COMP : | D6BEDCC | CE7C34C | CA57A4C | C6369CC | C42514C | C21410C |
614 */
615 static const u32 frq_comp2_map[] = { 0xD6BEDCC, 0xCE7C34C, 0xCA57A4C,
616 0xC6369CC, 0xC42514C, 0xC21410C
617 };
618 return frq_comp2_map[get_FRQ(tCK) - 3];
619}
620
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100621static u32 get_XOVER_CLK(u8 rankmap)
622{
623 return rankmap << 24;
624}
625
626static u32 get_XOVER_CMD(u8 rankmap)
627{
628 u32 reg;
629
630 // enable xover cmd
631 reg = 0x4000;
632
633 // enable xover ctl
634 if (rankmap & 0x3)
635 reg |= 0x20000;
636
637 if (rankmap & 0xc)
638 reg |= 0x4000000;
639
640 return reg;
641}
642
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700643static void dram_timing(ramctr_timing * ctrl)
644{
645 u8 val;
646 u32 val32;
647
648 /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure
649 * we cap it if we have faster DIMMs.
650 * Then, align it to the closest JEDEC standard frequency */
651 if (ctrl->tCK <= TCK_1066MHZ) {
652 ctrl->tCK = TCK_1066MHZ;
653 ctrl->edge_offset[0] = 16;
654 ctrl->edge_offset[1] = 7;
655 ctrl->edge_offset[2] = 7;
656 ctrl->timC_offset[0] = 18;
657 ctrl->timC_offset[1] = 7;
658 ctrl->timC_offset[2] = 7;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700659 ctrl->reg_320c_range_threshold = 13;
660 } else if (ctrl->tCK <= TCK_933MHZ) {
661 ctrl->tCK = TCK_933MHZ;
662 ctrl->edge_offset[0] = 14;
663 ctrl->edge_offset[1] = 6;
664 ctrl->edge_offset[2] = 6;
665 ctrl->timC_offset[0] = 15;
666 ctrl->timC_offset[1] = 6;
667 ctrl->timC_offset[2] = 6;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700668 ctrl->reg_320c_range_threshold = 15;
669 } else if (ctrl->tCK <= TCK_800MHZ) {
670 ctrl->tCK = TCK_800MHZ;
671 ctrl->edge_offset[0] = 13;
672 ctrl->edge_offset[1] = 5;
673 ctrl->edge_offset[2] = 5;
674 ctrl->timC_offset[0] = 14;
675 ctrl->timC_offset[1] = 5;
676 ctrl->timC_offset[2] = 5;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700677 ctrl->reg_320c_range_threshold = 15;
678 } else if (ctrl->tCK <= TCK_666MHZ) {
679 ctrl->tCK = TCK_666MHZ;
680 ctrl->edge_offset[0] = 10;
681 ctrl->edge_offset[1] = 4;
682 ctrl->edge_offset[2] = 4;
683 ctrl->timC_offset[0] = 11;
684 ctrl->timC_offset[1] = 4;
685 ctrl->timC_offset[2] = 4;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700686 ctrl->reg_320c_range_threshold = 16;
687 } else if (ctrl->tCK <= TCK_533MHZ) {
688 ctrl->tCK = TCK_533MHZ;
689 ctrl->edge_offset[0] = 8;
690 ctrl->edge_offset[1] = 3;
691 ctrl->edge_offset[2] = 3;
692 ctrl->timC_offset[0] = 9;
693 ctrl->timC_offset[1] = 3;
694 ctrl->timC_offset[2] = 3;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700695 ctrl->reg_320c_range_threshold = 17;
696 } else {
697 ctrl->tCK = TCK_400MHZ;
698 ctrl->edge_offset[0] = 6;
699 ctrl->edge_offset[1] = 2;
700 ctrl->edge_offset[2] = 2;
701 ctrl->timC_offset[0] = 6;
702 ctrl->timC_offset[1] = 2;
703 ctrl->timC_offset[2] = 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700704 ctrl->reg_320c_range_threshold = 17;
705 }
706
Patrick Rudolphd4c53e32016-06-14 20:07:32 +0200707 /* Initial phase between CLK/CMD pins */
708 ctrl->reg_c14_offset = (256000 / ctrl->tCK) / 66;
709
Patrick Rudolphb7b1b282016-06-14 18:44:28 +0200710 /* DLL_CONFIG_MDLL_W_TIMER */
711 ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
712
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700713 val32 = (1000 << 8) / ctrl->tCK;
714 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
715
716 /* Find CAS and CWL latencies */
717 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
718 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
719 /* Find lowest supported CAS latency that satisfies the minimum value */
720 while (!((ctrl->cas_supported >> (val - 4)) & 1)
721 && (ctrl->cas_supported >> (val - 4))) {
722 val++;
723 }
724 /* Is CAS supported */
Patrick Rudolph55409eb2016-06-15 20:28:32 +0200725 if (!(ctrl->cas_supported & (1 << (val - 4)))) {
726 printk(BIOS_ERR, "CAS %uT not supported. ", val);
727 val = 18;
728 /* Find highest supported CAS latency */
729 while (!((ctrl->cas_supported >> (val - 4)) & 1))
730 val--;
731
732 printk(BIOS_ERR, "Using CAS %uT instead.\n", val);
733 }
734
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700735 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
736 ctrl->CAS = val;
737 ctrl->CWL = get_CWL(ctrl->CAS);
738 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
739
740 /* Find tRCD */
741 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
742 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
743
744 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
745 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
746
747 /* Find tRAS */
748 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
749 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
750
751 /* Find tWR */
752 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
753 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
754
755 /* Find tFAW */
756 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
757 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
758
759 /* Find tRRD */
760 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
761 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
762
763 /* Find tRTP */
764 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
765 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
766
767 /* Find tWTR */
768 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
769 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
770
771 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
772 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
773 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
774
775 ctrl->tREFI = get_REFI(ctrl->tCK);
776 ctrl->tMOD = get_MOD(ctrl->tCK);
777 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
778 ctrl->tWLO = get_WLO(ctrl->tCK);
779 ctrl->tCKE = get_CKE(ctrl->tCK);
780 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
781 ctrl->tXP = get_XP(ctrl->tCK);
782 ctrl->tAONPD = get_AONPD(ctrl->tCK);
783}
784
785static void dram_freq(ramctr_timing * ctrl)
786{
787 if (ctrl->tCK > TCK_400MHZ) {
788 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
789 ctrl->tCK = TCK_400MHZ;
790 }
791 while (1) {
792 u8 val2;
793 u32 reg1 = 0;
794
795 /* Step 1 - Set target PCU frequency */
796
797 if (ctrl->tCK <= TCK_1066MHZ) {
798 ctrl->tCK = TCK_1066MHZ;
799 } else if (ctrl->tCK <= TCK_933MHZ) {
800 ctrl->tCK = TCK_933MHZ;
801 } else if (ctrl->tCK <= TCK_800MHZ) {
802 ctrl->tCK = TCK_800MHZ;
803 } else if (ctrl->tCK <= TCK_666MHZ) {
804 ctrl->tCK = TCK_666MHZ;
805 } else if (ctrl->tCK <= TCK_533MHZ) {
806 ctrl->tCK = TCK_533MHZ;
807 } else if (ctrl->tCK <= TCK_400MHZ) {
808 ctrl->tCK = TCK_400MHZ;
809 } else {
810 die ("No lock frequency found");
811 }
812
813 /* Frequency mulitplier. */
814 u32 FRQ = get_FRQ(ctrl->tCK);
815
Patrick Rudolph9c9bde32016-03-26 17:20:02 +0100816 /* The PLL will never lock if the required frequency is
817 * already set. Exit early to prevent a system hang.
818 */
819 reg1 = MCHBAR32(0x5e04);
820 val2 = (u8) reg1;
821 if (val2 == FRQ) {
822 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
823 (1000 << 8) / ctrl->tCK);
824 return;
825 }
826
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700827 /* Step 2 - Select frequency in the MCU */
828 reg1 = FRQ;
829 reg1 |= 0x80000000; // set running bit
830 MCHBAR32(0x5e00) = reg1;
831 while (reg1 & 0x80000000) {
832 printk(BIOS_DEBUG, " PLL busy...");
833 reg1 = MCHBAR32(0x5e00);
834 }
835 printk(BIOS_DEBUG, "done\n");
836
837 /* Step 3 - Verify lock frequency */
838 reg1 = MCHBAR32(0x5e04);
839 val2 = (u8) reg1;
840 if (val2 >= FRQ) {
841 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
842 (1000 << 8) / ctrl->tCK);
843 return;
844 }
845 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
846 ctrl->tCK++;
847 }
848}
849
850static void dram_xover(ramctr_timing * ctrl)
851{
852 u32 reg;
853 int channel;
854
855 FOR_ALL_CHANNELS {
856 // enable xover clk
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100857 reg = get_XOVER_CLK(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100858 printram("XOVER CLK [%x] = %x\n", channel * 0x100 + 0xc14,
859 reg);
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100860 MCHBAR32(channel * 0x100 + 0xc14) = reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700861
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100862 // enable xover ctl & xover cmd
863 reg = get_XOVER_CMD(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100864 printram("XOVER CMD [%x] = %x\n", 0x100 * channel + 0x320c,
865 reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700866 MCHBAR32(0x100 * channel + 0x320c) = reg;
867 }
868}
869
870static void dram_timing_regs(ramctr_timing * ctrl)
871{
872 u32 reg, addr, val32, cpu, stretch;
873 struct cpuid_result cpures;
874 int channel;
875
876 FOR_ALL_CHANNELS {
877 // DBP
878 reg = 0;
879 reg |= ctrl->tRCD;
880 reg |= (ctrl->tRP << 4);
881 reg |= (ctrl->CAS << 8);
882 reg |= (ctrl->CWL << 12);
883 reg |= (ctrl->tRAS << 16);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100884 printram("DBP [%x] = %x\n", 0x400 * channel + 0x4000, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700885 MCHBAR32(0x400 * channel + 0x4000) = reg;
886
887 // RAP
888 reg = 0;
889 reg |= ctrl->tRRD;
890 reg |= (ctrl->tRTP << 4);
891 reg |= (ctrl->tCKE << 8);
892 reg |= (ctrl->tWTR << 12);
893 reg |= (ctrl->tFAW << 16);
894 reg |= (ctrl->tWR << 24);
895 reg |= (3 << 30);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100896 printram("RAP [%x] = %x\n", 0x400 * channel + 0x4004, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700897 MCHBAR32(0x400 * channel + 0x4004) = reg;
898
899 // OTHP
900 addr = 0x400 * channel + 0x400c;
901 reg = 0;
902 reg |= ctrl->tXPDLL;
903 reg |= (ctrl->tXP << 5);
904 reg |= (ctrl->tAONPD << 8);
905 reg |= 0xa0000;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100906 printram("OTHP [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700907 MCHBAR32(addr) = reg;
908
909 MCHBAR32(0x400 * channel + 0x4014) = 0;
910
911 MCHBAR32(addr) |= 0x00020000;
912
913 // ODT stretch
914 reg = 0;
915
Ryan Salsamendie4da9aa2016-06-24 12:01:11 -0700916 cpures = cpuid(1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700917 cpu = cpures.eax;
918 if (IS_IVY_CPU(cpu)
919 || (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_D2(cpu))) {
920 stretch = 2;
921 addr = 0x400 * channel + 0x400c;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100922 printram("ODT stretch [%x] = %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700923 0x400 * channel + 0x400c, reg);
924 reg = MCHBAR32(addr);
925
926 if (((ctrl->rankmap[channel] & 3) == 0)
927 || (ctrl->rankmap[channel] & 0xc) == 0) {
928
929 // Rank 0 - operate on rank 2
930 reg = (reg & ~0xc0000) | (stretch << 18);
931
932 // Rank 2 - operate on rank 0
933 reg = (reg & ~0x30000) | (stretch << 16);
934
Patrick Rudolpha649a542016-01-17 18:32:06 +0100935 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700936 MCHBAR32(addr) = reg;
937 }
938
939 } else if (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_C(cpu)) {
940 stretch = 3;
941 addr = 0x400 * channel + 0x401c;
942 reg = MCHBAR32(addr);
943
944 if (((ctrl->rankmap[channel] & 3) == 0)
945 || (ctrl->rankmap[channel] & 0xc) == 0) {
946
947 // Rank 0 - operate on rank 2
948 reg = (reg & ~0x3000) | (stretch << 12);
949
950 // Rank 2 - operate on rank 0
951 reg = (reg & ~0xc00) | (stretch << 10);
952
Patrick Rudolpha649a542016-01-17 18:32:06 +0100953 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700954 MCHBAR32(addr) = reg;
955 }
956 } else {
957 stretch = 0;
958 }
959
960 // REFI
961 reg = 0;
962 val32 = ctrl->tREFI;
963 reg = (reg & ~0xffff) | val32;
964 val32 = ctrl->tRFC;
965 reg = (reg & ~0x1ff0000) | (val32 << 16);
966 val32 = (u32) (ctrl->tREFI * 9) / 1024;
967 reg = (reg & ~0xfe000000) | (val32 << 25);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100968 printram("REFI [%x] = %x\n", 0x400 * channel + 0x4298,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700969 reg);
970 MCHBAR32(0x400 * channel + 0x4298) = reg;
971
972 MCHBAR32(0x400 * channel + 0x4294) |= 0xff;
973
974 // SRFTP
975 reg = 0;
976 val32 = tDLLK;
977 reg = (reg & ~0xfff) | val32;
978 val32 = ctrl->tXSOffset;
979 reg = (reg & ~0xf000) | (val32 << 12);
980 val32 = tDLLK - ctrl->tXSOffset;
981 reg = (reg & ~0x3ff0000) | (val32 << 16);
982 val32 = ctrl->tMOD - 8;
983 reg = (reg & ~0xf0000000) | (val32 << 28);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100984 printram("SRFTP [%x] = %x\n", 0x400 * channel + 0x42a4,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700985 reg);
986 MCHBAR32(0x400 * channel + 0x42a4) = reg;
987 }
988}
989
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100990static void dram_dimm_mapping(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700991{
992 u32 reg, val32;
993 int channel;
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100994 dimm_info *info = &ctrl->info;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700995
996 FOR_ALL_CHANNELS {
997 dimm_attr *dimmA = 0;
998 dimm_attr *dimmB = 0;
999 reg = 0;
1000 val32 = 0;
1001 if (info->dimm[channel][0].size_mb >=
1002 info->dimm[channel][1].size_mb) {
1003 // dimm 0 is bigger, set it to dimmA
1004 dimmA = &info->dimm[channel][0];
1005 dimmB = &info->dimm[channel][1];
1006 reg |= (0 << 16);
1007 } else {
1008 // dimm 1 is bigger, set it to dimmA
1009 dimmA = &info->dimm[channel][1];
1010 dimmB = &info->dimm[channel][0];
1011 reg |= (1 << 16);
1012 }
1013 // dimmA
1014 if (dimmA && (dimmA->ranks > 0)) {
1015 val32 = dimmA->size_mb / 256;
1016 reg = (reg & ~0xff) | val32;
1017 val32 = dimmA->ranks - 1;
1018 reg = (reg & ~0x20000) | (val32 << 17);
1019 val32 = (dimmA->width / 8) - 1;
1020 reg = (reg & ~0x80000) | (val32 << 19);
1021 }
1022 // dimmB
1023 if (dimmB && (dimmB->ranks > 0)) {
1024 val32 = dimmB->size_mb / 256;
1025 reg = (reg & ~0xff00) | (val32 << 8);
1026 val32 = dimmB->ranks - 1;
1027 reg = (reg & ~0x40000) | (val32 << 18);
1028 val32 = (dimmB->width / 8) - 1;
1029 reg = (reg & ~0x100000) | (val32 << 20);
1030 }
1031 reg = (reg & ~0x200000) | (1 << 21); // rank interleave
1032 reg = (reg & ~0x400000) | (1 << 22); // enhanced interleave
1033
1034 // Save MAD-DIMM register
1035 if ((dimmA && (dimmA->ranks > 0))
1036 || (dimmB && (dimmB->ranks > 0))) {
1037 ctrl->mad_dimm[channel] = reg;
1038 } else {
1039 ctrl->mad_dimm[channel] = 0;
1040 }
1041 }
1042}
1043
1044static void dram_dimm_set_mapping(ramctr_timing * ctrl)
1045{
1046 int channel;
1047 FOR_ALL_CHANNELS {
1048 MCHBAR32(0x5004 + channel * 4) = ctrl->mad_dimm[channel];
1049 }
1050}
1051
1052static void dram_zones(ramctr_timing * ctrl, int training)
1053{
1054 u32 reg, ch0size, ch1size;
1055 u8 val;
1056 reg = 0;
1057 val = 0;
1058 if (training) {
1059 ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
1060 ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
1061 } else {
1062 ch0size = ctrl->channel_size_mb[0];
1063 ch1size = ctrl->channel_size_mb[1];
1064 }
1065
1066 if (ch0size >= ch1size) {
1067 reg = MCHBAR32(0x5014);
1068 val = ch1size / 256;
1069 reg = (reg & ~0xff000000) | val << 24;
1070 reg = (reg & ~0xff0000) | (2 * val) << 16;
1071 MCHBAR32(0x5014) = reg;
1072 MCHBAR32(0x5000) = 0x24;
1073 } else {
1074 reg = MCHBAR32(0x5014);
1075 val = ch0size / 256;
1076 reg = (reg & ~0xff000000) | val << 24;
1077 reg = (reg & ~0xff0000) | (2 * val) << 16;
1078 MCHBAR32(0x5014) = reg;
1079 MCHBAR32(0x5000) = 0x21;
1080 }
1081}
1082
1083static void dram_memorymap(ramctr_timing * ctrl, int me_uma_size)
1084{
1085 u32 reg, val, reclaim;
1086 u32 tom, gfxstolen, gttsize;
1087 size_t tsegsize, mmiosize, toludbase, touudbase, gfxstolenbase, gttbase,
1088 tsegbase, mestolenbase;
1089 size_t tsegbasedelta, remapbase, remaplimit;
1090 uint16_t ggc;
1091
Patrick Rudolph266a1f72016-06-09 18:13:34 +02001092 mmiosize = get_mmio_size();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001093
1094 ggc = pci_read_config16(NORTHBRIDGE, GGC);
1095 if (!(ggc & 2)) {
1096 gfxstolen = ((ggc >> 3) & 0x1f) * 32;
1097 gttsize = ((ggc >> 8) & 0x3);
1098 } else {
1099 gfxstolen = 0;
1100 gttsize = 0;
1101 }
1102
1103 tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;
1104
1105 tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];
1106
1107 mestolenbase = tom - me_uma_size;
1108
1109 toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize,
1110 tom - me_uma_size);
1111 gfxstolenbase = toludbase - gfxstolen;
1112 gttbase = gfxstolenbase - gttsize;
1113
1114 tsegbase = gttbase - tsegsize;
1115
1116 // Round tsegbase down to nearest address aligned to tsegsize
1117 tsegbasedelta = tsegbase & (tsegsize - 1);
1118 tsegbase &= ~(tsegsize - 1);
1119
1120 gttbase -= tsegbasedelta;
1121 gfxstolenbase -= tsegbasedelta;
1122 toludbase -= tsegbasedelta;
1123
Elyes HAOUAS15279a92016-07-28 21:05:26 +02001124 // Test if it is possible to reclaim a hole in the RAM addressing
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001125 if (tom - me_uma_size > toludbase) {
1126 // Reclaim is possible
1127 reclaim = 1;
1128 remapbase = MAX(4096, tom - me_uma_size);
1129 remaplimit =
1130 remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
1131 touudbase = remaplimit + 1;
1132 } else {
1133 // Reclaim not possible
1134 reclaim = 0;
1135 touudbase = tom - me_uma_size;
1136 }
1137
1138 // Update memory map in pci-e configuration space
Patrick Rudolpha649a542016-01-17 18:32:06 +01001139 printk(BIOS_DEBUG, "Update PCI-E configuration space:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001140
1141 // TOM (top of memory)
1142 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa0);
1143 val = tom & 0xfff;
1144 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001145 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001146 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa0, reg);
1147
1148 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa4);
1149 val = tom & 0xfffff000;
1150 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001151 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001152 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa4, reg);
1153
1154 // TOLUD (top of low used dram)
1155 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xbc);
1156 val = toludbase & 0xfff;
1157 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001158 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xbc, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001159 pcie_write_config32(PCI_DEV(0, 0, 0), 0xbc, reg);
1160
1161 // TOUUD LSB (top of upper usable dram)
1162 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa8);
1163 val = touudbase & 0xfff;
1164 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001165 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001166 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa8, reg);
1167
1168 // TOUUD MSB
1169 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xac);
1170 val = touudbase & 0xfffff000;
1171 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001172 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xac, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001173 pcie_write_config32(PCI_DEV(0, 0, 0), 0xac, reg);
1174
1175 if (reclaim) {
1176 // REMAP BASE
1177 pcie_write_config32(PCI_DEV(0, 0, 0), 0x90, remapbase << 20);
1178 pcie_write_config32(PCI_DEV(0, 0, 0), 0x94, remapbase >> 12);
1179
1180 // REMAP LIMIT
1181 pcie_write_config32(PCI_DEV(0, 0, 0), 0x98, remaplimit << 20);
1182 pcie_write_config32(PCI_DEV(0, 0, 0), 0x9c, remaplimit >> 12);
1183 }
1184 // TSEG
1185 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb8);
1186 val = tsegbase & 0xfff;
1187 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001188 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001189 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb8, reg);
1190
1191 // GFX stolen memory
1192 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb0);
1193 val = gfxstolenbase & 0xfff;
1194 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001195 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001196 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb0, reg);
1197
1198 // GTT stolen memory
1199 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb4);
1200 val = gttbase & 0xfff;
1201 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001202 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001203 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb4, reg);
1204
1205 if (me_uma_size) {
1206 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x7c);
1207 val = (0x80000 - me_uma_size) & 0xfffff000;
1208 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001209 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x7c, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001210 pcie_write_config32(PCI_DEV(0, 0, 0), 0x7c, reg);
1211
1212 // ME base
1213 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x70);
1214 val = mestolenbase & 0xfff;
1215 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001216 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x70, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001217 pcie_write_config32(PCI_DEV(0, 0, 0), 0x70, reg);
1218
1219 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x74);
1220 val = mestolenbase & 0xfffff000;
1221 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001222 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x74, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001223 pcie_write_config32(PCI_DEV(0, 0, 0), 0x74, reg);
1224
1225 // ME mask
1226 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x78);
1227 val = (0x80000 - me_uma_size) & 0xfff;
1228 reg = (reg & ~0xfff00000) | (val << 20);
1229 reg = (reg & ~0x400) | (1 << 10); // set lockbit on ME mem
1230
1231 reg = (reg & ~0x800) | (1 << 11); // set ME memory enable
Patrick Rudolpha649a542016-01-17 18:32:06 +01001232 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x78, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001233 pcie_write_config32(PCI_DEV(0, 0, 0), 0x78, reg);
1234 }
1235}
1236
1237static void dram_ioregs(ramctr_timing * ctrl)
1238{
1239 u32 reg, comp2;
1240
1241 int channel;
1242
1243 // IO clock
1244 FOR_ALL_CHANNELS {
1245 MCHBAR32(0xc00 + 0x100 * channel) = ctrl->rankmap[channel];
1246 }
1247
1248 // IO command
1249 FOR_ALL_CHANNELS {
1250 MCHBAR32(0x3200 + 0x100 * channel) = ctrl->rankmap[channel];
1251 }
1252
1253 // IO control
1254 FOR_ALL_POPULATED_CHANNELS {
1255 program_timings(ctrl, channel);
1256 }
1257
1258 // Rcomp
Patrick Rudolpha649a542016-01-17 18:32:06 +01001259 printram("RCOMP...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001260 reg = 0;
1261 while (reg == 0) {
1262 reg = MCHBAR32(0x5084) & 0x10000;
1263 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001264 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001265
1266 // Set comp2
1267 comp2 = get_COMP2(ctrl->tCK);
1268 MCHBAR32(0x3714) = comp2;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001269 printram("COMP2 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001270
1271 // Set comp1
1272 FOR_ALL_POPULATED_CHANNELS {
1273 reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
1274 reg = (reg & ~0xe00) | (1 << 9); //odt
1275 reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
1276 reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
1277 MCHBAR32(0x1810 + channel * 0x100) = reg;
1278 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001279 printram("COMP1 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001280
Patrick Rudolpha649a542016-01-17 18:32:06 +01001281 printram("FORCE RCOMP and wait 20us...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001282 MCHBAR32(0x5f08) |= 0x100;
1283 udelay(20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001284 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001285}
1286
1287static void wait_428c(int channel)
1288{
1289 while (1) {
1290 if (read32(DEFAULT_MCHBAR + 0x428c + (channel << 10)) & 0x50)
1291 return;
1292 }
1293}
1294
1295static void write_reset(ramctr_timing * ctrl)
1296{
1297 int channel, slotrank;
1298
1299 /* choose a populated channel. */
1300 channel = (ctrl->rankmap[0]) ? 0 : 1;
1301
1302 wait_428c(channel);
1303
1304 /* choose a populated rank. */
1305 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
1306
Patrick Rudolph371d2912015-10-09 13:33:25 +02001307 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001308 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1309 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x80c01);
1310
1311 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1312 (slotrank << 24) | 0x60000);
1313
1314 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1315
1316 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x400001);
1317 wait_428c(channel);
1318}
1319
1320static void dram_jedecreset(ramctr_timing * ctrl)
1321{
1322 u32 reg, addr;
1323 int channel;
1324
1325 while (!(MCHBAR32(0x5084) & 0x10000)) ;
1326 do {
1327 reg = MCHBAR32(0x428c);
1328 } while ((reg & 0x14) == 0);
1329
1330 // Set state of memory controller
1331 reg = 0x112;
1332 MCHBAR32(0x5030) = reg;
1333 MCHBAR32(0x4ea0) = 0;
1334 reg |= 2; //ddr reset
1335 MCHBAR32(0x5030) = reg;
1336
1337 // Assert dimm reset signal
1338 reg = MCHBAR32(0x5030);
1339 reg &= ~0x2;
1340 MCHBAR32(0x5030) = reg;
1341
1342 // Wait 200us
1343 udelay(200);
1344
1345 // Deassert dimm reset signal
1346 MCHBAR32(0x5030) |= 2;
1347
1348 // Wait 500us
1349 udelay(500);
1350
1351 // Enable DCLK
1352 MCHBAR32(0x5030) |= 4;
1353
1354 // XXX Wait 20ns
1355 udelay(1);
1356
1357 FOR_ALL_CHANNELS {
1358 // Set valid rank CKE
1359 reg = 0;
1360 reg = (reg & ~0xf) | ctrl->rankmap[channel];
1361 addr = 0x400 * channel + 0x42a0;
1362 MCHBAR32(addr) = reg;
1363
1364 // Wait 10ns for ranks to settle
1365 //udelay(0.01);
1366
1367 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
1368 MCHBAR32(addr) = reg;
1369
1370 // Write reset using a NOP
1371 write_reset(ctrl);
1372 }
1373}
1374
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001375static odtmap get_ODT(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001376{
1377 /* Get ODT based on rankmap: */
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001378 int dimms_per_ch = (ctrl->rankmap[channel] & 1)
1379 + ((ctrl->rankmap[channel] >> 2) & 1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001380
1381 if (dimms_per_ch == 1) {
1382 return (const odtmap){60, 60};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001383 } else {
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001384 return (const odtmap){120, 30};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001385 }
1386}
1387
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001388static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001389 int reg, u32 val)
1390{
1391 wait_428c(channel);
1392
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001393 if (ctrl->rank_mirror[channel][slotrank]) {
1394 /* DDR3 Rank1 Address mirror
1395 * swap the following pins:
1396 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1 */
1397 reg = ((reg >> 1) & 1) | ((reg << 1) & 2);
1398 val = (val & ~0x1f8) | ((val >> 1) & 0xa8)
1399 | ((val & 0xa8) << 1);
1400 }
1401
Patrick Rudolph371d2912015-10-09 13:33:25 +02001402 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001403 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
1404 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
1405 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1406 (slotrank << 24) | (reg << 20) | val | 0x60000);
1407 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1408
Patrick Rudolph371d2912015-10-09 13:33:25 +02001409 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001410 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
1411 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
1412 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
1413 (slotrank << 24) | (reg << 20) | val | 0x60000);
1414 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1415
Patrick Rudolph371d2912015-10-09 13:33:25 +02001416 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001417 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
1418 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1419 0x1001 | (ctrl->tMOD << 16));
1420 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1421 (slotrank << 24) | (reg << 20) | val | 0x60000);
1422 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1423 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
1424}
1425
1426static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
1427{
1428 u16 mr0reg, mch_cas, mch_wr;
1429 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 +02001430
1431 /* DLL Reset - self clearing - set after CLK frequency has been changed */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001432 mr0reg = 0x100;
1433
1434 // Convert CAS to MCH register friendly
1435 if (ctrl->CAS < 12) {
1436 mch_cas = (u16) ((ctrl->CAS - 4) << 1);
1437 } else {
1438 mch_cas = (u16) (ctrl->CAS - 12);
1439 mch_cas = ((mch_cas << 1) | 0x1);
1440 }
1441
1442 // Convert tWR to MCH register friendly
1443 mch_wr = mch_wr_t[ctrl->tWR - 5];
1444
1445 mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
1446 mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
1447 mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001448
1449 // Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001450 mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
1451 return mr0reg;
1452}
1453
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001454static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001455{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001456 write_mrreg(ctrl, channel, rank, 0,
1457 make_mr0(ctrl, rank));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001458}
1459
1460static u32 encode_odt(u32 odt)
1461{
1462 switch (odt) {
1463 case 30:
1464 return (1 << 9) | (1 << 2); // RZQ/8, RZQ/4
1465 case 60:
1466 return (1 << 2); // RZQ/4
1467 case 120:
1468 return (1 << 6); // RZQ/2
1469 default:
1470 case 0:
1471 return 0;
1472 }
1473}
1474
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001475static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001476{
1477 odtmap odt;
1478 u32 mr1reg;
1479
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001480 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001481 mr1reg = 0x2;
1482
1483 mr1reg |= encode_odt(odt.rttnom);
1484
1485 return mr1reg;
1486}
1487
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001488static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001489{
1490 u16 mr1reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001491
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001492 mr1reg = make_mr1(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001493
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001494 write_mrreg(ctrl, channel, rank, 1, mr1reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001495}
1496
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001497static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001498{
1499 u16 pasr, cwl, mr2reg;
1500 odtmap odt;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001501 int srt;
1502
1503 pasr = 0;
1504 cwl = ctrl->CWL - 5;
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001505 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001506
1507 srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;
1508
1509 mr2reg = 0;
1510 mr2reg = (mr2reg & ~0x7) | pasr;
1511 mr2reg = (mr2reg & ~0x38) | (cwl << 3);
1512 mr2reg = (mr2reg & ~0x40) | (ctrl->auto_self_refresh << 6);
1513 mr2reg = (mr2reg & ~0x80) | (srt << 7);
1514 mr2reg |= (odt.rttwr / 60) << 9;
1515
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001516 write_mrreg(ctrl, channel, rank, 2, mr2reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001517}
1518
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001519static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001520{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001521 write_mrreg(ctrl, channel, rank, 3, 0);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001522}
1523
1524static void dram_mrscommands(ramctr_timing * ctrl)
1525{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001526 u8 slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001527 u32 reg, addr;
1528 int channel;
1529
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001530 FOR_ALL_POPULATED_CHANNELS {
1531 FOR_ALL_POPULATED_RANKS {
1532 // MR2
1533 dram_mr2(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001534
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001535 // MR3
1536 dram_mr3(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001537
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001538 // MR1
1539 dram_mr1(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001540
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001541 // MR0
1542 dram_mr0(ctrl, slotrank, channel);
1543 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001544 }
1545
Patrick Rudolph371d2912015-10-09 13:33:25 +02001546 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001547 write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
1548 write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
1549 write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
1550 write32(DEFAULT_MCHBAR + 0x4e10, 0);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001551
1552 /* DRAM command ZQCL */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001553 write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
1554 write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
1555 write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
1556 write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001557
1558 /* execute command queue on all channels ? */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001559 write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
1560
1561 // Drain
1562 FOR_ALL_CHANNELS {
1563 // Wait for ref drained
1564 wait_428c(channel);
1565 }
1566
1567 // Refresh enable
1568 MCHBAR32(0x5030) |= 8;
1569
1570 FOR_ALL_POPULATED_CHANNELS {
1571 addr = 0x400 * channel + 0x4020;
1572 reg = MCHBAR32(addr);
1573 reg &= ~0x200000;
1574 MCHBAR32(addr) = reg;
1575
1576 wait_428c(channel);
1577
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001578 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001579
1580 // Drain
1581 wait_428c(channel);
1582
Patrick Rudolph371d2912015-10-09 13:33:25 +02001583 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001584 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1585 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
1586 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001587 (slotrank << 24) | 0x60000);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001588 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
1589 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x1);
1590
1591 // Drain
1592 wait_428c(channel);
1593 }
1594}
1595
1596const u32 lane_registers[] = {
1597 0x0000, 0x0200, 0x0400, 0x0600,
1598 0x1000, 0x1200, 0x1400, 0x1600,
1599 0x0800
1600};
1601
1602static void program_timings(ramctr_timing * ctrl, int channel)
1603{
1604 u32 reg32, reg_4024, reg_c14, reg_c18, reg_4028;
1605 int lane;
1606 int slotrank, slot;
1607 int full_shift = 0;
1608 u16 slot320c[NUM_SLOTS];
1609
1610 FOR_ALL_POPULATED_RANKS {
1611 if (full_shift < -ctrl->timings[channel][slotrank].val_320c)
1612 full_shift = -ctrl->timings[channel][slotrank].val_320c;
1613 }
1614
1615 for (slot = 0; slot < NUM_SLOTS; slot++)
1616 switch ((ctrl->rankmap[channel] >> (2 * slot)) & 3) {
1617 case 0:
1618 default:
1619 slot320c[slot] = 0x7f;
1620 break;
1621 case 1:
1622 slot320c[slot] =
1623 ctrl->timings[channel][2 * slot + 0].val_320c +
1624 full_shift;
1625 break;
1626 case 2:
1627 slot320c[slot] =
1628 ctrl->timings[channel][2 * slot + 1].val_320c +
1629 full_shift;
1630 break;
1631 case 3:
1632 slot320c[slot] =
1633 (ctrl->timings[channel][2 * slot].val_320c +
1634 ctrl->timings[channel][2 * slot +
1635 1].val_320c) / 2 +
1636 full_shift;
1637 break;
1638 }
1639
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001640 /* enable CMD XOVER */
1641 reg32 = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001642 reg32 |= ((slot320c[0] & 0x3f) << 6) | ((slot320c[0] & 0x40) << 9);
1643 reg32 |= (slot320c[1] & 0x7f) << 18;
1644 reg32 |= (full_shift & 0x3f) | ((full_shift & 0x40) << 6);
1645
1646 MCHBAR32(0x320c + 0x100 * channel) = reg32;
1647
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001648 /* enable CLK XOVER */
1649 reg_c14 = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001650 reg_c18 = 0;
1651
1652 FOR_ALL_POPULATED_RANKS {
1653 int shift =
1654 ctrl->timings[channel][slotrank].val_320c + full_shift;
1655 int offset_val_c14;
1656 if (shift < 0)
1657 shift = 0;
1658 offset_val_c14 = ctrl->reg_c14_offset + shift;
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001659 /* set CLK phase shift */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001660 reg_c14 |= (offset_val_c14 & 0x3f) << (6 * slotrank);
1661 reg_c18 |= ((offset_val_c14 >> 6) & 1) << slotrank;
1662 }
1663
1664 MCHBAR32(0xc14 + channel * 0x100) = reg_c14;
1665 MCHBAR32(0xc18 + channel * 0x100) = reg_c18;
1666
1667 reg_4028 = MCHBAR32(0x4028 + 0x400 * channel);
1668 reg_4028 &= 0xffff0000;
1669
1670 reg_4024 = 0;
1671
1672 FOR_ALL_POPULATED_RANKS {
1673 int post_timA_min_high = 7, post_timA_max_high = 0;
1674 int pre_timA_min_high = 7, pre_timA_max_high = 0;
1675 int shift_402x = 0;
1676 int shift =
1677 ctrl->timings[channel][slotrank].val_320c + full_shift;
1678
1679 if (shift < 0)
1680 shift = 0;
1681
1682 FOR_ALL_LANES {
1683 if (post_timA_min_high >
1684 ((ctrl->timings[channel][slotrank].lanes[lane].
1685 timA + shift) >> 6))
1686 post_timA_min_high =
1687 ((ctrl->timings[channel][slotrank].
1688 lanes[lane].timA + shift) >> 6);
1689 if (pre_timA_min_high >
1690 (ctrl->timings[channel][slotrank].lanes[lane].
1691 timA >> 6))
1692 pre_timA_min_high =
1693 (ctrl->timings[channel][slotrank].
1694 lanes[lane].timA >> 6);
1695 if (post_timA_max_high <
1696 ((ctrl->timings[channel][slotrank].lanes[lane].
1697 timA + shift) >> 6))
1698 post_timA_max_high =
1699 ((ctrl->timings[channel][slotrank].
1700 lanes[lane].timA + shift) >> 6);
1701 if (pre_timA_max_high <
1702 (ctrl->timings[channel][slotrank].lanes[lane].
1703 timA >> 6))
1704 pre_timA_max_high =
1705 (ctrl->timings[channel][slotrank].
1706 lanes[lane].timA >> 6);
1707 }
1708
1709 if (pre_timA_max_high - pre_timA_min_high <
1710 post_timA_max_high - post_timA_min_high)
1711 shift_402x = +1;
1712 else if (pre_timA_max_high - pre_timA_min_high >
1713 post_timA_max_high - post_timA_min_high)
1714 shift_402x = -1;
1715
1716 reg_4028 |=
1717 (ctrl->timings[channel][slotrank].val_4028 + shift_402x -
1718 post_timA_min_high) << (4 * slotrank);
1719 reg_4024 |=
1720 (ctrl->timings[channel][slotrank].val_4024 +
1721 shift_402x) << (8 * slotrank);
1722
1723 FOR_ALL_LANES {
1724 MCHBAR32(lane_registers[lane] + 0x10 + 0x100 * channel +
1725 4 * slotrank)
1726 =
1727 (((ctrl->timings[channel][slotrank].lanes[lane].
1728 timA + shift) & 0x3f)
1729 |
1730 ((ctrl->timings[channel][slotrank].lanes[lane].
1731 rising + shift) << 8)
1732 |
1733 (((ctrl->timings[channel][slotrank].lanes[lane].
1734 timA + shift -
1735 (post_timA_min_high << 6)) & 0x1c0) << 10)
Patrick Rudolph0188b132016-02-10 19:16:34 +01001736 | ((ctrl->timings[channel][slotrank].lanes[lane].
1737 falling + shift) << 20));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001738
1739 MCHBAR32(lane_registers[lane] + 0x20 + 0x100 * channel +
1740 4 * slotrank)
1741 =
1742 (((ctrl->timings[channel][slotrank].lanes[lane].
1743 timC + shift) & 0x3f)
1744 |
1745 (((ctrl->timings[channel][slotrank].lanes[lane].
1746 timB + shift) & 0x3f) << 8)
1747 |
1748 (((ctrl->timings[channel][slotrank].lanes[lane].
1749 timB + shift) & 0x1c0) << 9)
1750 |
1751 (((ctrl->timings[channel][slotrank].lanes[lane].
1752 timC + shift) & 0x40) << 13));
1753 }
1754 }
1755 MCHBAR32(0x4024 + 0x400 * channel) = reg_4024;
1756 MCHBAR32(0x4028 + 0x400 * channel) = reg_4028;
1757}
1758
1759static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
1760{
1761 wait_428c(channel);
1762
Patrick Rudolph371d2912015-10-09 13:33:25 +02001763 /* DRAM command MRS
1764 * write MR3 MPR enable
1765 * in this mode only RD and RDA are allowed
1766 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001767 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
1768 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1769 (0xc01 | (ctrl->tMOD << 16)));
1770 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1771 (slotrank << 24) | 0x360004);
1772 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1773
Patrick Rudolph371d2912015-10-09 13:33:25 +02001774 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001775 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
1776 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
1777 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
1778 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1779
Patrick Rudolph371d2912015-10-09 13:33:25 +02001780 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001781 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
1782 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1783 0x100f | ((ctrl->CAS + 36) << 16));
1784 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1785 (slotrank << 24) | 0x60000);
1786 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1787
Patrick Rudolph371d2912015-10-09 13:33:25 +02001788 /* DRAM command MRS
1789 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001790 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
1791 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
1792 (0xc01 | (ctrl->tMOD << 16)));
1793 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
1794 (slotrank << 24) | 0x360000);
1795 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
1796
1797 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
1798
1799 wait_428c(channel);
1800}
1801
1802static int does_lane_work(ramctr_timing * ctrl, int channel, int slotrank,
1803 int lane)
1804{
1805 u32 timA = ctrl->timings[channel][slotrank].lanes[lane].timA;
1806 return ((read32
1807 (DEFAULT_MCHBAR + lane_registers[lane] + channel * 0x100 + 4 +
1808 ((timA / 32) & 1) * 4)
1809 >> (timA % 32)) & 1);
1810}
1811
1812struct run {
1813 int middle;
1814 int end;
1815 int start;
1816 int all;
1817 int length;
1818};
1819
1820static struct run get_longest_zero_run(int *seq, int sz)
1821{
1822 int i, ls;
1823 int bl = 0, bs = 0;
1824 struct run ret;
1825
1826 ls = 0;
1827 for (i = 0; i < 2 * sz; i++)
1828 if (seq[i % sz]) {
1829 if (i - ls > bl) {
1830 bl = i - ls;
1831 bs = ls;
1832 }
1833 ls = i + 1;
1834 }
1835 if (bl == 0) {
1836 ret.middle = sz / 2;
1837 ret.start = 0;
1838 ret.end = sz;
1839 ret.all = 1;
1840 return ret;
1841 }
1842
1843 ret.start = bs % sz;
1844 ret.end = (bs + bl - 1) % sz;
1845 ret.middle = (bs + (bl - 1) / 2) % sz;
1846 ret.length = bl;
1847 ret.all = 0;
1848
1849 return ret;
1850}
1851
1852static void discover_timA_coarse(ramctr_timing * ctrl, int channel,
1853 int slotrank, int *upperA)
1854{
1855 int timA;
1856 int statistics[NUM_LANES][128];
1857 int lane;
1858
1859 for (timA = 0; timA < 128; timA++) {
1860 FOR_ALL_LANES {
1861 ctrl->timings[channel][slotrank].lanes[lane].timA = timA;
1862 }
1863 program_timings(ctrl, channel);
1864
1865 test_timA(ctrl, channel, slotrank);
1866
1867 FOR_ALL_LANES {
1868 statistics[lane][timA] =
1869 !does_lane_work(ctrl, channel, slotrank, lane);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001870 printram("Astat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001871 channel, slotrank, lane, timA,
1872 statistics[lane][timA]);
1873 }
1874 }
1875 FOR_ALL_LANES {
1876 struct run rn = get_longest_zero_run(statistics[lane], 128);
1877 ctrl->timings[channel][slotrank].lanes[lane].timA = rn.middle;
1878 upperA[lane] = rn.end;
1879 if (upperA[lane] < rn.middle)
1880 upperA[lane] += 128;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001881 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001882 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001883 printram("Aend: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001884 lane, upperA[lane]);
1885 }
1886}
1887
1888static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
1889 int *upperA)
1890{
1891 int timA_delta;
1892 int statistics[NUM_LANES][51];
1893 int lane, i;
1894
1895 memset(statistics, 0, sizeof(statistics));
1896
1897 for (timA_delta = -25; timA_delta <= 25; timA_delta++) {
1898 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
1899 timA = upperA[lane] + timA_delta + 0x40;
1900 program_timings(ctrl, channel);
1901
1902 for (i = 0; i < 100; i++) {
1903 test_timA(ctrl, channel, slotrank);
1904 FOR_ALL_LANES {
1905 statistics[lane][timA_delta + 25] +=
1906 does_lane_work(ctrl, channel, slotrank,
1907 lane);
1908 }
1909 }
1910 }
1911 FOR_ALL_LANES {
1912 int last_zero, first_all;
1913
1914 for (last_zero = -25; last_zero <= 25; last_zero++)
1915 if (statistics[lane][last_zero + 25])
1916 break;
1917 last_zero--;
1918 for (first_all = -25; first_all <= 25; first_all++)
1919 if (statistics[lane][first_all + 25] == 100)
1920 break;
1921
1922 printram("lane %d: %d, %d\n", lane, last_zero,
1923 first_all);
1924
1925 ctrl->timings[channel][slotrank].lanes[lane].timA =
1926 (last_zero + first_all) / 2 + upperA[lane];
Patrick Rudolpha649a542016-01-17 18:32:06 +01001927 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001928 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1929 }
1930}
1931
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001932static int discover_402x(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001933 int *upperA)
1934{
1935 int works[NUM_LANES];
1936 int lane;
1937 while (1) {
1938 int all_works = 1, some_works = 0;
1939 program_timings(ctrl, channel);
1940 test_timA(ctrl, channel, slotrank);
1941 FOR_ALL_LANES {
1942 works[lane] =
1943 !does_lane_work(ctrl, channel, slotrank, lane);
1944 if (works[lane])
1945 some_works = 1;
1946 else
1947 all_works = 0;
1948 }
1949 if (all_works)
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001950 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001951 if (!some_works) {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001952 if (ctrl->timings[channel][slotrank].val_4024 < 2) {
1953 printk(BIOS_EMERG, "402x discovery failed (1): %d, %d\n",
1954 channel, slotrank);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001955 return MAKE_ERR;
1956 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001957 ctrl->timings[channel][slotrank].val_4024 -= 2;
1958 printram("4024 -= 2;\n");
1959 continue;
1960 }
1961 ctrl->timings[channel][slotrank].val_4028 += 2;
1962 printram("4028 += 2;\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001963 if (ctrl->timings[channel][slotrank].val_4028 >= 0x10) {
1964 printk(BIOS_EMERG, "402x discovery failed (2): %d, %d\n",
1965 channel, slotrank);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001966 return MAKE_ERR;
1967 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001968 FOR_ALL_LANES if (works[lane]) {
1969 ctrl->timings[channel][slotrank].lanes[lane].timA +=
1970 128;
1971 upperA[lane] += 128;
1972 printram("increment %d, %d, %d\n", channel,
1973 slotrank, lane);
1974 }
1975 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001976 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001977}
1978
1979struct timA_minmax {
1980 int timA_min_high, timA_max_high;
1981};
1982
1983static void pre_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1984 struct timA_minmax *mnmx)
1985{
1986 int lane;
1987 mnmx->timA_min_high = 7;
1988 mnmx->timA_max_high = 0;
1989
1990 FOR_ALL_LANES {
1991 if (mnmx->timA_min_high >
1992 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1993 mnmx->timA_min_high =
1994 (ctrl->timings[channel][slotrank].lanes[lane].
1995 timA >> 6);
1996 if (mnmx->timA_max_high <
1997 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1998 mnmx->timA_max_high =
1999 (ctrl->timings[channel][slotrank].lanes[lane].
2000 timA >> 6);
2001 }
2002}
2003
2004static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
2005 struct timA_minmax *mnmx)
2006{
2007 struct timA_minmax post;
2008 int shift_402x = 0;
2009
2010 /* Get changed maxima. */
2011 pre_timA_change(ctrl, channel, slotrank, &post);
2012
2013 if (mnmx->timA_max_high - mnmx->timA_min_high <
2014 post.timA_max_high - post.timA_min_high)
2015 shift_402x = +1;
2016 else if (mnmx->timA_max_high - mnmx->timA_min_high >
2017 post.timA_max_high - post.timA_min_high)
2018 shift_402x = -1;
2019 else
2020 shift_402x = 0;
2021
2022 ctrl->timings[channel][slotrank].val_4028 += shift_402x;
2023 ctrl->timings[channel][slotrank].val_4024 += shift_402x;
2024 printram("4024 += %d;\n", shift_402x);
2025 printram("4028 += %d;\n", shift_402x);
2026}
2027
Patrick Rudolph371d2912015-10-09 13:33:25 +02002028/* Compensate the skew between DQS and DQs.
2029 * To ease PCB design a small skew between Data Strobe signals and
2030 * Data Signals is allowed.
2031 * The controller has to measure and compensate this skew for every byte-lane.
2032 * By delaying either all DQs signals or DQS signal, a full phase
2033 * shift can be introduced.
2034 * It is assumed that one byte-lane's DQs signals have the same routing delay.
2035 *
2036 * To measure the actual skew, the DRAM is placed in "read leveling" mode.
2037 * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
2038 * The memory controller iterates over all possible values to do a full phase shift
2039 * and issues read commands.
2040 * With DQS and DQs in phase the data read is expected to alternate on every byte:
2041 * 0xFF 0x00 0xFF ...
2042 * Once the controller has detected this pattern a bit in the result register is
2043 * set for the current phase shift.
2044 */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002045static int read_training(ramctr_timing * ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002046{
2047 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002048 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002049
2050 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002051 int all_high, some_high;
2052 int upperA[NUM_LANES];
2053 struct timA_minmax mnmx;
2054
2055 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002056
2057 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002058 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2059 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2060 0xc01 | (ctrl->tRP << 16));
2061 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2062 (slotrank << 24) | 0x60400);
2063 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2064 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2065
2066 write32(DEFAULT_MCHBAR + 0x3400, (slotrank << 2) | 0x8001);
2067
2068 ctrl->timings[channel][slotrank].val_4028 = 4;
2069 ctrl->timings[channel][slotrank].val_4024 = 55;
2070 program_timings(ctrl, channel);
2071
2072 discover_timA_coarse(ctrl, channel, slotrank, upperA);
2073
2074 all_high = 1;
2075 some_high = 0;
2076 FOR_ALL_LANES {
2077 if (ctrl->timings[channel][slotrank].lanes[lane].
2078 timA >= 0x40)
2079 some_high = 1;
2080 else
2081 all_high = 0;
2082 }
2083
2084 if (all_high) {
2085 ctrl->timings[channel][slotrank].val_4028--;
2086 printram("4028--;\n");
2087 FOR_ALL_LANES {
2088 ctrl->timings[channel][slotrank].lanes[lane].
2089 timA -= 0x40;
2090 upperA[lane] -= 0x40;
2091
2092 }
2093 } else if (some_high) {
2094 ctrl->timings[channel][slotrank].val_4024++;
2095 ctrl->timings[channel][slotrank].val_4028++;
2096 printram("4024++;\n");
2097 printram("4028++;\n");
2098 }
2099
2100 program_timings(ctrl, channel);
2101
2102 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2103
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002104 err = discover_402x(ctrl, channel, slotrank, upperA);
2105 if (err)
2106 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002107
2108 post_timA_change(ctrl, channel, slotrank, &mnmx);
2109 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2110
2111 discover_timA_fine(ctrl, channel, slotrank, upperA);
2112
2113 post_timA_change(ctrl, channel, slotrank, &mnmx);
2114 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2115
2116 FOR_ALL_LANES {
2117 ctrl->timings[channel][slotrank].lanes[lane].timA -= mnmx.timA_min_high * 0x40;
2118 }
2119 ctrl->timings[channel][slotrank].val_4028 -= mnmx.timA_min_high;
2120 printram("4028 -= %d;\n", mnmx.timA_min_high);
2121
2122 post_timA_change(ctrl, channel, slotrank, &mnmx);
2123
2124 printram("4/8: %d, %d, %x, %x\n", channel, slotrank,
2125 ctrl->timings[channel][slotrank].val_4024,
2126 ctrl->timings[channel][slotrank].val_4028);
2127
Patrick Rudolpha649a542016-01-17 18:32:06 +01002128 printram("final results:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002129 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01002130 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002131 lane,
2132 ctrl->timings[channel][slotrank].lanes[lane].timA);
2133
2134 write32(DEFAULT_MCHBAR + 0x3400, 0);
2135
Patrick Rudolph9b515682015-10-09 13:43:51 +02002136 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002137 }
2138
2139 FOR_ALL_POPULATED_CHANNELS {
2140 program_timings(ctrl, channel);
2141 }
2142 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2143 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
2144 + 4 * lane, 0);
2145 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002146 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002147}
2148
2149static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
2150{
2151 int lane;
2152
2153 FOR_ALL_LANES {
2154 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel + 4 * lane, 0);
2155 read32(DEFAULT_MCHBAR + 0x4140 + 0x400 * channel + 4 * lane);
2156 }
2157
2158 wait_428c(channel);
2159
Patrick Rudolph371d2912015-10-09 13:33:25 +02002160 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002161 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2162 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2163 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
2164 | 4 | (ctrl->tRCD << 16));
2165
2166 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2167 (slotrank << 24) | (6 << 16));
2168
2169 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
2170
Patrick Rudolph371d2912015-10-09 13:33:25 +02002171 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002172 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2173 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
2174 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2175 (slotrank << 24) | 8);
2176 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2177
Patrick Rudolph371d2912015-10-09 13:33:25 +02002178 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002179 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2180 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
2181 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2182 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2183
Patrick Rudolph371d2912015-10-09 13:33:25 +02002184 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002185 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2186 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2187 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2188 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2189 (slotrank << 24) | 8);
2190 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2191
2192 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2193
2194 wait_428c(channel);
2195
Patrick Rudolph371d2912015-10-09 13:33:25 +02002196 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002197 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2198 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2199 0xc01 | (ctrl->tRP << 16));
2200 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2201 (slotrank << 24) | 0x60400);
2202 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2203
Patrick Rudolph371d2912015-10-09 13:33:25 +02002204 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002205 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2206 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2207 (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
2208 | 8 | (ctrl->CAS << 16));
2209
2210 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2211 (slotrank << 24) | 0x60000);
2212
2213 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
2214
Patrick Rudolph371d2912015-10-09 13:33:25 +02002215 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002216 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2217 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2218 0x40011f4 | (max(ctrl->tRTP, 8) << 16));
2219 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2220 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2221
Patrick Rudolph371d2912015-10-09 13:33:25 +02002222 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002223 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2224 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2225 0xc01 | (ctrl->tRP << 16));
2226 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2227 (slotrank << 24) | 0x60400);
2228 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2229 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2230 wait_428c(channel);
2231}
2232
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002233static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002234{
2235 int timC;
2236 int statistics[NUM_LANES][MAX_TIMC + 1];
2237 int lane;
2238
2239 wait_428c(channel);
2240
Patrick Rudolph371d2912015-10-09 13:33:25 +02002241 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002242 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2243 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2244 0xc01 | (ctrl->tRP << 16));
2245 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2246 (slotrank << 24) | 0x60400);
2247 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2248 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2249
2250 for (timC = 0; timC <= MAX_TIMC; timC++) {
2251 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
2252 timC = timC;
2253 program_timings(ctrl, channel);
2254
2255 test_timC(ctrl, channel, slotrank);
2256
2257 FOR_ALL_LANES {
2258 statistics[lane][timC] =
2259 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2260 0x400 * channel);
2261 printram("Cstat: %d, %d, %d, %x, %x\n",
2262 channel, slotrank, lane, timC,
2263 statistics[lane][timC]);
2264 }
2265 }
2266 FOR_ALL_LANES {
2267 struct run rn =
2268 get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
2269 ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002270 if (rn.all) {
2271 printk(BIOS_EMERG, "timC discovery failed: %d, %d, %d\n",
2272 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002273 return MAKE_ERR;
2274 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01002275 printram("Cval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002276 lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
2277 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002278 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002279}
2280
2281static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
2282{
2283 int channel, ret = 0;
2284 FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
2285 ret++;
2286 return ret;
2287}
2288
2289static void fill_pattern0(ramctr_timing * ctrl, int channel, u32 a, u32 b)
2290{
2291 unsigned j;
2292 unsigned channel_offset =
2293 get_precedening_channels(ctrl, channel) * 0x40;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002294 for (j = 0; j < 16; j++)
2295 write32((void *)(0x04000000 + channel_offset + 4 * j), j & 2 ? b : a);
2296 sfence();
2297}
2298
2299static int num_of_channels(const ramctr_timing * ctrl)
2300{
2301 int ret = 0;
2302 int channel;
2303 FOR_ALL_POPULATED_CHANNELS ret++;
2304 return ret;
2305}
2306
2307static void fill_pattern1(ramctr_timing * ctrl, int channel)
2308{
2309 unsigned j;
2310 unsigned channel_offset =
2311 get_precedening_channels(ctrl, channel) * 0x40;
2312 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2313 for (j = 0; j < 16; j++)
2314 write32((void *)(0x04000000 + channel_offset + j * 4), 0xffffffff);
2315 for (j = 0; j < 16; j++)
2316 write32((void *)(0x04000000 + channel_offset + channel_step + j * 4), 0);
2317 sfence();
2318}
2319
2320static void precharge(ramctr_timing * ctrl)
2321{
2322 int channel, slotrank, lane;
2323
2324 FOR_ALL_POPULATED_CHANNELS {
2325 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2326 ctrl->timings[channel][slotrank].lanes[lane].falling =
2327 16;
2328 ctrl->timings[channel][slotrank].lanes[lane].rising =
2329 16;
Patrick Rudolpha649a542016-01-17 18:32:06 +01002330 }
2331
2332 program_timings(ctrl, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002333
2334 FOR_ALL_POPULATED_RANKS {
2335 wait_428c(channel);
2336
Patrick Rudolph371d2912015-10-09 13:33:25 +02002337 /* DRAM command MRS
2338 * write MR3 MPR enable
2339 * in this mode only RD and RDA are allowed
2340 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002341 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2342 0x1f000);
2343 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2344 0xc01 | (ctrl->tMOD << 16));
2345 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2346 (slotrank << 24) | 0x360004);
2347 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2348
Patrick Rudolph371d2912015-10-09 13:33:25 +02002349 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002350 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2351 0x1f105);
2352 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2353 0x4041003);
2354 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2355 (slotrank << 24) | 0);
2356 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2357
Patrick Rudolph371d2912015-10-09 13:33:25 +02002358 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002359 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2360 0x1f105);
2361 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2362 0x1001 | ((ctrl->CAS + 8) << 16));
2363 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2364 (slotrank << 24) | 0x60000);
2365 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2366
Patrick Rudolph371d2912015-10-09 13:33:25 +02002367 /* DRAM command MRS
2368 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002369 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2370 0x1f000);
2371 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2372 0xc01 | (ctrl->tMOD << 16));
2373 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2374 (slotrank << 24) | 0x360000);
2375 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2376 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2377 0xc0001);
2378
2379 wait_428c(channel);
2380 }
2381
2382 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2383 ctrl->timings[channel][slotrank].lanes[lane].falling =
2384 48;
2385 ctrl->timings[channel][slotrank].lanes[lane].rising =
2386 48;
2387 }
2388
2389 program_timings(ctrl, channel);
2390
2391 FOR_ALL_POPULATED_RANKS {
2392 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002393 /* DRAM command MRS
2394 * write MR3 MPR enable
2395 * in this mode only RD and RDA are allowed
2396 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002397 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2398 0x1f000);
2399 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2400 0xc01 | (ctrl->tMOD << 16));
2401 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2402 (slotrank << 24) | 0x360004);
2403 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2404
Patrick Rudolph371d2912015-10-09 13:33:25 +02002405 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002406 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2407 0x1f105);
2408 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2409 0x4041003);
2410 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2411 (slotrank << 24) | 0);
2412 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2413
Patrick Rudolph371d2912015-10-09 13:33:25 +02002414 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002415 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2416 0x1f105);
2417 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2418 0x1001 | ((ctrl->CAS + 8) << 16));
2419 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2420 (slotrank << 24) | 0x60000);
2421 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2422
Patrick Rudolph371d2912015-10-09 13:33:25 +02002423 /* DRAM command MRS
2424 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002425 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2426 0x1f000);
2427 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2428 0xc01 | (ctrl->tMOD << 16));
2429
2430 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2431 (slotrank << 24) | 0x360000);
2432 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2433
2434 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2435 0xc0001);
2436 wait_428c(channel);
2437 }
2438 }
2439}
2440
2441static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
2442{
Patrick Rudolph371d2912015-10-09 13:33:25 +02002443 /* enable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002444 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002445 0x80 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002446
2447 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002448 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002449 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
2450 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2451 0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
2452 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2453 8 | (slotrank << 24));
2454 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2455
Patrick Rudolph371d2912015-10-09 13:33:25 +02002456 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002457 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
2458 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2459 0x4000c01 | ((ctrl->CAS + 38) << 16));
2460 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2461 (slotrank << 24) | 4);
2462 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2463
2464 write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
2465 wait_428c(channel);
2466
Patrick Rudolph371d2912015-10-09 13:33:25 +02002467 /* disable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002468 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002469 0x1080 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002470}
2471
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002472static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002473{
2474 int timB;
2475 int statistics[NUM_LANES][128];
2476 int lane;
2477
2478 write32(DEFAULT_MCHBAR + 0x3400, 0x108052 | (slotrank << 2));
2479
2480 for (timB = 0; timB < 128; timB++) {
2481 FOR_ALL_LANES {
2482 ctrl->timings[channel][slotrank].lanes[lane].timB = timB;
2483 }
2484 program_timings(ctrl, channel);
2485
2486 test_timB(ctrl, channel, slotrank);
2487
2488 FOR_ALL_LANES {
2489 statistics[lane][timB] =
2490 !((read32
2491 (DEFAULT_MCHBAR + lane_registers[lane] +
2492 channel * 0x100 + 4 + ((timB / 32) & 1) * 4)
2493 >> (timB % 32)) & 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002494 printram("Bstat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002495 channel, slotrank, lane, timB,
2496 statistics[lane][timB]);
2497 }
2498 }
2499 FOR_ALL_LANES {
2500 struct run rn = get_longest_zero_run(statistics[lane], 128);
Patrick Rudolphd912f1d2016-02-15 20:07:42 +01002501 /* timC is a direct function of timB's 6 LSBs.
2502 * Some tests increments the value of timB by a small value,
2503 * which might cause the 6bit value to overflow, if it's close
2504 * to 0x3F. Increment the value by a small offset if it's likely
2505 * to overflow, to make sure it won't overflow while running
2506 * tests and bricks the system due to a non matching timC.
2507 *
2508 * TODO: find out why some tests (edge write discovery)
2509 * increment timB. */
2510 if ((rn.start & 0x3F) == 0x3E)
2511 rn.start += 2;
2512 else if ((rn.start & 0x3F) == 0x3F)
2513 rn.start += 1;
Vladimir Serbinenko3141eac2016-01-29 19:42:02 +01002514 ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002515 if (rn.all) {
2516 printk(BIOS_EMERG, "timB discovery failed: %d, %d, %d\n",
2517 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002518 return MAKE_ERR;
2519 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01002520 printram("Bval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002521 lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
2522 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002523 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002524}
2525
2526static int get_timB_high_adjust(u64 val)
2527{
2528 int i;
2529
2530 /* good */
2531 if (val == 0xffffffffffffffffLL)
2532 return 0;
2533
2534 if (val >= 0xf000000000000000LL) {
2535 /* needs negative adjustment */
2536 for (i = 0; i < 8; i++)
2537 if (val << (8 * (7 - i) + 4))
2538 return -i;
2539 } else {
2540 /* needs positive adjustment */
2541 for (i = 0; i < 8; i++)
2542 if (val >> (8 * (7 - i) + 4))
2543 return i;
2544 }
2545 return 8;
2546}
2547
2548static void adjust_high_timB(ramctr_timing * ctrl)
2549{
2550 int channel, slotrank, lane, old;
2551 write32(DEFAULT_MCHBAR + 0x3400, 0x200);
2552 FOR_ALL_POPULATED_CHANNELS {
2553 fill_pattern1(ctrl, channel);
2554 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 1);
2555 }
2556 FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
2557
2558 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x10001);
2559
2560 wait_428c(channel);
2561
Patrick Rudolph371d2912015-10-09 13:33:25 +02002562 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002563 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2564 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2565 0xc01 | (ctrl->tRCD << 16));
2566 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2567 (slotrank << 24) | 0x60000);
2568 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2569
Patrick Rudolph371d2912015-10-09 13:33:25 +02002570 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002571 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2572 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
2573 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2574 (slotrank << 24) | 0x8);
2575 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2576
Patrick Rudolph371d2912015-10-09 13:33:25 +02002577 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002578 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2579 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
2580 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2581 (slotrank << 24));
2582 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
2583
Patrick Rudolph371d2912015-10-09 13:33:25 +02002584 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002585 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2586 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2587 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2588 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2589 (slotrank << 24) | 0x8);
2590 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2591
2592 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2593
2594 wait_428c(channel);
2595
Patrick Rudolph371d2912015-10-09 13:33:25 +02002596 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002597 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2598 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2599 0xc01 | ((ctrl->tRP) << 16));
2600 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2601 (slotrank << 24) | 0x60400);
2602 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2603
Patrick Rudolph371d2912015-10-09 13:33:25 +02002604 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002605 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2606 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2607 0xc01 | ((ctrl->tRCD) << 16));
2608 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2609 (slotrank << 24) | 0x60000);
2610 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2611
Patrick Rudolph371d2912015-10-09 13:33:25 +02002612 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002613 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
2614 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2615 0x4000c01 |
2616 ((ctrl->tRP +
2617 ctrl->timings[channel][slotrank].val_4024 +
2618 ctrl->timings[channel][slotrank].val_4028) << 16));
2619 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2620 (slotrank << 24) | 0x60008);
2621 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2622
2623 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
2624 wait_428c(channel);
2625 FOR_ALL_LANES {
2626 u64 res =
2627 read32(DEFAULT_MCHBAR + lane_registers[lane] +
2628 0x100 * channel + 4);
2629 res |=
2630 ((u64) read32(DEFAULT_MCHBAR + lane_registers[lane] +
2631 0x100 * channel + 8)) << 32;
2632 old = ctrl->timings[channel][slotrank].lanes[lane].timB;
2633 ctrl->timings[channel][slotrank].lanes[lane].timB +=
2634 get_timB_high_adjust(res) * 64;
2635
Patrick Rudolpha649a542016-01-17 18:32:06 +01002636 printram("High adjust %d:%016llx\n", lane, res);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002637 printram("Bval+: %d, %d, %d, %x -> %x\n", channel,
2638 slotrank, lane, old,
2639 ctrl->timings[channel][slotrank].lanes[lane].
2640 timB);
2641 }
2642 }
2643 write32(DEFAULT_MCHBAR + 0x3400, 0);
2644}
2645
2646static void write_op(ramctr_timing * ctrl, int channel)
2647{
2648 int slotrank;
2649
2650 wait_428c(channel);
2651
2652 /* choose an existing rank. */
2653 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2654
Patrick Rudolph371d2912015-10-09 13:33:25 +02002655 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002656 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2657 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2658
2659 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2660 (slotrank << 24) | 0x60000);
2661
2662 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2663
2664 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2665 wait_428c(channel);
2666}
2667
Patrick Rudolph371d2912015-10-09 13:33:25 +02002668/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
2669 * DDR3 adopted the fly-by topology. The data and strobes signals reach
2670 * the chips at different times with respect to command, address and
2671 * clock signals.
2672 * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
2673 * shift can be introduced.
2674 * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
2675 *
2676 * To find the required phase shift the DRAM is placed in "write leveling" mode.
2677 * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
2678 * sampled value on the data lanes (DQs).
2679 */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002680static int write_training(ramctr_timing * ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002681{
2682 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002683 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002684
2685 FOR_ALL_POPULATED_CHANNELS
2686 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
2687 read32(DEFAULT_MCHBAR + 0x4008 +
2688 0x400 * channel) | 0x8000000);
2689
2690 FOR_ALL_POPULATED_CHANNELS {
2691 write_op(ctrl, channel);
2692 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2693 read32(DEFAULT_MCHBAR + 0x4020 +
2694 0x400 * channel) | 0x200000);
2695 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002696
2697 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002698 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2699 FOR_ALL_POPULATED_CHANNELS {
2700 write_op(ctrl, channel);
2701 }
2702
Patrick Rudolph371d2912015-10-09 13:33:25 +02002703 /* enable write leveling on all ranks
2704 * disable all DQ outputs
2705 * only NOP is allowed in this mode */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002706 FOR_ALL_CHANNELS
2707 FOR_ALL_POPULATED_RANKS
2708 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002709 make_mr1(ctrl, slotrank, channel) | 0x1080);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002710
2711 write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
2712
Patrick Rudolph9b515682015-10-09 13:43:51 +02002713 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002714
Patrick Rudolph371d2912015-10-09 13:33:25 +02002715 /* set any valid value for timB, it gets corrected later */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002716 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2717 err = discover_timB(ctrl, channel, slotrank);
2718 if (err)
2719 return err;
2720 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002721
Patrick Rudolph371d2912015-10-09 13:33:25 +02002722 /* disable write leveling on all ranks */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002723 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2724 write_mrreg(ctrl, channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002725 slotrank, 1, make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002726
2727 write32(DEFAULT_MCHBAR + 0x3400, 0);
2728
2729 FOR_ALL_POPULATED_CHANNELS
2730 wait_428c(channel);
2731
Patrick Rudolph371d2912015-10-09 13:33:25 +02002732 /* refresh enable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002733 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
2734
2735 FOR_ALL_POPULATED_CHANNELS {
2736 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2737 ~0x00200000 & read32(DEFAULT_MCHBAR + 0x4020 +
2738 0x400 * channel));
2739 read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
2740 wait_428c(channel);
2741
Patrick Rudolph371d2912015-10-09 13:33:25 +02002742 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002743 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2744 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
2745 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
2746 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2747
2748 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2749 wait_428c(channel);
2750 }
2751
Patrick Rudolph9b515682015-10-09 13:43:51 +02002752 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002753
2754 printram("CPE\n");
2755 precharge(ctrl);
2756 printram("CPF\n");
2757
2758 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2759 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2760 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2761 0);
2762 }
2763
2764 FOR_ALL_POPULATED_CHANNELS {
2765 fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
2766 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2767 }
2768
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002769 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2770 err = discover_timC(ctrl, channel, slotrank);
2771 if (err)
2772 return err;
2773 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002774
2775 FOR_ALL_POPULATED_CHANNELS
2776 program_timings(ctrl, channel);
2777
Patrick Rudolph371d2912015-10-09 13:33:25 +02002778 /* measure and adjust timB timings */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002779 adjust_high_timB(ctrl);
2780
2781 FOR_ALL_POPULATED_CHANNELS
2782 program_timings(ctrl, channel);
2783
2784 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2785 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2786 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2787 0);
2788 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002789 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002790}
2791
2792static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
2793{
2794 struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
2795 int timC_delta;
2796 int lanes_ok = 0;
2797 int ctr = 0;
2798 int lane;
2799
2800 for (timC_delta = -5; timC_delta <= 5; timC_delta++) {
2801 FOR_ALL_LANES {
2802 ctrl->timings[channel][slotrank].lanes[lane].timC =
2803 saved_rt.lanes[lane].timC + timC_delta;
2804 }
2805 program_timings(ctrl, channel);
2806 FOR_ALL_LANES {
2807 write32(DEFAULT_MCHBAR + 4 * lane + 0x4f40, 0);
2808 }
2809
2810 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2811
2812 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002813 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002814 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2815 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2816 ((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
2817 | 8 | (ctrl->tRCD << 16));
2818
2819 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2820 (slotrank << 24) | ctr | 0x60000);
2821
2822 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002823 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002824 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
2825 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2826 0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
2827 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2828 (slotrank << 24));
2829 write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
2830 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
2831
Patrick Rudolph371d2912015-10-09 13:33:25 +02002832 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002833 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2834 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2835 0x4001020 | (max(ctrl->tRTP, 8) << 16));
2836 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2837 (slotrank << 24));
2838 write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
2839 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
2840
Patrick Rudolph371d2912015-10-09 13:33:25 +02002841 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002842 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2843 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
2844 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2845 (slotrank << 24) | 0x60400);
2846 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2847
2848 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2849 wait_428c(channel);
2850 FOR_ALL_LANES {
2851 u32 r32 =
2852 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2853 0x400 * channel);
2854
2855 if (r32 == 0)
2856 lanes_ok |= 1 << lane;
2857 }
2858 ctr++;
2859 if (lanes_ok == ((1 << NUM_LANES) - 1))
2860 break;
2861 }
2862
2863 ctrl->timings[channel][slotrank] = saved_rt;
2864
2865 printram("3lanes: %x\n", lanes_ok);
2866 return lanes_ok != ((1 << NUM_LANES) - 1);
2867}
2868
2869#include "raminit_patterns.h"
2870
2871static void fill_pattern5(ramctr_timing * ctrl, int channel, int patno)
2872{
2873 unsigned i, j;
2874 unsigned channel_offset =
2875 get_precedening_channels(ctrl, channel) * 0x40;
2876 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2877
2878 if (patno) {
2879 u8 base8 = 0x80 >> ((patno - 1) % 8);
2880 u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
2881 for (i = 0; i < 32; i++) {
2882 for (j = 0; j < 16; j++) {
2883 u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;
2884 if (invert[patno - 1][i] & (1 << (j / 2)))
2885 val = ~val;
2886 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2887 j * 4), val);
2888 }
2889 }
2890
2891 } else {
2892 for (i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
2893 for (j = 0; j < 16; j++)
2894 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2895 j * 4), pattern[i][j]);
2896 }
2897 sfence();
2898 }
2899}
2900
2901static void reprogram_320c(ramctr_timing * ctrl)
2902{
2903 int channel, slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002904
2905 FOR_ALL_POPULATED_CHANNELS {
2906 wait_428c(channel);
2907
2908 /* choose an existing rank. */
2909 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2910
Patrick Rudolph371d2912015-10-09 13:33:25 +02002911 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002912 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2913 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2914
2915 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2916 (slotrank << 24) | 0x60000);
2917
2918 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2919
2920 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2921 wait_428c(channel);
2922 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2923 read32(DEFAULT_MCHBAR + 0x4020 +
2924 0x400 * channel) | 0x200000);
2925 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002926
2927 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002928 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2929 FOR_ALL_POPULATED_CHANNELS {
2930 wait_428c(channel);
2931
2932 /* choose an existing rank. */
2933 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2934
Patrick Rudolph371d2912015-10-09 13:33:25 +02002935 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002936 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2937 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2938
2939 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2940 (slotrank << 24) | 0x60000);
2941
2942 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2943
2944 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2945 wait_428c(channel);
2946 }
2947
2948 /* jedec reset */
2949 dram_jedecreset(ctrl);
2950 /* mrs commands. */
2951 dram_mrscommands(ctrl);
2952
Patrick Rudolph9b515682015-10-09 13:43:51 +02002953 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002954}
2955
2956#define MIN_C320C_LEN 13
2957
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002958static int try_cmd_stretch(ramctr_timing *ctrl, int cmd_stretch)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002959{
2960 struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
2961 int channel, slotrank;
2962 int c320c;
2963 int stat[NUM_SLOTRANKS][256];
2964
2965 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2966 saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
2967 }
2968
2969 FOR_ALL_POPULATED_CHANNELS {
2970 ctrl->cmd_stretch[channel] = cmd_stretch;
2971 }
2972
2973 FOR_ALL_POPULATED_CHANNELS
2974 MCHBAR32(0x4004 + 0x400 * channel) =
2975 ctrl->tRRD
2976 | (ctrl->tRTP << 4)
2977 | (ctrl->tCKE << 8)
2978 | (ctrl->tWTR << 12)
2979 | (ctrl->tFAW << 16)
2980 | (ctrl->tWR << 24)
2981 | (ctrl->cmd_stretch[channel] << 30);
2982
2983
2984 FOR_ALL_CHANNELS {
2985 int delta = 0;
2986 if (ctrl->cmd_stretch[channel] == 2)
2987 delta = 2;
2988 else if (ctrl->cmd_stretch[channel] == 0)
2989 delta = 4;
2990
2991 FOR_ALL_POPULATED_RANKS {
2992 ctrl->timings[channel][slotrank].val_4024 -= delta;
2993 }
2994 }
2995
2996 FOR_ALL_POPULATED_CHANNELS {
2997 for (c320c = -127; c320c <= 127; c320c++) {
2998 FOR_ALL_POPULATED_RANKS {
2999 ctrl->timings[channel][slotrank].val_320c = c320c;
3000 }
3001 program_timings(ctrl, channel);
3002 reprogram_320c(ctrl);
3003 FOR_ALL_POPULATED_RANKS {
3004 stat[slotrank][c320c + 127] =
3005 test_320c(ctrl, channel, slotrank);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003006 printram("3stat: %d, %d, %d: %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003007 channel, slotrank, c320c,
3008 stat[slotrank][c320c + 127]);
3009 }
3010 }
3011 FOR_ALL_POPULATED_RANKS {
3012 struct run rn =
3013 get_longest_zero_run(stat[slotrank], 255);
3014 ctrl->timings[channel][slotrank].val_320c =
3015 rn.middle - 127;
3016 printram("3val: %d, %d: %d\n", channel,
3017 slotrank,
3018 ctrl->timings[channel][slotrank].val_320c);
3019 if (rn.all || rn.length < MIN_C320C_LEN) {
3020 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3021 ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
3022 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003023 return MAKE_ERR;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003024 }
3025 }
3026 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003027 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003028}
3029
Patrick Rudolph371d2912015-10-09 13:33:25 +02003030/* Adjust CMD phase shift and try multiple command rates.
3031 * A command rate of 2T doubles the time needed for address and
3032 * command decode. */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003033static int command_training(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003034{
3035 int channel;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003036 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003037
3038 FOR_ALL_POPULATED_CHANNELS {
3039 fill_pattern5(ctrl, channel, 0);
3040 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
3041 }
3042
3043 /* try command rate 1T and 2T */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003044 err = try_cmd_stretch(ctrl, 0);
3045 if (err) {
3046 err = try_cmd_stretch(ctrl, 2);
3047 if (err) {
3048 printk(BIOS_EMERG, "c320c discovery failed\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003049 return err;
3050 }
3051 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003052
3053 FOR_ALL_POPULATED_CHANNELS {
3054 program_timings(ctrl, channel);
3055 }
3056
3057 reprogram_320c(ctrl);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003058 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003059}
3060
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003061static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003062 int *edges)
3063{
3064 int edge;
3065 int statistics[NUM_LANES][MAX_EDGE_TIMING + 1];
3066 int lane;
3067
3068 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3069 FOR_ALL_LANES {
3070 ctrl->timings[channel][slotrank].lanes[lane].rising =
3071 edge;
3072 ctrl->timings[channel][slotrank].lanes[lane].falling =
3073 edge;
3074 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003075 program_timings(ctrl, channel);
3076
3077 FOR_ALL_LANES {
3078 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
3079 4 * lane, 0);
3080 read32(DEFAULT_MCHBAR + 0x400 * channel + 4 * lane +
3081 0x4140);
3082 }
3083
3084 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003085 /* DRAM command MRS
3086 * write MR3 MPR enable
3087 * in this mode only RD and RDA are allowed
3088 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003089 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
3090 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3091 (0xc01 | (ctrl->tMOD << 16)));
3092 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3093 (slotrank << 24) | 0x360004);
3094 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3095
Patrick Rudolph371d2912015-10-09 13:33:25 +02003096 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003097 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
3098 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
3099 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3100 (slotrank << 24));
3101 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3102
Patrick Rudolph371d2912015-10-09 13:33:25 +02003103 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003104 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
3105 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3106 0x1001 | ((ctrl->CAS + 8) << 16));
3107 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3108 (slotrank << 24) | 0x60000);
3109 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3110
Patrick Rudolph371d2912015-10-09 13:33:25 +02003111 /* DRAM command MRS
3112 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003113 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
3114 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3115 (0xc01 | (ctrl->tMOD << 16)));
3116 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3117 (slotrank << 24) | 0x360000);
3118 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3119
3120 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
3121
3122 wait_428c(channel);
3123
3124 FOR_ALL_LANES {
3125 statistics[lane][edge] =
3126 read32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
3127 lane * 4);
3128 }
3129 }
3130 FOR_ALL_LANES {
3131 struct run rn =
3132 get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
3133 edges[lane] = rn.middle;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003134 if (rn.all) {
3135 printk(BIOS_EMERG, "edge discovery failed: %d, %d, %d\n",
3136 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003137 return MAKE_ERR;
3138 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01003139 printram("eval %d, %d, %d: %02x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003140 lane, edges[lane]);
3141 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003142 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003143}
3144
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003145static int discover_edges(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003146{
3147 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3148 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3149 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003150 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003151
3152 write32(DEFAULT_MCHBAR + 0x3400, 0);
3153
Patrick Rudolph9b515682015-10-09 13:43:51 +02003154 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003155
3156 FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
3157 write32(DEFAULT_MCHBAR + 4 * lane +
3158 0x400 * channel + 0x4080, 0);
3159 }
3160
3161 FOR_ALL_POPULATED_CHANNELS {
3162 fill_pattern0(ctrl, channel, 0, 0);
3163 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3164 FOR_ALL_LANES {
3165 read32(DEFAULT_MCHBAR + 0x400 * channel +
3166 lane * 4 + 0x4140);
3167 }
3168
3169 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3170 ctrl->timings[channel][slotrank].lanes[lane].falling =
3171 16;
3172 ctrl->timings[channel][slotrank].lanes[lane].rising =
3173 16;
3174 }
3175
3176 program_timings(ctrl, channel);
3177
3178 FOR_ALL_POPULATED_RANKS {
3179 wait_428c(channel);
3180
Patrick Rudolph371d2912015-10-09 13:33:25 +02003181 /* DRAM command MRS
3182 * MR3 enable MPR
3183 * write MR3 MPR enable
3184 * in this mode only RD and RDA are allowed
3185 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003186 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3187 0x1f000);
3188 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3189 0xc01 | (ctrl->tMOD << 16));
3190 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3191 (slotrank << 24) | 0x360004);
3192 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3193
Patrick Rudolph371d2912015-10-09 13:33:25 +02003194 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003195 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3196 0x1f105);
3197 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3198 0x4041003);
3199 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3200 (slotrank << 24) | 0);
3201 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3202
Patrick Rudolph371d2912015-10-09 13:33:25 +02003203 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003204 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3205 0x1f105);
3206 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3207 0x1001 | ((ctrl->CAS + 8) << 16));
3208 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3209 (slotrank << 24) | 0x60000);
3210 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3211
Patrick Rudolph371d2912015-10-09 13:33:25 +02003212 /* DRAM command MRS
3213 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003214 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3215 0x1f000);
3216 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3217 0xc01 | (ctrl->tMOD << 16));
3218 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3219 (slotrank << 24) | 0x360000);
3220 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3221 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3222 0xc0001);
3223
3224 wait_428c(channel);
3225 }
3226
Patrick Rudolph371d2912015-10-09 13:33:25 +02003227 /* XXX: check any measured value ? */
3228
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003229 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3230 ctrl->timings[channel][slotrank].lanes[lane].falling =
3231 48;
3232 ctrl->timings[channel][slotrank].lanes[lane].rising =
3233 48;
3234 }
3235
3236 program_timings(ctrl, channel);
3237
3238 FOR_ALL_POPULATED_RANKS {
3239 wait_428c(channel);
3240
Patrick Rudolph371d2912015-10-09 13:33:25 +02003241 /* DRAM command MRS
3242 * MR3 enable MPR
3243 * write MR3 MPR enable
3244 * in this mode only RD and RDA are allowed
3245 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003246 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3247 0x1f000);
3248 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3249 0xc01 | (ctrl->tMOD << 16));
3250 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3251 (slotrank << 24) | 0x360004);
3252 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3253
Patrick Rudolph371d2912015-10-09 13:33:25 +02003254 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003255 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3256 0x1f105);
3257 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3258 0x4041003);
3259 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3260 (slotrank << 24) | 0);
3261 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3262
Patrick Rudolph371d2912015-10-09 13:33:25 +02003263 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003264 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3265 0x1f105);
3266 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3267 0x1001 | ((ctrl->CAS + 8) << 16));
3268 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3269 (slotrank << 24) | 0x60000);
3270 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3271
Patrick Rudolph371d2912015-10-09 13:33:25 +02003272 /* DRAM command MRS
3273 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003274 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3275 0x1f000);
3276 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3277 0xc01 | (ctrl->tMOD << 16));
3278 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3279 (slotrank << 24) | 0x360000);
3280 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3281
3282 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3283 0xc0001);
3284 wait_428c(channel);
3285 }
3286
Patrick Rudolph371d2912015-10-09 13:33:25 +02003287 /* XXX: check any measured value ? */
3288
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003289 FOR_ALL_LANES {
3290 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
3291 lane * 4,
3292 ~read32(DEFAULT_MCHBAR + 0x4040 +
3293 0x400 * channel + lane * 4) & 0xff);
3294 }
3295
3296 fill_pattern0(ctrl, channel, 0, 0xffffffff);
3297 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3298 }
3299
3300 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3301 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003302 printram("discover falling edges:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003303
3304 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003305 err = discover_edges_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003306 falling_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003307 if (err)
3308 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003309 }
3310
3311 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003312 printram("discover rising edges:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003313
3314 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003315 err = discover_edges_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003316 rising_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003317 if (err)
3318 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003319 }
3320
3321 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3322
3323 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3324 ctrl->timings[channel][slotrank].lanes[lane].falling =
3325 falling_edges[channel][slotrank][lane];
3326 ctrl->timings[channel][slotrank].lanes[lane].rising =
3327 rising_edges[channel][slotrank][lane];
3328 }
3329
3330 FOR_ALL_POPULATED_CHANNELS {
3331 program_timings(ctrl, channel);
3332 }
3333
3334 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3335 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3336 0);
3337 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003338 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003339}
3340
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003341static int discover_edges_write_real(ramctr_timing *ctrl, int channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003342 int slotrank, int *edges)
3343{
3344 int edge;
3345 u32 raw_statistics[MAX_EDGE_TIMING + 1];
3346 int statistics[MAX_EDGE_TIMING + 1];
3347 const int reg3000b24[] = { 0, 0xc, 0x2c };
3348 int lane, i;
3349 int lower[NUM_LANES];
3350 int upper[NUM_LANES];
3351 int pat;
3352
3353 FOR_ALL_LANES {
3354 lower[lane] = 0;
3355 upper[lane] = MAX_EDGE_TIMING;
3356 }
3357
3358 for (i = 0; i < 3; i++) {
3359 write32(DEFAULT_MCHBAR + 0x3000 + 0x100 * channel,
3360 reg3000b24[i] << 24);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003361 printram("[%x] = 0x%08x\n",
3362 0x3000 + 0x100 * channel, reg3000b24[i] << 24);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003363 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3364 fill_pattern5(ctrl, channel, pat);
3365 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003366 printram("using pattern %d\n", pat);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003367 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3368 FOR_ALL_LANES {
3369 ctrl->timings[channel][slotrank].lanes[lane].
3370 rising = edge;
3371 ctrl->timings[channel][slotrank].lanes[lane].
3372 falling = edge;
3373 }
3374 program_timings(ctrl, channel);
3375
3376 FOR_ALL_LANES {
3377 write32(DEFAULT_MCHBAR + 0x4340 +
3378 0x400 * channel + 4 * lane, 0);
3379 read32(DEFAULT_MCHBAR + 0x400 * channel +
3380 4 * lane + 0x4140);
3381 }
3382 wait_428c(channel);
3383
Patrick Rudolph371d2912015-10-09 13:33:25 +02003384 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003385 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3386 0x1f006);
3387 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3388 0x4 | (ctrl->tRCD << 16)
3389 | (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) <<
3390 10));
3391 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3392 (slotrank << 24) | 0x60000);
3393 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
3394 0x240);
3395
Patrick Rudolph371d2912015-10-09 13:33:25 +02003396 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003397 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3398 0x1f201);
3399 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3400 0x8005020 | ((ctrl->tWTR + ctrl->CWL + 8) <<
3401 16));
3402 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3403 (slotrank << 24));
3404 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
3405 0x242);
3406
Patrick Rudolph371d2912015-10-09 13:33:25 +02003407 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003408 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3409 0x1f105);
3410 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3411 0x4005020 | (max(ctrl->tRTP, 8) << 16));
3412 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3413 (slotrank << 24));
3414 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
3415 0x242);
3416
Patrick Rudolph371d2912015-10-09 13:33:25 +02003417 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003418 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3419 0x1f002);
3420 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3421 0xc01 | (ctrl->tRP << 16));
3422 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3423 (slotrank << 24) | 0x60400);
3424 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3425
3426 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3427 0xc0001);
3428 wait_428c(channel);
3429 FOR_ALL_LANES {
3430 read32(DEFAULT_MCHBAR + 0x4340 +
3431 0x400 * channel + lane * 4);
3432 }
3433
3434 raw_statistics[edge] =
3435 MCHBAR32(0x436c + 0x400 * channel);
3436 }
3437 FOR_ALL_LANES {
3438 struct run rn;
3439 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++)
3440 statistics[edge] =
3441 ! !(raw_statistics[edge] & (1 << lane));
3442 rn = get_longest_zero_run(statistics,
3443 MAX_EDGE_TIMING + 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003444 printram("edges: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003445 channel, slotrank, i, rn.start, rn.middle,
3446 rn.end, rn.start + ctrl->edge_offset[i],
3447 rn.end - ctrl->edge_offset[i]);
3448 lower[lane] =
3449 max(rn.start + ctrl->edge_offset[i], lower[lane]);
3450 upper[lane] =
3451 min(rn.end - ctrl->edge_offset[i], upper[lane]);
3452 edges[lane] = (lower[lane] + upper[lane]) / 2;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003453 if (rn.all || (lower[lane] > upper[lane])) {
3454 printk(BIOS_EMERG, "edge write discovery failed: %d, %d, %d\n",
3455 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003456 return MAKE_ERR;
3457 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003458 }
3459 }
3460 }
3461
3462 write32(DEFAULT_MCHBAR + 0x3000, 0);
3463 printram("CPA\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003464 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003465}
3466
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003467static int discover_edges_write(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003468{
3469 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3470 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3471 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003472 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003473
3474 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3475 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003476 printram("discover falling edges write:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003477
3478 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003479 err = discover_edges_write_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003480 falling_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003481 if (err)
3482 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003483 }
3484
3485 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003486 printram("discover rising edges write:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003487
3488 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003489 err = discover_edges_write_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003490 rising_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003491 if (err)
3492 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003493 }
3494
3495 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3496
3497 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3498 ctrl->timings[channel][slotrank].lanes[lane].falling =
3499 falling_edges[channel][slotrank][lane];
3500 ctrl->timings[channel][slotrank].lanes[lane].rising =
3501 rising_edges[channel][slotrank][lane];
3502 }
3503
3504 FOR_ALL_POPULATED_CHANNELS
3505 program_timings(ctrl, channel);
3506
3507 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3508 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3509 0);
3510 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003511 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003512}
3513
3514static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
3515{
3516 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003517 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003518 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
3519 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3520 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD)
3521 << 10) | (ctrl->tRCD << 16) | 4);
3522 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3523 (slotrank << 24) | 0x60000);
3524 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
3525
Patrick Rudolph371d2912015-10-09 13:33:25 +02003526 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003527 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
3528 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3529 0x80011e0 |
3530 ((ctrl->tWTR + ctrl->CWL + 8) << 16));
3531 write32(DEFAULT_MCHBAR + 0x4204 +
3532 0x400 * channel, (slotrank << 24));
3533 write32(DEFAULT_MCHBAR + 0x4214 +
3534 0x400 * channel, 0x242);
3535
Patrick Rudolph371d2912015-10-09 13:33:25 +02003536 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003537 write32(DEFAULT_MCHBAR + 0x4228 +
3538 0x400 * channel, 0x1f105);
3539 write32(DEFAULT_MCHBAR + 0x4238 +
3540 0x400 * channel,
3541 0x40011e0 | (max(ctrl->tRTP, 8) << 16));
3542 write32(DEFAULT_MCHBAR + 0x4208 +
3543 0x400 * channel, (slotrank << 24));
3544 write32(DEFAULT_MCHBAR + 0x4218 +
3545 0x400 * channel, 0x242);
3546
Patrick Rudolph371d2912015-10-09 13:33:25 +02003547 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003548 write32(DEFAULT_MCHBAR + 0x422c +
3549 0x400 * channel, 0x1f002);
3550 write32(DEFAULT_MCHBAR + 0x423c +
3551 0x400 * channel,
3552 0x1001 | (ctrl->tRP << 16));
3553 write32(DEFAULT_MCHBAR + 0x420c +
3554 0x400 * channel,
3555 (slotrank << 24) | 0x60400);
3556 write32(DEFAULT_MCHBAR + 0x421c +
3557 0x400 * channel, 0);
3558
3559 write32(DEFAULT_MCHBAR + 0x4284 +
3560 0x400 * channel, 0xc0001);
3561 wait_428c(channel);
3562}
3563
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003564static int discover_timC_write(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003565{
3566 const u8 rege3c_b24[3] = { 0, 0xf, 0x2f };
3567 int i, pat;
3568
3569 int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3570 int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3571 int channel, slotrank, lane;
3572
3573 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3574 lower[channel][slotrank][lane] = 0;
3575 upper[channel][slotrank][lane] = MAX_TIMC;
3576 }
3577
3578 write32(DEFAULT_MCHBAR + 0x4ea8, 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003579 printram("discover timC write:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003580
3581 for (i = 0; i < 3; i++)
3582 FOR_ALL_POPULATED_CHANNELS {
3583 write32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100),
3584 (rege3c_b24[i] << 24)
3585 | (read32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100))
3586 & ~0x3f000000));
3587 udelay(2);
3588 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3589 FOR_ALL_POPULATED_RANKS {
3590 int timC;
3591 u32 raw_statistics[MAX_TIMC + 1];
3592 int statistics[MAX_TIMC + 1];
3593
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003594 /* Make sure rn.start < rn.end */
3595 statistics[MAX_TIMC] = 1;
3596
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003597 fill_pattern5(ctrl, channel, pat);
3598 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003599 for (timC = 0; timC < MAX_TIMC; timC++) {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003600 FOR_ALL_LANES
3601 ctrl->timings[channel][slotrank].lanes[lane].timC = timC;
3602 program_timings(ctrl, channel);
3603
3604 test_timC_write (ctrl, channel, slotrank);
3605
3606 raw_statistics[timC] =
3607 MCHBAR32(0x436c + 0x400 * channel);
3608 }
3609 FOR_ALL_LANES {
3610 struct run rn;
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003611 for (timC = 0; timC < MAX_TIMC; timC++)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003612 statistics[timC] =
3613 !!(raw_statistics[timC] &
3614 (1 << lane));
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003615
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003616 rn = get_longest_zero_run(statistics,
3617 MAX_TIMC + 1);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003618 if (rn.all) {
3619 printk(BIOS_EMERG, "timC write discovery failed: %d, %d, %d\n",
3620 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003621 return MAKE_ERR;
3622 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01003623 printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003624 channel, slotrank, i, rn.start,
3625 rn.middle, rn.end,
3626 rn.start + ctrl->timC_offset[i],
3627 rn.end - ctrl->timC_offset[i]);
3628 lower[channel][slotrank][lane] =
3629 max(rn.start + ctrl->timC_offset[i],
3630 lower[channel][slotrank][lane]);
3631 upper[channel][slotrank][lane] =
3632 min(rn.end - ctrl->timC_offset[i],
3633 upper[channel][slotrank][lane]);
3634
3635 }
3636 }
3637 }
3638 }
3639
3640 FOR_ALL_CHANNELS {
3641 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3642 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3643 ~0x3f000000));
3644 udelay(2);
3645 }
3646
3647 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3648
3649 printram("CPB\n");
3650
3651 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
Patrick Rudolpha649a542016-01-17 18:32:06 +01003652 printram("timC %d, %d, %d: %x\n", channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003653 slotrank, lane,
3654 (lower[channel][slotrank][lane] +
3655 upper[channel][slotrank][lane]) / 2);
3656 ctrl->timings[channel][slotrank].lanes[lane].timC =
3657 (lower[channel][slotrank][lane] +
3658 upper[channel][slotrank][lane]) / 2;
3659 }
3660 FOR_ALL_POPULATED_CHANNELS {
3661 program_timings(ctrl, channel);
3662 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003663 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003664}
3665
3666static void normalize_training(ramctr_timing * ctrl)
3667{
3668 int channel, slotrank, lane;
3669 int mat = 0;
3670
3671 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3672 int delta;
3673 FOR_ALL_LANES mat =
3674 max(ctrl->timings[channel][slotrank].lanes[lane].timA, mat);
3675 delta = (mat >> 6) - ctrl->timings[channel][slotrank].val_4028;
3676 ctrl->timings[channel][slotrank].val_4024 += delta;
3677 ctrl->timings[channel][slotrank].val_4028 += delta;
3678 }
3679
3680 FOR_ALL_POPULATED_CHANNELS {
3681 program_timings(ctrl, channel);
3682 }
3683}
3684
3685static void write_controller_mr(ramctr_timing * ctrl)
3686{
3687 int channel, slotrank;
3688
3689 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3690 write32(DEFAULT_MCHBAR + 0x0004 + (channel << 8) +
3691 lane_registers[slotrank], make_mr0(ctrl, slotrank));
3692 write32(DEFAULT_MCHBAR + 0x0008 + (channel << 8) +
Patrick Rudolph7e513d12016-01-10 14:22:34 +01003693 lane_registers[slotrank],
3694 make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003695 }
3696}
3697
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003698static int channel_test(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003699{
3700 int channel, slotrank, lane;
3701
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003702 slotrank = 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003703 FOR_ALL_POPULATED_CHANNELS
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003704 if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000) {
3705 printk(BIOS_EMERG, "Mini channel test failed (1): %d\n",
3706 channel);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003707 return MAKE_ERR;
3708 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003709 FOR_ALL_POPULATED_CHANNELS {
3710 fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
3711
3712 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3713 }
3714
3715 for (slotrank = 0; slotrank < 4; slotrank++)
3716 FOR_ALL_CHANNELS
3717 if (ctrl->rankmap[channel] & (1 << slotrank)) {
3718 FOR_ALL_LANES {
3719 write32(DEFAULT_MCHBAR + (0x4f40 + 4 * lane), 0);
3720 write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
3721 }
3722 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003723 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003724 write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
3725 write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
3726 write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
3727 0x00060000 | (slotrank << 24));
3728 write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003729 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003730 write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
3731 write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
3732 write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
3733 0x00000000 | (slotrank << 24));
3734 write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003735 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003736 write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
3737 write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
3738 write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
3739 0x00000000 | (slotrank << 24));
3740 write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003741 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003742 write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
3743 write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
3744 write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),
3745 0x00060400 | (slotrank << 24));
3746 write32(DEFAULT_MCHBAR + 0x421c + (channel << 10), 0x00000240);
3747 write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
3748 wait_428c(channel);
3749 FOR_ALL_LANES
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003750 if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane)) {
3751 printk(BIOS_EMERG, "Mini channel test failed (2): %d, %d, %d\n",
3752 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003753 return MAKE_ERR;
3754 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003755 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003756 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003757}
3758
3759static void set_scrambling_seed(ramctr_timing * ctrl)
3760{
3761 int channel;
3762
3763 /* FIXME: we hardcode seeds. Do we need to use some PRNG for them?
3764 I don't think so. */
3765 static u32 seeds[NUM_CHANNELS][3] = {
3766 {0x00009a36, 0xbafcfdcf, 0x46d1ab68},
3767 {0x00028bfa, 0x53fe4b49, 0x19ed5483}
3768 };
3769 FOR_ALL_POPULATED_CHANNELS {
3770 MCHBAR32(0x4020 + 0x400 * channel) &= ~0x10000000;
3771 write32(DEFAULT_MCHBAR + 0x4034, seeds[channel][0]);
3772 write32(DEFAULT_MCHBAR + 0x403c, seeds[channel][1]);
3773 write32(DEFAULT_MCHBAR + 0x4038, seeds[channel][2]);
3774 }
3775}
3776
3777static void set_4f8c(void)
3778{
3779 struct cpuid_result cpures;
3780 u32 cpu;
3781
Ryan Salsamendie4da9aa2016-06-24 12:01:11 -07003782 cpures = cpuid(1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003783 cpu = (cpures.eax);
3784 if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
3785 MCHBAR32(0x4f8c) = 0x141D1519;
3786 } else {
3787 MCHBAR32(0x4f8c) = 0x551D1519;
3788 }
3789}
3790
3791static void prepare_training(ramctr_timing * ctrl)
3792{
3793 int channel;
3794
3795 FOR_ALL_POPULATED_CHANNELS {
3796 // Always drive command bus
3797 MCHBAR32(0x4004 + 0x400 * channel) |= 0x20000000;
3798 }
3799
3800 udelay(1);
3801
3802 FOR_ALL_POPULATED_CHANNELS {
3803 wait_428c(channel);
3804 }
3805}
3806
3807static void set_4008c(ramctr_timing * ctrl)
3808{
3809 int channel, slotrank;
3810 u32 reg;
3811 FOR_ALL_POPULATED_CHANNELS {
3812 u32 b20, b4_8_12;
3813 int min_320c = 10000;
3814 int max_320c = -10000;
3815
3816 FOR_ALL_POPULATED_RANKS {
3817 max_320c = max(ctrl->timings[channel][slotrank].val_320c, max_320c);
3818 min_320c = min(ctrl->timings[channel][slotrank].val_320c, min_320c);
3819 }
3820
3821 if (max_320c - min_320c > 51)
3822 b20 = 0;
3823 else
3824 b20 = ctrl->ref_card_offset[channel];
3825
3826 if (ctrl->reg_320c_range_threshold < max_320c - min_320c)
3827 b4_8_12 = 0x3330;
3828 else
3829 b4_8_12 = 0x2220;
3830
3831 reg = read32(DEFAULT_MCHBAR + 0x400c + (channel << 10));
3832 write32(DEFAULT_MCHBAR + 0x400c + (channel << 10),
3833 (reg & 0xFFF0FFFF)
3834 | (ctrl->ref_card_offset[channel] << 16)
3835 | (ctrl->ref_card_offset[channel] << 18));
3836 write32(DEFAULT_MCHBAR + 0x4008 + (channel << 10),
3837 0x0a000000
3838 | (b20 << 20)
3839 | ((ctrl->ref_card_offset[channel] + 2) << 16)
3840 | b4_8_12);
3841 }
3842}
3843
3844static void set_42a0(ramctr_timing * ctrl)
3845{
3846 int channel;
3847 FOR_ALL_POPULATED_CHANNELS {
3848 write32(DEFAULT_MCHBAR + (0x42a0 + 0x400 * channel),
3849 0x00001000 | ctrl->rankmap[channel]);
3850 MCHBAR32(0x4004 + 0x400 * channel) &= ~0x20000000; // OK
3851 }
3852}
3853
3854static int encode_5d10(int ns)
3855{
3856 return (ns + 499) / 500;
3857}
3858
3859/* FIXME: values in this function should be hardware revision-dependent. */
3860static void final_registers(ramctr_timing * ctrl)
3861{
3862 int channel;
3863 int t1_cycles = 0, t1_ns = 0, t2_ns;
3864 int t3_ns;
3865 u32 r32;
3866
3867 write32(DEFAULT_MCHBAR + 0x4cd4, 0x00000046);
3868
3869 write32(DEFAULT_MCHBAR + 0x400c, (read32(DEFAULT_MCHBAR + 0x400c) & 0xFFFFCFFF) | 0x1000); // OK
3870 write32(DEFAULT_MCHBAR + 0x440c, (read32(DEFAULT_MCHBAR + 0x440c) & 0xFFFFCFFF) | 0x1000); // OK
3871 write32(DEFAULT_MCHBAR + 0x4cb0, 0x00000740);
3872 write32(DEFAULT_MCHBAR + 0x4380, 0x00000aaa); // OK
3873 write32(DEFAULT_MCHBAR + 0x4780, 0x00000aaa); // OK
3874 write32(DEFAULT_MCHBAR + 0x4f88, 0x5f7003ff); // OK
3875 write32(DEFAULT_MCHBAR + 0x5064, 0x00073000 | ctrl->reg_5064b0); // OK
3876
3877 FOR_ALL_CHANNELS {
3878 switch (ctrl->rankmap[channel]) {
3879 /* Unpopulated channel. */
3880 case 0:
3881 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0);
3882 break;
3883 /* Only single-ranked dimms. */
3884 case 1:
3885 case 4:
3886 case 5:
3887 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x373131);
3888 break;
3889 /* Dual-ranked dimms present. */
3890 default:
3891 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x9b6ea1);
3892 break;
3893 }
3894 }
3895
3896 write32 (DEFAULT_MCHBAR + 0x5880, 0xca9171e5);
3897 write32 (DEFAULT_MCHBAR + 0x5888,
3898 (read32 (DEFAULT_MCHBAR + 0x5888) & ~0xffffff) | 0xe4d5d0);
3899 write32 (DEFAULT_MCHBAR + 0x58a8, read32 (DEFAULT_MCHBAR + 0x58a8) & ~0x1f);
3900 write32 (DEFAULT_MCHBAR + 0x4294,
3901 (read32 (DEFAULT_MCHBAR + 0x4294) & ~0x30000)
3902 | (1 << 16));
3903 write32 (DEFAULT_MCHBAR + 0x4694,
3904 (read32 (DEFAULT_MCHBAR + 0x4694) & ~0x30000)
3905 | (1 << 16));
3906
3907 MCHBAR32(0x5030) |= 1; // OK
3908 MCHBAR32(0x5030) |= 0x80; // OK
3909 MCHBAR32(0x5f18) = 0xfa; // OK
3910
3911 /* Find a populated channel. */
3912 FOR_ALL_POPULATED_CHANNELS
3913 break;
3914
3915 t1_cycles = ((read32(DEFAULT_MCHBAR + 0x4290 + channel * 0x400) >> 8) & 0xff);
3916 r32 = read32(DEFAULT_MCHBAR + 0x5064);
3917 if (r32 & 0x20000)
3918 t1_cycles += (r32 & 0xfff);
3919 t1_cycles += (read32(DEFAULT_MCHBAR + channel * 0x400 + 0x42a4) & 0xfff);
3920 t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
3921 if (!(r32 & 0x20000))
3922 t1_ns += 500;
3923
3924 t2_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f10) >> 8) & 0xfff);
3925 if ( read32(DEFAULT_MCHBAR + 0x5f00) & 8 )
3926 {
3927 t3_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f20) >> 8) & 0xfff);
3928 t3_ns += 10 * (read32(DEFAULT_MCHBAR + 0x5f18) & 0xff);
3929 }
3930 else
3931 {
3932 t3_ns = 500;
3933 }
3934 printk(BIOS_DEBUG, "t123: %d, %d, %d\n",
3935 t1_ns, t2_ns, t3_ns);
3936 write32 (DEFAULT_MCHBAR + 0x5d10,
3937 ((encode_5d10(t1_ns) + encode_5d10(t2_ns)) << 16)
3938 | (encode_5d10(t1_ns) << 8)
3939 | ((encode_5d10(t3_ns) + encode_5d10(t2_ns) + encode_5d10(t1_ns)) << 24)
3940 | (read32(DEFAULT_MCHBAR + 0x5d10) & 0xC0C0C0C0)
3941 | 0xc);
3942}
3943
Patrick Rudolphbb9c90a2016-05-29 17:05:06 +02003944static void save_timings(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003945{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003946 /* Save the MRC S3 restore data to cbmem */
Patrick Rudolphbb9c90a2016-05-29 17:05:06 +02003947 store_current_mrc_cache(ctrl, sizeof(*ctrl));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003948}
3949
3950static void restore_timings(ramctr_timing * ctrl)
3951{
3952 int channel, slotrank, lane;
3953
3954 FOR_ALL_POPULATED_CHANNELS
3955 MCHBAR32(0x4004 + 0x400 * channel) =
3956 ctrl->tRRD
3957 | (ctrl->tRTP << 4)
3958 | (ctrl->tCKE << 8)
3959 | (ctrl->tWTR << 12)
3960 | (ctrl->tFAW << 16)
3961 | (ctrl->tWR << 24)
3962 | (ctrl->cmd_stretch[channel] << 30);
3963
3964 udelay(1);
3965
3966 FOR_ALL_POPULATED_CHANNELS {
3967 wait_428c(channel);
3968 }
3969
3970 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3971 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
3972 + 4 * lane, 0);
3973 }
3974
3975 FOR_ALL_POPULATED_CHANNELS
3976 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
3977 read32(DEFAULT_MCHBAR + 0x4008 +
3978 0x400 * channel) | 0x8000000);
3979
3980 FOR_ALL_POPULATED_CHANNELS {
3981 udelay (1);
3982 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
3983 read32(DEFAULT_MCHBAR + 0x4020 +
3984 0x400 * channel) | 0x200000);
3985 }
3986
3987 printram("CPE\n");
3988
3989 write32(DEFAULT_MCHBAR + 0x3400, 0);
3990 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3991
3992 printram("CP5b\n");
3993
3994 FOR_ALL_POPULATED_CHANNELS {
3995 program_timings(ctrl, channel);
3996 }
3997
3998 u32 reg, addr;
3999
4000 while (!(MCHBAR32(0x5084) & 0x10000)) ;
4001 do {
4002 reg = MCHBAR32(0x428c);
4003 } while ((reg & 0x14) == 0);
4004
4005 // Set state of memory controller
4006 MCHBAR32(0x5030) = 0x116;
4007 MCHBAR32(0x4ea0) = 0;
4008
4009 // Wait 500us
4010 udelay(500);
4011
4012 FOR_ALL_CHANNELS {
4013 // Set valid rank CKE
4014 reg = 0;
4015 reg = (reg & ~0xf) | ctrl->rankmap[channel];
4016 addr = 0x400 * channel + 0x42a0;
4017 MCHBAR32(addr) = reg;
4018
4019 // Wait 10ns for ranks to settle
4020 //udelay(0.01);
4021
4022 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
4023 MCHBAR32(addr) = reg;
4024
4025 // Write reset using a NOP
4026 write_reset(ctrl);
4027 }
4028
4029 /* mrs commands. */
4030 dram_mrscommands(ctrl);
4031
4032 printram("CP5c\n");
4033
4034 write32(DEFAULT_MCHBAR + 0x3000, 0);
4035
4036 FOR_ALL_CHANNELS {
4037 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
4038 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
4039 ~0x3f000000));
4040 udelay(2);
4041 }
4042
4043 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
4044}
4045
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004046static int try_init_dram_ddr3(ramctr_timing *ctrl, int fast_boot,
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004047 int s3_resume, int me_uma_size)
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004048{
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004049 int err;
4050
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004051 printk(BIOS_DEBUG, "Starting RAM training (%d).\n", fast_boot);
4052
4053 if (!fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004054 /* Find fastest common supported parameters */
4055 dram_find_common_params(ctrl);
4056
4057 dram_dimm_mapping(ctrl);
4058 }
4059
4060 /* Set MCU frequency */
4061 dram_freq(ctrl);
4062
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004063 if (!fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004064 /* Calculate timings */
4065 dram_timing(ctrl);
4066 }
4067
4068 /* Set version register */
4069 MCHBAR32(0x5034) = 0xC04EB002;
4070
4071 /* Enable crossover */
4072 dram_xover(ctrl);
4073
4074 /* Set timing and refresh registers */
4075 dram_timing_regs(ctrl);
4076
4077 /* Power mode preset */
4078 MCHBAR32(0x4e80) = 0x5500;
4079
4080 /* Set scheduler parameters */
4081 MCHBAR32(0x4c20) = 0x10100005;
4082
Elyes HAOUAS15279a92016-07-28 21:05:26 +02004083 /* Set CPU specific register */
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004084 set_4f8c();
4085
4086 /* Clear IO reset bit */
4087 MCHBAR32(0x5030) &= ~0x20;
4088
4089 /* Set MAD-DIMM registers */
4090 dram_dimm_set_mapping(ctrl);
4091 printk(BIOS_DEBUG, "Done dimm mapping\n");
4092
4093 /* Zone config */
4094 dram_zones(ctrl, 1);
4095
4096 /* Set memory map */
4097 dram_memorymap(ctrl, me_uma_size);
4098 printk(BIOS_DEBUG, "Done memory map\n");
4099
4100 /* Set IO registers */
4101 dram_ioregs(ctrl);
4102 printk(BIOS_DEBUG, "Done io registers\n");
4103
4104 udelay(1);
4105
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004106 if (fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004107 restore_timings(ctrl);
4108 } else {
4109 /* Do jedec ddr3 reset sequence */
4110 dram_jedecreset(ctrl);
4111 printk(BIOS_DEBUG, "Done jedec reset\n");
4112
4113 /* MRS commands */
4114 dram_mrscommands(ctrl);
4115 printk(BIOS_DEBUG, "Done MRS commands\n");
4116
4117 /* Prepare for memory training */
4118 prepare_training(ctrl);
4119
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004120 err = read_training(ctrl);
4121 if (err)
4122 return err;
4123
4124 err = write_training(ctrl);
4125 if (err)
4126 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004127
4128 printram("CP5a\n");
4129
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004130 err = discover_edges(ctrl);
4131 if (err)
4132 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004133
4134 printram("CP5b\n");
4135
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004136 err = command_training(ctrl);
4137 if (err)
4138 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004139
4140 printram("CP5c\n");
4141
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004142 err = discover_edges_write(ctrl);
4143 if (err)
4144 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004145
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004146 err = discover_timC_write(ctrl);
4147 if (err)
4148 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004149
4150 normalize_training(ctrl);
4151 }
4152
4153 set_4008c(ctrl);
4154
4155 write_controller_mr(ctrl);
4156
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004157 if (!s3_resume) {
4158 err = channel_test(ctrl);
4159 if (err)
4160 return err;
4161 }
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004162
4163 return 0;
4164}
4165
4166void init_dram_ddr3(spd_raw_data *spds, int mobile, int min_tck,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004167 int s3resume)
4168{
4169 int me_uma_size;
4170 int cbmem_was_inited;
Patrick Rudolph735ecce2016-03-26 10:42:27 +01004171 ramctr_timing ctrl;
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004172 int fast_boot;
4173 struct mrc_data_container *mrc_cache;
4174 ramctr_timing *ctrl_cached;
Patrick Rudolph31d19592016-03-26 12:22:34 +01004175 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004176
4177 MCHBAR32(0x5f00) |= 1;
Stefan Reinauer00636b02012-04-04 00:08:51 +02004178
Vadim Bendebury7a3f36a2012-04-18 15:47:32 -07004179 report_platform_info();
4180
Stefan Reinauer00636b02012-04-04 00:08:51 +02004181 /* Wait for ME to be ready */
4182 intel_early_me_init();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004183 me_uma_size = intel_early_me_uma_size();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004184
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004185 printk(BIOS_DEBUG, "Starting native Platform init\n");
Stefan Reinauer00636b02012-04-04 00:08:51 +02004186
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004187 u32 reg_5d10;
Stefan Reinauer00636b02012-04-04 00:08:51 +02004188
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004189 wait_txt_clear();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004190
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004191 wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 });
Stefan Reinauer00636b02012-04-04 00:08:51 +02004192
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004193 reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000
4194 if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */
4195 && reg_5d10 && !s3resume) {
4196 write32(DEFAULT_MCHBAR + 0x5d10, 0);
4197 /* Need reset. */
Stefan Reinauer00636b02012-04-04 00:08:51 +02004198 outb(0x6, 0xcf9);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004199
Patrick Georgi546953c2014-11-29 10:38:17 +01004200 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004201 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02004202
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004203 memset(&ctrl, 0, sizeof (ctrl));
4204
4205 early_pch_init_native();
4206 early_thermal_init();
4207
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004208 /* try to find timings in MRC cache */
4209 mrc_cache = find_current_mrc_cache();
4210 if (!mrc_cache || (mrc_cache->mrc_data_size < sizeof(ctrl))) {
4211 if (s3resume) {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004212 /* Failed S3 resume, reset to come up cleanly */
4213 outb(0x6, 0xcf9);
4214 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004215 }
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004216 ctrl_cached = NULL;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004217 } else {
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004218 ctrl_cached = (ramctr_timing *)mrc_cache->mrc_data;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004219 }
4220
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004221 /* verify MRC cache for fast boot */
4222 if (ctrl_cached) {
4223 /* check SPD CRC16 to make sure the DIMMs haven't been replaced */
4224 fast_boot = verify_crc16_spds_ddr3(spds, ctrl_cached);
4225 if (!fast_boot)
4226 printk(BIOS_DEBUG, "Stored timings CRC16 mismatch.\n");
4227 if (!fast_boot && s3resume) {
4228 /* Failed S3 resume, reset to come up cleanly */
4229 outb(0x6, 0xcf9);
4230 halt();
4231 }
4232 } else
4233 fast_boot = 0;
4234
4235 if (fast_boot) {
4236 printk(BIOS_DEBUG, "Trying stored timings.\n");
4237 memcpy(&ctrl, ctrl_cached, sizeof(ctrl));
4238
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004239 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004240 if (err) {
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004241 if (s3resume) {
4242 /* Failed S3 resume, reset to come up cleanly */
4243 outb(0x6, 0xcf9);
4244 halt();
4245 }
4246 /* no need to erase bad mrc cache here, it gets overwritten on
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004247 * successful boot. */
4248 printk(BIOS_ERR, "Stored timings are invalid !\n");
4249 fast_boot = 0;
4250 }
4251 }
4252 if (!fast_boot) {
4253 ctrl.mobile = mobile;
4254 ctrl.tCK = min_tck;
4255
4256 /* Get DDR3 SPD data */
4257 dram_find_spds_ddr3(spds, &ctrl);
4258
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004259 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004260 }
Patrick Rudolph2ccb74b2016-03-26 12:16:29 +01004261
4262 if (err && (ctrl.tCK < TCK_400MHZ)) {
4263 /* fallback: lower clock frequency */
4264 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4265 printram("Decreasing clock frequency.\n");
4266 ctrl.tCK++;
4267 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4268 }
4269
4270 if (err && (ctrl.tCK < TCK_400MHZ)) {
4271 /* fallback: lower clock frequency */
4272 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4273 printram("Decreasing clock frequency.\n");
4274 ctrl.tCK++;
4275 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4276 }
4277
4278 if (err) {
4279 /* fallback: disable failing channel */
4280 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4281 printram("Disable failing channel.\n");
4282
4283 /* Reset DDR3 frequency */
4284 dram_find_spds_ddr3(spds, &ctrl);
4285
4286 /* disable failing channel */
4287 disable_channel(&ctrl, GET_ERR_CHANNEL(err));
4288
4289 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4290 }
4291
Patrick Rudolph31d19592016-03-26 12:22:34 +01004292 if (err)
4293 die("raminit failed");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004294
4295 /* FIXME: should be hardware revision-dependent. */
4296 write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
4297
4298 set_scrambling_seed(&ctrl);
4299
4300 set_42a0(&ctrl);
4301
4302 final_registers(&ctrl);
4303
4304 /* Zone config */
4305 dram_zones(&ctrl, 0);
4306
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004307 if (!fast_boot)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004308 quick_ram_check();
4309
4310 intel_early_me_status();
4311 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
4312 intel_early_me_status();
4313
Stefan Reinauer00636b02012-04-04 00:08:51 +02004314 report_memory_config();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004315
4316 cbmem_was_inited = !cbmem_recovery(s3resume);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004317 if (!fast_boot)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004318 save_timings(&ctrl);
4319 if (s3resume && !cbmem_was_inited) {
4320 /* Failed S3 resume, reset to come up cleanly */
4321 outb(0x6, 0xcf9);
4322 halt();
4323 }
Patrick Rudolphb97009e2016-02-28 15:24:04 +01004324
Patrick Rudolph735ecce2016-03-26 10:42:27 +01004325 fill_smbios17(&ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02004326}
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004327
4328#define HOST_BRIDGE PCI_DEVFN(0, 0)
4329#define DEFAULT_TCK TCK_800MHZ
4330
4331static unsigned int get_mem_min_tck(void)
4332{
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004333 u32 reg32;
4334 u8 rev;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004335 const struct device *dev;
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004336 const struct northbridge_intel_sandybridge_config *cfg = NULL;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004337
4338 dev = dev_find_slot(0, HOST_BRIDGE);
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004339 if (dev)
4340 cfg = dev->chip_info;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004341
4342 /* If this is zero, it just means devicetree.cb didn't set it */
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004343 if (!cfg || cfg->max_mem_clock_mhz == 0) {
4344 rev = pci_read_config8(PCI_DEV(0, 0, 0), PCI_DEVICE_ID);
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004345
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004346 if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
4347 /* read Capabilities A Register DMFC bits */
4348 reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A);
4349 reg32 &= 0x7;
4350
4351 switch (reg32) {
4352 case 7: return TCK_533MHZ;
4353 case 6: return TCK_666MHZ;
4354 case 5: return TCK_800MHZ;
4355 /* reserved: */
4356 default:
4357 break;
4358 }
4359 } else {
4360 /* read Capabilities B Register DMFC bits */
4361 reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_B);
4362 reg32 = (reg32 >> 4) & 0x7;
4363
4364 switch (reg32) {
4365 case 7: return TCK_533MHZ;
4366 case 6: return TCK_666MHZ;
4367 case 5: return TCK_800MHZ;
4368 case 4: return TCK_933MHZ;
4369 case 3: return TCK_1066MHZ;
4370 case 2: return TCK_1200MHZ;
4371 case 1: return TCK_1333MHZ;
4372 /* reserved: */
4373 default:
4374 break;
4375 }
4376 }
4377 return DEFAULT_TCK;
4378 } else {
Patrick Rudolph7bddd302016-06-11 18:39:35 +02004379 if (cfg->max_mem_clock_mhz >= 1066)
4380 return TCK_1066MHZ;
4381 else if (cfg->max_mem_clock_mhz >= 933)
4382 return TCK_933MHZ;
4383 else if (cfg->max_mem_clock_mhz >= 800)
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004384 return TCK_800MHZ;
4385 else if (cfg->max_mem_clock_mhz >= 666)
4386 return TCK_666MHZ;
4387 else if (cfg->max_mem_clock_mhz >= 533)
4388 return TCK_533MHZ;
4389 else
4390 return TCK_400MHZ;
4391 }
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004392}
4393
Patrick Rudolph266a1f72016-06-09 18:13:34 +02004394#define DEFAULT_PCI_MMIO_SIZE 2048
4395
4396static unsigned int get_mmio_size(void)
4397{
4398 const struct device *dev;
4399 const struct northbridge_intel_sandybridge_config *cfg = NULL;
4400
4401 dev = dev_find_slot(0, HOST_BRIDGE);
4402 if (dev)
4403 cfg = dev->chip_info;
4404
4405 /* If this is zero, it just means devicetree.cb didn't set it */
4406 if (!cfg || cfg->pci_mmio_size == 0)
4407 return DEFAULT_PCI_MMIO_SIZE;
4408 else
4409 return cfg->pci_mmio_size;
4410}
4411
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004412void perform_raminit(int s3resume)
4413{
4414 spd_raw_data spd[4];
4415
4416 post_code(0x3a);
4417
4418 memset (spd, 0, sizeof (spd));
4419 mainboard_get_spd(spd);
4420
4421 timestamp_add_now(TS_BEFORE_INITRAM);
4422
4423 init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume);
4424}