blob: 1fbc766d2b53904708f86f7d11e48ca0b0a1891d [file] [log] [blame]
Marc Jones5dd4a202009-03-20 16:36:05 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
Marc Jones5dd4a202009-03-20 16:36:05 +000013 */
14
Marc Jones5dd4a202009-03-20 16:36:05 +000015#include <stdint.h>
Patrick Georgi12aba822009-04-30 07:07:22 +000016#include <string.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000017#include <device/pci_def.h>
18#include <device/pci_ids.h>
19#include <arch/io.h>
20#include <device/pnp_def.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000021#include <cpu/x86/lapic.h>
Edwin Beasanteb50c7d2010-07-06 21:05:04 +000022#include <pc80/mc146818rtc.h>
Patrick Georgi12584e22010-05-08 09:14:51 +000023#include <console/console.h>
Patrick Georgid0835952010-10-05 09:07:10 +000024#include <lib.h>
Uwe Hermann6dc92f02010-11-21 11:36:03 +000025#include <spd.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000026#include <cpu/amd/model_fxx_rev.h>
stepan836ae292010-12-08 05:42:47 +000027#include "southbridge/nvidia/mcp55/early_smbus.c" // for enable the FAN
Edward O'Callaghan77757c22015-01-04 21:33:39 +110028#include <northbridge/amd/amdk8/raminit.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000029#include "lib/delay.c"
Edward O'Callaghan77757c22015-01-04 21:33:39 +110030#include <cpu/x86/lapic.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000031#include "northbridge/amd/amdk8/reset_test.c"
Edward O'Callaghanbeb0f262014-04-29 13:09:50 +100032#include <superio/winbond/common/winbond.h>
33#include <superio/winbond/w83627hf/w83627hf.h>
Edward O'Callaghan77757c22015-01-04 21:33:39 +110034#include <cpu/x86/bist.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000035#include "northbridge/amd/amdk8/debug.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000036#include "northbridge/amd/amdk8/setup_resource_map.c"
stepan836ae292010-12-08 05:42:47 +000037#include "southbridge/nvidia/mcp55/early_ctrl.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000038
39#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
Uwe Hermann9b9791c2010-12-06 18:17:01 +000040#define DUMMY_DEV PNP_DEV(0x2e, 0)
Marc Jones5dd4a202009-03-20 16:36:05 +000041
Uwe Hermann7b997052010-11-21 22:47:22 +000042static void memreset(int controllers, const struct mem_controller *ctrl) { }
Marc Jones5dd4a202009-03-20 16:36:05 +000043
Marc Jones5dd4a202009-03-20 16:36:05 +000044static inline void activate_spd_rom(const struct mem_controller *ctrl)
45{
Stefan Reinauer523ebd92010-04-14 18:59:42 +000046#if 0
47/* We don't do any switching yet. */
Marc Jones5dd4a202009-03-20 16:36:05 +000048#define SMBUS_SWITCH1 0x48
49#define SMBUS_SWITCH2 0x49
50 unsigned device=(ctrl->channel0[0])>>8;
51 smbus_send_byte(SMBUS_SWITCH1, device);
52 smbus_send_byte(SMBUS_SWITCH2, (device >> 4) & 0x0f);
Stefan Reinauer523ebd92010-04-14 18:59:42 +000053#endif
Marc Jones5dd4a202009-03-20 16:36:05 +000054}
55
Marc Jones5dd4a202009-03-20 16:36:05 +000056static inline int spd_read_byte(unsigned device, unsigned address)
57{
58 return smbus_read_byte(device, address);
59}
60
Edward O'Callaghan77757c22015-01-04 21:33:39 +110061#include <northbridge/amd/amdk8/f.h>
Marc Jones5dd4a202009-03-20 16:36:05 +000062#include "northbridge/amd/amdk8/incoherent_ht.c"
Stefan Reinauer23836e22010-04-15 12:39:29 +000063#include "northbridge/amd/amdk8/coherent_ht.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000064#include "northbridge/amd/amdk8/raminit_f.c"
Stefan Reinauerc13093b2009-09-23 18:51:03 +000065#include "lib/generic_sdram.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000066#include "resourcemap.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000067#include "cpu/amd/dualcore/dualcore.c"
Edward O'Callaghan77757c22015-01-04 21:33:39 +110068#include <southbridge/nvidia/mcp55/early_setup_ss.h>
stepan836ae292010-12-08 05:42:47 +000069#include "southbridge/nvidia/mcp55/early_setup_car.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000070#include "cpu/amd/model_fxx/init_cpus.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000071#include "cpu/amd/model_fxx/fidvid.c"
Marc Jones5dd4a202009-03-20 16:36:05 +000072#include "northbridge/amd/amdk8/early_ht.c"
73
74static void sio_setup(void)
75{
Marc Jones5dd4a202009-03-20 16:36:05 +000076 uint32_t dword;
77 uint8_t byte;
78
79 enable_smbus();
80// smbusx_write_byte(1, (0x58>>1), 0, 0x80); /* select bank0 */
81 smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff); /* set FAN ctrl to DC mode */
82
83 byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
84 byte |= 0x20;
85 pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
86
87 dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
88 dword |= (1 << 0);
89 pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
90
91 dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
92 dword |= (1 << 16);
93 pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
Marc Jones5dd4a202009-03-20 16:36:05 +000094}
95
Marc Jones5dd4a202009-03-20 16:36:05 +000096/* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
97#define RC0 (2<<8)
98#define RC1 (1<<8)
99
Patrick Georgice6fb1e2010-03-17 22:44:39 +0000100void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
Marc Jones5dd4a202009-03-20 16:36:05 +0000101{
102/* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
103 don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
104 memory on each CPU must be an exact match.
105 */
106 static const uint16_t spd_addr[] = {
Stefan Reinauer523ebd92010-04-14 18:59:42 +0000107 // Node 0
Uwe Hermann6dc92f02010-11-21 11:36:03 +0000108 RC0 | DIMM0, RC0 | DIMM2,
109 RC0 | DIMM4, RC0 | DIMM6,
110 RC0 | DIMM1, RC0 | DIMM3,
111 RC0 | DIMM5, RC0 | DIMM7,
Stefan Reinauer523ebd92010-04-14 18:59:42 +0000112 // Node 1
Uwe Hermann6dc92f02010-11-21 11:36:03 +0000113 RC1 | DIMM0, RC1 | DIMM2,
114 RC1 | DIMM4, RC1 | DIMM6,
115 RC1 | DIMM1, RC1 | DIMM3,
116 RC1 | DIMM5, RC1 | DIMM7,
Marc Jones5dd4a202009-03-20 16:36:05 +0000117 };
118
Patrick Georgibbc880e2012-11-20 18:20:56 +0100119 struct sys_info *sysinfo = &sysinfo_car;
Marc Jones5dd4a202009-03-20 16:36:05 +0000120 int needs_reset = 0;
121 unsigned bsp_apicid = 0;
122
Patrick Georgi2bd91002010-03-18 16:46:50 +0000123 if (!cpu_init_detectedx && boot_cpu()) {
Patrick Georgice6fb1e2010-03-17 22:44:39 +0000124 /* Nothing special needs to be done to find bus 0 */
125 /* Allow the HT devices to be found */
Patrick Georgice6fb1e2010-03-17 22:44:39 +0000126 enumerate_ht_chain();
Patrick Georgice6fb1e2010-03-17 22:44:39 +0000127 sio_setup();
Patrick Georgice6fb1e2010-03-17 22:44:39 +0000128 }
129
Uwe Hermann7b997052010-11-21 22:47:22 +0000130 if (bist == 0)
Marc Jones5dd4a202009-03-20 16:36:05 +0000131 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
Marc Jones5dd4a202009-03-20 16:36:05 +0000132
Uwe Hermann9b9791c2010-12-06 18:17:01 +0000133 w83627hf_set_clksel_48(DUMMY_DEV);
Edward O'Callaghanbeb0f262014-04-29 13:09:50 +1000134 winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
Marc Jones5dd4a202009-03-20 16:36:05 +0000135
Marc Jones5dd4a202009-03-20 16:36:05 +0000136 console_init();
137
138 /* Halt if there was a built in self test failure */
139 report_bist_failure(bist);
140
Myles Watson08e0fb82010-03-22 16:33:25 +0000141 printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
Marc Jones5dd4a202009-03-20 16:36:05 +0000142
143 setup_mb_resource_map();
144
Stefan Reinauer069f4762015-01-05 13:02:32 -0800145 printk(BIOS_DEBUG, "bsp_apicid=%02x\n", bsp_apicid);
Marc Jones5dd4a202009-03-20 16:36:05 +0000146
Marc Jones5dd4a202009-03-20 16:36:05 +0000147 set_sysinfo_in_ram(0); // in BSP so could hold all ap until sysinfo is in ram
Kyösti Mälkkia1e924c2014-06-06 08:32:42 +0300148#if CONFIG_DEBUG_SMBUS
149 dump_smbus_registers();
150#endif
Marc Jones5dd4a202009-03-20 16:36:05 +0000151 setup_coherent_ht_domain(); // routing table and start other core0
152
153 wait_all_core0_started();
Patrick Georgie1667822012-05-05 15:29:32 +0200154#if CONFIG_LOGICAL_CPUS
Marc Jones5dd4a202009-03-20 16:36:05 +0000155 // It is said that we should start core1 after all core0 launched
156 /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
157 * So here need to make sure last core0 is started, esp for two way system,
158 * (there may be apic id conflicts in that case)
159 */
160 start_other_cores();
161 wait_all_other_cores_started(bsp_apicid);
162#endif
163
164 /* it will set up chains and store link pair for optimization later */
165 ht_setup_chains_x(sysinfo); // it will init sblnk and sbbusn, nodes, sbdn
166
Patrick Georgi76e81522010-11-16 21:25:29 +0000167#if CONFIG_SET_FIDVID
Marc Jones5dd4a202009-03-20 16:36:05 +0000168 {
169 msr_t msr;
170 msr = rdmsr(0xc0010042);
Stefan Reinauer069f4762015-01-05 13:02:32 -0800171 printk(BIOS_DEBUG, "begin msr fid, vid %08x%08x\n", msr.hi, msr.lo);
Marc Jones5dd4a202009-03-20 16:36:05 +0000172 }
Marc Jones5dd4a202009-03-20 16:36:05 +0000173 enable_fid_change();
Marc Jones5dd4a202009-03-20 16:36:05 +0000174 enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
Marc Jones5dd4a202009-03-20 16:36:05 +0000175 init_fidvid_bsp(bsp_apicid);
Marc Jones5dd4a202009-03-20 16:36:05 +0000176 // show final fid and vid
177 {
178 msr_t msr;
179 msr = rdmsr(0xc0010042);
Stefan Reinauer069f4762015-01-05 13:02:32 -0800180 printk(BIOS_DEBUG, "end msr fid, vid %08x%08x\n", msr.hi, msr.lo);
Marc Jones5dd4a202009-03-20 16:36:05 +0000181 }
182#endif
183
Paul Menzel4549e5a2014-02-02 22:05:48 +0100184 init_timer(); /* Need to use TMICT to synchronize FID/VID. */
Stefan Reinauerbcb8c972010-04-25 18:06:32 +0000185
Marc Jones5dd4a202009-03-20 16:36:05 +0000186 needs_reset |= optimize_link_coherent_ht();
187 needs_reset |= optimize_link_incoherent_ht(sysinfo);
188 needs_reset |= mcp55_early_setup_x();
189
190 // fidvid change will issue one LDTSTOP and the HT change will be effective too
191 if (needs_reset) {
Stefan Reinauer069f4762015-01-05 13:02:32 -0800192 printk(BIOS_INFO, "ht reset -\n");
Marc Jones5dd4a202009-03-20 16:36:05 +0000193 soft_reset();
194 }
Stefan Reinauerbcb8c972010-04-25 18:06:32 +0000195
Marc Jones5dd4a202009-03-20 16:36:05 +0000196 allow_all_aps_stop(bsp_apicid);
197
198 //It's the time to set ctrl in sysinfo now;
199 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
200
201 enable_smbus(); /* enable in sio_setup */
202
Marc Jones5dd4a202009-03-20 16:36:05 +0000203 /* all ap stopped? */
Marc Jones5dd4a202009-03-20 16:36:05 +0000204
205 sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
206
207 post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now
Marc Jones5dd4a202009-03-20 16:36:05 +0000208}