changes from AMD for making OLPC video work.
[coreboot.git] / src / southbridge / amd / cs5536 / cs5536_early_setup.c
1 #include <cpu/amd/gx2def.h>
2
3 /*
4  *
5  * cs5536_early_setup.c:        Early chipset initialization for CS5536 companion device
6  *
7  *
8  * This file implements the initialization sequence documented in section 4.2 of
9  * AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
10  *
11  */
12
13 #define CS5536_GLINK_PORT_NUM   0x02    /* the geode link port number to the CS5536 */       
14 #define CS5536_DEV_NUM          0x0F    /* default PCI device number for CS5536 */
15
16 /**
17  * @brief Setup PCI IDSEL for CS5536
18  *
19  * 
20  */
21
22 static void cs5536_setup_extmsr(void)
23 {
24         msr_t msr;
25
26         /* forward MSR access to CS5536_GLINK_PORT_NUM to CS5536_DEV_NUM */
27         msr.hi = msr.lo = 0x00000000;
28         if (CS5536_GLINK_PORT_NUM <= 4) {
29                 msr.lo = CS5536_DEV_NUM << ((CS5536_GLINK_PORT_NUM - 1) * 8);
30         } else {
31                 msr.hi = CS5536_DEV_NUM << ((CS5536_GLINK_PORT_NUM - 5) * 8);
32         }
33         wrmsr(0x5000201e, msr);
34 }
35
36 static void cs5536_setup_idsel(void)
37 {
38         /* write IDSEL to the write once register at address 0x0000 */
39         outl(0x1 << (CS5536_DEV_NUM + 10), 0);
40 }
41
42 static void cs5536_usb_swapsif(void)
43 {
44         msr_t msr;
45
46         msr = rdmsr(0x51600005);
47         //USB Serial short detect bit.
48         if (msr.hi & 0x10) {
49                 /* We need to preserve bits 32,33,35 and not clear any BIST error, but clear the
50                  * SERSHRT error bit */
51                 msr.hi &= 0xFFFFFFFB;
52                 wrmsr(0x51600005, msr);
53         }
54 }
55
56 static int cs5536_setup_iobase(void)
57 {
58         msr_t msr;
59
60         /* setup LBAR for SMBus controller */
61         __builtin_wrmsr(0x5140000b, 0x00006000, 0x0000f001);
62         /* setup LBAR for GPIO */
63         __builtin_wrmsr(0x5140000c, 0x00006100, 0x0000f001);
64         /* setup LBAR for MFGPT */
65         __builtin_wrmsr(0x5140000d, 0x00006200, 0x0000f001);
66         /* setup LBAR for ACPI */
67         __builtin_wrmsr(0x5140000e, 0x00009c00, 0x0000f001);
68         /* setup LBAR for PM Support */
69         __builtin_wrmsr(0x5140000f, 0x00009d00, 0x0000f001);
70 }
71
72 static void cs5536_setup_power_bottun(void)
73 {
74         /* not implemented yet */
75 #if 0
76         pwrBtn_setup:
77         ;
78         ;       Power Button Setup
79         ;
80         ;mov    eax, 0C0020000h                         ; 4 seconds + lock
81         mov     eax, 040020000h                         ; 4 seconds no lock
82         mov     dx, PMLogic_BASE + 40h
83         out     dx, eax
84
85         ; setup GPIO24, it is the external signal for 5536 vsb_work_aux
86         ; which controls all voltage rails except Vstandby & Vmem.
87         ; We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
88         ; If GPIO24 is not enabled then soft-off will not work.
89         mov     dx, GPIOH_OUT_AUX1_SELECT
90         mov     eax, GPIOH_24_SET
91         out     dx, eax
92         mov     dx, GPIOH_OUTPUT_ENABLE
93         out     dx, eax
94
95 #endif
96 }
97
98 static void cs5536_setup_gpio(void)
99 {
100         uint32_t val;
101
102         /* setup GPIO pins 14/15 for SDA/SCL */
103         val = (1<<14 | 1<<15);
104         /* Output Enable */
105         outl(0x3fffc000, 0x6100 + 0x04);
106         //outl(val, 0x6100 + 0x04);
107         /* Output AUX1 */
108         outl(0x3fffc000, 0x6100 + 0x10);
109         //outl(val, 0x6100 + 0x10);
110         /* Input Enable */
111         //outl(0x0f5af0a5, 0x6100 + 0x20);
112         outl(0x3fffc000, 0x6100 + 0x20);
113         //outl(val, 0x6100 + 0x20);
114         /* Input AUX1 */
115         //outl(0x3ffbc004, 0x6100 + 0x34);
116         outl(0x3fffc000, 0x6100 + 0x34);
117         //outl(val, 0x6100 + 0x34);
118
119 #if 0
120         /* changes proposed by Ollie; we will test this later. */
121         /* setup GPIO pins 14/15 for SDA/SCL */
122         val = GPIOL_15_SET | GPIOL_14_SET;
123         /* Output Enable */
124         //outl(0x3fffc000, 0x6100 + 0x04);
125         outl(val, 0x6100 + 0x04);
126         /* Output AUX1 */
127         //outl(0x3fffc000, 0x6100 + 0x10);
128         outl(val, 0x6100 + 0x10);
129         /* Input Enable */
130         //outl(0x3fffc000, 0x6100 + 0x20);
131         outl(val, 0x6100 + 0x20);
132         /* Input AUX1 */
133         //outl(0x3fffc000, 0x6100 + 0x34);
134         outl(val, 0x6100 + 0x34);
135 #endif
136 }
137
138 static void cs5536_disable_internal_uart(void)
139 {
140         /* not implemented yet */
141 #if 0
142         ; The UARTs default to enabled.
143         ; Disable and reset them and configure them later. (SIO init)
144         mov     ecx, MDD_UART1_CONF
145         RDMSR
146         mov     eax, 1h                                 ; reset
147         WRMSR
148         mov     eax, 0h                                 ; disabled
149         WRMSR
150
151         mov     ecx, MDD_UART2_CONF
152         RDMSR
153         mov     eax, 1h                                 ; reset
154         WRMSR
155         mov     eax, 0h                                 ; disabled
156         WRMSR
157
158 #endif
159 }
160
161 static void cs5536_setup_cis_mode(void)
162 {
163         msr_t msr;
164
165         /* setup CPU interface serial to mode C on both sides */
166         msr = __builtin_rdmsr(0x51000010);
167         msr.lo &= ~0x18;
168         msr.lo |= 0x10;
169         __builtin_wrmsr(0x51000010, msr.lo, msr.hi);
170         //Only do this if we are building for 5536
171         __builtin_wrmsr(0x54002010, 0x00000002, 0x00000000);
172 }
173
174 static void dummy(void)
175 {
176 }
177
178 /* see page 412 of the cs5536 companion book */
179 static int cs5536_setup_onchipuart(void)
180 {
181         unsigned long m;
182         /* 
183          * 1. Eanble GPIO 8 to OUT_AUX1, 9 to IN_AUX1
184          *    GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
185          * 2. Enable UART IO space in MDD
186          *    MSR 0x51400014 bit 18:16
187          * 3. Enable UART controller
188          *    MSR 0x5140003A bit 0, 1
189          * 4. IRQ routing on IRQ Mapper
190          *    MSR 0x51400021 bit [27:24]
191          */
192         msr_t msr;
193         msr.lo = 2;
194         msr.hi = 0;
195         /*  This enables COM2, but that should be done elsewhere
196         wrmsr(0x5140003e, msr);
197          */
198
199
200         /* enable COM1 */
201         wrmsr(0x5140003a, msr);
202         /* GPIO8 - UART1_TX */
203         /* Set: Output Enable  (0x4) */
204         m = inl(GPIOL_OUTPUT_ENABLE);
205         m |= GPIOL_8_SET;
206         m &= ~GPIOL_8_CLEAR;
207         outl(m,GPIOL_OUTPUT_ENABLE);
208         /* Set: OUTAUX1 Select (0x10) */
209         m = inl(GPIOL_OUT_AUX1_SELECT);
210         m |= GPIOL_8_SET;
211         m &= ~GPIOL_8_CLEAR;
212         outl(m,GPIOL_OUT_AUX1_SELECT);
213         /* Set: Pull Up        (0x18) */
214         m = inl(GPIOL_PULLUP_ENABLE);
215         m |= GPIOL_8_SET;
216         m &= ~GPIOL_8_CLEAR;
217         /* GPIO9 - UART1_RX */
218         /* Set: Pull Up        (0x18) */
219         m |= GPIOL_9_SET;
220         m &= ~GPIOL_9_CLEAR;
221         outl(m,GPIOL_PULLUP_ENABLE);
222         /* Set: Input Enable   (0x20) */
223         m = inl(GPIOL_INPUT_ENABLE);
224         m |= GPIOL_9_SET;
225         m &= ~GPIOL_9_CLEAR;
226         outl(m,GPIOL_INPUT_ENABLE);
227         /* Set: INAUX1 Select  (0x34) */
228         m = inl(GPIOL_IN_AUX1_SELECT);
229         m |= GPIOL_9_SET;
230         m &= ~GPIOL_9_CLEAR;
231         outl(m,GPIOL_IN_AUX1_SELECT);
232
233         msr = rdmsr(MDD_LEG_IO);
234         msr.lo |= 0x7 << 16;
235         wrmsr(MDD_LEG_IO,msr);
236 }
237
238 /* note: you can't do prints in here in most cases, 
239  * and we don't want to hang on serial, so they are 
240  * commented out 
241  */
242 static int cs5536_early_setup(void)
243 {
244         msr_t msr;
245
246         cs5536_setup_extmsr();
247
248         msr = rdmsr(GLCP_SYS_RSTPLL);
249         if (msr.lo & (0x3f << 26)) {
250                 /* PLL is already set and we are reboot from PLL reset */
251                 //print_debug("reboot from BIOS reset\n\r");
252                 return;
253         }
254         //print_debug("Setup idsel\r\n");
255         cs5536_setup_idsel();
256         //print_debug("Setup iobase\r\n");
257         cs5536_usb_swapsif();
258         cs5536_setup_iobase();
259         //print_debug("Setup gpio\r\n");
260         cs5536_setup_gpio();
261         //print_debug("Setup cis_mode\r\n");
262         cs5536_setup_cis_mode();
263         //print_debug("Setup smbus\r\n");
264         cs5536_enable_smbus();
265         dummy();
266 }