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