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