2 * This file is part of the coreboot project.
4 * Copyright (C) 2007 Advanced Micro Devices, Inc.
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.
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.
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
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.
27 * @brief Setup PCI IDSEL for CS5536
29 static void cs5536_setup_extmsr(void)
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);
38 msr.hi = CS5536_DEV_NUM << (unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
40 wrmsr(GLPCI_ExtMSR, msr);
43 static void cs5536_setup_idsel(void)
45 /* write IDSEL to the write once register at address 0x0000 */
46 outl(0x1 << (CS5536_DEV_NUM + 10), 0);
49 static void cs5536_usb_swapsif(void)
53 msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
54 //USB Serial short detect bit.
56 /* We need to preserve bits 32,33,35 and not clear any BIST
57 * error, but clear the SERSHRT error bit */
60 wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
64 static void cs5536_setup_iobase(void)
67 /* setup LBAR for SMBus controller */
69 msr.lo = SMBUS_IO_BASE;
70 wrmsr(MDD_LBAR_SMB, msr);
72 /* setup LBAR for GPIO */
74 msr.lo = GPIO_IO_BASE;
75 wrmsr(MDD_LBAR_GPIO, msr);
77 /* setup LBAR for MFGPT */
79 msr.lo = MFGPT_IO_BASE;
80 wrmsr(MDD_LBAR_MFGPT, msr);
82 /* setup LBAR for ACPI */
84 msr.lo = ACPI_IO_BASE;
85 wrmsr(MDD_LBAR_ACPI, msr);
87 /* setup LBAR for PM Support */
90 wrmsr(MDD_LBAR_PMS, msr);
93 static void cs5536_setup_power_button(void)
95 #if CONFIG_ENABLE_POWER_BUTTON
96 outl(0x40020000, PMS_IO_BASE + 0x40);
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.
104 outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUT_AUX1_SELECT);
105 outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUTPUT_ENABLE);
109 static void cs5536_setup_gpio(void)
113 /* setup GPIO pins 14/15 for SDA/SCL */
114 val = GPIOL_15_SET | GPIOL_14_SET;
116 outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
118 outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
120 outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
122 outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
125 void cs5536_disable_internal_uart(void)
128 /* The UARTs default to enabled.
129 * Disable and reset them and configure them later. (SIO init)
131 msr = rdmsr(MDD_UART1_CONF);
133 wrmsr(MDD_UART1_CONF, msr);
134 msr.lo = 0; // disabled
135 wrmsr(MDD_UART1_CONF, msr);
137 msr = rdmsr(MDD_UART2_CONF);
139 wrmsr(MDD_UART2_CONF, msr);
140 msr.lo = 0; // disabled
141 wrmsr(MDD_UART2_CONF, msr);
144 static void cs5536_setup_cis_mode(void)
148 /* setup CPU interface serial to mode B to match CPU */
149 msr = rdmsr(GLPCI_SB_CTRL);
152 wrmsr(GLPCI_SB_CTRL, msr);
156 * Enable the on-chip UART.
158 * See page 412 of the AMD Geode CS5536 Companion Device data book.
160 static void cs5536_setup_onchipuart1(void)
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
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);
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);
185 /* Set address to 0x3F8. */
186 msr = rdmsr(MDD_LEG_IO);
188 wrmsr(MDD_LEG_IO, msr);
190 /* Bit 1 = DEVEN (device enable)
191 * Bit 4 = EN_BANKS (allow access to the upper banks)
193 msr.lo = (1 << 4) | (1 << 1);
197 wrmsr(MDD_UART1_CONF, msr);
200 static void cs5536_setup_onchipuart2(void)
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);
215 /* Set: GPIO 3 + 3 Pull Up (0x18) */
216 outl(GPIOL_3_SET | GPIOL_4_SET,
217 GPIO_IO_BASE + GPIOL_PULLUP_ENABLE);
219 /* set address to 2F8 */
220 msr = rdmsr(MDD_LEG_IO);
222 wrmsr(MDD_LEG_IO, msr);
224 /* Bit 1 = DEVEN (device enable)
225 * Bit 4 = EN_BANKS (allow access to the upper banks
227 msr.lo = (1 << 4) | (1 << 1);
231 wrmsr(MDD_UART2_CONF, msr);
234 void cs5536_setup_onchipuart(int uart)
238 cs5536_setup_onchipuart1();
241 cs5536_setup_onchipuart2();
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
251 static void cs5536_early_setup(void)
255 cs5536_setup_extmsr();
256 cs5536_setup_cis_mode();
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");
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");
271 //print_debug("Setup smbus\n");
272 cs5536_enable_smbus();
273 //print_debug("Setup power button\n");
274 cs5536_setup_power_button();