blob: 013607beb468e86decb3626531832a800485ccb6 [file] [log] [blame]
Marc Jonesa67d4fd2007-05-04 19:05:36 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Uwe Hermann344e4572007-05-22 10:12:49 +00003 *
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.
Uwe Hermann344e4572007-05-22 10:12:49 +000014 */
Ronald G. Minnichfb937492006-06-10 22:57:15 +000015
Li-Ta Lo5d698962006-04-20 21:31:47 +000016/*
Li-Ta Lo5d698962006-04-20 21:31:47 +000017 * cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
Marc Jonesa67d4fd2007-05-04 19:05:36 +000018 * This file implements the initialization sequence documented in section 4.2 of
Nils Jacobsef15ff42010-12-29 20:31:31 +000019 * AMD Geode GX Processor CS5536 Companion Device GeodeROM Porting Guide.
Li-Ta Lo5d698962006-04-20 21:31:47 +000020 */
21
Li-Ta Lo5d698962006-04-20 21:31:47 +000022/**
23 * @brief Setup PCI IDSEL for CS5536
Li-Ta Lo5d698962006-04-20 21:31:47 +000024 */
Li-Ta Lo5d698962006-04-20 21:31:47 +000025static void cs5536_setup_extmsr(void)
26{
27 msr_t msr;
28
29 /* forward MSR access to CS5536_GLINK_PORT_NUM to CS5536_DEV_NUM */
30 msr.hi = msr.lo = 0x00000000;
Stefan Reinauer78b40332010-03-17 22:09:26 +000031#if CS5536_GLINK_PORT_NUM <= 4
32 msr.lo = CS5536_DEV_NUM << (unsigned char)((CS5536_GLINK_PORT_NUM - 1) * 8);
33#else
34 msr.hi = CS5536_DEV_NUM << (unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
35#endif
Marc Jonesa67d4fd2007-05-04 19:05:36 +000036 wrmsr(GLPCI_ExtMSR, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +000037}
38
39static void cs5536_setup_idsel(void)
40{
41 /* write IDSEL to the write once register at address 0x0000 */
42 outl(0x1 << (CS5536_DEV_NUM + 10), 0);
43}
44
45static void cs5536_usb_swapsif(void)
46{
47 msr_t msr;
48
Marc Jonesa67d4fd2007-05-04 19:05:36 +000049 msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
Li-Ta Lo5d698962006-04-20 21:31:47 +000050 //USB Serial short detect bit.
51 if (msr.hi & 0x10) {
Marc Jonesa67d4fd2007-05-04 19:05:36 +000052 /* We need to preserve bits 32,33,35 and not clear any BIST
53 * error, but clear the SERSHRT error bit */
54
Li-Ta Lo5d698962006-04-20 21:31:47 +000055 msr.hi &= 0xFFFFFFFB;
Marc Jonesa67d4fd2007-05-04 19:05:36 +000056 wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +000057 }
58}
59
Marc Jonesa67d4fd2007-05-04 19:05:36 +000060static void cs5536_setup_iobase(void)
Li-Ta Lo5d698962006-04-20 21:31:47 +000061{
62 msr_t msr;
Li-Ta Lo5d698962006-04-20 21:31:47 +000063 /* setup LBAR for SMBus controller */
Marc Jonesa67d4fd2007-05-04 19:05:36 +000064 msr.hi = 0x0000f001;
65 msr.lo = SMBUS_IO_BASE;
66 wrmsr(MDD_LBAR_SMB, msr);
67
Li-Ta Lo5d698962006-04-20 21:31:47 +000068 /* setup LBAR for GPIO */
Marc Jonesa67d4fd2007-05-04 19:05:36 +000069 msr.hi = 0x0000f001;
70 msr.lo = GPIO_IO_BASE;
71 wrmsr(MDD_LBAR_GPIO, msr);
72
Li-Ta Lo5d698962006-04-20 21:31:47 +000073 /* setup LBAR for MFGPT */
Marc Jonesa67d4fd2007-05-04 19:05:36 +000074 msr.hi = 0x0000f001;
75 msr.lo = MFGPT_IO_BASE;
76 wrmsr(MDD_LBAR_MFGPT, msr);
77
Li-Ta Lo5d698962006-04-20 21:31:47 +000078 /* setup LBAR for ACPI */
Marc Jonesa67d4fd2007-05-04 19:05:36 +000079 msr.hi = 0x0000f001;
80 msr.lo = ACPI_IO_BASE;
81 wrmsr(MDD_LBAR_ACPI, msr);
82
Li-Ta Lo5d698962006-04-20 21:31:47 +000083 /* setup LBAR for PM Support */
Marc Jonesa67d4fd2007-05-04 19:05:36 +000084 msr.hi = 0x0000f001;
85 msr.lo = PMS_IO_BASE;
86 wrmsr(MDD_LBAR_PMS, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +000087}
88
Marc Jonesa67d4fd2007-05-04 19:05:36 +000089static void cs5536_setup_power_button(void)
Li-Ta Lo5d698962006-04-20 21:31:47 +000090{
Peter Stuge51eafde2010-10-13 06:23:02 +000091#if CONFIG_ENABLE_POWER_BUTTON
Marc Jonesa67d4fd2007-05-04 19:05:36 +000092 outl(0x40020000, PMS_IO_BASE + 0x40);
Peter Stuge51eafde2010-10-13 06:23:02 +000093#endif
Li-Ta Lo5d698962006-04-20 21:31:47 +000094
Marc Jonesddf845f2007-05-10 23:22:27 +000095 /* setup WORK_AUX/GPIO24, it is the external signal for 5536
96 * vsb_work_aux controls all voltage rails except Vstandby & Vmem.
Jordan Crouse2a133f72007-05-10 18:43:57 +000097 * We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
Marc Jonesddf845f2007-05-10 23:22:27 +000098 * If WORK_AUX/GPIO24 is not enabled then soft-off will not work.
Jordan Crouse2a133f72007-05-10 18:43:57 +000099 */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000100 outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUT_AUX1_SELECT);
101 outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUTPUT_ENABLE);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000102
Li-Ta Lo5d698962006-04-20 21:31:47 +0000103}
104
105static void cs5536_setup_gpio(void)
106{
107 uint32_t val;
108
109 /* setup GPIO pins 14/15 for SDA/SCL */
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000110 val = GPIOL_15_SET | GPIOL_14_SET;
111 /* Output Enable */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000112 outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000113 /* Output AUX1 */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000114 outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000115 /* Input Enable */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000116 outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000117 /* Input AUX1 */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000118 outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000119}
120
Stefan Reinauer9839cbd2010-04-21 20:06:10 +0000121void cs5536_disable_internal_uart(void)
Li-Ta Lo5d698962006-04-20 21:31:47 +0000122{
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000123 msr_t msr;
Jordan Crouse2a133f72007-05-10 18:43:57 +0000124 /* The UARTs default to enabled.
Marc Jonesddf845f2007-05-10 23:22:27 +0000125 * Disable and reset them and configure them later. (SIO init)
Jordan Crouse2a133f72007-05-10 18:43:57 +0000126 */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000127 msr = rdmsr(MDD_UART1_CONF);
Jordan Crouse2a133f72007-05-10 18:43:57 +0000128 msr.lo = 1; // reset
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000129 wrmsr(MDD_UART1_CONF, msr);
Jordan Crouse2a133f72007-05-10 18:43:57 +0000130 msr.lo = 0; // disabled
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000131 wrmsr(MDD_UART1_CONF, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000132
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000133 msr = rdmsr(MDD_UART2_CONF);
Jordan Crouse2a133f72007-05-10 18:43:57 +0000134 msr.lo = 1; // reset
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000135 wrmsr(MDD_UART2_CONF, msr);
Jordan Crouse2a133f72007-05-10 18:43:57 +0000136 msr.lo = 0; // disabled
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000137 wrmsr(MDD_UART2_CONF, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000138}
139
140static void cs5536_setup_cis_mode(void)
141{
142 msr_t msr;
143
Nils Jacobs8098e422010-12-30 19:23:29 +0000144 /* Setup CPU serial SouthBridge interface to mode C. */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000145 msr = rdmsr(GLPCI_SB_CTRL);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000146 msr.lo &= ~0x18;
147 msr.lo |= 0x10;
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000148 wrmsr(GLPCI_SB_CTRL, msr);
Li-Ta Lo5d698962006-04-20 21:31:47 +0000149}
150
Edwin Beasante30db0e2010-02-09 10:22:33 +0000151/**
152 * Enable the on-chip UART.
153 *
154 * See page 412 of the AMD Geode CS5536 Companion Device data book.
155 */
Stefan Reinauer720297c2010-04-02 22:11:20 +0000156static void cs5536_setup_onchipuart1(void)
Li-Ta Lob7a09b42006-04-26 22:07:16 +0000157{
Ronald G. Minnich2f198002006-04-23 19:21:12 +0000158 msr_t msr;
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000159
160 /* Setup early for polling only mode.
Edwin Beasante30db0e2010-02-09 10:22:33 +0000161 * 1. Enable GPIO 8 to OUT_AUX1, 9 to IN_AUX1.
Jordan Crouse2a133f72007-05-10 18:43:57 +0000162 * GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
Edwin Beasante30db0e2010-02-09 10:22:33 +0000163 * 2. Enable UART I/O space in MDD.
Jordan Crouse2a133f72007-05-10 18:43:57 +0000164 * MSR 0x51400014 bit 18:16
Edwin Beasante30db0e2010-02-09 10:22:33 +0000165 * 3. Enable UART controller.
Jordan Crouse2a133f72007-05-10 18:43:57 +0000166 * MSR 0x5140003A bit 0, 1
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000167 */
168
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000169 /* GPIO8 - UART1_TX */
Edwin Beasante30db0e2010-02-09 10:22:33 +0000170 /* Set: Output Enable (0x4) */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000171 outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000172 /* Set: OUTAUX1 Select (0x10) */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000173 outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
Stefan Reinauer5a559d42010-02-03 13:49:24 +0000174
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000175 /* GPIO9 - UART1_RX */
Edwin Beasante30db0e2010-02-09 10:22:33 +0000176 /* Set: Input Enable (0x20) */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000177 outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
Edwin Beasante30db0e2010-02-09 10:22:33 +0000178 /* Set: INAUX1 Select (0x34) */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000179 outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000180
Edwin Beasante30db0e2010-02-09 10:22:33 +0000181 /* Set address to 0x3F8. */
Ronald G. Minnich070a10f2006-05-04 23:05:49 +0000182 msr = rdmsr(MDD_LEG_IO);
183 msr.lo |= 0x7 << 16;
Jordan Crouse2a133f72007-05-10 18:43:57 +0000184 wrmsr(MDD_LEG_IO, msr);
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000185
Edwin Beasante30db0e2010-02-09 10:22:33 +0000186 /* Bit 1 = DEVEN (device enable)
187 * Bit 4 = EN_BANKS (allow access to the upper banks)
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000188 */
189 msr.lo = (1 << 4) | (1 << 1);
190 msr.hi = 0;
191
Edwin Beasante30db0e2010-02-09 10:22:33 +0000192 /* Enable COM1. */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000193 wrmsr(MDD_UART1_CONF, msr);
Ronald G. Minnich2f198002006-04-23 19:21:12 +0000194}
195
Stefan Reinauer720297c2010-04-02 22:11:20 +0000196static void cs5536_setup_onchipuart2(void)
Edwin Beasante30db0e2010-02-09 10:22:33 +0000197{
198 msr_t msr;
199
200 /* GPIO4 - UART2_TX */
201 /* Set: Output Enable (0x4) */
202 outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
203 /* Set: OUTAUX1 Select (0x10) */
204 outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
205 /* GPIO4 - UART2_RX */
206 /* Set: Input Enable (0x20) */
207 outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
208 /* Set: INAUX1 Select (0x34) */
209 outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
210
211 /* Set: GPIO 3 + 3 Pull Up (0x18) */
212 outl(GPIOL_3_SET | GPIOL_4_SET,
213 GPIO_IO_BASE + GPIOL_PULLUP_ENABLE);
214
215 /* set address to 2F8 */
216 msr = rdmsr(MDD_LEG_IO);
217 msr.lo |= 0x5 << 20;
218 wrmsr(MDD_LEG_IO, msr);
219
220 /* Bit 1 = DEVEN (device enable)
221 * Bit 4 = EN_BANKS (allow access to the upper banks
222 */
223 msr.lo = (1 << 4) | (1 << 1);
224 msr.hi = 0;
225
226 /* enable COM2 */
227 wrmsr(MDD_UART2_CONF, msr);
228}
229
230void cs5536_setup_onchipuart(int uart)
231{
232 switch (uart) {
233 case 1:
234 cs5536_setup_onchipuart1();
235 break;
236 case 2:
237 cs5536_setup_onchipuart2();
238 break;
239 }
240}
241
242
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000243/* note: you can't do prints in here in most cases,
244 * and we don't want to hang on serial, so they are
245 * commented out
Ronald G. Minnich1656c182006-05-05 03:54:31 +0000246 */
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000247static void cs5536_early_setup(void)
Li-Ta Lo5d698962006-04-20 21:31:47 +0000248{
249 msr_t msr;
250
251 cs5536_setup_extmsr();
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000252 cs5536_setup_cis_mode();
Li-Ta Lo5d698962006-04-20 21:31:47 +0000253
254 msr = rdmsr(GLCP_SYS_RSTPLL);
255 if (msr.lo & (0x3f << 26)) {
256 /* PLL is already set and we are reboot from PLL reset */
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800257 //printk(BIOS_DEBUG, "reboot from BIOS reset\n");
Li-Ta Lo5d698962006-04-20 21:31:47 +0000258 return;
259 }
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800260 //printk(BIOS_DEBUG, "Setup idsel\n");
Li-Ta Lo5d698962006-04-20 21:31:47 +0000261 cs5536_setup_idsel();
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800262 //printk(BIOS_DEBUG, "Setup iobase\n");
Li-Ta Lo5d698962006-04-20 21:31:47 +0000263 cs5536_usb_swapsif();
264 cs5536_setup_iobase();
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800265 //printk(BIOS_DEBUG, "Setup gpio\n");
Li-Ta Lo5d698962006-04-20 21:31:47 +0000266 cs5536_setup_gpio();
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800267 //printk(BIOS_DEBUG, "Setup smbus\n");
Li-Ta Lo5d698962006-04-20 21:31:47 +0000268 cs5536_enable_smbus();
Stefan Reinauer5ab52dd2015-01-05 13:01:01 -0800269 //printk(BIOS_DEBUG, "Setup power button\n");
Marc Jonesa67d4fd2007-05-04 19:05:36 +0000270 cs5536_setup_power_button();
Li-Ta Lo5d698962006-04-20 21:31:47 +0000271}