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