4e0d3295127a5d1b3277aa262c2661bb815c3bbd
[coreboot.git] / src / northbridge / amd / lx / chipsetinit.c
1 #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/lxdef.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
19 struct msrinit {
20         unsigned long msrnum;
21         msr_t msr;
22 };
23
24 /*  Master Configuration Register for Bus Masters.*/
25 struct 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*/
38 struct 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*/
51 struct 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}},
56         {      MDD_SB_GLD_MSR_PM,       {.hi=0,.lo=0x050554111}}, /*  SMBus clock gating errata (PBZ 2226 & SiBZ 3977)*/
57         {      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
62 struct acpiinit {
63         unsigned short ioreg; 
64         unsigned long regdata;
65         unsigned short iolen;
66 };
67
68 struct 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 */
85 static 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 /* ***************************************************************************/
109 static void
110 pmChipsetInit(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
166 struct 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 };
171
172 struct 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
181 uint32_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  **************************************************************************/
201 static 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  
250 /* ***************************************************************************/
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 /* ***************************************************************************/
261 static void 
262 ChipsetGeodeLinkInit(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
287 void
288 chipsetinit (struct northbridge_amd_lx_config *nb){
289         msr_t msr;
290         struct msrinit *csi;
291         int i;
292         unsigned long msrnum;
293
294         outb( P80_CHIPSET_INIT, 0x80);
295         ChipsetGeodeLinkInit();
296 #if 0
297         /* 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         }
313 #endif
314
315
316         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         
326         /* 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
338         /*  Enable Post Primary IDE.*/
339         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;
356                 wrmsr(csi->msrnum, msr); // MSR - see table above
357         }
358
359
360         /*  Flash Setup*/
361         printk_err("%sDOING ChipsetFlashSetup()!!!!!!!!!!!!!!!!!!\n", nb->setupflash? " " : "NOT");
362         if (nb->setupflash)
363                 ChipsetFlashSetup();
364
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
375                         csi = CS5535_CLOCK_GATING_TABLE;
376
377                 for(; csi->msrnum; csi++){
378                         msr.lo = csi->msr.lo;
379                         msr.hi = csi->msr.hi;
380                         wrmsr(csi->msrnum, msr);        // MSR - see table above
381                 }
382         }
383
384 }