AMD K8 fam10-15: Consolidate post_cache_as_ram call
[coreboot.git] / src / mainboard / supermicro / h8dme / romstage.c
blobcacdd41b775da0c9acf72203e0a560c3505680aa
1 /*
2 * This file is part of the coreboot project.
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.
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.
15 #include <stdint.h>
16 #include <string.h>
17 #include <device/pci_def.h>
18 #include <device/pci_ids.h>
19 #include <arch/io.h>
20 #include <device/pnp_def.h>
21 #include <cpu/x86/lapic.h>
22 #include <pc80/mc146818rtc.h>
23 #include <console/console.h>
24 #include <lib.h>
25 #include <spd.h>
26 #include <cpu/amd/model_fxx_rev.h>
27 #include <southbridge/nvidia/mcp55/mcp55.h> // for enable the FAN
28 #include <northbridge/amd/amdk8/raminit.h>
29 #include <delay.h>
30 #include <cpu/x86/lapic.h>
31 #include <superio/winbond/common/winbond.h>
32 #include <superio/winbond/w83627hf/w83627hf.h>
33 #include <cpu/amd/car.h>
34 #include <cpu/x86/bist.h>
36 #include "northbridge/amd/amdk8/setup_resource_map.c"
38 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
39 #define DUMMY_DEV PNP_DEV(0x2e, 0)
41 unsigned get_sbdn(unsigned bus);
43 unsigned get_sbdn(unsigned bus)
45 pci_devfn_t dev;
47 /* Find the device. */
48 dev = pci_locate_device_on_bus(PCI_ID(PCI_VENDOR_ID_NVIDIA,
49 PCI_DEVICE_ID_NVIDIA_MCP55_HT), bus);
51 return (dev >> 15) & 0x1f;
54 void memreset(int controllers, const struct mem_controller *ctrl) { }
56 void activate_spd_rom(const struct mem_controller *ctrl)
58 #if 0
59 /* We don't do any switching yet. */
60 #define SMBUS_SWITCH1 0x48
61 #define SMBUS_SWITCH2 0x49
62 unsigned device=(ctrl->channel0[0])>>8;
63 smbus_send_byte(SMBUS_SWITCH1, device);
64 smbus_send_byte(SMBUS_SWITCH2, (device >> 4) & 0x0f);
65 #endif
68 int spd_read_byte(unsigned device, unsigned address)
70 return smbus_read_byte(device, address);
73 #include <northbridge/amd/amdk8/f.h>
74 #include "northbridge/amd/amdk8/incoherent_ht.c"
75 #include "lib/generic_sdram.c"
76 #include "resourcemap.c"
77 #include "cpu/amd/dualcore/dualcore.c"
78 #include <southbridge/nvidia/mcp55/early_setup_ss.h>
79 #include "southbridge/nvidia/mcp55/early_setup_car.c"
80 #include "cpu/amd/model_fxx/init_cpus.c"
81 #include "cpu/amd/model_fxx/fidvid.c"
82 #include "northbridge/amd/amdk8/early_ht.c"
84 static void sio_setup(void)
86 uint32_t dword;
87 uint8_t byte;
89 enable_smbus();
90 // smbusx_write_byte(1, (0x58 >> 1), 0, 0x80); /* select bank0 */
91 smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff); /* set FAN ctrl to DC mode */
93 byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
94 byte |= 0x20;
95 pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
97 dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
98 dword |= (1 << 0);
99 pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
101 dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
102 dword |= (1 << 16);
103 pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
106 /* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
107 #define RC0 (2 << 8)
108 #define RC1 (1 << 8)
110 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
112 /* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
113 don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
114 memory on each CPU must be an exact match.
116 static const uint16_t spd_addr[] = {
117 // Node 0
118 RC0 | DIMM0, RC0 | DIMM2,
119 RC0 | DIMM4, RC0 | DIMM6,
120 RC0 | DIMM1, RC0 | DIMM3,
121 RC0 | DIMM5, RC0 | DIMM7,
122 // Node 1
123 RC1 | DIMM0, RC1 | DIMM2,
124 RC1 | DIMM4, RC1 | DIMM6,
125 RC1 | DIMM1, RC1 | DIMM3,
126 RC1 | DIMM5, RC1 | DIMM7,
129 struct sys_info *sysinfo = &sysinfo_car;
130 int needs_reset = 0;
131 unsigned bsp_apicid = 0;
133 if (!cpu_init_detectedx && boot_cpu()) {
134 /* Nothing special needs to be done to find bus 0 */
135 /* Allow the HT devices to be found */
136 enumerate_ht_chain();
137 sio_setup();
140 if (bist == 0)
141 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
143 w83627hf_set_clksel_48(DUMMY_DEV);
144 winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
146 console_init();
148 /* Halt if there was a built in self test failure */
149 report_bist_failure(bist);
151 printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
153 setup_mb_resource_map();
155 printk(BIOS_DEBUG, "bsp_apicid=%02x\n", bsp_apicid);
157 set_sysinfo_in_ram(0); // in BSP so could hold all ap until sysinfo is in ram
158 #if IS_ENABLED(CONFIG_DEBUG_SMBUS)
159 dump_smbus_registers();
160 #endif
161 setup_coherent_ht_domain(); // routing table and start other core0
163 wait_all_core0_started();
164 #if IS_ENABLED(CONFIG_LOGICAL_CPUS)
165 // It is said that we should start core1 after all core0 launched
166 /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
167 * So here need to make sure last core0 is started, esp for two way system,
168 * (there may be apic id conflicts in that case)
170 start_other_cores();
171 wait_all_other_cores_started(bsp_apicid);
172 #endif
174 /* it will set up chains and store link pair for optimization later */
175 ht_setup_chains_x(sysinfo); // it will init sblnk and sbbusn, nodes, sbdn
177 #if IS_ENABLED(CONFIG_SET_FIDVID)
179 msr_t msr;
180 msr = rdmsr(0xc0010042);
181 printk(BIOS_DEBUG, "begin msr fid, vid %08x%08x\n", msr.hi, msr.lo);
183 enable_fid_change();
184 enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
185 init_fidvid_bsp(bsp_apicid);
186 // show final fid and vid
188 msr_t msr;
189 msr = rdmsr(0xc0010042);
190 printk(BIOS_DEBUG, "end msr fid, vid %08x%08x\n", msr.hi, msr.lo);
192 #endif
194 init_timer(); /* Need to use TMICT to synchronize FID/VID. */
196 needs_reset |= optimize_link_coherent_ht();
197 needs_reset |= optimize_link_incoherent_ht(sysinfo);
198 needs_reset |= mcp55_early_setup_x();
200 // fidvid change will issue one LDTSTOP and the HT change will be effective too
201 if (needs_reset) {
202 printk(BIOS_INFO, "ht reset -\n");
203 soft_reset();
206 allow_all_aps_stop(bsp_apicid);
208 //It's the time to set ctrl in sysinfo now;
209 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
211 enable_smbus(); /* enable in sio_setup */
213 /* all ap stopped? */
215 sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);