Please bear with me - another rename checkin. This qualifies as trivial, no
[coreboot.git] / src / southbridge / amd / cs5536 / 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 << 
37                         (unsigned char)((CS5536_GLINK_PORT_NUM - 1) * 8);
38         } else {
39                 msr.hi = CS5536_DEV_NUM << 
40                         (unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
41         }
42         wrmsr(GLPCI_ExtMSR, msr);
43 }
44
45 static void cs5536_setup_idsel(void)
46 {
47         /* write IDSEL to the write once register at address 0x0000 */
48         outl(0x1 << (CS5536_DEV_NUM + 10), 0);
49 }
50
51 static void cs5536_usb_swapsif(void)
52 {
53         msr_t msr;
54
55         msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
56         //USB Serial short detect bit.
57         if (msr.hi & 0x10) {
58                 /* We need to preserve bits 32,33,35 and not clear any BIST
59                  * error, but clear the SERSHRT error bit */
60
61                 msr.hi &= 0xFFFFFFFB;
62                 wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
63         }
64 }
65
66 static void cs5536_setup_iobase(void)
67 {
68         msr_t msr;
69         /* setup LBAR for SMBus controller */
70         msr.hi = 0x0000f001;
71         msr.lo = SMBUS_IO_BASE;
72         wrmsr(MDD_LBAR_SMB, msr);
73
74         /* setup LBAR for GPIO */
75         msr.hi = 0x0000f001;
76         msr.lo = GPIO_IO_BASE;
77         wrmsr(MDD_LBAR_GPIO, msr);
78
79         /* setup LBAR for MFGPT */
80         msr.hi = 0x0000f001;
81         msr.lo = MFGPT_IO_BASE;
82         wrmsr(MDD_LBAR_MFGPT, msr);
83
84         /* setup LBAR for ACPI */
85         msr.hi = 0x0000f001;
86         msr.lo = ACPI_IO_BASE;
87         wrmsr(MDD_LBAR_ACPI, msr);
88
89         /* setup LBAR for PM Support */
90         msr.hi = 0x0000f001;
91         msr.lo = PMS_IO_BASE;
92         wrmsr(MDD_LBAR_PMS, msr);
93 }
94
95 static void cs5536_setup_power_button(void)
96 {
97         /*      Power Button Setup */
98         outl(0x40020000, PMS_IO_BASE + 0x40);
99
100         /* setup WORK_AUX/GPIO24, it is the external signal for 5536
101          * vsb_work_aux controls all voltage rails except Vstandby & Vmem.
102          * We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
103          * If WORK_AUX/GPIO24 is not enabled then soft-off will not work.
104          */
105         outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUT_AUX1_SELECT);
106         outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUTPUT_ENABLE);
107
108 }
109
110 static void cs5536_setup_gpio(void)
111 {
112         uint32_t val;
113
114         /* setup GPIO pins 14/15 for SDA/SCL */
115         val = GPIOL_15_SET | GPIOL_14_SET;
116         /* Output Enable */
117         outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
118         /* Output AUX1 */
119         outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
120         /* Input Enable */
121         outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
122         /* Input AUX1 */
123         outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
124 }
125
126 static void cs5536_disable_internal_uart(void)
127 {
128         msr_t msr;
129         /* The UARTs default to enabled.
130          * Disable and reset them and configure them later. (SIO init)
131          */
132         msr = rdmsr(MDD_UART1_CONF);
133         msr.lo = 1;             // reset
134         wrmsr(MDD_UART1_CONF, msr);
135         msr.lo = 0;             // disabled
136         wrmsr(MDD_UART1_CONF, msr);
137
138         msr = rdmsr(MDD_UART2_CONF);
139         msr.lo = 1;             // reset
140         wrmsr(MDD_UART2_CONF, msr);
141         msr.lo = 0;             // disabled
142         wrmsr(MDD_UART2_CONF, msr);
143 }
144
145 static void cs5536_setup_cis_mode(void)
146 {
147         msr_t msr;
148
149         /* setup CPU interface serial to mode B to match CPU */
150         msr = rdmsr(GLPCI_SB_CTRL);
151         msr.lo &= ~0x18;
152         msr.lo |= 0x10;
153         wrmsr(GLPCI_SB_CTRL, msr);
154 }
155
156 /* see page 412 of the cs5536 companion book */
157 static void cs5536_setup_onchipuart(void)
158 {
159         msr_t msr;
160
161         /* Setup early for polling only mode.
162          * 1. Eanble GPIO 8 to OUT_AUX1, 9 to IN_AUX1
163          *        GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
164          * 2. Enable UART IO space in MDD
165          *        MSR 0x51400014 bit 18:16
166          * 3. Enable UART controller
167          *        MSR 0x5140003A bit 0, 1
168          */
169
170         /* GPIO8 - UART1_TX */
171         /* Set: Output Enable  (0x4) */
172         outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
173         /* Set: OUTAUX1 Select (0x10) */
174         outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
175         /* GPIO9 - UART1_RX */
176         /* Set: Input Enable   (0x20) */
177         outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
178         /* Set: INAUX1 Select  (0x34) */
179         outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
180
181         /* set address to 3F8 */
182         msr = rdmsr(MDD_LEG_IO);
183         msr.lo |= 0x7 << 16;
184         wrmsr(MDD_LEG_IO, msr);
185
186         /*      Bit 1 = DEVEN (device enable)
187          *      Bit 4 = EN_BANKS (allow access to the upper banks
188          */
189         msr.lo = (1 << 4) | (1 << 1);
190         msr.hi = 0;
191
192         /* enable COM1 */
193         wrmsr(MDD_UART1_CONF, msr);
194 }
195
196 /* note: you can't do prints in here in most cases,
197  * and we don't want to hang on serial, so they are
198  * commented out
199  */
200 static void cs5536_early_setup(void)
201 {
202         msr_t msr;
203
204         cs5536_setup_extmsr();
205         cs5536_setup_cis_mode();
206
207         msr = rdmsr(GLCP_SYS_RSTPLL);
208         if (msr.lo & (0x3f << 26)) {
209                 /* PLL is already set and we are reboot from PLL reset */
210                 //print_debug("reboot from BIOS reset\n\r");
211                 return;
212         }
213         //print_debug("Setup idsel\r\n");
214         cs5536_setup_idsel();
215         //print_debug("Setup iobase\r\n");
216         cs5536_usb_swapsif();
217         cs5536_setup_iobase();
218         //print_debug("Setup gpio\r\n");
219         cs5536_setup_gpio();
220         //print_debug("Setup smbus\r\n");
221         cs5536_enable_smbus();
222         //print_debug("Setup power button\r\n");
223         cs5536_setup_power_button();
224 }