blob: abb7cebcf277394dcf7578be10daa437cc6f7a88 [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;
659 ctrl->reg_c14_offset = 16;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700660 ctrl->reg_320c_range_threshold = 13;
661 } else if (ctrl->tCK <= TCK_933MHZ) {
662 ctrl->tCK = TCK_933MHZ;
663 ctrl->edge_offset[0] = 14;
664 ctrl->edge_offset[1] = 6;
665 ctrl->edge_offset[2] = 6;
666 ctrl->timC_offset[0] = 15;
667 ctrl->timC_offset[1] = 6;
668 ctrl->timC_offset[2] = 6;
669 ctrl->reg_c14_offset = 14;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700670 ctrl->reg_320c_range_threshold = 15;
671 } else if (ctrl->tCK <= TCK_800MHZ) {
672 ctrl->tCK = TCK_800MHZ;
673 ctrl->edge_offset[0] = 13;
674 ctrl->edge_offset[1] = 5;
675 ctrl->edge_offset[2] = 5;
676 ctrl->timC_offset[0] = 14;
677 ctrl->timC_offset[1] = 5;
678 ctrl->timC_offset[2] = 5;
679 ctrl->reg_c14_offset = 12;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700680 ctrl->reg_320c_range_threshold = 15;
681 } else if (ctrl->tCK <= TCK_666MHZ) {
682 ctrl->tCK = TCK_666MHZ;
683 ctrl->edge_offset[0] = 10;
684 ctrl->edge_offset[1] = 4;
685 ctrl->edge_offset[2] = 4;
686 ctrl->timC_offset[0] = 11;
687 ctrl->timC_offset[1] = 4;
688 ctrl->timC_offset[2] = 4;
689 ctrl->reg_c14_offset = 10;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700690 ctrl->reg_320c_range_threshold = 16;
691 } else if (ctrl->tCK <= TCK_533MHZ) {
692 ctrl->tCK = TCK_533MHZ;
693 ctrl->edge_offset[0] = 8;
694 ctrl->edge_offset[1] = 3;
695 ctrl->edge_offset[2] = 3;
696 ctrl->timC_offset[0] = 9;
697 ctrl->timC_offset[1] = 3;
698 ctrl->timC_offset[2] = 3;
699 ctrl->reg_c14_offset = 8;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700700 ctrl->reg_320c_range_threshold = 17;
701 } else {
702 ctrl->tCK = TCK_400MHZ;
703 ctrl->edge_offset[0] = 6;
704 ctrl->edge_offset[1] = 2;
705 ctrl->edge_offset[2] = 2;
706 ctrl->timC_offset[0] = 6;
707 ctrl->timC_offset[1] = 2;
708 ctrl->timC_offset[2] = 2;
709 ctrl->reg_c14_offset = 8;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700710 ctrl->reg_320c_range_threshold = 17;
711 }
712
Patrick Rudolphb7b1b282016-06-14 18:44:28 +0200713 /* DLL_CONFIG_MDLL_W_TIMER */
714 ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
715
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700716 val32 = (1000 << 8) / ctrl->tCK;
717 printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32);
718
719 /* Find CAS and CWL latencies */
720 val = (ctrl->tAA + ctrl->tCK - 1) / ctrl->tCK;
721 printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val);
722 /* Find lowest supported CAS latency that satisfies the minimum value */
723 while (!((ctrl->cas_supported >> (val - 4)) & 1)
724 && (ctrl->cas_supported >> (val - 4))) {
725 val++;
726 }
727 /* Is CAS supported */
728 if (!(ctrl->cas_supported & (1 << (val - 4))))
729 printk(BIOS_DEBUG, "CAS not supported\n");
730 printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val);
731 ctrl->CAS = val;
732 ctrl->CWL = get_CWL(ctrl->CAS);
733 printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
734
735 /* Find tRCD */
736 ctrl->tRCD = (ctrl->tRCD + ctrl->tCK - 1) / ctrl->tCK;
737 printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD);
738
739 ctrl->tRP = (ctrl->tRP + ctrl->tCK - 1) / ctrl->tCK;
740 printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP);
741
742 /* Find tRAS */
743 ctrl->tRAS = (ctrl->tRAS + ctrl->tCK - 1) / ctrl->tCK;
744 printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS);
745
746 /* Find tWR */
747 ctrl->tWR = (ctrl->tWR + ctrl->tCK - 1) / ctrl->tCK;
748 printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR);
749
750 /* Find tFAW */
751 ctrl->tFAW = (ctrl->tFAW + ctrl->tCK - 1) / ctrl->tCK;
752 printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW);
753
754 /* Find tRRD */
755 ctrl->tRRD = (ctrl->tRRD + ctrl->tCK - 1) / ctrl->tCK;
756 printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD);
757
758 /* Find tRTP */
759 ctrl->tRTP = (ctrl->tRTP + ctrl->tCK - 1) / ctrl->tCK;
760 printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP);
761
762 /* Find tWTR */
763 ctrl->tWTR = (ctrl->tWTR + ctrl->tCK - 1) / ctrl->tCK;
764 printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR);
765
766 /* Refresh-to-Active or Refresh-to-Refresh (tRFC) */
767 ctrl->tRFC = (ctrl->tRFC + ctrl->tCK - 1) / ctrl->tCK;
768 printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC);
769
770 ctrl->tREFI = get_REFI(ctrl->tCK);
771 ctrl->tMOD = get_MOD(ctrl->tCK);
772 ctrl->tXSOffset = get_XSOffset(ctrl->tCK);
773 ctrl->tWLO = get_WLO(ctrl->tCK);
774 ctrl->tCKE = get_CKE(ctrl->tCK);
775 ctrl->tXPDLL = get_XPDLL(ctrl->tCK);
776 ctrl->tXP = get_XP(ctrl->tCK);
777 ctrl->tAONPD = get_AONPD(ctrl->tCK);
778}
779
780static void dram_freq(ramctr_timing * ctrl)
781{
782 if (ctrl->tCK > TCK_400MHZ) {
783 printk (BIOS_ERR, "DRAM frequency is under lowest supported frequency (400 MHz). Increasing to 400 MHz as last resort");
784 ctrl->tCK = TCK_400MHZ;
785 }
786 while (1) {
787 u8 val2;
788 u32 reg1 = 0;
789
790 /* Step 1 - Set target PCU frequency */
791
792 if (ctrl->tCK <= TCK_1066MHZ) {
793 ctrl->tCK = TCK_1066MHZ;
794 } else if (ctrl->tCK <= TCK_933MHZ) {
795 ctrl->tCK = TCK_933MHZ;
796 } else if (ctrl->tCK <= TCK_800MHZ) {
797 ctrl->tCK = TCK_800MHZ;
798 } else if (ctrl->tCK <= TCK_666MHZ) {
799 ctrl->tCK = TCK_666MHZ;
800 } else if (ctrl->tCK <= TCK_533MHZ) {
801 ctrl->tCK = TCK_533MHZ;
802 } else if (ctrl->tCK <= TCK_400MHZ) {
803 ctrl->tCK = TCK_400MHZ;
804 } else {
805 die ("No lock frequency found");
806 }
807
808 /* Frequency mulitplier. */
809 u32 FRQ = get_FRQ(ctrl->tCK);
810
Patrick Rudolph9c9bde32016-03-26 17:20:02 +0100811 /* The PLL will never lock if the required frequency is
812 * already set. Exit early to prevent a system hang.
813 */
814 reg1 = MCHBAR32(0x5e04);
815 val2 = (u8) reg1;
816 if (val2 == FRQ) {
817 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
818 (1000 << 8) / ctrl->tCK);
819 return;
820 }
821
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700822 /* Step 2 - Select frequency in the MCU */
823 reg1 = FRQ;
824 reg1 |= 0x80000000; // set running bit
825 MCHBAR32(0x5e00) = reg1;
826 while (reg1 & 0x80000000) {
827 printk(BIOS_DEBUG, " PLL busy...");
828 reg1 = MCHBAR32(0x5e00);
829 }
830 printk(BIOS_DEBUG, "done\n");
831
832 /* Step 3 - Verify lock frequency */
833 reg1 = MCHBAR32(0x5e04);
834 val2 = (u8) reg1;
835 if (val2 >= FRQ) {
836 printk(BIOS_DEBUG, "MCU frequency is set at : %d MHz\n",
837 (1000 << 8) / ctrl->tCK);
838 return;
839 }
840 printk(BIOS_DEBUG, "PLL didn't lock. Retrying at lower frequency\n");
841 ctrl->tCK++;
842 }
843}
844
845static void dram_xover(ramctr_timing * ctrl)
846{
847 u32 reg;
848 int channel;
849
850 FOR_ALL_CHANNELS {
851 // enable xover clk
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100852 reg = get_XOVER_CLK(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100853 printram("XOVER CLK [%x] = %x\n", channel * 0x100 + 0xc14,
854 reg);
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100855 MCHBAR32(channel * 0x100 + 0xc14) = reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700856
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +0100857 // enable xover ctl & xover cmd
858 reg = get_XOVER_CMD(ctrl->rankmap[channel]);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100859 printram("XOVER CMD [%x] = %x\n", 0x100 * channel + 0x320c,
860 reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700861 MCHBAR32(0x100 * channel + 0x320c) = reg;
862 }
863}
864
865static void dram_timing_regs(ramctr_timing * ctrl)
866{
867 u32 reg, addr, val32, cpu, stretch;
868 struct cpuid_result cpures;
869 int channel;
870
871 FOR_ALL_CHANNELS {
872 // DBP
873 reg = 0;
874 reg |= ctrl->tRCD;
875 reg |= (ctrl->tRP << 4);
876 reg |= (ctrl->CAS << 8);
877 reg |= (ctrl->CWL << 12);
878 reg |= (ctrl->tRAS << 16);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100879 printram("DBP [%x] = %x\n", 0x400 * channel + 0x4000, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700880 MCHBAR32(0x400 * channel + 0x4000) = reg;
881
882 // RAP
883 reg = 0;
884 reg |= ctrl->tRRD;
885 reg |= (ctrl->tRTP << 4);
886 reg |= (ctrl->tCKE << 8);
887 reg |= (ctrl->tWTR << 12);
888 reg |= (ctrl->tFAW << 16);
889 reg |= (ctrl->tWR << 24);
890 reg |= (3 << 30);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100891 printram("RAP [%x] = %x\n", 0x400 * channel + 0x4004, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700892 MCHBAR32(0x400 * channel + 0x4004) = reg;
893
894 // OTHP
895 addr = 0x400 * channel + 0x400c;
896 reg = 0;
897 reg |= ctrl->tXPDLL;
898 reg |= (ctrl->tXP << 5);
899 reg |= (ctrl->tAONPD << 8);
900 reg |= 0xa0000;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100901 printram("OTHP [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700902 MCHBAR32(addr) = reg;
903
904 MCHBAR32(0x400 * channel + 0x4014) = 0;
905
906 MCHBAR32(addr) |= 0x00020000;
907
908 // ODT stretch
909 reg = 0;
910
911 cpures = cpuid(0);
912 cpu = cpures.eax;
913 if (IS_IVY_CPU(cpu)
914 || (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_D2(cpu))) {
915 stretch = 2;
916 addr = 0x400 * channel + 0x400c;
Patrick Rudolpha649a542016-01-17 18:32:06 +0100917 printram("ODT stretch [%x] = %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700918 0x400 * channel + 0x400c, reg);
919 reg = MCHBAR32(addr);
920
921 if (((ctrl->rankmap[channel] & 3) == 0)
922 || (ctrl->rankmap[channel] & 0xc) == 0) {
923
924 // Rank 0 - operate on rank 2
925 reg = (reg & ~0xc0000) | (stretch << 18);
926
927 // Rank 2 - operate on rank 0
928 reg = (reg & ~0x30000) | (stretch << 16);
929
Patrick Rudolpha649a542016-01-17 18:32:06 +0100930 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700931 MCHBAR32(addr) = reg;
932 }
933
934 } else if (IS_SANDY_CPU(cpu) && IS_SANDY_CPU_C(cpu)) {
935 stretch = 3;
936 addr = 0x400 * channel + 0x401c;
937 reg = MCHBAR32(addr);
938
939 if (((ctrl->rankmap[channel] & 3) == 0)
940 || (ctrl->rankmap[channel] & 0xc) == 0) {
941
942 // Rank 0 - operate on rank 2
943 reg = (reg & ~0x3000) | (stretch << 12);
944
945 // Rank 2 - operate on rank 0
946 reg = (reg & ~0xc00) | (stretch << 10);
947
Patrick Rudolpha649a542016-01-17 18:32:06 +0100948 printram("ODT stretch [%x] = %x\n", addr, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700949 MCHBAR32(addr) = reg;
950 }
951 } else {
952 stretch = 0;
953 }
954
955 // REFI
956 reg = 0;
957 val32 = ctrl->tREFI;
958 reg = (reg & ~0xffff) | val32;
959 val32 = ctrl->tRFC;
960 reg = (reg & ~0x1ff0000) | (val32 << 16);
961 val32 = (u32) (ctrl->tREFI * 9) / 1024;
962 reg = (reg & ~0xfe000000) | (val32 << 25);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100963 printram("REFI [%x] = %x\n", 0x400 * channel + 0x4298,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700964 reg);
965 MCHBAR32(0x400 * channel + 0x4298) = reg;
966
967 MCHBAR32(0x400 * channel + 0x4294) |= 0xff;
968
969 // SRFTP
970 reg = 0;
971 val32 = tDLLK;
972 reg = (reg & ~0xfff) | val32;
973 val32 = ctrl->tXSOffset;
974 reg = (reg & ~0xf000) | (val32 << 12);
975 val32 = tDLLK - ctrl->tXSOffset;
976 reg = (reg & ~0x3ff0000) | (val32 << 16);
977 val32 = ctrl->tMOD - 8;
978 reg = (reg & ~0xf0000000) | (val32 << 28);
Patrick Rudolpha649a542016-01-17 18:32:06 +0100979 printram("SRFTP [%x] = %x\n", 0x400 * channel + 0x42a4,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700980 reg);
981 MCHBAR32(0x400 * channel + 0x42a4) = reg;
982 }
983}
984
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100985static void dram_dimm_mapping(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700986{
987 u32 reg, val32;
988 int channel;
Patrick Rudolph735ecce2016-03-26 10:42:27 +0100989 dimm_info *info = &ctrl->info;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -0700990
991 FOR_ALL_CHANNELS {
992 dimm_attr *dimmA = 0;
993 dimm_attr *dimmB = 0;
994 reg = 0;
995 val32 = 0;
996 if (info->dimm[channel][0].size_mb >=
997 info->dimm[channel][1].size_mb) {
998 // dimm 0 is bigger, set it to dimmA
999 dimmA = &info->dimm[channel][0];
1000 dimmB = &info->dimm[channel][1];
1001 reg |= (0 << 16);
1002 } else {
1003 // dimm 1 is bigger, set it to dimmA
1004 dimmA = &info->dimm[channel][1];
1005 dimmB = &info->dimm[channel][0];
1006 reg |= (1 << 16);
1007 }
1008 // dimmA
1009 if (dimmA && (dimmA->ranks > 0)) {
1010 val32 = dimmA->size_mb / 256;
1011 reg = (reg & ~0xff) | val32;
1012 val32 = dimmA->ranks - 1;
1013 reg = (reg & ~0x20000) | (val32 << 17);
1014 val32 = (dimmA->width / 8) - 1;
1015 reg = (reg & ~0x80000) | (val32 << 19);
1016 }
1017 // dimmB
1018 if (dimmB && (dimmB->ranks > 0)) {
1019 val32 = dimmB->size_mb / 256;
1020 reg = (reg & ~0xff00) | (val32 << 8);
1021 val32 = dimmB->ranks - 1;
1022 reg = (reg & ~0x40000) | (val32 << 18);
1023 val32 = (dimmB->width / 8) - 1;
1024 reg = (reg & ~0x100000) | (val32 << 20);
1025 }
1026 reg = (reg & ~0x200000) | (1 << 21); // rank interleave
1027 reg = (reg & ~0x400000) | (1 << 22); // enhanced interleave
1028
1029 // Save MAD-DIMM register
1030 if ((dimmA && (dimmA->ranks > 0))
1031 || (dimmB && (dimmB->ranks > 0))) {
1032 ctrl->mad_dimm[channel] = reg;
1033 } else {
1034 ctrl->mad_dimm[channel] = 0;
1035 }
1036 }
1037}
1038
1039static void dram_dimm_set_mapping(ramctr_timing * ctrl)
1040{
1041 int channel;
1042 FOR_ALL_CHANNELS {
1043 MCHBAR32(0x5004 + channel * 4) = ctrl->mad_dimm[channel];
1044 }
1045}
1046
1047static void dram_zones(ramctr_timing * ctrl, int training)
1048{
1049 u32 reg, ch0size, ch1size;
1050 u8 val;
1051 reg = 0;
1052 val = 0;
1053 if (training) {
1054 ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
1055 ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
1056 } else {
1057 ch0size = ctrl->channel_size_mb[0];
1058 ch1size = ctrl->channel_size_mb[1];
1059 }
1060
1061 if (ch0size >= ch1size) {
1062 reg = MCHBAR32(0x5014);
1063 val = ch1size / 256;
1064 reg = (reg & ~0xff000000) | val << 24;
1065 reg = (reg & ~0xff0000) | (2 * val) << 16;
1066 MCHBAR32(0x5014) = reg;
1067 MCHBAR32(0x5000) = 0x24;
1068 } else {
1069 reg = MCHBAR32(0x5014);
1070 val = ch0size / 256;
1071 reg = (reg & ~0xff000000) | val << 24;
1072 reg = (reg & ~0xff0000) | (2 * val) << 16;
1073 MCHBAR32(0x5014) = reg;
1074 MCHBAR32(0x5000) = 0x21;
1075 }
1076}
1077
1078static void dram_memorymap(ramctr_timing * ctrl, int me_uma_size)
1079{
1080 u32 reg, val, reclaim;
1081 u32 tom, gfxstolen, gttsize;
1082 size_t tsegsize, mmiosize, toludbase, touudbase, gfxstolenbase, gttbase,
1083 tsegbase, mestolenbase;
1084 size_t tsegbasedelta, remapbase, remaplimit;
1085 uint16_t ggc;
1086
Patrick Rudolph266a1f72016-06-09 18:13:34 +02001087 mmiosize = get_mmio_size();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001088
1089 ggc = pci_read_config16(NORTHBRIDGE, GGC);
1090 if (!(ggc & 2)) {
1091 gfxstolen = ((ggc >> 3) & 0x1f) * 32;
1092 gttsize = ((ggc >> 8) & 0x3);
1093 } else {
1094 gfxstolen = 0;
1095 gttsize = 0;
1096 }
1097
1098 tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;
1099
1100 tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];
1101
1102 mestolenbase = tom - me_uma_size;
1103
1104 toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize,
1105 tom - me_uma_size);
1106 gfxstolenbase = toludbase - gfxstolen;
1107 gttbase = gfxstolenbase - gttsize;
1108
1109 tsegbase = gttbase - tsegsize;
1110
1111 // Round tsegbase down to nearest address aligned to tsegsize
1112 tsegbasedelta = tsegbase & (tsegsize - 1);
1113 tsegbase &= ~(tsegsize - 1);
1114
1115 gttbase -= tsegbasedelta;
1116 gfxstolenbase -= tsegbasedelta;
1117 toludbase -= tsegbasedelta;
1118
1119 // Test if it is possible to reclaim a hole in the ram addressing
1120 if (tom - me_uma_size > toludbase) {
1121 // Reclaim is possible
1122 reclaim = 1;
1123 remapbase = MAX(4096, tom - me_uma_size);
1124 remaplimit =
1125 remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
1126 touudbase = remaplimit + 1;
1127 } else {
1128 // Reclaim not possible
1129 reclaim = 0;
1130 touudbase = tom - me_uma_size;
1131 }
1132
1133 // Update memory map in pci-e configuration space
Patrick Rudolpha649a542016-01-17 18:32:06 +01001134 printk(BIOS_DEBUG, "Update PCI-E configuration space:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001135
1136 // TOM (top of memory)
1137 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa0);
1138 val = tom & 0xfff;
1139 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001140 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001141 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa0, reg);
1142
1143 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa4);
1144 val = tom & 0xfffff000;
1145 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001146 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001147 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa4, reg);
1148
1149 // TOLUD (top of low used dram)
1150 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xbc);
1151 val = toludbase & 0xfff;
1152 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001153 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xbc, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001154 pcie_write_config32(PCI_DEV(0, 0, 0), 0xbc, reg);
1155
1156 // TOUUD LSB (top of upper usable dram)
1157 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xa8);
1158 val = touudbase & 0xfff;
1159 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001160 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xa8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001161 pcie_write_config32(PCI_DEV(0, 0, 0), 0xa8, reg);
1162
1163 // TOUUD MSB
1164 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xac);
1165 val = touudbase & 0xfffff000;
1166 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001167 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xac, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001168 pcie_write_config32(PCI_DEV(0, 0, 0), 0xac, reg);
1169
1170 if (reclaim) {
1171 // REMAP BASE
1172 pcie_write_config32(PCI_DEV(0, 0, 0), 0x90, remapbase << 20);
1173 pcie_write_config32(PCI_DEV(0, 0, 0), 0x94, remapbase >> 12);
1174
1175 // REMAP LIMIT
1176 pcie_write_config32(PCI_DEV(0, 0, 0), 0x98, remaplimit << 20);
1177 pcie_write_config32(PCI_DEV(0, 0, 0), 0x9c, remaplimit >> 12);
1178 }
1179 // TSEG
1180 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb8);
1181 val = tsegbase & 0xfff;
1182 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001183 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb8, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001184 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb8, reg);
1185
1186 // GFX stolen memory
1187 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb0);
1188 val = gfxstolenbase & 0xfff;
1189 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001190 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb0, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001191 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb0, reg);
1192
1193 // GTT stolen memory
1194 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0xb4);
1195 val = gttbase & 0xfff;
1196 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001197 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0xb4, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001198 pcie_write_config32(PCI_DEV(0, 0, 0), 0xb4, reg);
1199
1200 if (me_uma_size) {
1201 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x7c);
1202 val = (0x80000 - me_uma_size) & 0xfffff000;
1203 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001204 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x7c, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001205 pcie_write_config32(PCI_DEV(0, 0, 0), 0x7c, reg);
1206
1207 // ME base
1208 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x70);
1209 val = mestolenbase & 0xfff;
1210 reg = (reg & ~0xfff00000) | (val << 20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001211 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x70, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001212 pcie_write_config32(PCI_DEV(0, 0, 0), 0x70, reg);
1213
1214 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x74);
1215 val = mestolenbase & 0xfffff000;
1216 reg = (reg & ~0x000fffff) | (val >> 12);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001217 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x74, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001218 pcie_write_config32(PCI_DEV(0, 0, 0), 0x74, reg);
1219
1220 // ME mask
1221 reg = pcie_read_config32(PCI_DEV(0, 0, 0), 0x78);
1222 val = (0x80000 - me_uma_size) & 0xfff;
1223 reg = (reg & ~0xfff00000) | (val << 20);
1224 reg = (reg & ~0x400) | (1 << 10); // set lockbit on ME mem
1225
1226 reg = (reg & ~0x800) | (1 << 11); // set ME memory enable
Patrick Rudolpha649a542016-01-17 18:32:06 +01001227 printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", 0x78, reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001228 pcie_write_config32(PCI_DEV(0, 0, 0), 0x78, reg);
1229 }
1230}
1231
1232static void dram_ioregs(ramctr_timing * ctrl)
1233{
1234 u32 reg, comp2;
1235
1236 int channel;
1237
1238 // IO clock
1239 FOR_ALL_CHANNELS {
1240 MCHBAR32(0xc00 + 0x100 * channel) = ctrl->rankmap[channel];
1241 }
1242
1243 // IO command
1244 FOR_ALL_CHANNELS {
1245 MCHBAR32(0x3200 + 0x100 * channel) = ctrl->rankmap[channel];
1246 }
1247
1248 // IO control
1249 FOR_ALL_POPULATED_CHANNELS {
1250 program_timings(ctrl, channel);
1251 }
1252
1253 // Rcomp
Patrick Rudolpha649a542016-01-17 18:32:06 +01001254 printram("RCOMP...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001255 reg = 0;
1256 while (reg == 0) {
1257 reg = MCHBAR32(0x5084) & 0x10000;
1258 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001259 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001260
1261 // Set comp2
1262 comp2 = get_COMP2(ctrl->tCK);
1263 MCHBAR32(0x3714) = comp2;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001264 printram("COMP2 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001265
1266 // Set comp1
1267 FOR_ALL_POPULATED_CHANNELS {
1268 reg = MCHBAR32(0x1810 + channel * 0x100); //ch0
1269 reg = (reg & ~0xe00) | (1 << 9); //odt
1270 reg = (reg & ~0xe00000) | (1 << 21); //clk drive up
1271 reg = (reg & ~0x38000000) | (1 << 27); //ctl drive up
1272 MCHBAR32(0x1810 + channel * 0x100) = reg;
1273 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01001274 printram("COMP1 done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001275
Patrick Rudolpha649a542016-01-17 18:32:06 +01001276 printram("FORCE RCOMP and wait 20us...");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001277 MCHBAR32(0x5f08) |= 0x100;
1278 udelay(20);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001279 printram("done\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001280}
1281
1282static void wait_428c(int channel)
1283{
1284 while (1) {
1285 if (read32(DEFAULT_MCHBAR + 0x428c + (channel << 10)) & 0x50)
1286 return;
1287 }
1288}
1289
1290static void write_reset(ramctr_timing * ctrl)
1291{
1292 int channel, slotrank;
1293
1294 /* choose a populated channel. */
1295 channel = (ctrl->rankmap[0]) ? 0 : 1;
1296
1297 wait_428c(channel);
1298
1299 /* choose a populated rank. */
1300 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
1301
Patrick Rudolph371d2912015-10-09 13:33:25 +02001302 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001303 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1304 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x80c01);
1305
1306 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1307 (slotrank << 24) | 0x60000);
1308
1309 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1310
1311 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x400001);
1312 wait_428c(channel);
1313}
1314
1315static void dram_jedecreset(ramctr_timing * ctrl)
1316{
1317 u32 reg, addr;
1318 int channel;
1319
1320 while (!(MCHBAR32(0x5084) & 0x10000)) ;
1321 do {
1322 reg = MCHBAR32(0x428c);
1323 } while ((reg & 0x14) == 0);
1324
1325 // Set state of memory controller
1326 reg = 0x112;
1327 MCHBAR32(0x5030) = reg;
1328 MCHBAR32(0x4ea0) = 0;
1329 reg |= 2; //ddr reset
1330 MCHBAR32(0x5030) = reg;
1331
1332 // Assert dimm reset signal
1333 reg = MCHBAR32(0x5030);
1334 reg &= ~0x2;
1335 MCHBAR32(0x5030) = reg;
1336
1337 // Wait 200us
1338 udelay(200);
1339
1340 // Deassert dimm reset signal
1341 MCHBAR32(0x5030) |= 2;
1342
1343 // Wait 500us
1344 udelay(500);
1345
1346 // Enable DCLK
1347 MCHBAR32(0x5030) |= 4;
1348
1349 // XXX Wait 20ns
1350 udelay(1);
1351
1352 FOR_ALL_CHANNELS {
1353 // Set valid rank CKE
1354 reg = 0;
1355 reg = (reg & ~0xf) | ctrl->rankmap[channel];
1356 addr = 0x400 * channel + 0x42a0;
1357 MCHBAR32(addr) = reg;
1358
1359 // Wait 10ns for ranks to settle
1360 //udelay(0.01);
1361
1362 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
1363 MCHBAR32(addr) = reg;
1364
1365 // Write reset using a NOP
1366 write_reset(ctrl);
1367 }
1368}
1369
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001370static odtmap get_ODT(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001371{
1372 /* Get ODT based on rankmap: */
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001373 int dimms_per_ch = (ctrl->rankmap[channel] & 1)
1374 + ((ctrl->rankmap[channel] >> 2) & 1);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001375
1376 if (dimms_per_ch == 1) {
1377 return (const odtmap){60, 60};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001378 } else {
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001379 return (const odtmap){120, 30};
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001380 }
1381}
1382
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001383static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001384 int reg, u32 val)
1385{
1386 wait_428c(channel);
1387
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001388 if (ctrl->rank_mirror[channel][slotrank]) {
1389 /* DDR3 Rank1 Address mirror
1390 * swap the following pins:
1391 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1 */
1392 reg = ((reg >> 1) & 1) | ((reg << 1) & 2);
1393 val = (val & ~0x1f8) | ((val >> 1) & 0xa8)
1394 | ((val & 0xa8) << 1);
1395 }
1396
Patrick Rudolph371d2912015-10-09 13:33:25 +02001397 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001398 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f000);
1399 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
1400 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1401 (slotrank << 24) | (reg << 20) | val | 0x60000);
1402 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1403
Patrick Rudolph371d2912015-10-09 13:33:25 +02001404 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001405 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f000);
1406 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x41001);
1407 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
1408 (slotrank << 24) | (reg << 20) | val | 0x60000);
1409 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1410
Patrick Rudolph371d2912015-10-09 13:33:25 +02001411 /* DRAM command MRS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001412 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x0f000);
1413 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1414 0x1001 | (ctrl->tMOD << 16));
1415 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1416 (slotrank << 24) | (reg << 20) | val | 0x60000);
1417 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1418 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
1419}
1420
1421static u32 make_mr0(ramctr_timing * ctrl, u8 rank)
1422{
1423 u16 mr0reg, mch_cas, mch_wr;
1424 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 +02001425
1426 /* DLL Reset - self clearing - set after CLK frequency has been changed */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001427 mr0reg = 0x100;
1428
1429 // Convert CAS to MCH register friendly
1430 if (ctrl->CAS < 12) {
1431 mch_cas = (u16) ((ctrl->CAS - 4) << 1);
1432 } else {
1433 mch_cas = (u16) (ctrl->CAS - 12);
1434 mch_cas = ((mch_cas << 1) | 0x1);
1435 }
1436
1437 // Convert tWR to MCH register friendly
1438 mch_wr = mch_wr_t[ctrl->tWR - 5];
1439
1440 mr0reg = (mr0reg & ~0x4) | (mch_cas & 0x1);
1441 mr0reg = (mr0reg & ~0x70) | ((mch_cas & 0xe) << 3);
1442 mr0reg = (mr0reg & ~0xe00) | (mch_wr << 9);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001443
1444 // Precharge PD - Fast (desktop) 0x1 or slow (mobile) 0x0 - mostly power-saving feature
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001445 mr0reg = (mr0reg & ~0x1000) | (!ctrl->mobile << 12);
1446 return mr0reg;
1447}
1448
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001449static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001450{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001451 write_mrreg(ctrl, channel, rank, 0,
1452 make_mr0(ctrl, rank));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001453}
1454
1455static u32 encode_odt(u32 odt)
1456{
1457 switch (odt) {
1458 case 30:
1459 return (1 << 9) | (1 << 2); // RZQ/8, RZQ/4
1460 case 60:
1461 return (1 << 2); // RZQ/4
1462 case 120:
1463 return (1 << 6); // RZQ/2
1464 default:
1465 case 0:
1466 return 0;
1467 }
1468}
1469
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001470static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001471{
1472 odtmap odt;
1473 u32 mr1reg;
1474
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001475 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001476 mr1reg = 0x2;
1477
1478 mr1reg |= encode_odt(odt.rttnom);
1479
1480 return mr1reg;
1481}
1482
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001483static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001484{
1485 u16 mr1reg;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001486
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001487 mr1reg = make_mr1(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001488
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001489 write_mrreg(ctrl, channel, rank, 1, mr1reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001490}
1491
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001492static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001493{
1494 u16 pasr, cwl, mr2reg;
1495 odtmap odt;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001496 int srt;
1497
1498 pasr = 0;
1499 cwl = ctrl->CWL - 5;
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001500 odt = get_ODT(ctrl, rank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001501
1502 srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;
1503
1504 mr2reg = 0;
1505 mr2reg = (mr2reg & ~0x7) | pasr;
1506 mr2reg = (mr2reg & ~0x38) | (cwl << 3);
1507 mr2reg = (mr2reg & ~0x40) | (ctrl->auto_self_refresh << 6);
1508 mr2reg = (mr2reg & ~0x80) | (srt << 7);
1509 mr2reg |= (odt.rttwr / 60) << 9;
1510
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001511 write_mrreg(ctrl, channel, rank, 2, mr2reg);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001512}
1513
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001514static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001515{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001516 write_mrreg(ctrl, channel, rank, 3, 0);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001517}
1518
1519static void dram_mrscommands(ramctr_timing * ctrl)
1520{
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001521 u8 slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001522 u32 reg, addr;
1523 int channel;
1524
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001525 FOR_ALL_POPULATED_CHANNELS {
1526 FOR_ALL_POPULATED_RANKS {
1527 // MR2
1528 dram_mr2(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001529
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001530 // MR3
1531 dram_mr3(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001532
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001533 // MR1
1534 dram_mr1(ctrl, slotrank, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001535
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001536 // MR0
1537 dram_mr0(ctrl, slotrank, channel);
1538 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001539 }
1540
Patrick Rudolph371d2912015-10-09 13:33:25 +02001541 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001542 write32(DEFAULT_MCHBAR + 0x4e20, 0x7);
1543 write32(DEFAULT_MCHBAR + 0x4e30, 0xf1001);
1544 write32(DEFAULT_MCHBAR + 0x4e00, 0x60002);
1545 write32(DEFAULT_MCHBAR + 0x4e10, 0);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001546
1547 /* DRAM command ZQCL */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001548 write32(DEFAULT_MCHBAR + 0x4e24, 0x1f003);
1549 write32(DEFAULT_MCHBAR + 0x4e34, 0x1901001);
1550 write32(DEFAULT_MCHBAR + 0x4e04, 0x60400);
1551 write32(DEFAULT_MCHBAR + 0x4e14, 0x288);
Patrick Rudolph371d2912015-10-09 13:33:25 +02001552
1553 /* execute command queue on all channels ? */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001554 write32(DEFAULT_MCHBAR + 0x4e84, 0x40004);
1555
1556 // Drain
1557 FOR_ALL_CHANNELS {
1558 // Wait for ref drained
1559 wait_428c(channel);
1560 }
1561
1562 // Refresh enable
1563 MCHBAR32(0x5030) |= 8;
1564
1565 FOR_ALL_POPULATED_CHANNELS {
1566 addr = 0x400 * channel + 0x4020;
1567 reg = MCHBAR32(addr);
1568 reg &= ~0x200000;
1569 MCHBAR32(addr) = reg;
1570
1571 wait_428c(channel);
1572
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001573 slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001574
1575 // Drain
1576 wait_428c(channel);
1577
Patrick Rudolph371d2912015-10-09 13:33:25 +02001578 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001579 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
1580 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
1581 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01001582 (slotrank << 24) | 0x60000);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001583 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
1584 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x1);
1585
1586 // Drain
1587 wait_428c(channel);
1588 }
1589}
1590
1591const u32 lane_registers[] = {
1592 0x0000, 0x0200, 0x0400, 0x0600,
1593 0x1000, 0x1200, 0x1400, 0x1600,
1594 0x0800
1595};
1596
1597static void program_timings(ramctr_timing * ctrl, int channel)
1598{
1599 u32 reg32, reg_4024, reg_c14, reg_c18, reg_4028;
1600 int lane;
1601 int slotrank, slot;
1602 int full_shift = 0;
1603 u16 slot320c[NUM_SLOTS];
1604
1605 FOR_ALL_POPULATED_RANKS {
1606 if (full_shift < -ctrl->timings[channel][slotrank].val_320c)
1607 full_shift = -ctrl->timings[channel][slotrank].val_320c;
1608 }
1609
1610 for (slot = 0; slot < NUM_SLOTS; slot++)
1611 switch ((ctrl->rankmap[channel] >> (2 * slot)) & 3) {
1612 case 0:
1613 default:
1614 slot320c[slot] = 0x7f;
1615 break;
1616 case 1:
1617 slot320c[slot] =
1618 ctrl->timings[channel][2 * slot + 0].val_320c +
1619 full_shift;
1620 break;
1621 case 2:
1622 slot320c[slot] =
1623 ctrl->timings[channel][2 * slot + 1].val_320c +
1624 full_shift;
1625 break;
1626 case 3:
1627 slot320c[slot] =
1628 (ctrl->timings[channel][2 * slot].val_320c +
1629 ctrl->timings[channel][2 * slot +
1630 1].val_320c) / 2 +
1631 full_shift;
1632 break;
1633 }
1634
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001635 /* enable CMD XOVER */
1636 reg32 = get_XOVER_CMD(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001637 reg32 |= ((slot320c[0] & 0x3f) << 6) | ((slot320c[0] & 0x40) << 9);
1638 reg32 |= (slot320c[1] & 0x7f) << 18;
1639 reg32 |= (full_shift & 0x3f) | ((full_shift & 0x40) << 6);
1640
1641 MCHBAR32(0x320c + 0x100 * channel) = reg32;
1642
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001643 /* enable CLK XOVER */
1644 reg_c14 = get_XOVER_CLK(ctrl->rankmap[channel]);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001645 reg_c18 = 0;
1646
1647 FOR_ALL_POPULATED_RANKS {
1648 int shift =
1649 ctrl->timings[channel][slotrank].val_320c + full_shift;
1650 int offset_val_c14;
1651 if (shift < 0)
1652 shift = 0;
1653 offset_val_c14 = ctrl->reg_c14_offset + shift;
Patrick Rudolpha1c3bed2016-01-24 14:07:15 +01001654 /* set CLK phase shift */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001655 reg_c14 |= (offset_val_c14 & 0x3f) << (6 * slotrank);
1656 reg_c18 |= ((offset_val_c14 >> 6) & 1) << slotrank;
1657 }
1658
1659 MCHBAR32(0xc14 + channel * 0x100) = reg_c14;
1660 MCHBAR32(0xc18 + channel * 0x100) = reg_c18;
1661
1662 reg_4028 = MCHBAR32(0x4028 + 0x400 * channel);
1663 reg_4028 &= 0xffff0000;
1664
1665 reg_4024 = 0;
1666
1667 FOR_ALL_POPULATED_RANKS {
1668 int post_timA_min_high = 7, post_timA_max_high = 0;
1669 int pre_timA_min_high = 7, pre_timA_max_high = 0;
1670 int shift_402x = 0;
1671 int shift =
1672 ctrl->timings[channel][slotrank].val_320c + full_shift;
1673
1674 if (shift < 0)
1675 shift = 0;
1676
1677 FOR_ALL_LANES {
1678 if (post_timA_min_high >
1679 ((ctrl->timings[channel][slotrank].lanes[lane].
1680 timA + shift) >> 6))
1681 post_timA_min_high =
1682 ((ctrl->timings[channel][slotrank].
1683 lanes[lane].timA + shift) >> 6);
1684 if (pre_timA_min_high >
1685 (ctrl->timings[channel][slotrank].lanes[lane].
1686 timA >> 6))
1687 pre_timA_min_high =
1688 (ctrl->timings[channel][slotrank].
1689 lanes[lane].timA >> 6);
1690 if (post_timA_max_high <
1691 ((ctrl->timings[channel][slotrank].lanes[lane].
1692 timA + shift) >> 6))
1693 post_timA_max_high =
1694 ((ctrl->timings[channel][slotrank].
1695 lanes[lane].timA + shift) >> 6);
1696 if (pre_timA_max_high <
1697 (ctrl->timings[channel][slotrank].lanes[lane].
1698 timA >> 6))
1699 pre_timA_max_high =
1700 (ctrl->timings[channel][slotrank].
1701 lanes[lane].timA >> 6);
1702 }
1703
1704 if (pre_timA_max_high - pre_timA_min_high <
1705 post_timA_max_high - post_timA_min_high)
1706 shift_402x = +1;
1707 else if (pre_timA_max_high - pre_timA_min_high >
1708 post_timA_max_high - post_timA_min_high)
1709 shift_402x = -1;
1710
1711 reg_4028 |=
1712 (ctrl->timings[channel][slotrank].val_4028 + shift_402x -
1713 post_timA_min_high) << (4 * slotrank);
1714 reg_4024 |=
1715 (ctrl->timings[channel][slotrank].val_4024 +
1716 shift_402x) << (8 * slotrank);
1717
1718 FOR_ALL_LANES {
1719 MCHBAR32(lane_registers[lane] + 0x10 + 0x100 * channel +
1720 4 * slotrank)
1721 =
1722 (((ctrl->timings[channel][slotrank].lanes[lane].
1723 timA + shift) & 0x3f)
1724 |
1725 ((ctrl->timings[channel][slotrank].lanes[lane].
1726 rising + shift) << 8)
1727 |
1728 (((ctrl->timings[channel][slotrank].lanes[lane].
1729 timA + shift -
1730 (post_timA_min_high << 6)) & 0x1c0) << 10)
Patrick Rudolph0188b132016-02-10 19:16:34 +01001731 | ((ctrl->timings[channel][slotrank].lanes[lane].
1732 falling + shift) << 20));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001733
1734 MCHBAR32(lane_registers[lane] + 0x20 + 0x100 * channel +
1735 4 * slotrank)
1736 =
1737 (((ctrl->timings[channel][slotrank].lanes[lane].
1738 timC + shift) & 0x3f)
1739 |
1740 (((ctrl->timings[channel][slotrank].lanes[lane].
1741 timB + shift) & 0x3f) << 8)
1742 |
1743 (((ctrl->timings[channel][slotrank].lanes[lane].
1744 timB + shift) & 0x1c0) << 9)
1745 |
1746 (((ctrl->timings[channel][slotrank].lanes[lane].
1747 timC + shift) & 0x40) << 13));
1748 }
1749 }
1750 MCHBAR32(0x4024 + 0x400 * channel) = reg_4024;
1751 MCHBAR32(0x4028 + 0x400 * channel) = reg_4028;
1752}
1753
1754static void test_timA(ramctr_timing * ctrl, int channel, int slotrank)
1755{
1756 wait_428c(channel);
1757
Patrick Rudolph371d2912015-10-09 13:33:25 +02001758 /* DRAM command MRS
1759 * write MR3 MPR enable
1760 * in this mode only RD and RDA are allowed
1761 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001762 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
1763 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
1764 (0xc01 | (ctrl->tMOD << 16)));
1765 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
1766 (slotrank << 24) | 0x360004);
1767 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
1768
Patrick Rudolph371d2912015-10-09 13:33:25 +02001769 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001770 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
1771 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x4040c01);
1772 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel, (slotrank << 24));
1773 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
1774
Patrick Rudolph371d2912015-10-09 13:33:25 +02001775 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001776 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
1777 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
1778 0x100f | ((ctrl->CAS + 36) << 16));
1779 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
1780 (slotrank << 24) | 0x60000);
1781 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
1782
Patrick Rudolph371d2912015-10-09 13:33:25 +02001783 /* DRAM command MRS
1784 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001785 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
1786 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
1787 (0xc01 | (ctrl->tMOD << 16)));
1788 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
1789 (slotrank << 24) | 0x360000);
1790 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
1791
1792 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
1793
1794 wait_428c(channel);
1795}
1796
1797static int does_lane_work(ramctr_timing * ctrl, int channel, int slotrank,
1798 int lane)
1799{
1800 u32 timA = ctrl->timings[channel][slotrank].lanes[lane].timA;
1801 return ((read32
1802 (DEFAULT_MCHBAR + lane_registers[lane] + channel * 0x100 + 4 +
1803 ((timA / 32) & 1) * 4)
1804 >> (timA % 32)) & 1);
1805}
1806
1807struct run {
1808 int middle;
1809 int end;
1810 int start;
1811 int all;
1812 int length;
1813};
1814
1815static struct run get_longest_zero_run(int *seq, int sz)
1816{
1817 int i, ls;
1818 int bl = 0, bs = 0;
1819 struct run ret;
1820
1821 ls = 0;
1822 for (i = 0; i < 2 * sz; i++)
1823 if (seq[i % sz]) {
1824 if (i - ls > bl) {
1825 bl = i - ls;
1826 bs = ls;
1827 }
1828 ls = i + 1;
1829 }
1830 if (bl == 0) {
1831 ret.middle = sz / 2;
1832 ret.start = 0;
1833 ret.end = sz;
1834 ret.all = 1;
1835 return ret;
1836 }
1837
1838 ret.start = bs % sz;
1839 ret.end = (bs + bl - 1) % sz;
1840 ret.middle = (bs + (bl - 1) / 2) % sz;
1841 ret.length = bl;
1842 ret.all = 0;
1843
1844 return ret;
1845}
1846
1847static void discover_timA_coarse(ramctr_timing * ctrl, int channel,
1848 int slotrank, int *upperA)
1849{
1850 int timA;
1851 int statistics[NUM_LANES][128];
1852 int lane;
1853
1854 for (timA = 0; timA < 128; timA++) {
1855 FOR_ALL_LANES {
1856 ctrl->timings[channel][slotrank].lanes[lane].timA = timA;
1857 }
1858 program_timings(ctrl, channel);
1859
1860 test_timA(ctrl, channel, slotrank);
1861
1862 FOR_ALL_LANES {
1863 statistics[lane][timA] =
1864 !does_lane_work(ctrl, channel, slotrank, lane);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001865 printram("Astat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001866 channel, slotrank, lane, timA,
1867 statistics[lane][timA]);
1868 }
1869 }
1870 FOR_ALL_LANES {
1871 struct run rn = get_longest_zero_run(statistics[lane], 128);
1872 ctrl->timings[channel][slotrank].lanes[lane].timA = rn.middle;
1873 upperA[lane] = rn.end;
1874 if (upperA[lane] < rn.middle)
1875 upperA[lane] += 128;
Patrick Rudolpha649a542016-01-17 18:32:06 +01001876 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001877 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
Patrick Rudolpha649a542016-01-17 18:32:06 +01001878 printram("Aend: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001879 lane, upperA[lane]);
1880 }
1881}
1882
1883static void discover_timA_fine(ramctr_timing * ctrl, int channel, int slotrank,
1884 int *upperA)
1885{
1886 int timA_delta;
1887 int statistics[NUM_LANES][51];
1888 int lane, i;
1889
1890 memset(statistics, 0, sizeof(statistics));
1891
1892 for (timA_delta = -25; timA_delta <= 25; timA_delta++) {
1893 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
1894 timA = upperA[lane] + timA_delta + 0x40;
1895 program_timings(ctrl, channel);
1896
1897 for (i = 0; i < 100; i++) {
1898 test_timA(ctrl, channel, slotrank);
1899 FOR_ALL_LANES {
1900 statistics[lane][timA_delta + 25] +=
1901 does_lane_work(ctrl, channel, slotrank,
1902 lane);
1903 }
1904 }
1905 }
1906 FOR_ALL_LANES {
1907 int last_zero, first_all;
1908
1909 for (last_zero = -25; last_zero <= 25; last_zero++)
1910 if (statistics[lane][last_zero + 25])
1911 break;
1912 last_zero--;
1913 for (first_all = -25; first_all <= 25; first_all++)
1914 if (statistics[lane][first_all + 25] == 100)
1915 break;
1916
1917 printram("lane %d: %d, %d\n", lane, last_zero,
1918 first_all);
1919
1920 ctrl->timings[channel][slotrank].lanes[lane].timA =
1921 (last_zero + first_all) / 2 + upperA[lane];
Patrick Rudolpha649a542016-01-17 18:32:06 +01001922 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001923 lane, ctrl->timings[channel][slotrank].lanes[lane].timA);
1924 }
1925}
1926
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001927static int discover_402x(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001928 int *upperA)
1929{
1930 int works[NUM_LANES];
1931 int lane;
1932 while (1) {
1933 int all_works = 1, some_works = 0;
1934 program_timings(ctrl, channel);
1935 test_timA(ctrl, channel, slotrank);
1936 FOR_ALL_LANES {
1937 works[lane] =
1938 !does_lane_work(ctrl, channel, slotrank, lane);
1939 if (works[lane])
1940 some_works = 1;
1941 else
1942 all_works = 0;
1943 }
1944 if (all_works)
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001945 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001946 if (!some_works) {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001947 if (ctrl->timings[channel][slotrank].val_4024 < 2) {
1948 printk(BIOS_EMERG, "402x discovery failed (1): %d, %d\n",
1949 channel, slotrank);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001950 return MAKE_ERR;
1951 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001952 ctrl->timings[channel][slotrank].val_4024 -= 2;
1953 printram("4024 -= 2;\n");
1954 continue;
1955 }
1956 ctrl->timings[channel][slotrank].val_4028 += 2;
1957 printram("4028 += 2;\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001958 if (ctrl->timings[channel][slotrank].val_4028 >= 0x10) {
1959 printk(BIOS_EMERG, "402x discovery failed (2): %d, %d\n",
1960 channel, slotrank);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001961 return MAKE_ERR;
1962 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001963 FOR_ALL_LANES if (works[lane]) {
1964 ctrl->timings[channel][slotrank].lanes[lane].timA +=
1965 128;
1966 upperA[lane] += 128;
1967 printram("increment %d, %d, %d\n", channel,
1968 slotrank, lane);
1969 }
1970 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01001971 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07001972}
1973
1974struct timA_minmax {
1975 int timA_min_high, timA_max_high;
1976};
1977
1978static void pre_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
1979 struct timA_minmax *mnmx)
1980{
1981 int lane;
1982 mnmx->timA_min_high = 7;
1983 mnmx->timA_max_high = 0;
1984
1985 FOR_ALL_LANES {
1986 if (mnmx->timA_min_high >
1987 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1988 mnmx->timA_min_high =
1989 (ctrl->timings[channel][slotrank].lanes[lane].
1990 timA >> 6);
1991 if (mnmx->timA_max_high <
1992 (ctrl->timings[channel][slotrank].lanes[lane].timA >> 6))
1993 mnmx->timA_max_high =
1994 (ctrl->timings[channel][slotrank].lanes[lane].
1995 timA >> 6);
1996 }
1997}
1998
1999static void post_timA_change(ramctr_timing * ctrl, int channel, int slotrank,
2000 struct timA_minmax *mnmx)
2001{
2002 struct timA_minmax post;
2003 int shift_402x = 0;
2004
2005 /* Get changed maxima. */
2006 pre_timA_change(ctrl, channel, slotrank, &post);
2007
2008 if (mnmx->timA_max_high - mnmx->timA_min_high <
2009 post.timA_max_high - post.timA_min_high)
2010 shift_402x = +1;
2011 else if (mnmx->timA_max_high - mnmx->timA_min_high >
2012 post.timA_max_high - post.timA_min_high)
2013 shift_402x = -1;
2014 else
2015 shift_402x = 0;
2016
2017 ctrl->timings[channel][slotrank].val_4028 += shift_402x;
2018 ctrl->timings[channel][slotrank].val_4024 += shift_402x;
2019 printram("4024 += %d;\n", shift_402x);
2020 printram("4028 += %d;\n", shift_402x);
2021}
2022
Patrick Rudolph371d2912015-10-09 13:33:25 +02002023/* Compensate the skew between DQS and DQs.
2024 * To ease PCB design a small skew between Data Strobe signals and
2025 * Data Signals is allowed.
2026 * The controller has to measure and compensate this skew for every byte-lane.
2027 * By delaying either all DQs signals or DQS signal, a full phase
2028 * shift can be introduced.
2029 * It is assumed that one byte-lane's DQs signals have the same routing delay.
2030 *
2031 * To measure the actual skew, the DRAM is placed in "read leveling" mode.
2032 * In read leveling mode the DRAM-chip outputs an alternating periodic pattern.
2033 * The memory controller iterates over all possible values to do a full phase shift
2034 * and issues read commands.
2035 * With DQS and DQs in phase the data read is expected to alternate on every byte:
2036 * 0xFF 0x00 0xFF ...
2037 * Once the controller has detected this pattern a bit in the result register is
2038 * set for the current phase shift.
2039 */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002040static int read_training(ramctr_timing * ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002041{
2042 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002043 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002044
2045 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002046 int all_high, some_high;
2047 int upperA[NUM_LANES];
2048 struct timA_minmax mnmx;
2049
2050 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002051
2052 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002053 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2054 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2055 0xc01 | (ctrl->tRP << 16));
2056 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2057 (slotrank << 24) | 0x60400);
2058 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2059 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2060
2061 write32(DEFAULT_MCHBAR + 0x3400, (slotrank << 2) | 0x8001);
2062
2063 ctrl->timings[channel][slotrank].val_4028 = 4;
2064 ctrl->timings[channel][slotrank].val_4024 = 55;
2065 program_timings(ctrl, channel);
2066
2067 discover_timA_coarse(ctrl, channel, slotrank, upperA);
2068
2069 all_high = 1;
2070 some_high = 0;
2071 FOR_ALL_LANES {
2072 if (ctrl->timings[channel][slotrank].lanes[lane].
2073 timA >= 0x40)
2074 some_high = 1;
2075 else
2076 all_high = 0;
2077 }
2078
2079 if (all_high) {
2080 ctrl->timings[channel][slotrank].val_4028--;
2081 printram("4028--;\n");
2082 FOR_ALL_LANES {
2083 ctrl->timings[channel][slotrank].lanes[lane].
2084 timA -= 0x40;
2085 upperA[lane] -= 0x40;
2086
2087 }
2088 } else if (some_high) {
2089 ctrl->timings[channel][slotrank].val_4024++;
2090 ctrl->timings[channel][slotrank].val_4028++;
2091 printram("4024++;\n");
2092 printram("4028++;\n");
2093 }
2094
2095 program_timings(ctrl, channel);
2096
2097 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2098
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002099 err = discover_402x(ctrl, channel, slotrank, upperA);
2100 if (err)
2101 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002102
2103 post_timA_change(ctrl, channel, slotrank, &mnmx);
2104 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2105
2106 discover_timA_fine(ctrl, channel, slotrank, upperA);
2107
2108 post_timA_change(ctrl, channel, slotrank, &mnmx);
2109 pre_timA_change(ctrl, channel, slotrank, &mnmx);
2110
2111 FOR_ALL_LANES {
2112 ctrl->timings[channel][slotrank].lanes[lane].timA -= mnmx.timA_min_high * 0x40;
2113 }
2114 ctrl->timings[channel][slotrank].val_4028 -= mnmx.timA_min_high;
2115 printram("4028 -= %d;\n", mnmx.timA_min_high);
2116
2117 post_timA_change(ctrl, channel, slotrank, &mnmx);
2118
2119 printram("4/8: %d, %d, %x, %x\n", channel, slotrank,
2120 ctrl->timings[channel][slotrank].val_4024,
2121 ctrl->timings[channel][slotrank].val_4028);
2122
Patrick Rudolpha649a542016-01-17 18:32:06 +01002123 printram("final results:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002124 FOR_ALL_LANES
Patrick Rudolpha649a542016-01-17 18:32:06 +01002125 printram("Aval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002126 lane,
2127 ctrl->timings[channel][slotrank].lanes[lane].timA);
2128
2129 write32(DEFAULT_MCHBAR + 0x3400, 0);
2130
Patrick Rudolph9b515682015-10-09 13:43:51 +02002131 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002132 }
2133
2134 FOR_ALL_POPULATED_CHANNELS {
2135 program_timings(ctrl, channel);
2136 }
2137 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2138 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
2139 + 4 * lane, 0);
2140 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002141 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002142}
2143
2144static void test_timC(ramctr_timing * ctrl, int channel, int slotrank)
2145{
2146 int lane;
2147
2148 FOR_ALL_LANES {
2149 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel + 4 * lane, 0);
2150 read32(DEFAULT_MCHBAR + 0x4140 + 0x400 * channel + 4 * lane);
2151 }
2152
2153 wait_428c(channel);
2154
Patrick Rudolph371d2912015-10-09 13:33:25 +02002155 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002156 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2157 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2158 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD) << 10)
2159 | 4 | (ctrl->tRCD << 16));
2160
2161 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2162 (slotrank << 24) | (6 << 16));
2163
2164 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
2165
Patrick Rudolph371d2912015-10-09 13:33:25 +02002166 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002167 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2168 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8041001);
2169 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2170 (slotrank << 24) | 8);
2171 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2172
Patrick Rudolph371d2912015-10-09 13:33:25 +02002173 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002174 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2175 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x80411f4);
2176 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2177 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2178
Patrick Rudolph371d2912015-10-09 13:33:25 +02002179 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002180 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2181 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2182 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2183 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2184 (slotrank << 24) | 8);
2185 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2186
2187 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2188
2189 wait_428c(channel);
2190
Patrick Rudolph371d2912015-10-09 13:33:25 +02002191 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002192 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2193 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2194 0xc01 | (ctrl->tRP << 16));
2195 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2196 (slotrank << 24) | 0x60400);
2197 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2198
Patrick Rudolph371d2912015-10-09 13:33:25 +02002199 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002200 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2201 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2202 (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) << 10)
2203 | 8 | (ctrl->CAS << 16));
2204
2205 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2206 (slotrank << 24) | 0x60000);
2207
2208 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x244);
2209
Patrick Rudolph371d2912015-10-09 13:33:25 +02002210 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002211 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2212 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2213 0x40011f4 | (max(ctrl->tRTP, 8) << 16));
2214 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel, (slotrank << 24));
2215 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x242);
2216
Patrick Rudolph371d2912015-10-09 13:33:25 +02002217 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002218 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2219 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2220 0xc01 | (ctrl->tRP << 16));
2221 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2222 (slotrank << 24) | 0x60400);
2223 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2224 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2225 wait_428c(channel);
2226}
2227
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002228static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002229{
2230 int timC;
2231 int statistics[NUM_LANES][MAX_TIMC + 1];
2232 int lane;
2233
2234 wait_428c(channel);
2235
Patrick Rudolph371d2912015-10-09 13:33:25 +02002236 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002237 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2238 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2239 0xc01 | (ctrl->tRP << 16));
2240 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2241 (slotrank << 24) | 0x60400);
2242 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2243 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2244
2245 for (timC = 0; timC <= MAX_TIMC; timC++) {
2246 FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].
2247 timC = timC;
2248 program_timings(ctrl, channel);
2249
2250 test_timC(ctrl, channel, slotrank);
2251
2252 FOR_ALL_LANES {
2253 statistics[lane][timC] =
2254 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2255 0x400 * channel);
2256 printram("Cstat: %d, %d, %d, %x, %x\n",
2257 channel, slotrank, lane, timC,
2258 statistics[lane][timC]);
2259 }
2260 }
2261 FOR_ALL_LANES {
2262 struct run rn =
2263 get_longest_zero_run(statistics[lane], MAX_TIMC + 1);
2264 ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002265 if (rn.all) {
2266 printk(BIOS_EMERG, "timC discovery failed: %d, %d, %d\n",
2267 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002268 return MAKE_ERR;
2269 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01002270 printram("Cval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002271 lane, ctrl->timings[channel][slotrank].lanes[lane].timC);
2272 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002273 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002274}
2275
2276static int get_precedening_channels(ramctr_timing * ctrl, int target_channel)
2277{
2278 int channel, ret = 0;
2279 FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
2280 ret++;
2281 return ret;
2282}
2283
2284static void fill_pattern0(ramctr_timing * ctrl, int channel, u32 a, u32 b)
2285{
2286 unsigned j;
2287 unsigned channel_offset =
2288 get_precedening_channels(ctrl, channel) * 0x40;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002289 for (j = 0; j < 16; j++)
2290 write32((void *)(0x04000000 + channel_offset + 4 * j), j & 2 ? b : a);
2291 sfence();
2292}
2293
2294static int num_of_channels(const ramctr_timing * ctrl)
2295{
2296 int ret = 0;
2297 int channel;
2298 FOR_ALL_POPULATED_CHANNELS ret++;
2299 return ret;
2300}
2301
2302static void fill_pattern1(ramctr_timing * ctrl, int channel)
2303{
2304 unsigned j;
2305 unsigned channel_offset =
2306 get_precedening_channels(ctrl, channel) * 0x40;
2307 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2308 for (j = 0; j < 16; j++)
2309 write32((void *)(0x04000000 + channel_offset + j * 4), 0xffffffff);
2310 for (j = 0; j < 16; j++)
2311 write32((void *)(0x04000000 + channel_offset + channel_step + j * 4), 0);
2312 sfence();
2313}
2314
2315static void precharge(ramctr_timing * ctrl)
2316{
2317 int channel, slotrank, lane;
2318
2319 FOR_ALL_POPULATED_CHANNELS {
2320 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2321 ctrl->timings[channel][slotrank].lanes[lane].falling =
2322 16;
2323 ctrl->timings[channel][slotrank].lanes[lane].rising =
2324 16;
Patrick Rudolpha649a542016-01-17 18:32:06 +01002325 }
2326
2327 program_timings(ctrl, channel);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002328
2329 FOR_ALL_POPULATED_RANKS {
2330 wait_428c(channel);
2331
Patrick Rudolph371d2912015-10-09 13:33:25 +02002332 /* DRAM command MRS
2333 * write MR3 MPR enable
2334 * in this mode only RD and RDA are allowed
2335 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002336 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2337 0x1f000);
2338 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2339 0xc01 | (ctrl->tMOD << 16));
2340 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2341 (slotrank << 24) | 0x360004);
2342 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2343
Patrick Rudolph371d2912015-10-09 13:33:25 +02002344 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002345 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2346 0x1f105);
2347 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2348 0x4041003);
2349 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2350 (slotrank << 24) | 0);
2351 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2352
Patrick Rudolph371d2912015-10-09 13:33:25 +02002353 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002354 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2355 0x1f105);
2356 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2357 0x1001 | ((ctrl->CAS + 8) << 16));
2358 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2359 (slotrank << 24) | 0x60000);
2360 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2361
Patrick Rudolph371d2912015-10-09 13:33:25 +02002362 /* DRAM command MRS
2363 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002364 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2365 0x1f000);
2366 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2367 0xc01 | (ctrl->tMOD << 16));
2368 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2369 (slotrank << 24) | 0x360000);
2370 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2371 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2372 0xc0001);
2373
2374 wait_428c(channel);
2375 }
2376
2377 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2378 ctrl->timings[channel][slotrank].lanes[lane].falling =
2379 48;
2380 ctrl->timings[channel][slotrank].lanes[lane].rising =
2381 48;
2382 }
2383
2384 program_timings(ctrl, channel);
2385
2386 FOR_ALL_POPULATED_RANKS {
2387 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002388 /* DRAM command MRS
2389 * write MR3 MPR enable
2390 * in this mode only RD and RDA are allowed
2391 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002392 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
2393 0x1f000);
2394 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2395 0xc01 | (ctrl->tMOD << 16));
2396 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2397 (slotrank << 24) | 0x360004);
2398 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2399
Patrick Rudolph371d2912015-10-09 13:33:25 +02002400 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002401 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
2402 0x1f105);
2403 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2404 0x4041003);
2405 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2406 (slotrank << 24) | 0);
2407 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2408
Patrick Rudolph371d2912015-10-09 13:33:25 +02002409 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002410 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
2411 0x1f105);
2412 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2413 0x1001 | ((ctrl->CAS + 8) << 16));
2414 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2415 (slotrank << 24) | 0x60000);
2416 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2417
Patrick Rudolph371d2912015-10-09 13:33:25 +02002418 /* DRAM command MRS
2419 * write MR3 MPR disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002420 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
2421 0x1f000);
2422 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2423 0xc01 | (ctrl->tMOD << 16));
2424
2425 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2426 (slotrank << 24) | 0x360000);
2427 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
2428
2429 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
2430 0xc0001);
2431 wait_428c(channel);
2432 }
2433 }
2434}
2435
2436static void test_timB(ramctr_timing * ctrl, int channel, int slotrank)
2437{
Patrick Rudolph371d2912015-10-09 13:33:25 +02002438 /* enable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002439 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002440 0x80 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002441
2442 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002443 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002444 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f207);
2445 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2446 0x8000c01 | ((ctrl->CWL + ctrl->tWLO) << 16));
2447 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2448 8 | (slotrank << 24));
2449 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2450
Patrick Rudolph371d2912015-10-09 13:33:25 +02002451 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002452 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f107);
2453 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2454 0x4000c01 | ((ctrl->CAS + 38) << 16));
2455 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2456 (slotrank << 24) | 4);
2457 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2458
2459 write32(DEFAULT_MCHBAR + 0x400 * channel + 0x4284, 0x40001);
2460 wait_428c(channel);
2461
Patrick Rudolph371d2912015-10-09 13:33:25 +02002462 /* disable DQs on this slotrank */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002463 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002464 0x1080 | make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002465}
2466
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002467static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002468{
2469 int timB;
2470 int statistics[NUM_LANES][128];
2471 int lane;
2472
2473 write32(DEFAULT_MCHBAR + 0x3400, 0x108052 | (slotrank << 2));
2474
2475 for (timB = 0; timB < 128; timB++) {
2476 FOR_ALL_LANES {
2477 ctrl->timings[channel][slotrank].lanes[lane].timB = timB;
2478 }
2479 program_timings(ctrl, channel);
2480
2481 test_timB(ctrl, channel, slotrank);
2482
2483 FOR_ALL_LANES {
2484 statistics[lane][timB] =
2485 !((read32
2486 (DEFAULT_MCHBAR + lane_registers[lane] +
2487 channel * 0x100 + 4 + ((timB / 32) & 1) * 4)
2488 >> (timB % 32)) & 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01002489 printram("Bstat: %d, %d, %d: %x, %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002490 channel, slotrank, lane, timB,
2491 statistics[lane][timB]);
2492 }
2493 }
2494 FOR_ALL_LANES {
2495 struct run rn = get_longest_zero_run(statistics[lane], 128);
Patrick Rudolphd912f1d2016-02-15 20:07:42 +01002496 /* timC is a direct function of timB's 6 LSBs.
2497 * Some tests increments the value of timB by a small value,
2498 * which might cause the 6bit value to overflow, if it's close
2499 * to 0x3F. Increment the value by a small offset if it's likely
2500 * to overflow, to make sure it won't overflow while running
2501 * tests and bricks the system due to a non matching timC.
2502 *
2503 * TODO: find out why some tests (edge write discovery)
2504 * increment timB. */
2505 if ((rn.start & 0x3F) == 0x3E)
2506 rn.start += 2;
2507 else if ((rn.start & 0x3F) == 0x3F)
2508 rn.start += 1;
Vladimir Serbinenko3141eac2016-01-29 19:42:02 +01002509 ctrl->timings[channel][slotrank].lanes[lane].timB = rn.start;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002510 if (rn.all) {
2511 printk(BIOS_EMERG, "timB discovery failed: %d, %d, %d\n",
2512 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002513 return MAKE_ERR;
2514 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01002515 printram("Bval: %d, %d, %d: %x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002516 lane, ctrl->timings[channel][slotrank].lanes[lane].timB);
2517 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002518 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002519}
2520
2521static int get_timB_high_adjust(u64 val)
2522{
2523 int i;
2524
2525 /* good */
2526 if (val == 0xffffffffffffffffLL)
2527 return 0;
2528
2529 if (val >= 0xf000000000000000LL) {
2530 /* needs negative adjustment */
2531 for (i = 0; i < 8; i++)
2532 if (val << (8 * (7 - i) + 4))
2533 return -i;
2534 } else {
2535 /* needs positive adjustment */
2536 for (i = 0; i < 8; i++)
2537 if (val >> (8 * (7 - i) + 4))
2538 return i;
2539 }
2540 return 8;
2541}
2542
2543static void adjust_high_timB(ramctr_timing * ctrl)
2544{
2545 int channel, slotrank, lane, old;
2546 write32(DEFAULT_MCHBAR + 0x3400, 0x200);
2547 FOR_ALL_POPULATED_CHANNELS {
2548 fill_pattern1(ctrl, channel);
2549 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 1);
2550 }
2551 FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
2552
2553 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x10001);
2554
2555 wait_428c(channel);
2556
Patrick Rudolph371d2912015-10-09 13:33:25 +02002557 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002558 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2559 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2560 0xc01 | (ctrl->tRCD << 16));
2561 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2562 (slotrank << 24) | 0x60000);
2563 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
2564
Patrick Rudolph371d2912015-10-09 13:33:25 +02002565 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002566 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f207);
2567 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x8040c01);
2568 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2569 (slotrank << 24) | 0x8);
2570 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x3e0);
2571
Patrick Rudolph371d2912015-10-09 13:33:25 +02002572 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002573 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f201);
2574 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel, 0x8041003);
2575 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2576 (slotrank << 24));
2577 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x3e2);
2578
Patrick Rudolph371d2912015-10-09 13:33:25 +02002579 /* DRAM command NOP */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002580 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f207);
2581 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
2582 0x8000c01 | ((ctrl->CWL + ctrl->tWTR + 5) << 16));
2583 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2584 (slotrank << 24) | 0x8);
2585 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x3e0);
2586
2587 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2588
2589 wait_428c(channel);
2590
Patrick Rudolph371d2912015-10-09 13:33:25 +02002591 /* DRAM command PREA */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002592 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f002);
2593 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2594 0xc01 | ((ctrl->tRP) << 16));
2595 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2596 (slotrank << 24) | 0x60400);
2597 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x240);
2598
Patrick Rudolph371d2912015-10-09 13:33:25 +02002599 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002600 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f006);
2601 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2602 0xc01 | ((ctrl->tRCD) << 16));
2603 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2604 (slotrank << 24) | 0x60000);
2605 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
2606
Patrick Rudolph371d2912015-10-09 13:33:25 +02002607 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002608 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x3f105);
2609 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2610 0x4000c01 |
2611 ((ctrl->tRP +
2612 ctrl->timings[channel][slotrank].val_4024 +
2613 ctrl->timings[channel][slotrank].val_4028) << 16));
2614 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2615 (slotrank << 24) | 0x60008);
2616 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
2617
2618 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0x80001);
2619 wait_428c(channel);
2620 FOR_ALL_LANES {
2621 u64 res =
2622 read32(DEFAULT_MCHBAR + lane_registers[lane] +
2623 0x100 * channel + 4);
2624 res |=
2625 ((u64) read32(DEFAULT_MCHBAR + lane_registers[lane] +
2626 0x100 * channel + 8)) << 32;
2627 old = ctrl->timings[channel][slotrank].lanes[lane].timB;
2628 ctrl->timings[channel][slotrank].lanes[lane].timB +=
2629 get_timB_high_adjust(res) * 64;
2630
Patrick Rudolpha649a542016-01-17 18:32:06 +01002631 printram("High adjust %d:%016llx\n", lane, res);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002632 printram("Bval+: %d, %d, %d, %x -> %x\n", channel,
2633 slotrank, lane, old,
2634 ctrl->timings[channel][slotrank].lanes[lane].
2635 timB);
2636 }
2637 }
2638 write32(DEFAULT_MCHBAR + 0x3400, 0);
2639}
2640
2641static void write_op(ramctr_timing * ctrl, int channel)
2642{
2643 int slotrank;
2644
2645 wait_428c(channel);
2646
2647 /* choose an existing rank. */
2648 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2649
Patrick Rudolph371d2912015-10-09 13:33:25 +02002650 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002651 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2652 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2653
2654 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2655 (slotrank << 24) | 0x60000);
2656
2657 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2658
2659 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2660 wait_428c(channel);
2661}
2662
Patrick Rudolph371d2912015-10-09 13:33:25 +02002663/* Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
2664 * DDR3 adopted the fly-by topology. The data and strobes signals reach
2665 * the chips at different times with respect to command, address and
2666 * clock signals.
2667 * By delaying either all DQ/DQs or all CMD/ADDR/CLK signals, a full phase
2668 * shift can be introduced.
2669 * It is assumed that the CLK/ADDR/CMD signals have the same routing delay.
2670 *
2671 * To find the required phase shift the DRAM is placed in "write leveling" mode.
2672 * In this mode the DRAM-chip samples the CLK on every DQS edge and feeds back the
2673 * sampled value on the data lanes (DQs).
2674 */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002675static int write_training(ramctr_timing * ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002676{
2677 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002678 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002679
2680 FOR_ALL_POPULATED_CHANNELS
2681 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
2682 read32(DEFAULT_MCHBAR + 0x4008 +
2683 0x400 * channel) | 0x8000000);
2684
2685 FOR_ALL_POPULATED_CHANNELS {
2686 write_op(ctrl, channel);
2687 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2688 read32(DEFAULT_MCHBAR + 0x4020 +
2689 0x400 * channel) | 0x200000);
2690 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002691
2692 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002693 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2694 FOR_ALL_POPULATED_CHANNELS {
2695 write_op(ctrl, channel);
2696 }
2697
Patrick Rudolph371d2912015-10-09 13:33:25 +02002698 /* enable write leveling on all ranks
2699 * disable all DQ outputs
2700 * only NOP is allowed in this mode */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002701 FOR_ALL_CHANNELS
2702 FOR_ALL_POPULATED_RANKS
2703 write_mrreg(ctrl, channel, slotrank, 1,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002704 make_mr1(ctrl, slotrank, channel) | 0x1080);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002705
2706 write32(DEFAULT_MCHBAR + 0x3400, 0x108052);
2707
Patrick Rudolph9b515682015-10-09 13:43:51 +02002708 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002709
Patrick Rudolph371d2912015-10-09 13:33:25 +02002710 /* set any valid value for timB, it gets corrected later */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002711 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2712 err = discover_timB(ctrl, channel, slotrank);
2713 if (err)
2714 return err;
2715 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002716
Patrick Rudolph371d2912015-10-09 13:33:25 +02002717 /* disable write leveling on all ranks */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002718 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
2719 write_mrreg(ctrl, channel,
Patrick Rudolph7e513d12016-01-10 14:22:34 +01002720 slotrank, 1, make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002721
2722 write32(DEFAULT_MCHBAR + 0x3400, 0);
2723
2724 FOR_ALL_POPULATED_CHANNELS
2725 wait_428c(channel);
2726
Patrick Rudolph371d2912015-10-09 13:33:25 +02002727 /* refresh enable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002728 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) | 8);
2729
2730 FOR_ALL_POPULATED_CHANNELS {
2731 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2732 ~0x00200000 & read32(DEFAULT_MCHBAR + 0x4020 +
2733 0x400 * channel));
2734 read32(DEFAULT_MCHBAR + 0x428c + 0x400 * channel);
2735 wait_428c(channel);
2736
Patrick Rudolph371d2912015-10-09 13:33:25 +02002737 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002738 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2739 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x659001);
2740 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel, 0x60000);
2741 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2742
2743 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2744 wait_428c(channel);
2745 }
2746
Patrick Rudolph9b515682015-10-09 13:43:51 +02002747 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002748
2749 printram("CPE\n");
2750 precharge(ctrl);
2751 printram("CPF\n");
2752
2753 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2754 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2755 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2756 0);
2757 }
2758
2759 FOR_ALL_POPULATED_CHANNELS {
2760 fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
2761 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
2762 }
2763
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002764 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2765 err = discover_timC(ctrl, channel, slotrank);
2766 if (err)
2767 return err;
2768 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002769
2770 FOR_ALL_POPULATED_CHANNELS
2771 program_timings(ctrl, channel);
2772
Patrick Rudolph371d2912015-10-09 13:33:25 +02002773 /* measure and adjust timB timings */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002774 adjust_high_timB(ctrl);
2775
2776 FOR_ALL_POPULATED_CHANNELS
2777 program_timings(ctrl, channel);
2778
2779 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
2780 read32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane);
2781 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
2782 0);
2783 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002784 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002785}
2786
2787static int test_320c(ramctr_timing * ctrl, int channel, int slotrank)
2788{
2789 struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
2790 int timC_delta;
2791 int lanes_ok = 0;
2792 int ctr = 0;
2793 int lane;
2794
2795 for (timC_delta = -5; timC_delta <= 5; timC_delta++) {
2796 FOR_ALL_LANES {
2797 ctrl->timings[channel][slotrank].lanes[lane].timC =
2798 saved_rt.lanes[lane].timC + timC_delta;
2799 }
2800 program_timings(ctrl, channel);
2801 FOR_ALL_LANES {
2802 write32(DEFAULT_MCHBAR + 4 * lane + 0x4f40, 0);
2803 }
2804
2805 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
2806
2807 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002808 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002809 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
2810 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
2811 ((max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1)) << 10)
2812 | 8 | (ctrl->tRCD << 16));
2813
2814 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2815 (slotrank << 24) | ctr | 0x60000);
2816
2817 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02002818 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002819 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
2820 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
2821 0x8001020 | ((ctrl->CWL + ctrl->tWTR + 8) << 16));
2822 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
2823 (slotrank << 24));
2824 write32(DEFAULT_MCHBAR + 0x4244 + 0x400 * channel, 0x389abcd);
2825 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0x20e42);
2826
Patrick Rudolph371d2912015-10-09 13:33:25 +02002827 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002828 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
2829 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
2830 0x4001020 | (max(ctrl->tRTP, 8) << 16));
2831 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
2832 (slotrank << 24));
2833 write32(DEFAULT_MCHBAR + 0x4248 + 0x400 * channel, 0x389abcd);
2834 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0x20e42);
2835
Patrick Rudolph371d2912015-10-09 13:33:25 +02002836 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002837 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f002);
2838 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel, 0xf1001);
2839 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
2840 (slotrank << 24) | 0x60400);
2841 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0x240);
2842
2843 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
2844 wait_428c(channel);
2845 FOR_ALL_LANES {
2846 u32 r32 =
2847 read32(DEFAULT_MCHBAR + 0x4340 + 4 * lane +
2848 0x400 * channel);
2849
2850 if (r32 == 0)
2851 lanes_ok |= 1 << lane;
2852 }
2853 ctr++;
2854 if (lanes_ok == ((1 << NUM_LANES) - 1))
2855 break;
2856 }
2857
2858 ctrl->timings[channel][slotrank] = saved_rt;
2859
2860 printram("3lanes: %x\n", lanes_ok);
2861 return lanes_ok != ((1 << NUM_LANES) - 1);
2862}
2863
2864#include "raminit_patterns.h"
2865
2866static void fill_pattern5(ramctr_timing * ctrl, int channel, int patno)
2867{
2868 unsigned i, j;
2869 unsigned channel_offset =
2870 get_precedening_channels(ctrl, channel) * 0x40;
2871 unsigned channel_step = 0x40 * num_of_channels(ctrl);
2872
2873 if (patno) {
2874 u8 base8 = 0x80 >> ((patno - 1) % 8);
2875 u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
2876 for (i = 0; i < 32; i++) {
2877 for (j = 0; j < 16; j++) {
2878 u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;
2879 if (invert[patno - 1][i] & (1 << (j / 2)))
2880 val = ~val;
2881 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2882 j * 4), val);
2883 }
2884 }
2885
2886 } else {
2887 for (i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
2888 for (j = 0; j < 16; j++)
2889 write32((void *)(0x04000000 + channel_offset + i * channel_step +
2890 j * 4), pattern[i][j]);
2891 }
2892 sfence();
2893 }
2894}
2895
2896static void reprogram_320c(ramctr_timing * ctrl)
2897{
2898 int channel, slotrank;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002899
2900 FOR_ALL_POPULATED_CHANNELS {
2901 wait_428c(channel);
2902
2903 /* choose an existing rank. */
2904 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2905
Patrick Rudolph371d2912015-10-09 13:33:25 +02002906 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002907 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2908 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2909
2910 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2911 (slotrank << 24) | 0x60000);
2912
2913 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2914
2915 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2916 wait_428c(channel);
2917 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
2918 read32(DEFAULT_MCHBAR + 0x4020 +
2919 0x400 * channel) | 0x200000);
2920 }
Patrick Rudolph371d2912015-10-09 13:33:25 +02002921
2922 /* refresh disable */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002923 write32(DEFAULT_MCHBAR + 0x5030, read32(DEFAULT_MCHBAR + 0x5030) & ~8);
2924 FOR_ALL_POPULATED_CHANNELS {
2925 wait_428c(channel);
2926
2927 /* choose an existing rank. */
2928 slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
2929
Patrick Rudolph371d2912015-10-09 13:33:25 +02002930 /* DRAM command ZQCS */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002931 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x0f003);
2932 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel, 0x41001);
2933
2934 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
2935 (slotrank << 24) | 0x60000);
2936
2937 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x3e0);
2938
2939 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 1);
2940 wait_428c(channel);
2941 }
2942
2943 /* jedec reset */
2944 dram_jedecreset(ctrl);
2945 /* mrs commands. */
2946 dram_mrscommands(ctrl);
2947
Patrick Rudolph9b515682015-10-09 13:43:51 +02002948 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002949}
2950
2951#define MIN_C320C_LEN 13
2952
Patrick Rudolph24a845b2016-03-25 18:19:47 +01002953static int try_cmd_stretch(ramctr_timing *ctrl, int cmd_stretch)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07002954{
2955 struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
2956 int channel, slotrank;
2957 int c320c;
2958 int stat[NUM_SLOTRANKS][256];
2959
2960 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
2961 saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
2962 }
2963
2964 FOR_ALL_POPULATED_CHANNELS {
2965 ctrl->cmd_stretch[channel] = cmd_stretch;
2966 }
2967
2968 FOR_ALL_POPULATED_CHANNELS
2969 MCHBAR32(0x4004 + 0x400 * channel) =
2970 ctrl->tRRD
2971 | (ctrl->tRTP << 4)
2972 | (ctrl->tCKE << 8)
2973 | (ctrl->tWTR << 12)
2974 | (ctrl->tFAW << 16)
2975 | (ctrl->tWR << 24)
2976 | (ctrl->cmd_stretch[channel] << 30);
2977
2978
2979 FOR_ALL_CHANNELS {
2980 int delta = 0;
2981 if (ctrl->cmd_stretch[channel] == 2)
2982 delta = 2;
2983 else if (ctrl->cmd_stretch[channel] == 0)
2984 delta = 4;
2985
2986 FOR_ALL_POPULATED_RANKS {
2987 ctrl->timings[channel][slotrank].val_4024 -= delta;
2988 }
2989 }
2990
2991 FOR_ALL_POPULATED_CHANNELS {
2992 for (c320c = -127; c320c <= 127; c320c++) {
2993 FOR_ALL_POPULATED_RANKS {
2994 ctrl->timings[channel][slotrank].val_320c = c320c;
2995 }
2996 program_timings(ctrl, channel);
2997 reprogram_320c(ctrl);
2998 FOR_ALL_POPULATED_RANKS {
2999 stat[slotrank][c320c + 127] =
3000 test_320c(ctrl, channel, slotrank);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003001 printram("3stat: %d, %d, %d: %x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003002 channel, slotrank, c320c,
3003 stat[slotrank][c320c + 127]);
3004 }
3005 }
3006 FOR_ALL_POPULATED_RANKS {
3007 struct run rn =
3008 get_longest_zero_run(stat[slotrank], 255);
3009 ctrl->timings[channel][slotrank].val_320c =
3010 rn.middle - 127;
3011 printram("3val: %d, %d: %d\n", channel,
3012 slotrank,
3013 ctrl->timings[channel][slotrank].val_320c);
3014 if (rn.all || rn.length < MIN_C320C_LEN) {
3015 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3016 ctrl->timings[channel][slotrank] = saved_timings[channel][slotrank];
3017 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003018 return MAKE_ERR;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003019 }
3020 }
3021 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003022 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003023}
3024
Patrick Rudolph371d2912015-10-09 13:33:25 +02003025/* Adjust CMD phase shift and try multiple command rates.
3026 * A command rate of 2T doubles the time needed for address and
3027 * command decode. */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003028static int command_training(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003029{
3030 int channel;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003031 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003032
3033 FOR_ALL_POPULATED_CHANNELS {
3034 fill_pattern5(ctrl, channel, 0);
3035 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
3036 }
3037
3038 /* try command rate 1T and 2T */
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003039 err = try_cmd_stretch(ctrl, 0);
3040 if (err) {
3041 err = try_cmd_stretch(ctrl, 2);
3042 if (err) {
3043 printk(BIOS_EMERG, "c320c discovery failed\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003044 return err;
3045 }
3046 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003047
3048 FOR_ALL_POPULATED_CHANNELS {
3049 program_timings(ctrl, channel);
3050 }
3051
3052 reprogram_320c(ctrl);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003053 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003054}
3055
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003056static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003057 int *edges)
3058{
3059 int edge;
3060 int statistics[NUM_LANES][MAX_EDGE_TIMING + 1];
3061 int lane;
3062
3063 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3064 FOR_ALL_LANES {
3065 ctrl->timings[channel][slotrank].lanes[lane].rising =
3066 edge;
3067 ctrl->timings[channel][slotrank].lanes[lane].falling =
3068 edge;
3069 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003070 program_timings(ctrl, channel);
3071
3072 FOR_ALL_LANES {
3073 write32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
3074 4 * lane, 0);
3075 read32(DEFAULT_MCHBAR + 0x400 * channel + 4 * lane +
3076 0x4140);
3077 }
3078
3079 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003080 /* DRAM command MRS
3081 * write MR3 MPR enable
3082 * in this mode only RD and RDA are allowed
3083 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003084 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f000);
3085 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3086 (0xc01 | (ctrl->tMOD << 16)));
3087 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3088 (slotrank << 24) | 0x360004);
3089 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3090
Patrick Rudolph371d2912015-10-09 13:33:25 +02003091 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003092 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f105);
3093 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel, 0x40411f4);
3094 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3095 (slotrank << 24));
3096 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3097
Patrick Rudolph371d2912015-10-09 13:33:25 +02003098 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003099 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel, 0x1f105);
3100 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3101 0x1001 | ((ctrl->CAS + 8) << 16));
3102 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3103 (slotrank << 24) | 0x60000);
3104 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3105
Patrick Rudolph371d2912015-10-09 13:33:25 +02003106 /* DRAM command MRS
3107 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003108 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel, 0x1f000);
3109 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3110 (0xc01 | (ctrl->tMOD << 16)));
3111 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3112 (slotrank << 24) | 0x360000);
3113 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3114
3115 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel, 0xc0001);
3116
3117 wait_428c(channel);
3118
3119 FOR_ALL_LANES {
3120 statistics[lane][edge] =
3121 read32(DEFAULT_MCHBAR + 0x4340 + 0x400 * channel +
3122 lane * 4);
3123 }
3124 }
3125 FOR_ALL_LANES {
3126 struct run rn =
3127 get_longest_zero_run(statistics[lane], MAX_EDGE_TIMING + 1);
3128 edges[lane] = rn.middle;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003129 if (rn.all) {
3130 printk(BIOS_EMERG, "edge discovery failed: %d, %d, %d\n",
3131 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003132 return MAKE_ERR;
3133 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01003134 printram("eval %d, %d, %d: %02x\n", channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003135 lane, edges[lane]);
3136 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003137 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003138}
3139
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003140static int discover_edges(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003141{
3142 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3143 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3144 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003145 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003146
3147 write32(DEFAULT_MCHBAR + 0x3400, 0);
3148
Patrick Rudolph9b515682015-10-09 13:43:51 +02003149 toggle_io_reset();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003150
3151 FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
3152 write32(DEFAULT_MCHBAR + 4 * lane +
3153 0x400 * channel + 0x4080, 0);
3154 }
3155
3156 FOR_ALL_POPULATED_CHANNELS {
3157 fill_pattern0(ctrl, channel, 0, 0);
3158 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3159 FOR_ALL_LANES {
3160 read32(DEFAULT_MCHBAR + 0x400 * channel +
3161 lane * 4 + 0x4140);
3162 }
3163
3164 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3165 ctrl->timings[channel][slotrank].lanes[lane].falling =
3166 16;
3167 ctrl->timings[channel][slotrank].lanes[lane].rising =
3168 16;
3169 }
3170
3171 program_timings(ctrl, channel);
3172
3173 FOR_ALL_POPULATED_RANKS {
3174 wait_428c(channel);
3175
Patrick Rudolph371d2912015-10-09 13:33:25 +02003176 /* DRAM command MRS
3177 * MR3 enable MPR
3178 * write MR3 MPR enable
3179 * in this mode only RD and RDA are allowed
3180 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003181 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3182 0x1f000);
3183 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3184 0xc01 | (ctrl->tMOD << 16));
3185 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3186 (slotrank << 24) | 0x360004);
3187 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3188
Patrick Rudolph371d2912015-10-09 13:33:25 +02003189 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003190 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3191 0x1f105);
3192 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3193 0x4041003);
3194 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3195 (slotrank << 24) | 0);
3196 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3197
Patrick Rudolph371d2912015-10-09 13:33:25 +02003198 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003199 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3200 0x1f105);
3201 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3202 0x1001 | ((ctrl->CAS + 8) << 16));
3203 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3204 (slotrank << 24) | 0x60000);
3205 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3206
Patrick Rudolph371d2912015-10-09 13:33:25 +02003207 /* DRAM command MRS
3208 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003209 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3210 0x1f000);
3211 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3212 0xc01 | (ctrl->tMOD << 16));
3213 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3214 (slotrank << 24) | 0x360000);
3215 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3216 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3217 0xc0001);
3218
3219 wait_428c(channel);
3220 }
3221
Patrick Rudolph371d2912015-10-09 13:33:25 +02003222 /* XXX: check any measured value ? */
3223
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003224 FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3225 ctrl->timings[channel][slotrank].lanes[lane].falling =
3226 48;
3227 ctrl->timings[channel][slotrank].lanes[lane].rising =
3228 48;
3229 }
3230
3231 program_timings(ctrl, channel);
3232
3233 FOR_ALL_POPULATED_RANKS {
3234 wait_428c(channel);
3235
Patrick Rudolph371d2912015-10-09 13:33:25 +02003236 /* DRAM command MRS
3237 * MR3 enable MPR
3238 * write MR3 MPR enable
3239 * in this mode only RD and RDA are allowed
3240 * all reads return a predefined pattern */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003241 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3242 0x1f000);
3243 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3244 0xc01 | (ctrl->tMOD << 16));
3245 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3246 (slotrank << 24) | 0x360004);
3247 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0);
3248
Patrick Rudolph371d2912015-10-09 13:33:25 +02003249 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003250 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3251 0x1f105);
3252 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3253 0x4041003);
3254 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3255 (slotrank << 24) | 0);
3256 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel, 0);
3257
Patrick Rudolph371d2912015-10-09 13:33:25 +02003258 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003259 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3260 0x1f105);
3261 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3262 0x1001 | ((ctrl->CAS + 8) << 16));
3263 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3264 (slotrank << 24) | 0x60000);
3265 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel, 0);
3266
Patrick Rudolph371d2912015-10-09 13:33:25 +02003267 /* DRAM command MRS
3268 * MR3 disable MPR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003269 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3270 0x1f000);
3271 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3272 0xc01 | (ctrl->tMOD << 16));
3273 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3274 (slotrank << 24) | 0x360000);
3275 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3276
3277 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3278 0xc0001);
3279 wait_428c(channel);
3280 }
3281
Patrick Rudolph371d2912015-10-09 13:33:25 +02003282 /* XXX: check any measured value ? */
3283
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003284 FOR_ALL_LANES {
3285 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel +
3286 lane * 4,
3287 ~read32(DEFAULT_MCHBAR + 0x4040 +
3288 0x400 * channel + lane * 4) & 0xff);
3289 }
3290
3291 fill_pattern0(ctrl, channel, 0, 0xffffffff);
3292 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3293 }
3294
3295 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3296 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003297 printram("discover falling edges:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003298
3299 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003300 err = discover_edges_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003301 falling_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003302 if (err)
3303 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003304 }
3305
3306 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003307 printram("discover rising edges:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003308
3309 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003310 err = discover_edges_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003311 rising_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003312 if (err)
3313 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003314 }
3315
3316 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3317
3318 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3319 ctrl->timings[channel][slotrank].lanes[lane].falling =
3320 falling_edges[channel][slotrank][lane];
3321 ctrl->timings[channel][slotrank].lanes[lane].rising =
3322 rising_edges[channel][slotrank][lane];
3323 }
3324
3325 FOR_ALL_POPULATED_CHANNELS {
3326 program_timings(ctrl, channel);
3327 }
3328
3329 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3330 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3331 0);
3332 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003333 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003334}
3335
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003336static int discover_edges_write_real(ramctr_timing *ctrl, int channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003337 int slotrank, int *edges)
3338{
3339 int edge;
3340 u32 raw_statistics[MAX_EDGE_TIMING + 1];
3341 int statistics[MAX_EDGE_TIMING + 1];
3342 const int reg3000b24[] = { 0, 0xc, 0x2c };
3343 int lane, i;
3344 int lower[NUM_LANES];
3345 int upper[NUM_LANES];
3346 int pat;
3347
3348 FOR_ALL_LANES {
3349 lower[lane] = 0;
3350 upper[lane] = MAX_EDGE_TIMING;
3351 }
3352
3353 for (i = 0; i < 3; i++) {
3354 write32(DEFAULT_MCHBAR + 0x3000 + 0x100 * channel,
3355 reg3000b24[i] << 24);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003356 printram("[%x] = 0x%08x\n",
3357 0x3000 + 0x100 * channel, reg3000b24[i] << 24);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003358 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3359 fill_pattern5(ctrl, channel, pat);
3360 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003361 printram("using pattern %d\n", pat);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003362 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++) {
3363 FOR_ALL_LANES {
3364 ctrl->timings[channel][slotrank].lanes[lane].
3365 rising = edge;
3366 ctrl->timings[channel][slotrank].lanes[lane].
3367 falling = edge;
3368 }
3369 program_timings(ctrl, channel);
3370
3371 FOR_ALL_LANES {
3372 write32(DEFAULT_MCHBAR + 0x4340 +
3373 0x400 * channel + 4 * lane, 0);
3374 read32(DEFAULT_MCHBAR + 0x400 * channel +
3375 4 * lane + 0x4140);
3376 }
3377 wait_428c(channel);
3378
Patrick Rudolph371d2912015-10-09 13:33:25 +02003379 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003380 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel,
3381 0x1f006);
3382 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3383 0x4 | (ctrl->tRCD << 16)
3384 | (max(ctrl->tRRD, (ctrl->tFAW >> 2) + 1) <<
3385 10));
3386 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3387 (slotrank << 24) | 0x60000);
3388 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel,
3389 0x240);
3390
Patrick Rudolph371d2912015-10-09 13:33:25 +02003391 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003392 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel,
3393 0x1f201);
3394 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3395 0x8005020 | ((ctrl->tWTR + ctrl->CWL + 8) <<
3396 16));
3397 write32(DEFAULT_MCHBAR + 0x4204 + 0x400 * channel,
3398 (slotrank << 24));
3399 write32(DEFAULT_MCHBAR + 0x4214 + 0x400 * channel,
3400 0x242);
3401
Patrick Rudolph371d2912015-10-09 13:33:25 +02003402 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003403 write32(DEFAULT_MCHBAR + 0x4228 + 0x400 * channel,
3404 0x1f105);
3405 write32(DEFAULT_MCHBAR + 0x4238 + 0x400 * channel,
3406 0x4005020 | (max(ctrl->tRTP, 8) << 16));
3407 write32(DEFAULT_MCHBAR + 0x4208 + 0x400 * channel,
3408 (slotrank << 24));
3409 write32(DEFAULT_MCHBAR + 0x4218 + 0x400 * channel,
3410 0x242);
3411
Patrick Rudolph371d2912015-10-09 13:33:25 +02003412 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003413 write32(DEFAULT_MCHBAR + 0x422c + 0x400 * channel,
3414 0x1f002);
3415 write32(DEFAULT_MCHBAR + 0x423c + 0x400 * channel,
3416 0xc01 | (ctrl->tRP << 16));
3417 write32(DEFAULT_MCHBAR + 0x420c + 0x400 * channel,
3418 (slotrank << 24) | 0x60400);
3419 write32(DEFAULT_MCHBAR + 0x421c + 0x400 * channel, 0);
3420
3421 write32(DEFAULT_MCHBAR + 0x4284 + 0x400 * channel,
3422 0xc0001);
3423 wait_428c(channel);
3424 FOR_ALL_LANES {
3425 read32(DEFAULT_MCHBAR + 0x4340 +
3426 0x400 * channel + lane * 4);
3427 }
3428
3429 raw_statistics[edge] =
3430 MCHBAR32(0x436c + 0x400 * channel);
3431 }
3432 FOR_ALL_LANES {
3433 struct run rn;
3434 for (edge = 0; edge <= MAX_EDGE_TIMING; edge++)
3435 statistics[edge] =
3436 ! !(raw_statistics[edge] & (1 << lane));
3437 rn = get_longest_zero_run(statistics,
3438 MAX_EDGE_TIMING + 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003439 printram("edges: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003440 channel, slotrank, i, rn.start, rn.middle,
3441 rn.end, rn.start + ctrl->edge_offset[i],
3442 rn.end - ctrl->edge_offset[i]);
3443 lower[lane] =
3444 max(rn.start + ctrl->edge_offset[i], lower[lane]);
3445 upper[lane] =
3446 min(rn.end - ctrl->edge_offset[i], upper[lane]);
3447 edges[lane] = (lower[lane] + upper[lane]) / 2;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003448 if (rn.all || (lower[lane] > upper[lane])) {
3449 printk(BIOS_EMERG, "edge write discovery failed: %d, %d, %d\n",
3450 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003451 return MAKE_ERR;
3452 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003453 }
3454 }
3455 }
3456
3457 write32(DEFAULT_MCHBAR + 0x3000, 0);
3458 printram("CPA\n");
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003459 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003460}
3461
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003462static int discover_edges_write(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003463{
3464 int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3465 int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3466 int channel, slotrank, lane;
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003467 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003468
3469 /* FIXME: under some conditions (older chipsets?) vendor BIOS sets both edges to the same value. */
3470 write32(DEFAULT_MCHBAR + 0x4eb0, 0x300);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003471 printram("discover falling edges write:\n[%x] = %x\n", 0x4eb0, 0x300);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003472
3473 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003474 err = discover_edges_write_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003475 falling_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003476 if (err)
3477 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003478 }
3479
3480 write32(DEFAULT_MCHBAR + 0x4eb0, 0x200);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003481 printram("discover rising edges write:\n[%x] = %x\n", 0x4eb0, 0x200);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003482
3483 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003484 err = discover_edges_write_real(ctrl, channel, slotrank,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003485 rising_edges[channel][slotrank]);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003486 if (err)
3487 return err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003488 }
3489
3490 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3491
3492 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3493 ctrl->timings[channel][slotrank].lanes[lane].falling =
3494 falling_edges[channel][slotrank][lane];
3495 ctrl->timings[channel][slotrank].lanes[lane].rising =
3496 rising_edges[channel][slotrank][lane];
3497 }
3498
3499 FOR_ALL_POPULATED_CHANNELS
3500 program_timings(ctrl, channel);
3501
3502 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3503 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel + 4 * lane,
3504 0);
3505 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003506 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003507}
3508
3509static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
3510{
3511 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003512 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003513 write32(DEFAULT_MCHBAR + 0x4220 + 0x400 * channel, 0x1f006);
3514 write32(DEFAULT_MCHBAR + 0x4230 + 0x400 * channel,
3515 (max((ctrl->tFAW >> 2) + 1, ctrl->tRRD)
3516 << 10) | (ctrl->tRCD << 16) | 4);
3517 write32(DEFAULT_MCHBAR + 0x4200 + 0x400 * channel,
3518 (slotrank << 24) | 0x60000);
3519 write32(DEFAULT_MCHBAR + 0x4210 + 0x400 * channel, 0x244);
3520
Patrick Rudolph371d2912015-10-09 13:33:25 +02003521 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003522 write32(DEFAULT_MCHBAR + 0x4224 + 0x400 * channel, 0x1f201);
3523 write32(DEFAULT_MCHBAR + 0x4234 + 0x400 * channel,
3524 0x80011e0 |
3525 ((ctrl->tWTR + ctrl->CWL + 8) << 16));
3526 write32(DEFAULT_MCHBAR + 0x4204 +
3527 0x400 * channel, (slotrank << 24));
3528 write32(DEFAULT_MCHBAR + 0x4214 +
3529 0x400 * channel, 0x242);
3530
Patrick Rudolph371d2912015-10-09 13:33:25 +02003531 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003532 write32(DEFAULT_MCHBAR + 0x4228 +
3533 0x400 * channel, 0x1f105);
3534 write32(DEFAULT_MCHBAR + 0x4238 +
3535 0x400 * channel,
3536 0x40011e0 | (max(ctrl->tRTP, 8) << 16));
3537 write32(DEFAULT_MCHBAR + 0x4208 +
3538 0x400 * channel, (slotrank << 24));
3539 write32(DEFAULT_MCHBAR + 0x4218 +
3540 0x400 * channel, 0x242);
3541
Patrick Rudolph371d2912015-10-09 13:33:25 +02003542 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003543 write32(DEFAULT_MCHBAR + 0x422c +
3544 0x400 * channel, 0x1f002);
3545 write32(DEFAULT_MCHBAR + 0x423c +
3546 0x400 * channel,
3547 0x1001 | (ctrl->tRP << 16));
3548 write32(DEFAULT_MCHBAR + 0x420c +
3549 0x400 * channel,
3550 (slotrank << 24) | 0x60400);
3551 write32(DEFAULT_MCHBAR + 0x421c +
3552 0x400 * channel, 0);
3553
3554 write32(DEFAULT_MCHBAR + 0x4284 +
3555 0x400 * channel, 0xc0001);
3556 wait_428c(channel);
3557}
3558
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003559static int discover_timC_write(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003560{
3561 const u8 rege3c_b24[3] = { 0, 0xf, 0x2f };
3562 int i, pat;
3563
3564 int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3565 int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
3566 int channel, slotrank, lane;
3567
3568 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3569 lower[channel][slotrank][lane] = 0;
3570 upper[channel][slotrank][lane] = MAX_TIMC;
3571 }
3572
3573 write32(DEFAULT_MCHBAR + 0x4ea8, 1);
Patrick Rudolpha649a542016-01-17 18:32:06 +01003574 printram("discover timC write:\n");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003575
3576 for (i = 0; i < 3; i++)
3577 FOR_ALL_POPULATED_CHANNELS {
3578 write32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100),
3579 (rege3c_b24[i] << 24)
3580 | (read32(DEFAULT_MCHBAR + 0xe3c + (channel * 0x100))
3581 & ~0x3f000000));
3582 udelay(2);
3583 for (pat = 0; pat < NUM_PATTERNS; pat++) {
3584 FOR_ALL_POPULATED_RANKS {
3585 int timC;
3586 u32 raw_statistics[MAX_TIMC + 1];
3587 int statistics[MAX_TIMC + 1];
3588
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003589 /* Make sure rn.start < rn.end */
3590 statistics[MAX_TIMC] = 1;
3591
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003592 fill_pattern5(ctrl, channel, pat);
3593 write32(DEFAULT_MCHBAR + 0x4288 + 0x400 * channel, 0x1f);
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003594 for (timC = 0; timC < MAX_TIMC; timC++) {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003595 FOR_ALL_LANES
3596 ctrl->timings[channel][slotrank].lanes[lane].timC = timC;
3597 program_timings(ctrl, channel);
3598
3599 test_timC_write (ctrl, channel, slotrank);
3600
3601 raw_statistics[timC] =
3602 MCHBAR32(0x436c + 0x400 * channel);
3603 }
3604 FOR_ALL_LANES {
3605 struct run rn;
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003606 for (timC = 0; timC < MAX_TIMC; timC++)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003607 statistics[timC] =
3608 !!(raw_statistics[timC] &
3609 (1 << lane));
Patrick Rudolph77e45d32016-02-28 16:14:45 +01003610
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003611 rn = get_longest_zero_run(statistics,
3612 MAX_TIMC + 1);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003613 if (rn.all) {
3614 printk(BIOS_EMERG, "timC write discovery failed: %d, %d, %d\n",
3615 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003616 return MAKE_ERR;
3617 }
Patrick Rudolpha649a542016-01-17 18:32:06 +01003618 printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x, 0x%02x-0x%02x\n",
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003619 channel, slotrank, i, rn.start,
3620 rn.middle, rn.end,
3621 rn.start + ctrl->timC_offset[i],
3622 rn.end - ctrl->timC_offset[i]);
3623 lower[channel][slotrank][lane] =
3624 max(rn.start + ctrl->timC_offset[i],
3625 lower[channel][slotrank][lane]);
3626 upper[channel][slotrank][lane] =
3627 min(rn.end - ctrl->timC_offset[i],
3628 upper[channel][slotrank][lane]);
3629
3630 }
3631 }
3632 }
3633 }
3634
3635 FOR_ALL_CHANNELS {
3636 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
3637 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
3638 ~0x3f000000));
3639 udelay(2);
3640 }
3641
3642 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
3643
3644 printram("CPB\n");
3645
3646 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
Patrick Rudolpha649a542016-01-17 18:32:06 +01003647 printram("timC %d, %d, %d: %x\n", channel,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003648 slotrank, lane,
3649 (lower[channel][slotrank][lane] +
3650 upper[channel][slotrank][lane]) / 2);
3651 ctrl->timings[channel][slotrank].lanes[lane].timC =
3652 (lower[channel][slotrank][lane] +
3653 upper[channel][slotrank][lane]) / 2;
3654 }
3655 FOR_ALL_POPULATED_CHANNELS {
3656 program_timings(ctrl, channel);
3657 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003658 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003659}
3660
3661static void normalize_training(ramctr_timing * ctrl)
3662{
3663 int channel, slotrank, lane;
3664 int mat = 0;
3665
3666 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3667 int delta;
3668 FOR_ALL_LANES mat =
3669 max(ctrl->timings[channel][slotrank].lanes[lane].timA, mat);
3670 delta = (mat >> 6) - ctrl->timings[channel][slotrank].val_4028;
3671 ctrl->timings[channel][slotrank].val_4024 += delta;
3672 ctrl->timings[channel][slotrank].val_4028 += delta;
3673 }
3674
3675 FOR_ALL_POPULATED_CHANNELS {
3676 program_timings(ctrl, channel);
3677 }
3678}
3679
3680static void write_controller_mr(ramctr_timing * ctrl)
3681{
3682 int channel, slotrank;
3683
3684 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
3685 write32(DEFAULT_MCHBAR + 0x0004 + (channel << 8) +
3686 lane_registers[slotrank], make_mr0(ctrl, slotrank));
3687 write32(DEFAULT_MCHBAR + 0x0008 + (channel << 8) +
Patrick Rudolph7e513d12016-01-10 14:22:34 +01003688 lane_registers[slotrank],
3689 make_mr1(ctrl, slotrank, channel));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003690 }
3691}
3692
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003693static int channel_test(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003694{
3695 int channel, slotrank, lane;
3696
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003697 slotrank = 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003698 FOR_ALL_POPULATED_CHANNELS
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003699 if (read32(DEFAULT_MCHBAR + 0x42a0 + (channel << 10)) & 0xa000) {
3700 printk(BIOS_EMERG, "Mini channel test failed (1): %d\n",
3701 channel);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003702 return MAKE_ERR;
3703 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003704 FOR_ALL_POPULATED_CHANNELS {
3705 fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
3706
3707 write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0);
3708 }
3709
3710 for (slotrank = 0; slotrank < 4; slotrank++)
3711 FOR_ALL_CHANNELS
3712 if (ctrl->rankmap[channel] & (1 << slotrank)) {
3713 FOR_ALL_LANES {
3714 write32(DEFAULT_MCHBAR + (0x4f40 + 4 * lane), 0);
3715 write32(DEFAULT_MCHBAR + (0x4d40 + 4 * lane), 0);
3716 }
3717 wait_428c(channel);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003718 /* DRAM command ACT */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003719 write32(DEFAULT_MCHBAR + 0x4220 + (channel << 10), 0x0001f006);
3720 write32(DEFAULT_MCHBAR + 0x4230 + (channel << 10), 0x0028a004);
3721 write32(DEFAULT_MCHBAR + 0x4200 + (channel << 10),
3722 0x00060000 | (slotrank << 24));
3723 write32(DEFAULT_MCHBAR + 0x4210 + (channel << 10), 0x00000244);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003724 /* DRAM command WR */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003725 write32(DEFAULT_MCHBAR + 0x4224 + (channel << 10), 0x0001f201);
3726 write32(DEFAULT_MCHBAR + 0x4234 + (channel << 10), 0x08281064);
3727 write32(DEFAULT_MCHBAR + 0x4204 + (channel << 10),
3728 0x00000000 | (slotrank << 24));
3729 write32(DEFAULT_MCHBAR + 0x4214 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003730 /* DRAM command RD */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003731 write32(DEFAULT_MCHBAR + 0x4228 + (channel << 10), 0x0001f105);
3732 write32(DEFAULT_MCHBAR + 0x4238 + (channel << 10), 0x04281064);
3733 write32(DEFAULT_MCHBAR + 0x4208 + (channel << 10),
3734 0x00000000 | (slotrank << 24));
3735 write32(DEFAULT_MCHBAR + 0x4218 + (channel << 10), 0x00000242);
Patrick Rudolph371d2912015-10-09 13:33:25 +02003736 /* DRAM command PRE */
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003737 write32(DEFAULT_MCHBAR + 0x422c + (channel << 10), 0x0001f002);
3738 write32(DEFAULT_MCHBAR + 0x423c + (channel << 10), 0x00280c01);
3739 write32(DEFAULT_MCHBAR + 0x420c + (channel << 10),
3740 0x00060400 | (slotrank << 24));
3741 write32(DEFAULT_MCHBAR + 0x421c + (channel << 10), 0x00000240);
3742 write32(DEFAULT_MCHBAR + 0x4284 + (channel << 10), 0x000c0001);
3743 wait_428c(channel);
3744 FOR_ALL_LANES
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003745 if (read32(DEFAULT_MCHBAR + 0x4340 + (channel << 10) + 4 * lane)) {
3746 printk(BIOS_EMERG, "Mini channel test failed (2): %d, %d, %d\n",
3747 channel, slotrank, lane);
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003748 return MAKE_ERR;
3749 }
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003750 }
Patrick Rudolph24a845b2016-03-25 18:19:47 +01003751 return 0;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003752}
3753
3754static void set_scrambling_seed(ramctr_timing * ctrl)
3755{
3756 int channel;
3757
3758 /* FIXME: we hardcode seeds. Do we need to use some PRNG for them?
3759 I don't think so. */
3760 static u32 seeds[NUM_CHANNELS][3] = {
3761 {0x00009a36, 0xbafcfdcf, 0x46d1ab68},
3762 {0x00028bfa, 0x53fe4b49, 0x19ed5483}
3763 };
3764 FOR_ALL_POPULATED_CHANNELS {
3765 MCHBAR32(0x4020 + 0x400 * channel) &= ~0x10000000;
3766 write32(DEFAULT_MCHBAR + 0x4034, seeds[channel][0]);
3767 write32(DEFAULT_MCHBAR + 0x403c, seeds[channel][1]);
3768 write32(DEFAULT_MCHBAR + 0x4038, seeds[channel][2]);
3769 }
3770}
3771
3772static void set_4f8c(void)
3773{
3774 struct cpuid_result cpures;
3775 u32 cpu;
3776
3777 cpures = cpuid(0);
3778 cpu = (cpures.eax);
3779 if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
3780 MCHBAR32(0x4f8c) = 0x141D1519;
3781 } else {
3782 MCHBAR32(0x4f8c) = 0x551D1519;
3783 }
3784}
3785
3786static void prepare_training(ramctr_timing * ctrl)
3787{
3788 int channel;
3789
3790 FOR_ALL_POPULATED_CHANNELS {
3791 // Always drive command bus
3792 MCHBAR32(0x4004 + 0x400 * channel) |= 0x20000000;
3793 }
3794
3795 udelay(1);
3796
3797 FOR_ALL_POPULATED_CHANNELS {
3798 wait_428c(channel);
3799 }
3800}
3801
3802static void set_4008c(ramctr_timing * ctrl)
3803{
3804 int channel, slotrank;
3805 u32 reg;
3806 FOR_ALL_POPULATED_CHANNELS {
3807 u32 b20, b4_8_12;
3808 int min_320c = 10000;
3809 int max_320c = -10000;
3810
3811 FOR_ALL_POPULATED_RANKS {
3812 max_320c = max(ctrl->timings[channel][slotrank].val_320c, max_320c);
3813 min_320c = min(ctrl->timings[channel][slotrank].val_320c, min_320c);
3814 }
3815
3816 if (max_320c - min_320c > 51)
3817 b20 = 0;
3818 else
3819 b20 = ctrl->ref_card_offset[channel];
3820
3821 if (ctrl->reg_320c_range_threshold < max_320c - min_320c)
3822 b4_8_12 = 0x3330;
3823 else
3824 b4_8_12 = 0x2220;
3825
3826 reg = read32(DEFAULT_MCHBAR + 0x400c + (channel << 10));
3827 write32(DEFAULT_MCHBAR + 0x400c + (channel << 10),
3828 (reg & 0xFFF0FFFF)
3829 | (ctrl->ref_card_offset[channel] << 16)
3830 | (ctrl->ref_card_offset[channel] << 18));
3831 write32(DEFAULT_MCHBAR + 0x4008 + (channel << 10),
3832 0x0a000000
3833 | (b20 << 20)
3834 | ((ctrl->ref_card_offset[channel] + 2) << 16)
3835 | b4_8_12);
3836 }
3837}
3838
3839static void set_42a0(ramctr_timing * ctrl)
3840{
3841 int channel;
3842 FOR_ALL_POPULATED_CHANNELS {
3843 write32(DEFAULT_MCHBAR + (0x42a0 + 0x400 * channel),
3844 0x00001000 | ctrl->rankmap[channel]);
3845 MCHBAR32(0x4004 + 0x400 * channel) &= ~0x20000000; // OK
3846 }
3847}
3848
3849static int encode_5d10(int ns)
3850{
3851 return (ns + 499) / 500;
3852}
3853
3854/* FIXME: values in this function should be hardware revision-dependent. */
3855static void final_registers(ramctr_timing * ctrl)
3856{
3857 int channel;
3858 int t1_cycles = 0, t1_ns = 0, t2_ns;
3859 int t3_ns;
3860 u32 r32;
3861
3862 write32(DEFAULT_MCHBAR + 0x4cd4, 0x00000046);
3863
3864 write32(DEFAULT_MCHBAR + 0x400c, (read32(DEFAULT_MCHBAR + 0x400c) & 0xFFFFCFFF) | 0x1000); // OK
3865 write32(DEFAULT_MCHBAR + 0x440c, (read32(DEFAULT_MCHBAR + 0x440c) & 0xFFFFCFFF) | 0x1000); // OK
3866 write32(DEFAULT_MCHBAR + 0x4cb0, 0x00000740);
3867 write32(DEFAULT_MCHBAR + 0x4380, 0x00000aaa); // OK
3868 write32(DEFAULT_MCHBAR + 0x4780, 0x00000aaa); // OK
3869 write32(DEFAULT_MCHBAR + 0x4f88, 0x5f7003ff); // OK
3870 write32(DEFAULT_MCHBAR + 0x5064, 0x00073000 | ctrl->reg_5064b0); // OK
3871
3872 FOR_ALL_CHANNELS {
3873 switch (ctrl->rankmap[channel]) {
3874 /* Unpopulated channel. */
3875 case 0:
3876 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0);
3877 break;
3878 /* Only single-ranked dimms. */
3879 case 1:
3880 case 4:
3881 case 5:
3882 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x373131);
3883 break;
3884 /* Dual-ranked dimms present. */
3885 default:
3886 write32(DEFAULT_MCHBAR + 0x4384 + channel * 0x400, 0x9b6ea1);
3887 break;
3888 }
3889 }
3890
3891 write32 (DEFAULT_MCHBAR + 0x5880, 0xca9171e5);
3892 write32 (DEFAULT_MCHBAR + 0x5888,
3893 (read32 (DEFAULT_MCHBAR + 0x5888) & ~0xffffff) | 0xe4d5d0);
3894 write32 (DEFAULT_MCHBAR + 0x58a8, read32 (DEFAULT_MCHBAR + 0x58a8) & ~0x1f);
3895 write32 (DEFAULT_MCHBAR + 0x4294,
3896 (read32 (DEFAULT_MCHBAR + 0x4294) & ~0x30000)
3897 | (1 << 16));
3898 write32 (DEFAULT_MCHBAR + 0x4694,
3899 (read32 (DEFAULT_MCHBAR + 0x4694) & ~0x30000)
3900 | (1 << 16));
3901
3902 MCHBAR32(0x5030) |= 1; // OK
3903 MCHBAR32(0x5030) |= 0x80; // OK
3904 MCHBAR32(0x5f18) = 0xfa; // OK
3905
3906 /* Find a populated channel. */
3907 FOR_ALL_POPULATED_CHANNELS
3908 break;
3909
3910 t1_cycles = ((read32(DEFAULT_MCHBAR + 0x4290 + channel * 0x400) >> 8) & 0xff);
3911 r32 = read32(DEFAULT_MCHBAR + 0x5064);
3912 if (r32 & 0x20000)
3913 t1_cycles += (r32 & 0xfff);
3914 t1_cycles += (read32(DEFAULT_MCHBAR + channel * 0x400 + 0x42a4) & 0xfff);
3915 t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
3916 if (!(r32 & 0x20000))
3917 t1_ns += 500;
3918
3919 t2_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f10) >> 8) & 0xfff);
3920 if ( read32(DEFAULT_MCHBAR + 0x5f00) & 8 )
3921 {
3922 t3_ns = 10 * ((read32(DEFAULT_MCHBAR + 0x5f20) >> 8) & 0xfff);
3923 t3_ns += 10 * (read32(DEFAULT_MCHBAR + 0x5f18) & 0xff);
3924 }
3925 else
3926 {
3927 t3_ns = 500;
3928 }
3929 printk(BIOS_DEBUG, "t123: %d, %d, %d\n",
3930 t1_ns, t2_ns, t3_ns);
3931 write32 (DEFAULT_MCHBAR + 0x5d10,
3932 ((encode_5d10(t1_ns) + encode_5d10(t2_ns)) << 16)
3933 | (encode_5d10(t1_ns) << 8)
3934 | ((encode_5d10(t3_ns) + encode_5d10(t2_ns) + encode_5d10(t1_ns)) << 24)
3935 | (read32(DEFAULT_MCHBAR + 0x5d10) & 0xC0C0C0C0)
3936 | 0xc);
3937}
3938
Patrick Rudolphbb9c90a2016-05-29 17:05:06 +02003939static void save_timings(ramctr_timing *ctrl)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003940{
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003941 /* Save the MRC S3 restore data to cbmem */
Patrick Rudolphbb9c90a2016-05-29 17:05:06 +02003942 store_current_mrc_cache(ctrl, sizeof(*ctrl));
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07003943}
3944
3945static void restore_timings(ramctr_timing * ctrl)
3946{
3947 int channel, slotrank, lane;
3948
3949 FOR_ALL_POPULATED_CHANNELS
3950 MCHBAR32(0x4004 + 0x400 * channel) =
3951 ctrl->tRRD
3952 | (ctrl->tRTP << 4)
3953 | (ctrl->tCKE << 8)
3954 | (ctrl->tWTR << 12)
3955 | (ctrl->tFAW << 16)
3956 | (ctrl->tWR << 24)
3957 | (ctrl->cmd_stretch[channel] << 30);
3958
3959 udelay(1);
3960
3961 FOR_ALL_POPULATED_CHANNELS {
3962 wait_428c(channel);
3963 }
3964
3965 FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
3966 write32(DEFAULT_MCHBAR + 0x4080 + 0x400 * channel
3967 + 4 * lane, 0);
3968 }
3969
3970 FOR_ALL_POPULATED_CHANNELS
3971 write32(DEFAULT_MCHBAR + 0x4008 + 0x400 * channel,
3972 read32(DEFAULT_MCHBAR + 0x4008 +
3973 0x400 * channel) | 0x8000000);
3974
3975 FOR_ALL_POPULATED_CHANNELS {
3976 udelay (1);
3977 write32(DEFAULT_MCHBAR + 0x4020 + 0x400 * channel,
3978 read32(DEFAULT_MCHBAR + 0x4020 +
3979 0x400 * channel) | 0x200000);
3980 }
3981
3982 printram("CPE\n");
3983
3984 write32(DEFAULT_MCHBAR + 0x3400, 0);
3985 write32(DEFAULT_MCHBAR + 0x4eb0, 0);
3986
3987 printram("CP5b\n");
3988
3989 FOR_ALL_POPULATED_CHANNELS {
3990 program_timings(ctrl, channel);
3991 }
3992
3993 u32 reg, addr;
3994
3995 while (!(MCHBAR32(0x5084) & 0x10000)) ;
3996 do {
3997 reg = MCHBAR32(0x428c);
3998 } while ((reg & 0x14) == 0);
3999
4000 // Set state of memory controller
4001 MCHBAR32(0x5030) = 0x116;
4002 MCHBAR32(0x4ea0) = 0;
4003
4004 // Wait 500us
4005 udelay(500);
4006
4007 FOR_ALL_CHANNELS {
4008 // Set valid rank CKE
4009 reg = 0;
4010 reg = (reg & ~0xf) | ctrl->rankmap[channel];
4011 addr = 0x400 * channel + 0x42a0;
4012 MCHBAR32(addr) = reg;
4013
4014 // Wait 10ns for ranks to settle
4015 //udelay(0.01);
4016
4017 reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
4018 MCHBAR32(addr) = reg;
4019
4020 // Write reset using a NOP
4021 write_reset(ctrl);
4022 }
4023
4024 /* mrs commands. */
4025 dram_mrscommands(ctrl);
4026
4027 printram("CP5c\n");
4028
4029 write32(DEFAULT_MCHBAR + 0x3000, 0);
4030
4031 FOR_ALL_CHANNELS {
4032 write32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c,
4033 0 | (read32(DEFAULT_MCHBAR + (channel * 0x100) + 0xe3c) &
4034 ~0x3f000000));
4035 udelay(2);
4036 }
4037
4038 write32(DEFAULT_MCHBAR + 0x4ea8, 0);
4039}
4040
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004041static int try_init_dram_ddr3(ramctr_timing *ctrl, int fast_boot,
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004042 int s3_resume, int me_uma_size)
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004043{
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004044 int err;
4045
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004046 printk(BIOS_DEBUG, "Starting RAM training (%d).\n", fast_boot);
4047
4048 if (!fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004049 /* Find fastest common supported parameters */
4050 dram_find_common_params(ctrl);
4051
4052 dram_dimm_mapping(ctrl);
4053 }
4054
4055 /* Set MCU frequency */
4056 dram_freq(ctrl);
4057
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004058 if (!fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004059 /* Calculate timings */
4060 dram_timing(ctrl);
4061 }
4062
4063 /* Set version register */
4064 MCHBAR32(0x5034) = 0xC04EB002;
4065
4066 /* Enable crossover */
4067 dram_xover(ctrl);
4068
4069 /* Set timing and refresh registers */
4070 dram_timing_regs(ctrl);
4071
4072 /* Power mode preset */
4073 MCHBAR32(0x4e80) = 0x5500;
4074
4075 /* Set scheduler parameters */
4076 MCHBAR32(0x4c20) = 0x10100005;
4077
4078 /* Set cpu specific register */
4079 set_4f8c();
4080
4081 /* Clear IO reset bit */
4082 MCHBAR32(0x5030) &= ~0x20;
4083
4084 /* Set MAD-DIMM registers */
4085 dram_dimm_set_mapping(ctrl);
4086 printk(BIOS_DEBUG, "Done dimm mapping\n");
4087
4088 /* Zone config */
4089 dram_zones(ctrl, 1);
4090
4091 /* Set memory map */
4092 dram_memorymap(ctrl, me_uma_size);
4093 printk(BIOS_DEBUG, "Done memory map\n");
4094
4095 /* Set IO registers */
4096 dram_ioregs(ctrl);
4097 printk(BIOS_DEBUG, "Done io registers\n");
4098
4099 udelay(1);
4100
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004101 if (fast_boot) {
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004102 restore_timings(ctrl);
4103 } else {
4104 /* Do jedec ddr3 reset sequence */
4105 dram_jedecreset(ctrl);
4106 printk(BIOS_DEBUG, "Done jedec reset\n");
4107
4108 /* MRS commands */
4109 dram_mrscommands(ctrl);
4110 printk(BIOS_DEBUG, "Done MRS commands\n");
4111
4112 /* Prepare for memory training */
4113 prepare_training(ctrl);
4114
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004115 err = read_training(ctrl);
4116 if (err)
4117 return err;
4118
4119 err = write_training(ctrl);
4120 if (err)
4121 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004122
4123 printram("CP5a\n");
4124
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004125 err = discover_edges(ctrl);
4126 if (err)
4127 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004128
4129 printram("CP5b\n");
4130
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004131 err = command_training(ctrl);
4132 if (err)
4133 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004134
4135 printram("CP5c\n");
4136
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004137 err = discover_edges_write(ctrl);
4138 if (err)
4139 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004140
Patrick Rudolph24a845b2016-03-25 18:19:47 +01004141 err = discover_timC_write(ctrl);
4142 if (err)
4143 return err;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004144
4145 normalize_training(ctrl);
4146 }
4147
4148 set_4008c(ctrl);
4149
4150 write_controller_mr(ctrl);
4151
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004152 if (!s3_resume) {
4153 err = channel_test(ctrl);
4154 if (err)
4155 return err;
4156 }
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004157
4158 return 0;
4159}
4160
4161void init_dram_ddr3(spd_raw_data *spds, int mobile, int min_tck,
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004162 int s3resume)
4163{
4164 int me_uma_size;
4165 int cbmem_was_inited;
Patrick Rudolph735ecce2016-03-26 10:42:27 +01004166 ramctr_timing ctrl;
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004167 int fast_boot;
4168 struct mrc_data_container *mrc_cache;
4169 ramctr_timing *ctrl_cached;
Patrick Rudolph31d19592016-03-26 12:22:34 +01004170 int err;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004171
4172 MCHBAR32(0x5f00) |= 1;
Stefan Reinauer00636b02012-04-04 00:08:51 +02004173
Vadim Bendebury7a3f36a2012-04-18 15:47:32 -07004174 report_platform_info();
4175
Stefan Reinauer00636b02012-04-04 00:08:51 +02004176 /* Wait for ME to be ready */
4177 intel_early_me_init();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004178 me_uma_size = intel_early_me_uma_size();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004179
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004180 printk(BIOS_DEBUG, "Starting native Platform init\n");
Stefan Reinauer00636b02012-04-04 00:08:51 +02004181
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004182 u32 reg_5d10;
Stefan Reinauer00636b02012-04-04 00:08:51 +02004183
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004184 wait_txt_clear();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004185
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004186 wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 });
Stefan Reinauer00636b02012-04-04 00:08:51 +02004187
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004188 reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000
4189 if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */
4190 && reg_5d10 && !s3resume) {
4191 write32(DEFAULT_MCHBAR + 0x5d10, 0);
4192 /* Need reset. */
Stefan Reinauer00636b02012-04-04 00:08:51 +02004193 outb(0x6, 0xcf9);
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004194
Patrick Georgi546953c2014-11-29 10:38:17 +01004195 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004196 }
Stefan Reinauer00636b02012-04-04 00:08:51 +02004197
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004198 memset(&ctrl, 0, sizeof (ctrl));
4199
4200 early_pch_init_native();
4201 early_thermal_init();
4202
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004203 /* try to find timings in MRC cache */
4204 mrc_cache = find_current_mrc_cache();
4205 if (!mrc_cache || (mrc_cache->mrc_data_size < sizeof(ctrl))) {
4206 if (s3resume) {
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004207 /* Failed S3 resume, reset to come up cleanly */
4208 outb(0x6, 0xcf9);
4209 halt();
Stefan Reinauer00636b02012-04-04 00:08:51 +02004210 }
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004211 ctrl_cached = NULL;
Patrick Rudolph27e085a2016-03-26 10:59:02 +01004212 } else {
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004213 ctrl_cached = (ramctr_timing *)mrc_cache->mrc_data;
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004214 }
4215
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004216 /* verify MRC cache for fast boot */
4217 if (ctrl_cached) {
4218 /* check SPD CRC16 to make sure the DIMMs haven't been replaced */
4219 fast_boot = verify_crc16_spds_ddr3(spds, ctrl_cached);
4220 if (!fast_boot)
4221 printk(BIOS_DEBUG, "Stored timings CRC16 mismatch.\n");
4222 if (!fast_boot && s3resume) {
4223 /* Failed S3 resume, reset to come up cleanly */
4224 outb(0x6, 0xcf9);
4225 halt();
4226 }
4227 } else
4228 fast_boot = 0;
4229
4230 if (fast_boot) {
4231 printk(BIOS_DEBUG, "Trying stored timings.\n");
4232 memcpy(&ctrl, ctrl_cached, sizeof(ctrl));
4233
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004234 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004235 if (err) {
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004236 if (s3resume) {
4237 /* Failed S3 resume, reset to come up cleanly */
4238 outb(0x6, 0xcf9);
4239 halt();
4240 }
4241 /* no need to erase bad mrc cache here, it gets overwritten on
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004242 * successful boot. */
4243 printk(BIOS_ERR, "Stored timings are invalid !\n");
4244 fast_boot = 0;
4245 }
4246 }
4247 if (!fast_boot) {
4248 ctrl.mobile = mobile;
4249 ctrl.tCK = min_tck;
4250
4251 /* Get DDR3 SPD data */
4252 dram_find_spds_ddr3(spds, &ctrl);
4253
Patrick Rudolph588ccaa2016-04-20 18:00:27 +02004254 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004255 }
Patrick Rudolph2ccb74b2016-03-26 12:16:29 +01004256
4257 if (err && (ctrl.tCK < TCK_400MHZ)) {
4258 /* fallback: lower clock frequency */
4259 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4260 printram("Decreasing clock frequency.\n");
4261 ctrl.tCK++;
4262 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4263 }
4264
4265 if (err && (ctrl.tCK < TCK_400MHZ)) {
4266 /* fallback: lower clock frequency */
4267 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4268 printram("Decreasing clock frequency.\n");
4269 ctrl.tCK++;
4270 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4271 }
4272
4273 if (err) {
4274 /* fallback: disable failing channel */
4275 printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
4276 printram("Disable failing channel.\n");
4277
4278 /* Reset DDR3 frequency */
4279 dram_find_spds_ddr3(spds, &ctrl);
4280
4281 /* disable failing channel */
4282 disable_channel(&ctrl, GET_ERR_CHANNEL(err));
4283
4284 err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
4285 }
4286
Patrick Rudolph31d19592016-03-26 12:22:34 +01004287 if (err)
4288 die("raminit failed");
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004289
4290 /* FIXME: should be hardware revision-dependent. */
4291 write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
4292
4293 set_scrambling_seed(&ctrl);
4294
4295 set_42a0(&ctrl);
4296
4297 final_registers(&ctrl);
4298
4299 /* Zone config */
4300 dram_zones(&ctrl, 0);
4301
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004302 if (!fast_boot)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004303 quick_ram_check();
4304
4305 intel_early_me_status();
4306 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
4307 intel_early_me_status();
4308
Stefan Reinauer00636b02012-04-04 00:08:51 +02004309 report_memory_config();
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004310
4311 cbmem_was_inited = !cbmem_recovery(s3resume);
Patrick Rudolph56abd4d2016-03-13 11:07:45 +01004312 if (!fast_boot)
Alexandru Gagniucecf2eb42015-09-28 21:39:12 -07004313 save_timings(&ctrl);
4314 if (s3resume && !cbmem_was_inited) {
4315 /* Failed S3 resume, reset to come up cleanly */
4316 outb(0x6, 0xcf9);
4317 halt();
4318 }
Patrick Rudolphb97009e2016-02-28 15:24:04 +01004319
Patrick Rudolph735ecce2016-03-26 10:42:27 +01004320 fill_smbios17(&ctrl);
Stefan Reinauer00636b02012-04-04 00:08:51 +02004321}
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004322
4323#define HOST_BRIDGE PCI_DEVFN(0, 0)
4324#define DEFAULT_TCK TCK_800MHZ
4325
4326static unsigned int get_mem_min_tck(void)
4327{
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004328 u32 reg32;
4329 u8 rev;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004330 const struct device *dev;
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004331 const struct northbridge_intel_sandybridge_config *cfg = NULL;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004332
4333 dev = dev_find_slot(0, HOST_BRIDGE);
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004334 if (dev)
4335 cfg = dev->chip_info;
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004336
4337 /* If this is zero, it just means devicetree.cb didn't set it */
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004338 if (!cfg || cfg->max_mem_clock_mhz == 0) {
4339 rev = pci_read_config8(PCI_DEV(0, 0, 0), PCI_DEVICE_ID);
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004340
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004341 if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
4342 /* read Capabilities A Register DMFC bits */
4343 reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A);
4344 reg32 &= 0x7;
4345
4346 switch (reg32) {
4347 case 7: return TCK_533MHZ;
4348 case 6: return TCK_666MHZ;
4349 case 5: return TCK_800MHZ;
4350 /* reserved: */
4351 default:
4352 break;
4353 }
4354 } else {
4355 /* read Capabilities B Register DMFC bits */
4356 reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_B);
4357 reg32 = (reg32 >> 4) & 0x7;
4358
4359 switch (reg32) {
4360 case 7: return TCK_533MHZ;
4361 case 6: return TCK_666MHZ;
4362 case 5: return TCK_800MHZ;
4363 case 4: return TCK_933MHZ;
4364 case 3: return TCK_1066MHZ;
4365 case 2: return TCK_1200MHZ;
4366 case 1: return TCK_1333MHZ;
4367 /* reserved: */
4368 default:
4369 break;
4370 }
4371 }
4372 return DEFAULT_TCK;
4373 } else {
Patrick Rudolph7bddd302016-06-11 18:39:35 +02004374 if (cfg->max_mem_clock_mhz >= 1066)
4375 return TCK_1066MHZ;
4376 else if (cfg->max_mem_clock_mhz >= 933)
4377 return TCK_933MHZ;
4378 else if (cfg->max_mem_clock_mhz >= 800)
Patrick Rudolph9f3f9152016-01-26 20:02:14 +01004379 return TCK_800MHZ;
4380 else if (cfg->max_mem_clock_mhz >= 666)
4381 return TCK_666MHZ;
4382 else if (cfg->max_mem_clock_mhz >= 533)
4383 return TCK_533MHZ;
4384 else
4385 return TCK_400MHZ;
4386 }
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004387}
4388
Patrick Rudolph266a1f72016-06-09 18:13:34 +02004389#define DEFAULT_PCI_MMIO_SIZE 2048
4390
4391static unsigned int get_mmio_size(void)
4392{
4393 const struct device *dev;
4394 const struct northbridge_intel_sandybridge_config *cfg = NULL;
4395
4396 dev = dev_find_slot(0, HOST_BRIDGE);
4397 if (dev)
4398 cfg = dev->chip_info;
4399
4400 /* If this is zero, it just means devicetree.cb didn't set it */
4401 if (!cfg || cfg->pci_mmio_size == 0)
4402 return DEFAULT_PCI_MMIO_SIZE;
4403 else
4404 return cfg->pci_mmio_size;
4405}
4406
Vladimir Serbinenkoffbb3c02016-02-10 01:36:25 +01004407void perform_raminit(int s3resume)
4408{
4409 spd_raw_data spd[4];
4410
4411 post_code(0x3a);
4412
4413 memset (spd, 0, sizeof (spd));
4414 mainboard_get_spd(spd);
4415
4416 timestamp_add_now(TS_BEFORE_INITRAM);
4417
4418 init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume);
4419}