blob: 3bd73f7c9cea79f04e00c3bda156806c8c0c7bdf [file] [log] [blame]
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +00001#include <console/console.h>
2#include <arch/io.h>
3#include <stdint.h>
4#include <device/device.h>
5#include <device/pci.h>
6#include <device/pci_ids.h>
7#include <stdlib.h>
8#include <string.h>
9#include <bitops.h>
10#include "chip.h"
11#include "northbridge.h"
12#include <cpu/amd/gx2def.h>
13#include <cpu/x86/msr.h>
14#include <cpu/x86/cache.h>
15
16
17/* the structs in this file only set msr.lo. But ... that may not always be true */
18
19struct msrinit {
20 unsigned long msrnum;
21 msr_t msr;
22};
23
24/* Master Configuration Register for Bus Masters.*/
25struct msrinit SB_MASTER_CONF_TABLE[] = {
26 {USB1_SB_GLD_MSR_CONF, {.hi=0,.lo=0x00008f000}}, /* NOTE: Must be 1st entry in table*/
27 {USB2_SB_GLD_MSR_CONF, {.hi=0,.lo=0x00008f000}},
28 {ATA_SB_GLD_MSR_CONF, {.hi=0,.lo=0x00048f000}},
29 {AC97_SB_GLD_MSR_CONF, {.hi=0,.lo=0x00008f000}},
30 {MDD_SB_GLD_MSR_CONF, {.hi=0,.lo=0x00000f000}},
31/* GLPCI_SB_GLD_MSR_CONF, 0x0FFFFFFFF*/
32/* GLCP_SB_GLD_MSR_CONF, 0x0FFFFFFFF*/
33/* GLIU_SB_GLD_MSR_CONF, 0x0*/
34 {0,{0,0}}
35};
36
37/* 5535_A3 Clock Gating*/
38struct msrinit CS5535_CLOCK_GATING_TABLE[] = {
39 { USB1_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
40 { USB2_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
41 { GLIU_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000004}},
42 { GLPCI_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
43 { GLCP_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000004}},
44 { MDD_SB_GLD_MSR_PM, {.hi=0,.lo=0x050554111}},
45 { ATA_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
46 { AC97_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
47 {0,{0,0}}
48};
49
50/* 5536 Clock Gating*/
51struct msrinit CS5536_CLOCK_GATING_TABLE[] = {
52/* MSR Setting*/
53 { GLIU_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000004}},
54 { GLPCI_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
55 { GLCP_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000004}},
Ronald G. Minnichfb937492006-06-10 22:57:15 +000056 { MDD_SB_GLD_MSR_PM, {.hi=0,.lo=0x050554111}}, /* SMBus clock gating errata (PBZ 2226 & SiBZ 3977)*/
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +000057 { ATA_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
58 { AC97_SB_GLD_MSR_PM, {.hi=0,.lo=0x000000005}},
59 {0,{0,0}}
60};
61
62struct acpiinit {
63 unsigned short ioreg;
64 unsigned long regdata;
65 unsigned short iolen;
66};
67
68struct acpiinit acpi_init_table[] = {
69 {ACPI_BASE+0x00, 0x01000000, 4},
70 {ACPI_BASE+0x08, 0, 4},
71 {ACPI_BASE+0x0C, 0, 4},
72 {ACPI_BASE+0x1C, 0, 4},
73 {ACPI_BASE+0x18, 0x0FFFFFFFF, 4},
74 {ACPI_BASE+0x00, 0x0000FFFF, 4},
75
76 {PM_SCLK, 0x000000E00, 4},
77 {PM_SED, 0x000004601, 4},
78 {PM_SIDD, 0x000008C02, 4},
79 {PM_WKD, 0x0000000A0, 4},
80 {PM_WKXD, 0x0000000A0, 4},
81 {0,0,0}
82};
83
84/* return 1 if we are a 5536-based system */
85static int is_5536(void){
86 msr_t msr;
87 msr = rdmsr(GLIU_SB_GLD_MSR_CAP);
88 msr.lo >>= 20;
89 printk_debug("is_5536: msr.lo is 0x%x(==5 means 5536)\n", msr.lo&0xf);
90 return ((msr.lo&0xf) == 5);
91}
92/* ***************************************************************************/
93/* **/
94/* * pmChipsetInit*/
95/* **/
96/* * Program ACPI LBAR and initialize ACPI registers.*/
97/* * */
98/* **/
99/* * Entry:*/
100/* * None*/
101/* **/
102/* * Exit:*/
103/* * None*/
104/* **/
105/* * Destroys:*/
106/* * None*/
107/* **/
108/* ***************************************************************************/
109static void
110pmChipsetInit(void) {
111 unsigned long val = 0;
112 unsigned short port;
113
114 port = (PMLogic_BASE + 0x010);
115 val = 0x0E00 ; /* 1ms*/
116 outl(val, port);
117
118 /* PM_WKXD*/
119 /* Make sure bits[3:0]=0000b to clear the*/
120 /* saved Sx state*/
121 port = (PMLogic_BASE + 0x034);
122 val = 0x0A0 ; /* 5ms*/
123 outl(val, port);
124
125 /* PM_WKD*/
126 port = (PMLogic_BASE + 0x030);
127 outl(val, port);
128
129 /* PM_SED*/
130 port = (PMLogic_BASE + 0x014);
131/* mov eax, 0x057642 ; 100ms, works*/
132 val = 0x04601 ; /* 5ms*/
133 outl(val, port);
134
135 /* PM_SIDD*/
136 port = (PMLogic_BASE + 0x020);
137/* mov eax, 0x0AEC84 ; 200ms, works*/
138 val = 0x08C02 ; /* 10ms*/
139 outl(val, port);
140
141 /* GPIO24 OUT_AUX1 function is the external signal for 5535's vsb_working_aux*/
142 /* which is de-asserted when 5535 enters Standby(S3 or S5) state.*/
143 /* On Hawk, GPIO24 controls all voltage rails except Vmem and Vstandby. This means*/
144 /* GX2 will be fully de-powered if this control de-asserts in S3/S5.*/
145 /* */
146 /* GPIO24 is setup in preChipsetInit for two reasons*/
147 /* 1. GPIO24 at reset defaults to disabled, since this signal is vsb_work_aux on*/
148 /* Hawk it controls the FET's for all voltage rails except Vstanby & Vmem.*/
149 /* BIOS needs to enable GPIO24 as OUT_AUX1 & OUTPUT_EN early so it is driven*/
150 /* by 5535.*/
151 /* 2. Non-PM builds will require GPIO24 enabled for instant-off power button*/
152 /* */
153
154 /* GPIO11 OUT_AUX1 function is the external signal for 5535's slp_clk_n which is asserted*/
155 /* when 5535 enters Sleep(S1) state.*/
156 /* On Hawk, GPIO11 is connected to control input of external clock generator*/
157 /* for 14MHz, PCI, USB & LPC clocks.*/
158 /* Programming of GPIO11 will be done by VSA PM code. During VSA Init. BIOS writes*/
159 /* PM Core Virual Register indicating if S1 Clocks should be On or Off. This is based*/
160 /* on a Setup item. We do not want to leave GPIO11 enabled because of a Hawk board*/
161 /* problem. With GPIO11 enabled in S3, something is back-driving GPIO11 causing it to*/
162 /* float to 1.6-1.7V.*/
163
164}
165
Ronald G. Minnichda7ee9f2006-07-21 19:21:38 +0000166struct FLASH_DEVICE {
167 unsigned char fType; /* Flash type: NOR or NAND */
168 unsigned char fInterface; /* Flash interface: I/O or Memory */
169 unsigned long fMask; /* Flash size/mask */
170};
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000171
Ronald G. Minnichda7ee9f2006-07-21 19:21:38 +0000172struct FLASH_DEVICE FlashInitTable[] = {
173 { FLASH_TYPE_NAND, FLASH_IF_MEM, FLASH_MEM_4K }, /* CS0, or Flash Device 0 */
174 { FLASH_TYPE_NONE, 0, 0 }, /* CS1, or Flash Device 1 */
175 { FLASH_TYPE_NONE, 0, 0 }, /* CS2, or Flash Device 2 */
176 { FLASH_TYPE_NONE, 0, 0 }, /* CS3, or Flash Device 3 */
177};
178
179#define FlashInitTableLen (sizeof(FlashInitTable)/sizeof(FlashInitTable[0]))
180
181uint32_t FlashPort[] = {
182 MDD_LBAR_FLSH0,
183 MDD_LBAR_FLSH1,
184 MDD_LBAR_FLSH2,
185 MDD_LBAR_FLSH3
186 };
187
188/***************************************************************************
189 *
190 * ChipsetFlashSetup
191 *
192 * Flash LBARs need to be setup before VSA init so the PCI BARs have
193 * correct size info. Call this routine only if flash needs to be
194 * configured (don't call it if you want IDE).
195 *
196 * Entry:
197 * Exit:
198 * Destroys:
199 *
200 **************************************************************************/
201static void ChipsetFlashSetup(void)
202{
203 msr_t msr;
204 int i;
205 int numEnabled = 0;
206
207 printk_debug("ChipsetFlashSetup++\n");
208 for (i = 0; i < FlashInitTableLen; i++) {
209 if (FlashInitTable[i].fType != FLASH_TYPE_NONE) {
210 printk_debug("Enable CS%d\n", i);
211 /* we need to configure the memory/IO mask */
212 msr = rdmsr(FlashPort[i]);
213 msr.hi = 0; /* start with the "enabled" bit clear */
214 if (FlashInitTable[i].fType == FLASH_TYPE_NAND)
215 msr.hi |= 0x00000002;
216 else
217 msr.hi &= ~0x00000002;
218 if (FlashInitTable[i].fInterface == FLASH_IF_MEM)
219 msr.hi |= 0x00000004;
220 else
221 msr.hi &= ~0x00000004;
222 msr.hi |= FlashInitTable[i].fMask;
223 printk_debug("WRMSR(0x%08X, %08X_%08X)\n", FlashPort[i], msr.hi, msr.lo);
224 wrmsr(FlashPort[i], msr);
225
226 /* now write-enable the device */
227 msr = rdmsr(MDD_NORF_CNTRL);
228 msr.lo |= (1 << i);
229 printk_debug("WRMSR(0x%08X, %08X_%08X)\n", MDD_NORF_CNTRL, msr.hi, msr.lo);
230 wrmsr(MDD_NORF_CNTRL, msr);
231
232 /* update the number enabled */
233 numEnabled++;
234 }
235 }
236
237 /* enable the flash */
238 if (0 != numEnabled) {
239 msr = rdmsr(MDD_PIN_OPT);
240 msr.lo &= ~1; /* PIN_OPT_IDE */
241 printk_debug("WRMSR(0x%08X, %08X_%08X)\n", MDD_PIN_OPT, msr.hi, msr.lo);
242 wrmsr(MDD_PIN_OPT, msr);
243 }
244 printk_debug("ChipsetFlashSetup--\n");
245
246}
247
248
249
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000250/* ***************************************************************************/
251/* **/
252/* * ChipsetGeodeLinkInit*/
253/* * Handle chipset specific GeodeLink settings here. */
254/* * Called from GeodeLink init code.*/
255/* **/
256/* * Entry:*/
257/* * Exit:*/
258/* * Destroys: GS*/
259/* **/
260/* ***************************************************************************/
261static void
262ChipsetGeodeLinkInit(void){
263 msr_t msr;
264 unsigned long msrnum;
265 unsigned long totalmem;
266
267 if (is_5536())
268 return;
269 /* SWASIF for A1 DMA */
270 /* Set all memory to "just above systop" PCI so DMA will work*/
271 /* check A1*/
272 msrnum = MSR_SB_GLCP + 0x17;
273 msr = rdmsr(msrnum);
274 if ((msr.lo&0xff) == 0x11)
275 return;
276
277 totalmem = sizeram() << 20 - 1;
278 totalmem >>= 12;
279 totalmem = ~totalmem;
280 totalmem &= 0xfffff;
281 msr.lo = totalmem;
282 msr.hi = 0x20000000; /* Port 1 (PCI)*/
283 msrnum = MSR_SB_GLIU + 0x20; /* */;
284 wrmsr(msrnum, msr);
285}
286
287void
Ronald G. Minnichda7ee9f2006-07-21 19:21:38 +0000288chipsetinit (struct northbridge_amd_gx2_config *nb){
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000289 msr_t msr;
290 struct msrinit *csi;
291 int i;
292 unsigned long msrnum;
293
294 outb( P80_CHIPSET_INIT, 0x80);
295 ChipsetGeodeLinkInit();
Li-Ta Lod8d8fff2006-04-13 17:00:38 +0000296#if 0
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000297 /* we hope NEVER to be in linuxbios when S3 resumes
298 if (! IsS3Resume()) */
299 {
300 struct acpiinit *aci = acpi_init_table;
301 while (aci->ioreg){
302 if (aci->iolen == 2) {
303 outw(aci->regdata, aci->ioreg);
304 inw(aci->ioreg);
305 } else {
306 outl(aci->regdata, aci->ioreg);
307 inl(aci->ioreg);
308 }
309 }
310
311 pmChipsetInit();
312 }
Li-Ta Lod8d8fff2006-04-13 17:00:38 +0000313#endif
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000314
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000315
Ronald G. Minnichfb937492006-06-10 22:57:15 +0000316 if (!is_5536()) {
317 /* Setup USB. Need more details. #118.18*/
318 msrnum = MSR_SB_USB1 + 8;
319 msr.lo = 0x00012090;
320 msr.hi = 0;
321 wrmsr(msrnum, msr);
322 msrnum = MSR_SB_USB2 + 8;
323 wrmsr(msrnum, msr);
324 }
325
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000326 /* set hd IRQ */
327 outl (GPIOL_2_SET, GPIOL_INPUT_ENABLE);
328 outl (GPIOL_2_SET, GPIOL_IN_AUX1_SELECT);
329
330 /* Allow IO read and writes during a ATA DMA operation.*/
331 /* This could be done in the HD rom but do it here for easier debugging.*/
332
333 msrnum = ATA_SB_GLD_MSR_ERR;
334 msr = rdmsr(msrnum);
335 msr.lo &= ~0x100;
336 wrmsr(msrnum, msr);
337
Li-Ta Lod8d8fff2006-04-13 17:00:38 +0000338 /* Enable Post Primary IDE.*/
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000339 msrnum = GLPCI_SB_CTRL;
340 msr = rdmsr(msrnum);
341 msr.lo |= GLPCI_CRTL_PPIDE_SET;
342 wrmsr(msrnum, msr);
343
344
345 /* Set up Master Configuration Register*/
346 /* If 5536, use same master config settings as 5535, except for OHCI MSRs*/
347 if (is_5536())
348 i = 2;
349 else
350 i = 0;
351
352 csi = &SB_MASTER_CONF_TABLE[i];
353 for(; csi->msrnum; csi++){
354 msr.lo = csi->msr.lo;
355 msr.hi = csi->msr.hi;
Ronald G. Minnichfb937492006-06-10 22:57:15 +0000356 wrmsr(csi->msrnum, msr); // MSR - see table above
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000357 }
358
359
360 /* Flash Setup*/
Ronald G. Minnichda7ee9f2006-07-21 19:21:38 +0000361 printk_err("%sDOING ChipsetFlashSetup()!!!!!!!!!!!!!!!!!!\n", nb->setupflash? "NOT " : "");
362 if (nb->setupflash)
363 ChipsetFlashSetup();
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000364
365
366
367 /* */
368 /* Set up Hardware Clock Gating*/
369 /* */
370 /* if (getnvram(TOKEN_SB_CLK_GATE) != TVALUE_DISABLE) */
371 {
372 if (is_5536())
373 csi = CS5536_CLOCK_GATING_TABLE;
374 else
Ronald G. Minnichfb937492006-06-10 22:57:15 +0000375 csi = CS5535_CLOCK_GATING_TABLE;
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000376
377 for(; csi->msrnum; csi++){
378 msr.lo = csi->msr.lo;
379 msr.hi = csi->msr.hi;
Ronald G. Minnichfb937492006-06-10 22:57:15 +0000380 wrmsr(csi->msrnum, msr); // MSR - see table above
Ronald G. Minnich4b8cf1d2006-04-10 23:32:23 +0000381 }
382 }
383
384}