blob: 028af4c9387238069e07391e77843f0f1a285a7a [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>
Timothy Pearson4551b682015-11-24 14:12:08 -060022#include <device/pci_def.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060023#include <arch/io.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020024#include <device/pci_ops.h>
Elyes HAOUASd2b9ec12018-10-27 09:41:02 +020025#include <arch/cpu.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060026#include <cpu/x86/lapic.h>
27#include <console/console.h>
Kyösti Mälkkic2a921b2017-09-04 23:58:38 +030028#include <romstage_handoff.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060029#include <timestamp.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060030#include <spd.h>
31#include <cpu/amd/model_10xxx_rev.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060032#include <delay.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060033#include <superio/winbond/common/winbond.h>
34#include <superio/winbond/w83667hg-a/w83667hg-a.h>
35#include <cpu/x86/bist.h>
36#include <smp/spinlock.h>
Damien Zammit75a3d1f2016-11-28 00:29:10 +110037#include <cpu/amd/car.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +020038#include <cpu/amd/msr.h>
Nico Huber718c6fa2018-10-11 22:54:25 +020039#include <southbridge/amd/common/reset.h>
Timothy Pearson4551b682015-11-24 14:12:08 -060040#include <southbridge/amd/sb700/sb700.h>
41#include <southbridge/amd/sb700/smbus.h>
42#include <southbridge/amd/sr5650/sr5650.h>
Damien Zammit75a3d1f2016-11-28 00:29:10 +110043#include <northbridge/amd/amdfam10/raminit.h>
44#include <northbridge/amd/amdht/ht_wrapper.h>
45#include <cpu/amd/family_10h-family_15h/init_cpus.h>
46#include <arch/early_variables.h>
47#include <cbmem.h>
48
Damien Zammit75a3d1f2016-11-28 00:29:10 +110049#include "cpu/amd/quadcore/quadcore.c"
Timothy Pearson4551b682015-11-24 14:12:08 -060050
Timothy Pearsonca543392016-05-18 13:33:13 -050051#define SERIAL_0_DEV PNP_DEV(0x2e, W83667HG_A_SP1)
52#define SERIAL_1_DEV PNP_DEV(0x2e, W83667HG_A_SP2)
Timothy Pearson4551b682015-11-24 14:12:08 -060053
Damien Zammit75a3d1f2016-11-28 00:29:10 +110054void activate_spd_rom(const struct mem_controller *ctrl);
Elyes HAOUASdd35e2c2018-09-20 17:33:50 +020055int spd_read_byte(unsigned int device, unsigned int address);
Damien Zammit75a3d1f2016-11-28 00:29:10 +110056extern struct sys_info sysinfo_car;
Timothy Pearson4551b682015-11-24 14:12:08 -060057
Elyes HAOUASdd35e2c2018-09-20 17:33:50 +020058inline int spd_read_byte(unsigned int device, unsigned int address)
Timothy Pearson4551b682015-11-24 14:12:08 -060059{
60 return do_smbus_read_byte(SMBUS_AUX_IO_BASE, device, address);
61}
62
Timothy Pearson4551b682015-11-24 14:12:08 -060063/*
64 * ASUS KCMA-D8 specific SPD enable/disable magic.
65 *
66 * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings:
67 * 0: Disabled
68 * 1: Normal SPI access
69 * 2: CPU0 SPD
70 * 3: CPU1 SPD
71 *
72 * Disable SPD access after RAM init to allow access to standard SMBus/I2C offsets
73 * which is required e.g. by lm-sensors.
74 */
75
76/* Relevant GPIO register information is available in the
77 * AMD SP5100 Register Reference Guide rev. 3.03, page 130
78 */
79static void switch_spd_mux(uint8_t channel)
80{
81 uint8_t byte;
82
83 byte = pci_read_config8(PCI_DEV(0, 0x14, 0), 0x54);
84 byte &= ~0xc; /* Clear SPD mux GPIOs */
85 byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */
86 byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */
87 pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte);
88}
89
90static const uint8_t spd_addr_fam15[] = {
91 // Socket 0 Node 0 ("Node 0")
92 RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearsonb251a502015-11-24 14:17:49 -060093 // Socket 1 Node 0 ("Node 1")
Timothy Pearson4551b682015-11-24 14:12:08 -060094 RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearson4551b682015-11-24 14:12:08 -060095};
96
97static const uint8_t spd_addr_fam10[] = {
98 // Socket 0 Node 0 ("Node 0")
99 RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
Timothy Pearsonb251a502015-11-24 14:17:49 -0600100 // Socket 1 Node 0 ("Node 1")
Timothy Pearson4551b682015-11-24 14:12:08 -0600101 RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
102};
103
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100104void activate_spd_rom(const struct mem_controller *ctrl) {
Timothy Pearson4551b682015-11-24 14:12:08 -0600105 printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id);
Timothy Pearsonb251a502015-11-24 14:17:49 -0600106 if (ctrl->node_id == 0) {
107 printk(BIOS_DEBUG, "enable_spd_node0()\n");
108 switch_spd_mux(0x2);
109 } else if (ctrl->node_id == 1) {
110 printk(BIOS_DEBUG, "enable_spd_node1()\n");
111 switch_spd_mux(0x3);
112 }
Timothy Pearson4551b682015-11-24 14:12:08 -0600113}
114
115/* Voltages are specified by index
Jonathan Neuschäfer482d16f2017-11-20 02:09:19 +0100116 * Valid indices for this platform are:
Timothy Pearson4551b682015-11-24 14:12:08 -0600117 * 0: 1.5V
118 * 1: 1.35V
119 * 2: 1.25V
120 * 3: 1.15V
121 */
122static void set_ddr3_voltage(uint8_t node, uint8_t index) {
123 uint8_t byte;
124 uint8_t value = 0;
125
126 if (index == 0)
127 value = 0x0;
128 else if (index == 1)
129 value = 0x1;
130 else if (index == 2)
131 value = 0x4;
132 else if (index == 3)
133 value = 0x5;
134 if (node == 1)
135 value <<= 1;
136
137 /* Set GPIOs */
138 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd1);
139 if (node == 0)
140 byte &= ~0x5;
141 if (node == 1)
142 byte &= ~0xa;
143 byte |= value;
144 pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd1, byte);
145
146 /* Enable GPIO output drivers */
147 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd0);
148 byte &= 0x0f;
149 pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd0, byte);
150
151 printk(BIOS_DEBUG, "Node %02d DIMM voltage set to index %02x\n", node, index);
152}
153
154void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
155 struct DCTStatStruc *pDCTstatA) {
156 /* This mainboard allows the DIMM voltage to be set per-socket.
157 * Therefore, for each socket, iterate over all DIMMs to find the
158 * lowest supported voltage common to all DIMMs on that socket.
159 */
160 uint8_t nvram;
161 uint8_t dimm;
162 uint8_t node;
163 uint8_t socket;
164 uint8_t allowed_voltages = 0xf; /* The mainboard VRMs allow 1.15V, 1.25V, 1.35V, and 1.5V */
165 uint8_t socket_allowed_voltages = allowed_voltages;
166 uint32_t set_voltage = 0;
167
168 if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) {
169 switch (nvram) {
170 case 2:
171 allowed_voltages = 0x7; /* Allow 1.25V, 1.35V, and 1.5V */
172 break;
173 case 1:
174 allowed_voltages = 0x3; /* Allow 1.35V and 1.5V */
175 break;
176 case 0:
177 default:
178 allowed_voltages = 0x1; /* Allow 1.5V only */
179 break;
180 }
181 }
182
183 for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
Timothy Pearsonb251a502015-11-24 14:17:49 -0600184 socket = node;
Timothy Pearson4551b682015-11-24 14:12:08 -0600185 struct DCTStatStruc *pDCTstat;
186 pDCTstat = pDCTstatA + node;
187
188 /* reset socket_allowed_voltages before processing each socket */
Timothy Pearsonb251a502015-11-24 14:17:49 -0600189 socket_allowed_voltages = allowed_voltages;
Timothy Pearson4551b682015-11-24 14:12:08 -0600190
191 if (pDCTstat->NodePresent) {
192 for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
193 if (pDCTstat->DIMMValid & (1 << dimm)) {
194 socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm];
195 }
196 }
Timothy Pearson4551b682015-11-24 14:12:08 -0600197
Timothy Pearson4551b682015-11-24 14:12:08 -0600198 /* Set voltages */
199 if (socket_allowed_voltages & 0x8) {
200 set_voltage = 0x8;
201 set_ddr3_voltage(socket, 3);
202 } else if (socket_allowed_voltages & 0x4) {
203 set_voltage = 0x4;
204 set_ddr3_voltage(socket, 2);
205 } else if (socket_allowed_voltages & 0x2) {
206 set_voltage = 0x2;
207 set_ddr3_voltage(socket, 1);
208 } else {
209 set_voltage = 0x1;
210 set_ddr3_voltage(socket, 0);
211 }
212
213 /* Save final DIMM voltages for MCT and SMBIOS use */
Timothy Pearsonb251a502015-11-24 14:17:49 -0600214 for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
215 pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
Timothy Pearson4551b682015-11-24 14:12:08 -0600216 }
217 }
218 }
219
220 /* Allow the DDR supply voltages to settle */
221 udelay(100000);
222}
223
224static void set_peripheral_control_lines(void) {
225 uint8_t byte;
Timothy Pearson4551b682015-11-24 14:12:08 -0600226
Timothy Pearsonb251a502015-11-24 14:17:49 -0600227 /* Enable PCICLK5 */
228 outb(0x41, 0xcd6);
229 outb(0x02, 0xcd7);
Timothy Pearson4551b682015-11-24 14:12:08 -0600230
231 /* Enable the RTC AltCentury register */
232 outb(0x41, 0xcd6);
233 byte = inb(0xcd7);
234 byte |= 0x10;
235 outb(byte, 0xcd7);
236}
237
238#ifdef TEST_MEMORY
239static void execute_memory_test(void)
240{
241 /* Test DRAM functionality */
242 uint32_t i;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500243 uint32_t v;
244 uint32_t w;
245 uint32_t x;
246 uint32_t y;
247 uint32_t z;
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200248 uint32_t *dataptr;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500249 uint32_t readback;
250 uint32_t start = 0x300000;
251 printk(BIOS_DEBUG, "Writing test pattern 1 to memory...\n");
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200252 for (i = 0; i < 0x1000000; i = i + 8) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500253 dataptr = (void *)(start + i);
Timothy Pearson4551b682015-11-24 14:12:08 -0600254 *dataptr = 0x55555555;
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500255 dataptr = (void *)(start + i + 4);
Timothy Pearson4551b682015-11-24 14:12:08 -0600256 *dataptr = 0xaaaaaaaa;
257 }
258 printk(BIOS_DEBUG, "Done!\n");
259 printk(BIOS_DEBUG, "Testing memory...\n");
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200260 for (i = 0; i < 0x1000000; i = i + 8) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500261 dataptr = (void *)(start + i);
Timothy Pearson4551b682015-11-24 14:12:08 -0600262 readback = *dataptr;
263 if (readback != 0x55555555)
264 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0x55555555);
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500265 dataptr = (void *)(start + i + 4);
Timothy Pearson4551b682015-11-24 14:12:08 -0600266 readback = *dataptr;
267 if (readback != 0xaaaaaaaa)
268 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0xaaaaaaaa);
269 }
270 printk(BIOS_DEBUG, "Done!\n");
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500271 printk(BIOS_DEBUG, "Writing test pattern 2 to memory...\n");
272 /* Set up the PRNG seeds for initial write */
273 w = 0x55555555;
274 x = 0xaaaaaaaa;
275 y = 0x12345678;
276 z = 0x87654321;
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200277 for (i = 0; i < 0x1000000; i = i + 4) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500278 /* Use Xorshift as a PRNG to stress test the bus */
279 v = x;
280 v ^= v << 11;
281 v ^= v >> 8;
282 x = y;
283 y = z;
284 z = w;
285 w ^= w >> 19;
286 w ^= v;
287 dataptr = (void *)(start + i);
288 *dataptr = w;
289 }
290 printk(BIOS_DEBUG, "Done!\n");
291 printk(BIOS_DEBUG, "Testing memory...\n");
292 /* Reset the PRNG seeds for readback */
293 w = 0x55555555;
294 x = 0xaaaaaaaa;
295 y = 0x12345678;
296 z = 0x87654321;
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200297 for (i = 0; i < 0x1000000; i = i + 4) {
Timothy Pearson99e27ce2016-04-24 20:33:29 -0500298 /* Use Xorshift as a PRNG to stress test the bus */
299 v = x;
300 v ^= v << 11;
301 v ^= v >> 8;
302 x = y;
303 y = z;
304 z = w;
305 w ^= w >> 19;
306 w ^= v;
307 dataptr = (void *)(start + i);
308 readback = *dataptr;
309 if (readback != w)
310 printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, w);
311 }
312 printk(BIOS_DEBUG, "Done!\n");
Timothy Pearson4551b682015-11-24 14:12:08 -0600313}
314#endif
315
316static spinlock_t printk_spinlock CAR_GLOBAL;
317
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200318spinlock_t *romstage_console_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600319{
320 return car_get_var_ptr(&printk_spinlock);
321}
322
323void initialize_romstage_console_lock(void)
324{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100325 spin_unlock(romstage_console_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600326}
327
328static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL;
329
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200330spinlock_t *romstage_nvram_cbfs_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600331{
332 return car_get_var_ptr(&nvram_cbfs_spinlock);
333}
334
335void initialize_romstage_nvram_cbfs_lock(void)
336{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100337 spin_unlock(romstage_nvram_cbfs_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600338}
339
340static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL;
341
Elyes HAOUAS95bca332018-07-08 12:38:11 +0200342spinlock_t *romstage_microcode_cbfs_lock(void)
Timothy Pearson4551b682015-11-24 14:12:08 -0600343{
344 return car_get_var_ptr(&microcode_cbfs_spinlock);
345}
346
347void initialize_romstage_microcode_cbfs_lock(void)
348{
Patrick Georgi06a629e2017-01-24 12:30:04 +0100349 spin_unlock(romstage_microcode_cbfs_lock());
Timothy Pearson4551b682015-11-24 14:12:08 -0600350}
351
352void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
353{
354 uint32_t esp;
355 __asm__ volatile (
356 "movl %%esp, %0"
357 : "=r" (esp)
358 );
359
360 struct sys_info *sysinfo = &sysinfo_car;
361
362 /* Limit the maximum HT speed to 2.6GHz to prevent lockups
363 * due to HT CPU <--> CPU wiring not being validated to 3.2GHz
364 */
365 sysinfo->ht_link_cfg.ht_speed_limit = 2600;
366
367 uint32_t bsp_apicid = 0, val;
368 uint8_t byte;
Timothy Pearsone9205d52016-04-06 13:27:04 -0500369 uint8_t power_on_reset = 0;
Timothy Pearson4551b682015-11-24 14:12:08 -0600370 msr_t msr;
371
372 int s3resume = acpi_is_wakeup_s3();
373
374 if (!cpu_init_detectedx && boot_cpu()) {
375 /* Initial timestamp */
376 timestamp_init(timestamp_get());
377 timestamp_add_now(TS_START_ROMSTAGE);
378
379 /* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */
380 initialize_romstage_console_lock();
381 initialize_romstage_nvram_cbfs_lock();
382 initialize_romstage_microcode_cbfs_lock();
383
384 /* Nothing special needs to be done to find bus 0 */
385 /* Allow the HT devices to be found */
386 set_bsp_node_CHtExtNodeCfgEn();
387 enumerate_ht_chain();
388
389 /* SR56x0 pcie bridges block pci_locate_device() before pcie training.
390 * disable all pcie bridges on SR56x0 to work around it
391 */
392 sr5650_disable_pcie_bridge();
393
394 /* Initialize southbridge */
395 sb7xx_51xx_pci_port80();
396
Timothy Pearsonca543392016-05-18 13:33:13 -0500397 /* Configure secondary serial port pin mux */
398 winbond_set_pinmux(SERIAL_1_DEV, 0x2a, W83667HG_SPI_PINMUX_GPIO4_SERIAL_B_MASK, W83667HG_SPI_PINMUX_SERIAL_B);
399
Timothy Pearson4551b682015-11-24 14:12:08 -0600400 /* Initialize early serial */
Timothy Pearsonca543392016-05-18 13:33:13 -0500401 winbond_enable_serial(SERIAL_0_DEV, CONFIG_TTYS0_BASE);
Timothy Pearson4551b682015-11-24 14:12:08 -0600402 console_init();
403
404 /* Disable LPC legacy DMA support to prevent lockup */
405 byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0x78);
406 byte &= ~(1 << 0);
407 pci_write_config8(PCI_DEV(0, 0x14, 3), 0x78, byte);
408 }
409
410 printk(BIOS_SPEW, "Initial stack pointer: %08x\n", esp);
411
412 post_code(0x30);
413
414 if (bist == 0)
415 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
416
417 post_code(0x32);
418
419 enable_sr5650_dev8();
420 sb7xx_51xx_lpc_init();
421
422 if (CONFIG_MAX_PHYSICAL_CPUS != 2)
423 printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD C32 board!\n", CONFIG_MAX_PHYSICAL_CPUS);
424
425 /* Halt if there was a built in self test failure */
426 report_bist_failure(bist);
427
428 val = cpuid_eax(1);
429 printk(BIOS_DEBUG, "BSP Family_Model: %08x\n", val);
430 printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
431 printk(BIOS_DEBUG, "bsp_apicid = %02x\n", bsp_apicid);
432 printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx\n", cpu_init_detectedx);
433
434 /* Setup sysinfo defaults */
435 set_sysinfo_in_ram(0);
436
Timothy Pearsone9205d52016-04-06 13:27:04 -0500437 if (!sb7xx_51xx_decode_last_reset())
438 power_on_reset = 1;
439
440 initialize_mca(1, power_on_reset);
Timothy Pearson4551b682015-11-24 14:12:08 -0600441 update_microcode(val);
442
443 post_code(0x33);
444
445 cpuSetAMDMSR(0);
446 post_code(0x34);
447
448 amd_ht_init(sysinfo);
449 amd_ht_fixup(sysinfo);
450 post_code(0x35);
451
452 /* Setup nodes PCI space and start core 0 AP init. */
453 finalize_node_setup(sysinfo);
454
455 /* Setup any mainboard PCI settings etc. */
456 setup_mb_resource_map();
Timothy Pearsone9205d52016-04-06 13:27:04 -0500457 initialize_mca(0, power_on_reset);
Timothy Pearson4551b682015-11-24 14:12:08 -0600458 post_code(0x36);
459
460 /* Wait for all the APs core0 started by finalize_node_setup. */
461 wait_all_core0_started();
462
463 /* run _early_setup before soft-reset. */
464 sr5650_early_setup();
465 sb7xx_51xx_early_setup();
466
467 if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) {
468 /* Core0 on each node is configured. Now setup any additional cores. */
469 printk(BIOS_DEBUG, "start_other_cores()\n");
470 start_other_cores(bsp_apicid);
471 post_code(0x37);
472 wait_all_other_cores_started(bsp_apicid);
473 }
474
475 if (IS_ENABLED(CONFIG_SET_FIDVID)) {
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200476 msr = rdmsr(MSR_COFVID_STS);
Timothy Pearson4551b682015-11-24 14:12:08 -0600477 printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
478
479 /* FIXME: The sb fid change may survive the warm reset and only need to be done once */
480 enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
481
482 post_code(0x39);
483
484 #if IS_ENABLED(CONFIG_SET_FIDVID)
485 if (!warm_reset_detect(0)) { // BSP is node 0
486 init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
487 } else {
488 init_fidvid_stage2(bsp_apicid, 0); // BSP is node 0
489 }
490 #endif
491
492 post_code(0x3A);
493
494 /* show final fid and vid */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200495 msr = rdmsr(MSR_COFVID_STS);
Timothy Pearson4551b682015-11-24 14:12:08 -0600496 printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
497 }
498
499 post_code(0x38);
500
501 init_timer(); // Need to use TMICT to synconize FID/VID
502
503 sr5650_htinit();
504
505 /* Reset for HT, FIDVID, PLL and errata changes to take effect. */
506 if (!warm_reset_detect(0)) {
507 printk(BIOS_INFO, "...WARM RESET...\n\n\n");
508 soft_reset();
Jonathan Neuschäferec48c742017-09-29 02:45:31 +0200509 die("After soft_reset - shouldn't see this message!!!\n");
Timothy Pearson4551b682015-11-24 14:12:08 -0600510 }
511
512 sr5650_htinit_dect_and_enable_isochronous_link();
513
514 /* Set default DDR memory voltage
515 * This will be overridden later during RAM initialization
516 */
517 set_lpc_sticky_ctl(1); /* Retain LPC/IMC GPIO configuration during S3 sleep */
518 if (!s3resume) { /* Avoid supply voltage glitches while the DIMMs are retaining data */
519 set_ddr3_voltage(0, 0); /* Node 0 */
520 set_ddr3_voltage(1, 0); /* Node 1 */
521 }
522
523 /* Set up peripheral control lines */
524 set_peripheral_control_lines();
525
526 post_code(0x3B);
527
Elyes HAOUAS8ab989e2016-07-30 17:46:17 +0200528 /* Wait for all APs to be stopped, otherwise RAM initialization may hang */
Timothy Pearson4551b682015-11-24 14:12:08 -0600529 if (IS_ENABLED(CONFIG_LOGICAL_CPUS))
530 wait_all_other_cores_stopped(bsp_apicid);
531
532 /* It's the time to set ctrl in sysinfo now; */
533 printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes);
534 if (is_fam15h())
535 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam15);
536 else
537 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam10);
538 post_code(0x3D);
539
540#if 0
541 /* FIXME
542 * After the AMD K10 code has been converted to use
543 * IS_ENABLED(CONFIG_DEBUG_SMBUS) uncomment this block
544 */
545 if (IS_ENABLED(CONFIG_DEBUG_SMBUS)) {
546 dump_spd_registers(&cpu[0]);
Elyes HAOUASd54e8592018-05-28 13:18:17 +0200547 dump_smbus_registers();
Timothy Pearson4551b682015-11-24 14:12:08 -0600548 }
549#endif
550
551 post_code(0x40);
552
Timothy Pearson4551b682015-11-24 14:12:08 -0600553 raminit_amdmct(sysinfo);
Timothy Pearson4551b682015-11-24 14:12:08 -0600554
555#ifdef TEST_MEMORY
556 execute_memory_test();
557#endif
558
Timothy Pearson4551b682015-11-24 14:12:08 -0600559 if (s3resume)
560 cbmem_initialize();
561 else
562 cbmem_initialize_empty();
563 post_code(0x41);
564
Kyösti Mälkkic2a921b2017-09-04 23:58:38 +0300565 romstage_handoff_init(s3resume);
566
Timothy Pearson4551b682015-11-24 14:12:08 -0600567 amdmct_cbmem_store_info(sysinfo);
Timothy Pearson4551b682015-11-24 14:12:08 -0600568
569 printk(BIOS_DEBUG, "disable_spd()\n");
570 switch_spd_mux(0x1);
571
572 sr5650_before_pci_init();
573 sb7xx_51xx_before_pci_init();
574
575 /* Configure SP5100 GPIOs to match vendor settings */
576 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x50, 0x0170);
577 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x54, 0x0707);
578 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x56, 0x0bb0);
579 pci_write_config16(PCI_DEV(0, 0x14, 0), 0x5a, 0x0ff0);
Timothy Pearson4551b682015-11-24 14:12:08 -0600580}
581
582/**
583 * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
584 * Description:
585 * This routine is called every time a non-coherent chain is processed.
586 * BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
587 * swap list. The first part of the list controls the BUID assignment and the
588 * second part of the list provides the device to device linking. Device orientation
589 * can be detected automatically, or explicitly. See documentation for more details.
590 *
591 * Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
592 * based on each device's unit count.
593 *
594 * Parameters:
595 * @param[in] node = The node on which this chain is located
596 * @param[in] link = The link on the host for this chain
597 * @param[out] List = supply a pointer to a list
598 */
599BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
600{
601 /* Force BUID to 0 */
602 static const u8 swaplist[] = {0, 0, 0xFF, 0, 0xFF};
Timothy Pearsonb251a502015-11-24 14:17:49 -0600603 if ((node == 0) && (link == 2)) { /* BSP SB link */
Timothy Pearson4551b682015-11-24 14:12:08 -0600604 *List = swaplist;
605 return 1;
606 }
607
608 return 0;
609}