first round name simplification. drop the <component>_ prefix.
[coreboot.git] / src / southbridge / amd / cs5536 / early_setup.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 /*
21  * cs5536_early_setup.c:        Early chipset initialization for CS5536 companion device
22  *      This file implements the initialization sequence documented in section 4.2 of
23  *      AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
24  */
25
26 /**
27  * @brief Setup PCI IDSEL for CS5536
28  */
29 static void cs5536_setup_extmsr(void)
30 {
31         msr_t msr;
32
33         /* forward MSR access to CS5536_GLINK_PORT_NUM to CS5536_DEV_NUM */
34         msr.hi = msr.lo = 0x00000000;
35 #if CS5536_GLINK_PORT_NUM <= 4
36         msr.lo = CS5536_DEV_NUM << (unsigned char)((CS5536_GLINK_PORT_NUM - 1) * 8);
37 #else
38         msr.hi = CS5536_DEV_NUM << (unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
39 #endif
40         wrmsr(GLPCI_ExtMSR, msr);
41 }
42
43 static void cs5536_setup_idsel(void)
44 {
45         /* write IDSEL to the write once register at address 0x0000 */
46         outl(0x1 << (CS5536_DEV_NUM + 10), 0);
47 }
48
49 static void cs5536_usb_swapsif(void)
50 {
51         msr_t msr;
52
53         msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
54         //USB Serial short detect bit.
55         if (msr.hi & 0x10) {
56                 /* We need to preserve bits 32,33,35 and not clear any BIST
57                  * error, but clear the SERSHRT error bit */
58
59                 msr.hi &= 0xFFFFFFFB;
60                 wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
61         }
62 }
63
64 static void cs5536_setup_iobase(void)
65 {
66         msr_t msr;
67         /* setup LBAR for SMBus controller */
68         msr.hi = 0x0000f001;
69         msr.lo = SMBUS_IO_BASE;
70         wrmsr(MDD_LBAR_SMB, msr);
71
72         /* setup LBAR for GPIO */
73         msr.hi = 0x0000f001;
74         msr.lo = GPIO_IO_BASE;
75         wrmsr(MDD_LBAR_GPIO, msr);
76
77         /* setup LBAR for MFGPT */
78         msr.hi = 0x0000f001;
79         msr.lo = MFGPT_IO_BASE;
80         wrmsr(MDD_LBAR_MFGPT, msr);
81
82         /* setup LBAR for ACPI */
83         msr.hi = 0x0000f001;
84         msr.lo = ACPI_IO_BASE;
85         wrmsr(MDD_LBAR_ACPI, msr);
86
87         /* setup LBAR for PM Support */
88         msr.hi = 0x0000f001;
89         msr.lo = PMS_IO_BASE;
90         wrmsr(MDD_LBAR_PMS, msr);
91 }
92
93 static void cs5536_setup_power_button(void)
94 {
95 #if CONFIG_ENABLE_POWER_BUTTON
96         outl(0x40020000, PMS_IO_BASE + 0x40);
97 #endif
98
99         /* setup WORK_AUX/GPIO24, it is the external signal for 5536
100          * vsb_work_aux controls all voltage rails except Vstandby & Vmem.
101          * We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
102          * If WORK_AUX/GPIO24 is not enabled then soft-off will not work.
103          */
104         outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUT_AUX1_SELECT);
105         outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUTPUT_ENABLE);
106
107 }
108
109 static void cs5536_setup_gpio(void)
110 {
111         uint32_t val;
112
113         /* setup GPIO pins 14/15 for SDA/SCL */
114         val = GPIOL_15_SET | GPIOL_14_SET;
115         /* Output Enable */
116         outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
117         /* Output AUX1 */
118         outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
119         /* Input Enable */
120         outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
121         /* Input AUX1 */
122         outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
123 }
124
125 void cs5536_disable_internal_uart(void)
126 {
127         msr_t msr;
128         /* The UARTs default to enabled.
129          * Disable and reset them and configure them later. (SIO init)
130          */
131         msr = rdmsr(MDD_UART1_CONF);
132         msr.lo = 1;             // reset
133         wrmsr(MDD_UART1_CONF, msr);
134         msr.lo = 0;             // disabled
135         wrmsr(MDD_UART1_CONF, msr);
136
137         msr = rdmsr(MDD_UART2_CONF);
138         msr.lo = 1;             // reset
139         wrmsr(MDD_UART2_CONF, msr);
140         msr.lo = 0;             // disabled
141         wrmsr(MDD_UART2_CONF, msr);
142 }
143
144 static void cs5536_setup_cis_mode(void)
145 {
146         msr_t msr;
147
148         /* setup CPU interface serial to mode B to match CPU */
149         msr = rdmsr(GLPCI_SB_CTRL);
150         msr.lo &= ~0x18;
151         msr.lo |= 0x10;
152         wrmsr(GLPCI_SB_CTRL, msr);
153 }
154
155 /**
156  * Enable the on-chip UART.
157  *
158  * See page 412 of the AMD Geode CS5536 Companion Device data book.
159  */
160 static void cs5536_setup_onchipuart1(void)
161 {
162         msr_t msr;
163
164         /* Setup early for polling only mode.
165          * 1. Enable GPIO 8 to OUT_AUX1, 9 to IN_AUX1.
166          *        GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
167          * 2. Enable UART I/O space in MDD.
168          *        MSR 0x51400014 bit 18:16
169          * 3. Enable UART controller.
170          *        MSR 0x5140003A bit 0, 1
171          */
172
173         /* GPIO8 - UART1_TX */
174         /* Set: Output Enable (0x4) */
175         outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
176         /* Set: OUTAUX1 Select (0x10) */
177         outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
178
179         /* GPIO9 - UART1_RX */
180         /* Set: Input Enable (0x20) */
181         outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
182         /* Set: INAUX1 Select (0x34) */
183         outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
184
185         /* Set address to 0x3F8. */
186         msr = rdmsr(MDD_LEG_IO);
187         msr.lo |= 0x7 << 16;
188         wrmsr(MDD_LEG_IO, msr);
189
190         /* Bit 1 = DEVEN (device enable)
191          * Bit 4 = EN_BANKS (allow access to the upper banks)
192          */
193         msr.lo = (1 << 4) | (1 << 1);
194         msr.hi = 0;
195
196         /* Enable COM1. */
197         wrmsr(MDD_UART1_CONF, msr);
198 }
199
200 static void cs5536_setup_onchipuart2(void)
201 {
202         msr_t msr;
203
204         /* GPIO4 - UART2_TX */
205         /* Set: Output Enable  (0x4) */
206         outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
207         /* Set: OUTAUX1 Select (0x10) */
208         outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
209         /* GPIO4 - UART2_RX */
210         /* Set: Input Enable   (0x20) */
211         outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
212         /* Set: INAUX1 Select  (0x34) */
213         outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
214
215         /* Set: GPIO 3 + 3 Pull Up  (0x18) */
216         outl(GPIOL_3_SET | GPIOL_4_SET,
217              GPIO_IO_BASE + GPIOL_PULLUP_ENABLE);
218
219         /* set address to 2F8 */
220         msr = rdmsr(MDD_LEG_IO);
221         msr.lo |= 0x5 << 20;
222         wrmsr(MDD_LEG_IO, msr);
223
224         /* Bit 1 = DEVEN (device enable)
225          * Bit 4 = EN_BANKS (allow access to the upper banks
226          */
227         msr.lo = (1 << 4) | (1 << 1);
228         msr.hi = 0;
229
230         /* enable COM2 */
231         wrmsr(MDD_UART2_CONF, msr);
232 }
233
234 void cs5536_setup_onchipuart(int uart)
235 {
236         switch (uart) {
237         case 1:
238                 cs5536_setup_onchipuart1();
239                 break;
240         case 2:
241                 cs5536_setup_onchipuart2();
242                 break;
243         }
244 }
245
246
247 /* note: you can't do prints in here in most cases,
248  * and we don't want to hang on serial, so they are
249  * commented out
250  */
251 static void cs5536_early_setup(void)
252 {
253         msr_t msr;
254
255         cs5536_setup_extmsr();
256         cs5536_setup_cis_mode();
257
258         msr = rdmsr(GLCP_SYS_RSTPLL);
259         if (msr.lo & (0x3f << 26)) {
260                 /* PLL is already set and we are reboot from PLL reset */
261                 //print_debug("reboot from BIOS reset\n");
262                 return;
263         }
264         //print_debug("Setup idsel\n");
265         cs5536_setup_idsel();
266         //print_debug("Setup iobase\n");
267         cs5536_usb_swapsif();
268         cs5536_setup_iobase();
269         //print_debug("Setup gpio\n");
270         cs5536_setup_gpio();
271         //print_debug("Setup smbus\n");
272         cs5536_enable_smbus();
273         //print_debug("Setup power button\n");
274         cs5536_setup_power_button();
275 }