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