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