4f32816ebb79764ecee12b6a2564fc39aa2c5654
[coreboot.git] / src / mainboard / supermicro / h8dme / romstage.c
1 /*
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.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  */
18
19 #if CONFIG_K8_REV_F_SUPPORT == 1
20 #define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
21 #endif
22
23 #include <stdint.h>
24 #include <string.h>
25 #include <device/pci_def.h>
26 #include <device/pci_ids.h>
27 #include <arch/io.h>
28 #include <device/pnp_def.h>
29 #include <arch/romcc_io.h>
30 #include <cpu/x86/lapic.h>
31 #include <pc80/mc146818rtc.h>
32
33 #include <console/console.h>
34 #include <lib.h>
35 #include <spd.h>
36
37 #include <cpu/amd/model_fxx_rev.h>
38
39 // for enable the FAN
40 #include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
41 #include "northbridge/amd/amdk8/raminit.h"
42 #include "cpu/amd/model_fxx/apic_timer.c"
43 #include "lib/delay.c"
44
45 #include "cpu/x86/lapic/boot_cpu.c"
46 #include "northbridge/amd/amdk8/reset_test.c"
47 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
48 #include "superio/winbond/w83627hf/w83627hf_early_init.c"
49
50 #include "cpu/x86/bist.h"
51
52 #include "northbridge/amd/amdk8/debug.c"
53
54 #include "cpu/x86/mtrr/earlymtrr.c"
55
56 #include "northbridge/amd/amdk8/setup_resource_map.c"
57
58 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
59
60 #include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
61
62 static void memreset(int controllers, const struct mem_controller *ctrl)
63 {
64 }
65
66 static inline void dump_smbus_registers(void)
67 {
68         u32 device;
69
70         print_debug("\n");
71         for (device = 1; device < 0x80; device++) {
72                 int j;
73                 if (smbus_read_byte(device, 0) < 0)
74                         continue;
75                 printk(BIOS_DEBUG, "smbus: %02x", device);
76                 for (j = 0; j < 256; j++) {
77                         int status;
78                         unsigned char byte;
79                         status = smbus_read_byte(device, j);
80                         if (status < 0) {
81                                 break;
82                         }
83                         if ((j & 0xf) == 0) {
84                                 printk(BIOS_DEBUG, "\n%02x: ", j);
85                         }
86                         byte = status & 0xff;
87                         printk(BIOS_DEBUG, "%02x ", byte);
88                 }
89                 print_debug("\n");
90         }
91 }
92
93 static inline void activate_spd_rom(const struct mem_controller *ctrl)
94 {
95 #if 0
96 /* We don't do any switching yet. */
97 #define SMBUS_SWITCH1 0x48
98 #define SMBUS_SWITCH2 0x49
99         unsigned device=(ctrl->channel0[0])>>8;
100         smbus_send_byte(SMBUS_SWITCH1, device);
101         smbus_send_byte(SMBUS_SWITCH2, (device >> 4) & 0x0f);
102 #endif
103 }
104
105 #if 0
106 static int smbus_send_byte_one(unsigned device, unsigned char val)
107 {
108         return do_smbus_send_byte(SMBUS1_IO_BASE, device, val);
109 }
110
111 static inline void change_i2c_mux(unsigned device)
112 {
113 #define SMBUS_SWITCH1 0x48
114 #define SMBUS_SWITHC2 0x49
115         smbus_send_byte(SMBUS_SWITCH1, device & 0x0f);
116         smbus_send_byte_one(SMBUS_SWITCH2, (device >> 4) & 0x0f);
117         int ret;
118         print_debug("change_i2c_mux i="); print_debug_hex8(device); print_debug("\n");
119         dump_smbus_registers();
120         ret = smbus_send_byte(SMBUS_SWITCH1, device);
121         print_debug("change_i2c_mux ret="); print_debug_hex32(ret); print_debug("\n");
122         dump_smbus_registers();
123         ret = smbus_send_byte_one(SMBUS_SWITCH2, device);
124         print_debug("change_i2c_mux ret="); print_debug_hex32(ret); print_debug("\n");
125         dump_smbus_registers();
126 }
127 #endif
128
129 static inline int spd_read_byte(unsigned device, unsigned address)
130 {
131         return smbus_read_byte(device, address);
132 }
133
134 #include "northbridge/amd/amdk8/amdk8_f.h"
135 #include "northbridge/amd/amdk8/incoherent_ht.c"
136 #include "northbridge/amd/amdk8/coherent_ht.c"
137 #include "northbridge/amd/amdk8/raminit_f.c"
138 #include "lib/generic_sdram.c"
139
140 #include "resourcemap.c"
141
142 #include "cpu/amd/dualcore/dualcore.c"
143
144 #define MCP55_PCI_E_X_0 4
145
146 #include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
147 #include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
148
149 #include "cpu/amd/car/post_cache_as_ram.c"
150
151 #include "cpu/amd/model_fxx/init_cpus.c"
152
153 #include "cpu/amd/model_fxx/fidvid.c"
154
155 #include "southbridge/nvidia/mcp55/mcp55_enable_rom.c"
156 #include "northbridge/amd/amdk8/early_ht.c"
157
158 static void sio_setup(void)
159 {
160         uint32_t dword;
161         uint8_t byte;
162
163         enable_smbus();
164 //      smbusx_write_byte(1, (0x58>>1), 0, 0x80); /* select bank0 */
165         smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff);  /* set FAN ctrl to DC mode */
166
167         byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
168         byte |= 0x20;
169         pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
170
171         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
172         dword |= (1 << 0);
173         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
174
175         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
176         dword |= (1 << 16);
177         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
178 }
179
180 /* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
181 #define RC0 (2<<8)
182 #define RC1 (1<<8)
183
184 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
185 {
186 /* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
187    don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
188    memory on each CPU must be an exact match.
189  */
190         static const uint16_t spd_addr[] = {
191                 // Node 0
192                 RC0 | DIMM0, RC0 | DIMM2,
193                 RC0 | DIMM4, RC0 | DIMM6,
194                 RC0 | DIMM1, RC0 | DIMM3,
195                 RC0 | DIMM5, RC0 | DIMM7,
196                 // Node 1
197                 RC1 | DIMM0, RC1 | DIMM2,
198                 RC1 | DIMM4, RC1 | DIMM6,
199                 RC1 | DIMM1, RC1 | DIMM3,
200                 RC1 | DIMM5, RC1 | DIMM7,
201         };
202
203         struct sys_info *sysinfo = (struct sys_info *)(CONFIG_DCACHE_RAM_BASE
204                 + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
205
206         int needs_reset = 0;
207         unsigned bsp_apicid = 0;
208
209         if (!cpu_init_detectedx && boot_cpu()) {
210                 /* Nothing special needs to be done to find bus 0 */
211                 /* Allow the HT devices to be found */
212
213                 enumerate_ht_chain();
214
215                 sio_setup();
216
217                 /* Setup the mcp55 */
218                 mcp55_enable_rom();
219         }
220
221         if (bist == 0) {
222                 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
223         }
224
225         pnp_enter_ext_func_mode(SERIAL_DEV);
226         pnp_write_config(SERIAL_DEV, 0x24, 0x84 | (1 << 6));
227         w83627hf_enable_dev(SERIAL_DEV, CONFIG_TTYS0_BASE);
228         pnp_exit_ext_func_mode(SERIAL_DEV);
229
230         uart_init();
231         console_init();
232
233         /* Halt if there was a built in self test failure */
234         report_bist_failure(bist);
235
236         printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
237
238         setup_mb_resource_map();
239
240         print_debug("bsp_apicid=");
241         print_debug_hex8(bsp_apicid);
242         print_debug("\n");
243
244 #if CONFIG_MEM_TRAIN_SEQ == 1
245         set_sysinfo_in_ram(0);  // in BSP so could hold all ap until sysinfo is in ram
246 #endif
247 /*      dump_smbus_registers(); */
248         setup_coherent_ht_domain();     // routing table and start other core0
249
250         wait_all_core0_started();
251 #if CONFIG_LOGICAL_CPUS==1
252         // It is said that we should start core1 after all core0 launched
253         /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
254          * So here need to make sure last core0 is started, esp for two way system,
255          * (there may be apic id conflicts in that case)
256          */
257         start_other_cores();
258         wait_all_other_cores_started(bsp_apicid);
259 #endif
260
261         /* it will set up chains and store link pair for optimization later */
262         ht_setup_chains_x(sysinfo);     // it will init sblnk and sbbusn, nodes, sbdn
263
264 #if CONFIG_SET_FIDVID
265
266         {
267                 msr_t msr;
268                 msr = rdmsr(0xc0010042);
269                 print_debug("begin msr fid, vid ");
270                 print_debug_hex32(msr.hi);
271                 print_debug_hex32(msr.lo);
272                 print_debug("\n");
273
274         }
275
276         enable_fid_change();
277
278         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
279
280         init_fidvid_bsp(bsp_apicid);
281
282         // show final fid and vid
283         {
284                 msr_t msr;
285                 msr = rdmsr(0xc0010042);
286                 print_debug("end   msr fid, vid ");
287                 print_debug_hex32(msr.hi);
288                 print_debug_hex32(msr.lo);
289                 print_debug("\n");
290
291         }
292 #endif
293
294         init_timer(); /* Need to use TMICT to synconize FID/VID. */
295
296         needs_reset |= optimize_link_coherent_ht();
297         needs_reset |= optimize_link_incoherent_ht(sysinfo);
298         needs_reset |= mcp55_early_setup_x();
299
300         // fidvid change will issue one LDTSTOP and the HT change will be effective too
301         if (needs_reset) {
302                 print_info("ht reset -\n");
303                 soft_reset();
304         }
305
306         allow_all_aps_stop(bsp_apicid);
307
308         //It's the time to set ctrl in sysinfo now;
309         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
310
311         enable_smbus();         /* enable in sio_setup */
312
313         /* all ap stopped? */
314
315         sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
316
317         post_cache_as_ram();    // bsp swtich stack to ram and copy sysinfo ram now
318
319 }
320