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