blob: 1d616a6ae880490c0e4daabca84932cbce6a8549 [file] [log] [blame]
Timothy Pearson4551b682015-11-24 14:12:08 -06001/*
2 * This file is part of the coreboot project.
3 *
Timothy Pearson99e27ce2016-04-24 20:33:29 -05004 * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
Timothy Pearson4551b682015-11-24 14:12:08 -06005 *
6 * Copyright (C) 2007 AMD
7 * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <stdint.h>
21#include <string.h>
22#include <reset.h>
23#include <device/pci_def.h>
24#include <device/pci_ids.h>
25#include <arch/io.h>
26#include <device/pnp_def.h>
27#include <cpu/x86/lapic.h>
28#include <console/console.h>
Kyösti Mälkkic2a921b2017-09-04 23:58:38 +030029#include <romstage_handoff.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060030#include <timestamp.h>
31#include <lib.h>
32#include <spd.h>
33#include <cpu/amd/model_10xxx_rev.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060034#include <delay.h>
35#include <cpu/x86/lapic.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060036#include <superio/winbond/common/winbond.h>
37#include <superio/winbond/w83667hg-a/w83667hg-a.h>
38#include <cpu/x86/bist.h>
39#include <smp/spinlock.h>
Damien Zammit75a3d1f2016-11-28 00:29:10 +110040#include <cpu/amd/car.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060041#include <southbridge/amd/sb700/sb700.h>
42#include <southbridge/amd/sb700/smbus.h>
43#include <southbridge/amd/sr5650/sr5650.h>
Damien Zammit75a3d1f2016-11-28 00:29:10 +110044#include <northbridge/amd/amdfam10/raminit.h>
45#include <northbridge/amd/amdht/ht_wrapper.h>
46#include <cpu/amd/family_10h-family_15h/init_cpus.h>
47#include <arch/early_variables.h>
48#include <cbmem.h>
49
50#include "resourcemap.c"
51#include "cpu/amd/quadcore/quadcore.c"
Timothy Pearson4551b682015-11-24 14:12:08 -060052
Timothy Pearsonca543392016-05-18 13:33:13 -050053#define SERIAL_0_DEV PNP_DEV(0x2e, W83667HG_A_SP1)
54#define SERIAL_1_DEV PNP_DEV(0x2e, W83667HG_A_SP2)
Timothy Pearson4551b682015-11-24 14:12:08 -060055
Damien Zammit75a3d1f2016-11-28 00:29:10 +110056void activate_spd_rom(const struct mem_controller *ctrl);
Elyes HAOUASdd35e2c2018-09-20 17:33:50 +020057int spd_read_byte(unsigned int device, unsigned int address);
Damien Zammit75a3d1f2016-11-28 00:29:10 +110058extern struct sys_info sysinfo_car;
Timothy Pearson4551b682015-11-24 14:12:08 -060059
Elyes HAOUASdd35e2c2018-09-20 17:33:50 +020060inline int spd_read_byte(unsigned int device, unsigned int address)
Timothy Pearson4551b682015-11-24 14:12:08 -060061{
62 return do_smbus_read_byte(SMBUS_AUX_IO_BASE, device, address);
63}
64
Timothy Pearson4551b682015-11-24 14:12:08 -060065/*
66 * ASUS KCMA-D8 specific SPD enable/disable magic.
67 *
68 * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings:
69 * 0: Disabled
70 * 1: Normal SPI access
71 * 2: CPU0 SPD
72 * 3: CPU1 SPD
73 *
74 * Disable SPD access after RAM init to allow access to standard SMBus/I2C offsets
75 * which is required e.g. by lm-sensors.
76 */
77
78/* Relevant GPIO register information is available in the
79 * AMD SP5100 Register Reference Guide rev. 3.03, page 130
80 */
81static void switch_spd_mux(uint8_t channel)
82{
83 uint8_t byte;
84
85 byte = pci_read_config8(PCI_DEV(0, 0x14, 0), 0x54);
86 byte &= ~0xc; /* Clear SPD mux GPIOs */
87 byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */
88 byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */
89 pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte);
90}
91
92static const uint8_t spd_addr_fam15[] = {
93 // Socket 0 Node 0 ("Node 0")
94 RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearsonb251a502015-11-24 14:17:49 -060095 // Socket 1 Node 0 ("Node 1")
Timothy Pearson4551b682015-11-24 14:12:08 -060096 RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearson4551b682015-11-24 14:12:08 -060097};
98
99static const uint8_t spd_addr_fam10[] = {
100 // Socket 0 Node 0 ("Node 0")
101 RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearsonb251a502015-11-24 14:17:49 -0600102 // Socket 1 Node 0 ("Node 1")
Timothy Pearson4551b682015-11-24 14:12:08 -0600103 RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
104};
105
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100106void activate_spd_rom(const struct mem_controller *ctrl) {
Timothy Pearson4551b682015-11-24 14:12:08 -0600107 printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id);
Timothy Pearsonb251a502015-11-24 14:17:49 -0600108 if (ctrl->node_id == 0) {
109 printk(BIOS_DEBUG, "enable_spd_node0()\n");
110 switch_spd_mux(0x2);
111 } else if (ctrl->node_id == 1) {
112 printk(BIOS_DEBUG, "enable_spd_node1()\n");
113 switch_spd_mux(0x3);
114 }
Timothy Pearson4551b682015-11-24 14:12:08 -0600115}
116
117/* Voltages are specified by index
Jonathan Neuschäfer482d16f2017-11-20 02:09:19 +0100118 * Valid indices for this platform are:
Timothy Pearson4551b682015-11-24 14:12:08 -0600119 * 0: 1.5V
120 * 1: 1.35V
121 * 2: 1.25V
122 * 3: 1.15V
123 */
124static void set_ddr3_voltage(uint8_t node, uint8_t index) {
125 uint8_t byte;
126 uint8_t value = 0;
127
128 if (index == 0)
129 value = 0x0;
130 else if (index == 1)
131 value = 0x1;
132 else if (index == 2)
133 value = 0x4;
134 else if (index == 3)
135 value = 0x5;
136 if (node == 1)
137 value <<= 1;
138
139 /* Set GPIOs */
140 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd1);
141 if (node == 0)
142 byte &= ~0x5;
143 if (node == 1)
144 byte &= ~0xa;
145 byte |= value;
146 pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd1, byte);
147
148 /* Enable GPIO output drivers */
149 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd0);
150 byte &= 0x0f;
151 pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd0, byte);
152
153 printk(BIOS_DEBUG, "Node %02d DIMM voltage set to index %02x\n", node, index);
154}
155
156void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
157 struct DCTStatStruc *pDCTstatA) {
158 /* This mainboard allows the DIMM voltage to be set per-socket.
159 * Therefore, for each socket, iterate over all DIMMs to find the
160 * lowest supported voltage common to all DIMMs on that socket.
161 */
162 uint8_t nvram;
163 uint8_t dimm;
164 uint8_t node;
165 uint8_t socket;
166 uint8_t allowed_voltages = 0xf; /* The mainboard VRMs allow 1.15V, 1.25V, 1.35V, and 1.5V */
167 uint8_t socket_allowed_voltages = allowed_voltages;
168 uint32_t set_voltage = 0;
169
170 if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) {
171 switch (nvram) {
172 case 2:
173 allowed_voltages = 0x7; /* Allow 1.25V, 1.35V, and 1.5V */
174 break;
175 case 1:
176 allowed_voltages = 0x3; /* Allow 1.35V and 1.5V */
177 break;
178 case 0:
179 default:
180 allowed_voltages = 0x1; /* Allow 1.5V only */
181 break;
182 }
183 }
184
185 for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
Timothy Pearsonb251a502015-11-24 14:17:49 -0600186 socket = node;
Timothy Pearson4551b682015-11-24 14:12:08 -0600187 struct DCTStatStruc *pDCTstat;
188 pDCTstat = pDCTstatA + node;
189
190 /* reset socket_allowed_voltages before processing each socket */
Timothy Pearsonb251a502015-11-24 14:17:49 -0600191 socket_allowed_voltages = allowed_voltages;
Timothy Pearson4551b682015-11-24 14:12:08 -0600192
193 if (pDCTstat->NodePresent) {
194 for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
195 if (pDCTstat->DIMMValid & (1 << dimm)) {
196 socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm];
197 }
198 }
Timothy Pearson4551b682015-11-24 14:12:08 -0600199
Timothy Pearson4551b682015-11-24 14:12:08 -0600200 /* Set voltages */
201 if (socket_allowed_voltages & 0x8) {
202 set_voltage = 0x8;
203 set_ddr3_voltage(socket, 3);
204 } else if (socket_allowed_voltages & 0x4) {
205 set_voltage = 0x4;
206 set_ddr3_voltage(socket, 2);
207 } else if (socket_allowed_voltages & 0x2) {
208 set_voltage = 0x2;
209 set_ddr3_voltage(socket, 1);
210 } else {
211 set_voltage = 0x1;
212 set_ddr3_voltage(socket, 0);
213 }
214
215 /* Save final DIMM voltages for MCT and SMBIOS use */
Timothy Pearsonb251a502015-11-24 14:17:49 -0600216 for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
217 pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
Timothy Pearson4551b682015-11-24 14:12:08 -0600218 }
219 }
220 }
221
222 /* Allow the DDR supply voltages to settle */
223 udelay(100000);
224}
225
226static void set_peripheral_control_lines(void) {
227 uint8_t byte;
Timothy Pearson4551b682015-11-24 14:12:08 -0600228
Timothy Pearsonb251a502015-11-24 14:17:49 -0600229 /* Enable PCICLK5 */
230 outb(0x41, 0xcd6);
231 outb(0x02, 0xcd7);
Timothy Pearson4551b682015-11-24 14:12:08 -0600232
233 /* Enable the RTC AltCentury register */
234 outb(0x41, 0xcd6);
235 byte = inb(0xcd7);
236 byte |= 0x10;
237 outb(byte, 0xcd7);
238}
239
240#ifdef TEST_MEMORY
241static void execute_memory_test(void)
242{
243 /* Test DRAM functionality */
244 uint32_t i;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500245 uint32_t v;
246 uint32_t w;
247 uint32_t x;
248 uint32_t y;
249 uint32_t z;
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200250 uint32_t *dataptr;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500251 uint32_t readback;
252 uint32_t start = 0x300000;
253 printk(BIOS_DEBUG, "Writing test pattern 1 to memory...\n");
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200254 for (i = 0; i < 0x1000000; i = i + 8) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500255 dataptr = (void *)(start + i);
Timothy Pearson4551b682015-11-24 14:12:08 -0600256 *dataptr = 0x55555555;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500257 dataptr = (void *)(start + i + 4);
Timothy Pearson4551b682015-11-24 14:12:08 -0600258 *dataptr = 0xaaaaaaaa;
259 }
260 printk(BIOS_DEBUG, "Done!\n");
261 printk(BIOS_DEBUG, "Testing memory...\n");
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200262 for (i = 0; i < 0x1000000; i = i + 8) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500263 dataptr = (void *)(start + i);
Timothy Pearson4551b682015-11-24 14:12:08 -0600264 readback = *dataptr;
265 if (readback != 0x55555555)
266 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0x55555555);
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500267 dataptr = (void *)(start + i + 4);
Timothy Pearson4551b682015-11-24 14:12:08 -0600268 readback = *dataptr;
269 if (readback != 0xaaaaaaaa)
270 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0xaaaaaaaa);
271 }
272 printk(BIOS_DEBUG, "Done!\n");
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500273 printk(BIOS_DEBUG, "Writing test pattern 2 to memory...\n");
274 /* Set up the PRNG seeds for initial write */
275 w = 0x55555555;
276 x = 0xaaaaaaaa;
277 y = 0x12345678;
278 z = 0x87654321;
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200279 for (i = 0; i < 0x1000000; i = i + 4) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500280 /* Use Xorshift as a PRNG to stress test the bus */
281 v = x;
282 v ^= v << 11;
283 v ^= v >> 8;
284 x = y;
285 y = z;
286 z = w;
287 w ^= w >> 19;
288 w ^= v;
289 dataptr = (void *)(start + i);
290 *dataptr = w;
291 }
292 printk(BIOS_DEBUG, "Done!\n");
293 printk(BIOS_DEBUG, "Testing memory...\n");
294 /* Reset the PRNG seeds for readback */
295 w = 0x55555555;
296 x = 0xaaaaaaaa;
297 y = 0x12345678;
298 z = 0x87654321;
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200299 for (i = 0; i < 0x1000000; i = i + 4) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500300 /* Use Xorshift as a PRNG to stress test the bus */
301 v = x;
302 v ^= v << 11;
303 v ^= v >> 8;
304 x = y;
305 y = z;
306 z = w;
307 w ^= w >> 19;
308 w ^= v;
309 dataptr = (void *)(start + i);
310 readback = *dataptr;
311 if (readback != w)
312 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, w);
313 }
314 printk(BIOS_DEBUG, "Done!\n");
Timothy Pearson4551b682015-11-24 14:12:08 -0600315}
316#endif
317
318static spinlock_t printk_spinlock CAR_GLOBAL;
319
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200320spinlock_t *romstage_console_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600321{
322 return car_get_var_ptr(&printk_spinlock);
323}
324
325void initialize_romstage_console_lock(void)
326{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100327 spin_unlock(romstage_console_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600328}
329
330static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL;
331
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200332spinlock_t *romstage_nvram_cbfs_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600333{
334 return car_get_var_ptr(&nvram_cbfs_spinlock);
335}
336
337void initialize_romstage_nvram_cbfs_lock(void)
338{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100339 spin_unlock(romstage_nvram_cbfs_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600340}
341
342static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL;
343
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200344spinlock_t *romstage_microcode_cbfs_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600345{
346 return car_get_var_ptr(&microcode_cbfs_spinlock);
347}
348
349void initialize_romstage_microcode_cbfs_lock(void)
350{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100351 spin_unlock(romstage_microcode_cbfs_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600352}
353
354void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
355{
356 uint32_t esp;
357 __asm__ volatile (
358 "movl %%esp, %0"
359 : "=r" (esp)
360 );
361
362 struct sys_info *sysinfo = &sysinfo_car;
363
364 /* Limit the maximum HT speed to 2.6GHz to prevent lockups
365 * due to HT CPU <--> CPU wiring not being validated to 3.2GHz
366 */
367 sysinfo->ht_link_cfg.ht_speed_limit = 2600;
368
369 uint32_t bsp_apicid = 0, val;
370 uint8_t byte;
Timothy Pearsone9205d52016-04-06 13:27:04 -0500371 uint8_t power_on_reset = 0;
Timothy Pearson4551b682015-11-24 14:12:08 -0600372 msr_t msr;
373
374 int s3resume = acpi_is_wakeup_s3();
375
376 if (!cpu_init_detectedx && boot_cpu()) {
377 /* Initial timestamp */
378 timestamp_init(timestamp_get());
379 timestamp_add_now(TS_START_ROMSTAGE);
380
381 /* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */
382 initialize_romstage_console_lock();
383 initialize_romstage_nvram_cbfs_lock();
384 initialize_romstage_microcode_cbfs_lock();
385
386 /* Nothing special needs to be done to find bus 0 */
387 /* Allow the HT devices to be found */
388 set_bsp_node_CHtExtNodeCfgEn();
389 enumerate_ht_chain();
390
391 /* SR56x0 pcie bridges block pci_locate_device() before pcie training.
392 * disable all pcie bridges on SR56x0 to work around it
393 */
394 sr5650_disable_pcie_bridge();
395
396 /* Initialize southbridge */
397 sb7xx_51xx_pci_port80();
398
Timothy Pearsonca543392016-05-18 13:33:13 -0500399 /* Configure secondary serial port pin mux */
400 winbond_set_pinmux(SERIAL_1_DEV, 0x2a, W83667HG_SPI_PINMUX_GPIO4_SERIAL_B_MASK, W83667HG_SPI_PINMUX_SERIAL_B);
401
Timothy Pearson4551b682015-11-24 14:12:08 -0600402 /* Initialize early serial */
Timothy Pearsonca543392016-05-18 13:33:13 -0500403 winbond_enable_serial(SERIAL_0_DEV, CONFIG_TTYS0_BASE);
Timothy Pearson4551b682015-11-24 14:12:08 -0600404 console_init();
405
406 /* Disable LPC legacy DMA support to prevent lockup */
407 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0x78);
408 byte &= ~(1 << 0);
409 pci_write_config8(PCI_DEV(0, 0x14, 3), 0x78, byte);
410 }
411
412 printk(BIOS_SPEW, "Initial stack pointer: %08x\n", esp);
413
414 post_code(0x30);
415
416 if (bist == 0)
417 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
418
419 post_code(0x32);
420
421 enable_sr5650_dev8();
422 sb7xx_51xx_lpc_init();
423
424 if (CONFIG_MAX_PHYSICAL_CPUS != 2)
425 printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD C32 board!\n", CONFIG_MAX_PHYSICAL_CPUS);
426
427 /* Halt if there was a built in self test failure */
428 report_bist_failure(bist);
429
430 val = cpuid_eax(1);
431 printk(BIOS_DEBUG, "BSP Family_Model: %08x\n", val);
432 printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
433 printk(BIOS_DEBUG, "bsp_apicid = %02x\n", bsp_apicid);
434 printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx\n", cpu_init_detectedx);
435
436 /* Setup sysinfo defaults */
437 set_sysinfo_in_ram(0);
438
Timothy Pearsone9205d52016-04-06 13:27:04 -0500439 if (!sb7xx_51xx_decode_last_reset())
440 power_on_reset = 1;
441
442 initialize_mca(1, power_on_reset);
Timothy Pearson4551b682015-11-24 14:12:08 -0600443 update_microcode(val);
444
445 post_code(0x33);
446
447 cpuSetAMDMSR(0);
448 post_code(0x34);
449
450 amd_ht_init(sysinfo);
451 amd_ht_fixup(sysinfo);
452 post_code(0x35);
453
454 /* Setup nodes PCI space and start core 0 AP init. */
455 finalize_node_setup(sysinfo);
456
457 /* Setup any mainboard PCI settings etc. */
458 setup_mb_resource_map();
Timothy Pearsone9205d52016-04-06 13:27:04 -0500459 initialize_mca(0, power_on_reset);
Timothy Pearson4551b682015-11-24 14:12:08 -0600460 post_code(0x36);
461
462 /* Wait for all the APs core0 started by finalize_node_setup. */
463 wait_all_core0_started();
464
465 /* run _early_setup before soft-reset. */
466 sr5650_early_setup();
467 sb7xx_51xx_early_setup();
468
469 if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) {
470 /* Core0 on each node is configured. Now setup any additional cores. */
471 printk(BIOS_DEBUG, "start_other_cores()\n");
472 start_other_cores(bsp_apicid);
473 post_code(0x37);
474 wait_all_other_cores_started(bsp_apicid);
475 }
476
477 if (IS_ENABLED(CONFIG_SET_FIDVID)) {
478 msr = rdmsr(0xc0010071);
479 printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
480
481 /* FIXME: The sb fid change may survive the warm reset and only need to be done once */
482 enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
483
484 post_code(0x39);
485
486 #if IS_ENABLED(CONFIG_SET_FIDVID)
487 if (!warm_reset_detect(0)) { // BSP is node 0
488 init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
489 } else {
490 init_fidvid_stage2(bsp_apicid, 0); // BSP is node 0
491 }
492 #endif
493
494 post_code(0x3A);
495
496 /* show final fid and vid */
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200497 msr = rdmsr(0xc0010071);
Timothy Pearson4551b682015-11-24 14:12:08 -0600498 printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
499 }
500
501 post_code(0x38);
502
503 init_timer(); // Need to use TMICT to synconize FID/VID
504
505 sr5650_htinit();
506
507 /* Reset for HT, FIDVID, PLL and errata changes to take effect. */
508 if (!warm_reset_detect(0)) {
509 printk(BIOS_INFO, "...WARM RESET...\n\n\n");
510 soft_reset();
Jonathan Neuschäferec48c742017-09-29 02:45:31 +0200511 die("After soft_reset - shouldn't see this message!!!\n");
Timothy Pearson4551b682015-11-24 14:12:08 -0600512 }
513
514 sr5650_htinit_dect_and_enable_isochronous_link();
515
516 /* Set default DDR memory voltage
517 * This will be overridden later during RAM initialization
518 */
519 set_lpc_sticky_ctl(1); /* Retain LPC/IMC GPIO configuration during S3 sleep */
520 if (!s3resume) { /* Avoid supply voltage glitches while the DIMMs are retaining data */
521 set_ddr3_voltage(0, 0); /* Node 0 */
522 set_ddr3_voltage(1, 0); /* Node 1 */
523 }
524
525 /* Set up peripheral control lines */
526 set_peripheral_control_lines();
527
528 post_code(0x3B);
529
Elyes HAOUAS8ab989e2016-07-30 17:46:17 +0200530 /* Wait for all APs to be stopped, otherwise RAM initialization may hang */
Timothy Pearson4551b682015-11-24 14:12:08 -0600531 if (IS_ENABLED(CONFIG_LOGICAL_CPUS))
532 wait_all_other_cores_stopped(bsp_apicid);
533
534 /* It's the time to set ctrl in sysinfo now; */
535 printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes);
536 if (is_fam15h())
537 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam15);
538 else
539 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam10);
540 post_code(0x3D);
541
542#if 0
543 /* FIXME
544 * After the AMD K10 code has been converted to use
545 * IS_ENABLED(CONFIG_DEBUG_SMBUS) uncomment this block
546 */
547 if (IS_ENABLED(CONFIG_DEBUG_SMBUS)) {
548 dump_spd_registers(&cpu[0]);
Elyes HAOUASd54e8592018-05-28 13:18:17 +0200549 dump_smbus_registers();
Timothy Pearson4551b682015-11-24 14:12:08 -0600550 }
551#endif
552
553 post_code(0x40);
554
555 timestamp_add_now(TS_BEFORE_INITRAM);
556 printk(BIOS_DEBUG, "raminit_amdmct()\n");
557 raminit_amdmct(sysinfo);
558 timestamp_add_now(TS_AFTER_INITRAM);
559
560#ifdef TEST_MEMORY
561 execute_memory_test();
562#endif
563
Timothy Pearson4551b682015-11-24 14:12:08 -0600564 if (s3resume)
565 cbmem_initialize();
566 else
567 cbmem_initialize_empty();
568 post_code(0x41);
569
Kyösti Mälkkic2a921b2017-09-04 23:58:38 +0300570 romstage_handoff_init(s3resume);
571
Timothy Pearson4551b682015-11-24 14:12:08 -0600572 amdmct_cbmem_store_info(sysinfo);
Timothy Pearson4551b682015-11-24 14:12:08 -0600573
574 printk(BIOS_DEBUG, "disable_spd()\n");
575 switch_spd_mux(0x1);
576
577 sr5650_before_pci_init();
578 sb7xx_51xx_before_pci_init();
579
580 /* Configure SP5100 GPIOs to match vendor settings */
581 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x50, 0x0170);
582 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x54, 0x0707);
583 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x56, 0x0bb0);
584 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x5a, 0x0ff0);
Timothy Pearson4551b682015-11-24 14:12:08 -0600585}
586
587/**
588 * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
589 * Description:
590 * This routine is called every time a non-coherent chain is processed.
591 * BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
592 * swap list. The first part of the list controls the BUID assignment and the
593 * second part of the list provides the device to device linking. Device orientation
594 * can be detected automatically, or explicitly. See documentation for more details.
595 *
596 * Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
597 * based on each device's unit count.
598 *
599 * Parameters:
600 * @param[in] node = The node on which this chain is located
601 * @param[in] link = The link on the host for this chain
602 * @param[out] List = supply a pointer to a list
603 */
604BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
605{
606 /* Force BUID to 0 */
607 static const u8 swaplist[] = {0, 0, 0xFF, 0, 0xFF};
Timothy Pearsonb251a502015-11-24 14:17:49 -0600608 if ((node == 0) && (link == 2)) { /* BSP SB link */
Timothy Pearson4551b682015-11-24 14:12:08 -0600609 *List = swaplist;
610 return 1;
611 }
612
613 return 0;
614}