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