Since some people disapprove of white space cleanups mixed in regular commits
[coreboot.git] / src / southbridge / amd / cs5535 / cs5535_early_setup.c
1 /*
2  *
3  * cs5535_early_setup.c:        Early chipset initialization for CS5535 companion device
4  *
5  *
6  * This file implements the initialization sequence documented in section 4.2 of
7  * AMD Geode GX Processor CS5535 Companion Device GoedeROM Porting Guide.
8  *
9  */
10
11 #define CS5535_GLINK_PORT_NUM   0x02    /* the geode link port number to the CS5535 */
12 #define CS5535_DEV_NUM          0x0F    /* default PCI device number for CS5535 */
13
14 /**
15  * @brief Setup PCI IDSEL for CS5535
16  *
17  *
18  */
19
20 static void cs5535_setup_extmsr(void)
21 {
22         msr_t msr;
23
24         /* forward MSR access to CS5535_GLINK_PORT_NUM to CS5535_DEV_NUM */
25         msr.hi = msr.lo = 0x00000000;
26 #if CS5535_GLINK_PORT_NUM <= 4
27         msr.lo = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 1) * 8);
28 #else
29         msr.hi = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 5) * 8);
30 #endif
31         wrmsr(0x5000201e, msr);
32 }
33
34 static void cs5535_setup_idsel(void)
35 {
36         /* write IDSEL to the write once register at address 0x0000 */
37         outl(0x1 << (CS5535_DEV_NUM + 10), 0);
38 }
39
40 static void cs5535_usb_swapsif(void)
41 {
42         msr_t msr;
43
44         msr = rdmsr(0x51600005);
45         //USB Serial short detect bit.
46         if (msr.hi & 0x10) {
47                 /* We need to preserve bits 32,33,35 and not clear any BIST error, but clear the
48                  * SERSHRT error bit */
49                 msr.hi &= 0xFFFFFFFB;
50                 wrmsr(0x51600005, msr);
51         }
52 }
53
54 static int cs5535_setup_iobase(void)
55 {
56         msr_t msr;
57
58         /* setup LBAR for SMBus controller */
59         __builtin_wrmsr(0x5140000b, 0x00006000, 0x0000f001);
60         /* setup LBAR for GPIO */
61         __builtin_wrmsr(0x5140000c, 0x00006100, 0x0000f001);
62         /* setup LBAR for MFGPT */
63         __builtin_wrmsr(0x5140000d, 0x00006200, 0x0000f001);
64         /* setup LBAR for ACPI */
65         __builtin_wrmsr(0x5140000e, 0x00009c00, 0x0000f001);
66         /* setup LBAR for PM Support */
67         __builtin_wrmsr(0x5140000f, 0x00009d00, 0x0000f001);
68 }
69
70 static void cs5535_setup_power_bottun(void)
71 {
72         /* not implemented yet */
73 #if 0
74         pwrBtn_setup:
75         ;
76         ;       Power Button Setup
77         ;
78         ;mov    eax, 0C0020000h                         ; 4 seconds + lock
79         mov     eax, 040020000h                         ; 4 seconds no lock
80         mov     dx, PMLogic_BASE + 40h
81         out     dx, eax
82
83         ; setup GPIO24, it is the external signal for 5535 vsb_work_aux
84         ; which controls all voltage rails except Vstandby & Vmem.
85         ; We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
86         ; If GPIO24 is not enabled then soft-off will not work.
87         mov     dx, GPIOH_OUT_AUX1_SELECT
88         mov     eax, GPIOH_24_SET
89         out     dx, eax
90         mov     dx, GPIOH_OUTPUT_ENABLE
91         out     dx, eax
92
93 #endif
94 }
95
96 static void cs5535_setup_gpio(void)
97 {
98         uint32_t val;
99
100         /* setup GPIO pins 14/15 for SDA/SCL */
101         val = (1<<14 | 1<<15);
102         /* Output Enable */
103         outl(0x3fffc000, 0x6100 + 0x04);
104         //outl(val, 0x6100 + 0x04);
105         /* Output AUX1 */
106         outl(0x3fffc000, 0x6100 + 0x10);
107         //outl(val, 0x6100 + 0x10);
108         /* Input Enable */
109         //outl(0x0f5af0a5, 0x6100 + 0x20);
110         outl(0x3fffc000, 0x6100 + 0x20);
111         //outl(val, 0x6100 + 0x20);
112         /* Input AUX1 */
113         //outl(0x3ffbc004, 0x6100 + 0x34);
114         outl(0x3fffc000, 0x6100 + 0x34);
115         //outl(val, 0x6100 + 0x34);
116 }
117
118 static void cs5535_disable_internal_uart(void)
119 {
120         /* not implemented yet */
121 #if 0
122         ; The UARTs default to enabled.
123         ; Disable and reset them and configure them later. (SIO init)
124         mov     ecx, MDD_UART1_CONF
125         RDMSR
126         mov     eax, 1h                                 ; reset
127         WRMSR
128         mov     eax, 0h                                 ; disabled
129         WRMSR
130
131         mov     ecx, MDD_UART2_CONF
132         RDMSR
133         mov     eax, 1h                                 ; reset
134         WRMSR
135         mov     eax, 0h                                 ; disabled
136         WRMSR
137
138 #endif
139 }
140
141 static void cs5535_setup_cis_mode(void)
142 {
143         msr_t msr;
144
145         /* setup CPU interface serial to mode C on both sides */
146         msr = __builtin_rdmsr(0x51000010);
147         msr.lo &= ~0x18;
148         msr.lo |= 0x10;
149         __builtin_wrmsr(0x51000010, msr.lo, msr.hi);
150         //Only do this if we are building for 5535
151         __builtin_wrmsr(0x54002010, 0x00000002, 0x00000000);
152 }
153
154 static void dummy(void)
155 {
156 }
157
158 static int cs5535_early_setup(void)
159 {
160         msr_t msr;
161
162         cs5535_setup_extmsr();
163
164         msr = rdmsr(GLCP_SYS_RSTPLL);
165         if (msr.lo & (0x3f << 26)) {
166                 /* PLL is already set and we are reboot from PLL reset */
167                 print_debug("reboot from BIOS reset\n");
168                 return;
169         }
170         print_debug("Setup idsel\n");
171         cs5535_setup_idsel();
172         print_debug("Setup iobase\n");
173         cs5535_usb_swapsif();
174         cs5535_setup_iobase();
175         print_debug("Setup gpio\n");
176         cs5535_setup_gpio();
177         print_debug("Setup cis_mode\n");
178         cs5535_setup_cis_mode();
179         print_debug("Setup smbus\n");
180         cs5535_enable_smbus();
181         dummy();
182 }