ecaa2f93e61aca56ef86dc36e7ee7ffe9337a5c7
[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 #include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
145 #include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
146
147 #include "cpu/amd/car/post_cache_as_ram.c"
148
149 #include "cpu/amd/model_fxx/init_cpus.c"
150
151 #include "cpu/amd/model_fxx/fidvid.c"
152
153 #include "southbridge/nvidia/mcp55/mcp55_enable_rom.c"
154 #include "northbridge/amd/amdk8/early_ht.c"
155
156 static void sio_setup(void)
157 {
158         uint32_t dword;
159         uint8_t byte;
160
161         enable_smbus();
162 //      smbusx_write_byte(1, (0x58>>1), 0, 0x80); /* select bank0 */
163         smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff);  /* set FAN ctrl to DC mode */
164
165         byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
166         byte |= 0x20;
167         pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
168
169         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
170         dword |= (1 << 0);
171         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
172
173         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
174         dword |= (1 << 16);
175         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
176 }
177
178 /* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
179 #define RC0 (2<<8)
180 #define RC1 (1<<8)
181
182 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
183 {
184 /* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
185    don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
186    memory on each CPU must be an exact match.
187  */
188         static const uint16_t spd_addr[] = {
189                 // Node 0
190                 RC0 | DIMM0, RC0 | DIMM2,
191                 RC0 | DIMM4, RC0 | DIMM6,
192                 RC0 | DIMM1, RC0 | DIMM3,
193                 RC0 | DIMM5, RC0 | DIMM7,
194                 // Node 1
195                 RC1 | DIMM0, RC1 | DIMM2,
196                 RC1 | DIMM4, RC1 | DIMM6,
197                 RC1 | DIMM1, RC1 | DIMM3,
198                 RC1 | DIMM5, RC1 | DIMM7,
199         };
200
201         struct sys_info *sysinfo = (struct sys_info *)(CONFIG_DCACHE_RAM_BASE
202                 + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
203
204         int needs_reset = 0;
205         unsigned bsp_apicid = 0;
206
207         if (!cpu_init_detectedx && boot_cpu()) {
208                 /* Nothing special needs to be done to find bus 0 */
209                 /* Allow the HT devices to be found */
210
211                 enumerate_ht_chain();
212
213                 sio_setup();
214
215                 /* Setup the mcp55 */
216                 mcp55_enable_rom();
217         }
218
219         if (bist == 0) {
220                 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
221         }
222
223         pnp_enter_ext_func_mode(SERIAL_DEV);
224         pnp_write_config(SERIAL_DEV, 0x24, 0x84 | (1 << 6));
225         w83627hf_enable_dev(SERIAL_DEV, CONFIG_TTYS0_BASE);
226         pnp_exit_ext_func_mode(SERIAL_DEV);
227
228         uart_init();
229         console_init();
230
231         /* Halt if there was a built in self test failure */
232         report_bist_failure(bist);
233
234         printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
235
236         setup_mb_resource_map();
237
238         print_debug("bsp_apicid=");
239         print_debug_hex8(bsp_apicid);
240         print_debug("\n");
241
242 #if CONFIG_MEM_TRAIN_SEQ == 1
243         set_sysinfo_in_ram(0);  // in BSP so could hold all ap until sysinfo is in ram
244 #endif
245 /*      dump_smbus_registers(); */
246         setup_coherent_ht_domain();     // routing table and start other core0
247
248         wait_all_core0_started();
249 #if CONFIG_LOGICAL_CPUS==1
250         // It is said that we should start core1 after all core0 launched
251         /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
252          * So here need to make sure last core0 is started, esp for two way system,
253          * (there may be apic id conflicts in that case)
254          */
255         start_other_cores();
256         wait_all_other_cores_started(bsp_apicid);
257 #endif
258
259         /* it will set up chains and store link pair for optimization later */
260         ht_setup_chains_x(sysinfo);     // it will init sblnk and sbbusn, nodes, sbdn
261
262 #if CONFIG_SET_FIDVID
263
264         {
265                 msr_t msr;
266                 msr = rdmsr(0xc0010042);
267                 print_debug("begin msr fid, vid ");
268                 print_debug_hex32(msr.hi);
269                 print_debug_hex32(msr.lo);
270                 print_debug("\n");
271
272         }
273
274         enable_fid_change();
275
276         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
277
278         init_fidvid_bsp(bsp_apicid);
279
280         // show final fid and vid
281         {
282                 msr_t msr;
283                 msr = rdmsr(0xc0010042);
284                 print_debug("end   msr fid, vid ");
285                 print_debug_hex32(msr.hi);
286                 print_debug_hex32(msr.lo);
287                 print_debug("\n");
288
289         }
290 #endif
291
292         init_timer(); /* Need to use TMICT to synconize FID/VID. */
293
294         needs_reset |= optimize_link_coherent_ht();
295         needs_reset |= optimize_link_incoherent_ht(sysinfo);
296         needs_reset |= mcp55_early_setup_x();
297
298         // fidvid change will issue one LDTSTOP and the HT change will be effective too
299         if (needs_reset) {
300                 print_info("ht reset -\n");
301                 soft_reset();
302         }
303
304         allow_all_aps_stop(bsp_apicid);
305
306         //It's the time to set ctrl in sysinfo now;
307         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
308
309         enable_smbus();         /* enable in sio_setup */
310
311         /* all ap stopped? */
312
313         sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
314
315         post_cache_as_ram();    // bsp swtich stack to ram and copy sysinfo ram now
316
317 }
318