ec5e1ddad91790efc80231859f740759b1b3190d
[coreboot.git] / src / mainboard / tyan / s4882 / romstage.c
1 #include <stdint.h>
2 #include <string.h>
3 #include <device/pci_def.h>
4 #include <arch/io.h>
5 #include <device/pnp_def.h>
6 #include <arch/romcc_io.h>
7 #include <cpu/x86/lapic.h>
8 #include <pc80/mc146818rtc.h>
9 #include <console/console.h>
10 #include <lib.h>
11
12 #include <cpu/amd/model_fxx_rev.h>
13 #include "northbridge/amd/amdk8/incoherent_ht.c"
14 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
15 #include "northbridge/amd/amdk8/raminit.h"
16 #include "cpu/amd/model_fxx/apic_timer.c"
17 #include "lib/delay.c"
18
19 #include "cpu/x86/lapic/boot_cpu.c"
20 #include "northbridge/amd/amdk8/reset_test.c"
21 #include "northbridge/amd/amdk8/debug.c"
22 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
23
24 #include "cpu/x86/mtrr/earlymtrr.c"
25 #include "cpu/x86/bist.h"
26
27 #include "northbridge/amd/amdk8/setup_resource_map.c"
28
29 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
30
31 #include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
32
33 static void memreset_setup(void)
34 {
35    if (is_cpu_pre_c0()) {
36         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 16);  //REVC_MEMRST_EN=0
37    }
38    else {
39         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 16);  //REVC_MEMRST_EN=1
40    }
41         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 17);
42 }
43
44 static void memreset(int controllers, const struct mem_controller *ctrl)
45 {
46    if (is_cpu_pre_c0()) {
47         udelay(800);
48         outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 17); //REVB_MEMRST_L=1
49         udelay(90);
50    }
51 }
52 static inline void activate_spd_rom(const struct mem_controller *ctrl)
53 {
54 #define SMBUS_HUB 0x18
55         int ret,i;
56         unsigned device=(ctrl->channel0[0])>>8;
57         /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
58         i=2;
59         do {
60                 ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
61         } while ((ret!=0) && (i-->0));
62
63         smbus_write_byte(SMBUS_HUB, 0x03, 0);
64 }
65 #if 0
66 static inline void change_i2c_mux(unsigned device)
67 {
68 #define SMBUS_HUB 0x18
69         int ret, i;
70         print_debug("change_i2c_mux i="); print_debug_hex8(device); print_debug("\n");
71         i=2;
72         do {
73                 ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
74                 print_debug("change_i2c_mux 1 ret="); print_debug_hex32(ret); print_debug("\n");
75         } while ((ret!=0) && (i-->0));
76         ret = smbus_write_byte(SMBUS_HUB, 0x03, 0);
77         print_debug("change_i2c_mux 2 ret="); print_debug_hex32(ret); print_debug("\n");
78 }
79 #endif
80
81 static inline int spd_read_byte(unsigned device, unsigned address)
82 {
83         return smbus_read_byte(device, address);
84 }
85
86
87 #include "northbridge/amd/amdk8/raminit.c"
88 #include "northbridge/amd/amdk8/coherent_ht.c"
89 #include "lib/generic_sdram.c"
90
91  /* tyan does not want the default */
92 #include "resourcemap.c"
93
94 #include "cpu/amd/dualcore/dualcore.c"
95 #include <spd.h>
96
97 #define RC0 ((1<<2)<<8)
98 #define RC1 ((1<<1)<<8)
99 #define RC2 ((1<<4)<<8)
100 #define RC3 ((1<<3)<<8)
101
102 #include "cpu/amd/car/post_cache_as_ram.c"
103
104 #include "cpu/amd/model_fxx/init_cpus.c"
105
106 #include "southbridge/amd/amd8111/amd8111_enable_rom.c"
107 #include "northbridge/amd/amdk8/early_ht.c"
108
109 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
110 {
111         static const uint16_t spd_addr [] = {
112                         RC0|DIMM0, RC0|DIMM2, 0, 0,
113                         RC0|DIMM1, RC0|DIMM3, 0, 0,
114 #if CONFIG_MAX_PHYSICAL_CPUS > 1
115                         RC1|DIMM0, RC1|DIMM2, 0, 0,
116                         RC1|DIMM1, RC1|DIMM3, 0, 0,
117 #endif
118 #if CONFIG_MAX_PHYSICAL_CPUS > 2
119                         RC2|DIMM0, RC2|DIMM2, 0, 0,
120                         RC2|DIMM1, RC2|DIMM3, 0, 0,
121                         RC3|DIMM0, RC3|DIMM2, 0, 0,
122                         RC3|DIMM1, RC3|DIMM3, 0, 0,
123 #endif
124         };
125
126         int needs_reset;
127         unsigned bsp_apicid = 0;
128
129         struct mem_controller ctrl[8];
130         unsigned nodes;
131
132         if (!cpu_init_detectedx && boot_cpu()) {
133                 /* Nothing special needs to be done to find bus 0 */
134                 /* Allow the HT devices to be found */
135
136                 enumerate_ht_chain();
137
138                 amd8111_enable_rom();
139         }
140
141         if (bist == 0) {
142                 bsp_apicid = init_cpus(cpu_init_detectedx);
143         }
144
145
146         w83627hf_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
147         uart_init();
148         console_init();
149
150         /* Halt if there was a built in self test failure */
151         report_bist_failure(bist);
152
153         setup_s4882_resource_map();
154
155         needs_reset = setup_coherent_ht_domain();
156
157         wait_all_core0_started();
158 #if CONFIG_LOGICAL_CPUS==1
159         // It is said that we should start core1 after all core0 launched
160         start_other_cores();
161         wait_all_other_cores_started(bsp_apicid);
162 #endif
163
164         // automatically set that for you, but you might meet tight space
165         needs_reset |= ht_setup_chains_x();
166
167         if (needs_reset) {
168                 print_info("ht reset -\n");
169                 soft_reset();
170         }
171
172         allow_all_aps_stop(bsp_apicid);
173
174         nodes = get_nodes();
175         //It's the time to set ctrl now;
176         fill_mem_ctrl(nodes, ctrl, spd_addr);
177
178         enable_smbus();
179
180         memreset_setup();
181         sdram_initialize(nodes, ctrl);
182
183         post_cache_as_ram();
184
185 }
186