Change fadt revision back to 3.
[coreboot.git] / src / southbridge / amd / sb800 / early_setup.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2010 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 as published by
8  * the Free Software Foundation; version 2 of the License.
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 #ifndef  _SB800_EARLY_SETUP_C_
21 #define  _SB800_EARLY_SETUP_C_
22
23 #include <reset.h>
24 #include <arch/cpu.h>
25 #include <cbmem.h>
26 #include "sb800.h"
27 #include "smbus.c"
28
29 #define SMBUS_IO_BASE 0x6000    /* Is it a temporary SMBus I/O base address? */
30          /*SIZE 0x40 */
31
32 static void pmio_write(u8 reg, u8 value)
33 {
34         outb(reg, PM_INDEX);
35         outb(value, PM_INDEX + 1);
36 }
37
38 static u8 pmio_read(u8 reg)
39 {
40         outb(reg, PM_INDEX);
41         return inb(PM_INDEX + 1);
42 }
43
44 static void sb800_acpi_init(void) {
45         pmio_write(0x60, ACPI_PM_EVT_BLK & 0xFF);
46         pmio_write(0x61, ACPI_PM_EVT_BLK >> 8);
47         pmio_write(0x62, ACPI_PM1_CNT_BLK & 0xFF);
48         pmio_write(0x63, ACPI_PM1_CNT_BLK >> 8);
49         pmio_write(0x64, ACPI_PM_TMR_BLK & 0xFF);
50         pmio_write(0x65, ACPI_PM_TMR_BLK >> 8);
51         pmio_write(0x68, ACPI_GPE0_BLK & 0xFF);
52         pmio_write(0x69, ACPI_GPE0_BLK >> 8);
53
54         /* CpuControl is in \_PR.CPU0, 6 bytes */
55         pmio_write(0x66, ACPI_CPU_CONTROL & 0xFF);
56         pmio_write(0x67, ACPI_CPU_CONTROL >> 8);
57
58         pmio_write(0x6A, 0xB0); /* AcpiSmiCmdLo */
59         pmio_write(0x6B, 0);    /* AcpiSmiCmdHi */
60
61         pmio_write(0x6E, 0xB8); /* AcpiPmaCntBlkLo */
62         pmio_write(0x6F, 0);    /* AcpiPmaCntBlkHi */
63
64         pmio_write(0x6C, ACPI_PMA_CNT_BLK & 0xFF);
65         pmio_write(0x6D, ACPI_PMA_CNT_BLK >> 8);
66
67         pmio_write(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2); /* AcpiDecodeEnable, When set, SB uses
68                                         * the contents of the PM registers at
69                                         * index 60-6B to decode ACPI I/O address.
70                                         * AcpiSmiEn & SmiCmdEn*/
71         /* RTC_En_En, TMR_En_En, GBL_EN_EN */
72         outl(0x1, ACPI_PM1_CNT_BLK);              /* set SCI_EN */
73 }
74
75 /* RPR 2.28 Get SB ASIC Revision.*/
76 static u8 get_sb800_revision(void)
77 {
78         device_t dev;
79         u8 rev_id;
80         u8 rev = 0;
81
82         /* if (rev != 0) return rev; */
83
84         dev = PCI_DEV(0, 0x14, 0);//pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
85
86         if (dev == PCI_DEV_INVALID) {
87                 die("SMBUS controller not found\n");
88                 /* NOT REACHED */
89         }
90         rev_id =  pci_read_config8(dev, 0x08);
91
92         if (rev_id == 0x40) {
93                 rev = REV_SB800_A11;
94         } else if (rev_id == 0x41) {
95                 rev = REV_SB800_A12;
96         } else {
97                 die("It is not SB800 or SB810\r\n");
98         }
99
100         return rev;
101 }
102
103 void sb800_clk_output_48Mhz(void)
104 {
105         /* AcpiMMioDecodeEn */
106         u8 reg8;
107         reg8 = pmio_read(0x24);
108         reg8 |= 1;
109         reg8 &= ~(1 << 1);
110         pmio_write(0x24, reg8);
111
112         *(volatile u32 *)(0xFED80000+0xE00+0x40) &= ~((1 << 0) | (1 << 2)); /* 48Mhz */
113         *(volatile u32 *)(0xFED80000+0xE00+0x40) |= 1 << 1; /* 48Mhz */
114 }
115 /***************************************
116 * Legacy devices are mapped to LPC space.
117 *       Serial port 0
118 *       KBC Port
119 *       ACPI Micro-controller port
120 *       LPC ROM size
121 *       This function does not change port 0x80 decoding.
122 *       Console output through any port besides 0x3f8 is unsupported.
123 *       If you use FWH ROMs, you have to setup IDSEL.
124 ***************************************/
125 static void sb800_lpc_init(void)
126 {
127         u8 reg8;
128         device_t dev;
129
130         //dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);   /* SMBUS controller */
131         dev = PCI_DEV(0, 0x14, 0);
132         /* NOTE: Set BootTimerDisable, otherwise it would keep rebooting!!
133          * This bit has no meaning if debug strap is not enabled. So if the
134          * board keeps rebooting and the code fails to reach here, we could
135          * disable the debug strap first. */
136         reg8 = pmio_read(0x44+3);
137         reg8 |= 1 << 7;
138         pmio_write(0x44+3, reg8);
139
140         /* Enable lpc controller */
141         reg8 = pmio_read(0xEC);
142         reg8 |= 1 << 0;
143         pmio_write(0xEC, reg8);
144
145         dev = PCI_DEV(0, 0x14, 3);//pci_locate_device(PCI_ID(0x1002, 0x439d), 0);       /* LPC Controller */
146         /* Decode port 0x3f8-0x3ff (Serial 0) */
147         //#warning Serial port decode on LPC is hardcoded to 0x3f8
148         reg8 = pci_read_config8(dev, 0x44);
149         reg8 |= 1 << 6;
150         pci_write_config8(dev, 0x44, reg8);
151
152         /* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
153         reg8 = pci_read_config8(dev, 0x47);
154         reg8 |= (1 << 5) | (1 << 6);
155         pci_write_config8(dev, 0x47, reg8);
156
157         /* SuperIO, LPC ROM */
158         reg8 = pci_read_config8(dev, 0x48);
159         /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
160         reg8 |= (1 << 1) | (1 << 0);
161         /* Decode variable LPC ROM address ranges 1&2 (see register 0x68-0x6b, 0x6c-0x6f) */
162         reg8 |= (1 << 3) | (1 << 4);
163         /* Decode port 0x70-0x73 (RTC) */
164         reg8 |= 1 << 6;
165         pci_write_config8(dev, 0x48, reg8);
166 }
167
168 /* what is its usage? */
169 static u32 get_sbdn(u32 bus)
170 {
171         device_t dev;
172
173         /* Find the device. */
174         dev = PCI_DEV(bus, 0x14, 0);//pci_locate_device_on_bus(PCI_ID(0x1002, 0x4385), bus);
175         return (dev >> 15) & 0x1f;
176 }
177
178 static u8 dual_core(void)
179 {
180         return (pci_read_config32(PCI_DEV(0, 0x18, 3), 0xE8) & (0x3<<12)) != 0;
181 }
182
183 /*
184  * RPR 2.6 C-state and VID/FID change for the K8 platform.
185  */
186 static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
187 {
188         u8 byte;
189         byte = pmio_read(0x80);
190         if (dual_core())
191                 byte |= 1 << 2 | 1 << 1;
192         byte |= 1 << 3;
193         byte |= 1 << 4;
194         byte &= ~(1 << 7);
195         pmio_write(0x80, byte);
196
197         byte = pmio_read(0x7E);
198         byte |= 1 << 6;
199         byte &= ~(1 << 2);
200         pmio_write(0x7E, byte);
201
202         pmio_write(0x94, 0x01);
203
204         byte = pmio_read(0x89);
205         byte |= 1 << 4;
206         pmio_write(0x89, byte);
207
208         byte = pmio_read(0x9b);
209         byte &= ~(7 << 4);
210         byte |= 1 << 4;
211         pmio_write(0x9b, byte);
212
213         pmio_write(0x99, 0x10);
214
215         pmio_write(0x9A, 0x00);
216         pmio_write(0x96, 0x10);
217         pmio_write(0x97, 0x00);
218
219         byte = pmio_read(0x81);
220         byte &= ~(1 << 1);
221         pmio_write(0x81, byte);
222 }
223
224 void hard_reset(void)
225 {
226         set_bios_reset();
227
228         /* full reset */
229         outb(0x0a, 0x0cf9);
230         outb(0x0e, 0x0cf9);
231 }
232
233 void soft_reset(void)
234 {
235         set_bios_reset();
236         /* link reset */
237         outb(0x06, 0x0cf9);
238 }
239
240 void sb800_pci_port80(void)
241 {
242         u8 byte;
243         device_t dev;
244
245         /* P2P Bridge */
246         dev = PCI_DEV(0, 0x14, 4);//pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
247
248         /* Chip Control: Enable subtractive decoding */
249         byte = pci_read_config8(dev, 0x40);
250         byte |= 1 << 5;
251         pci_write_config8(dev, 0x40, byte);
252
253         /* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
254         byte = pci_read_config8(dev, 0x4B);
255         byte |= 1 << 7;
256         pci_write_config8(dev, 0x4B, byte);
257
258         /* The same IO Base and IO Limit here is meaningful because we set the
259          * bridge to be subtractive. During early setup stage, we have to make
260          * sure that data can go through port 0x80.
261          */
262         /* IO Base: 0xf000 */
263         byte = pci_read_config8(dev, 0x1C);
264         byte |= 0xF << 4;
265         pci_write_config8(dev, 0x1C, byte);
266
267         /* IO Limit: 0xf000 */
268         byte = pci_read_config8(dev, 0x1D);
269         byte |= 0xF << 4;
270         pci_write_config8(dev, 0x1D, byte);
271
272         /* PCI Command: Enable IO response */
273         byte = pci_read_config8(dev, 0x04);
274         byte |= 1 << 0;
275         pci_write_config8(dev, 0x04, byte);
276
277         /* LPC controller */
278         dev = PCI_DEV(0, 0x14, 3);;//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
279
280         byte = pci_read_config8(dev, 0x4A);
281         byte &= ~(1 << 5);      /* disable lpc port 80 */
282         pci_write_config8(dev, 0x4A, byte);
283 }
284
285 #define BIT0    (1 << 0)
286 #define BIT1    (1 << 1)
287 #define BIT2    (1 << 2)
288 #define BIT3    (1 << 3)
289 #define BIT4    (1 << 4)
290 #define BIT5    (1 << 5)
291 #define BIT6    (1 << 6)
292 #define BIT7    (1 << 7)
293
294 struct pm_entry {
295         u8      port;
296         u8      mask;
297         u8      bit;
298 };
299 struct pm_entry const pm_table[] =
300 {
301         {0x5D, 0x00, BIT0},
302         {0xD2, 0xCF, BIT4 + BIT5},
303         {0x12, 0x00, BIT0},
304         {0x28, 0xFF, BIT0},
305         {0x44 + 3, 0x7F, BIT7},
306         {0x48, 0xFF, BIT0},
307         {0x00, 0xFF, 0x0E},
308         {0x00 + 2, 0xFF, 0x40},
309         {0x00 + 3, 0xFF, 0x08},
310         {0x34, 0xEF, BIT0 + BIT1},
311         {0xEC, 0xFD, BIT1},
312         {0x5B, 0xF9, BIT1 + BIT2},
313         {0x08, 0xFE, BIT2 + BIT4},
314         {0x08 + 1, 0xFF, BIT0},
315         {0x54, 0x00, BIT4 + BIT7},
316         {0x04 + 3, 0xFD, BIT1},
317         {0x74, 0xF6, BIT0 + BIT3},
318         {0xF0, ~BIT2, 0x00},
319         {0xF8,     0x00, 0x6C},
320         {0xF8 + 1, 0x00, 0x27},
321         {0xF8 + 2, 0x00, 0x00},
322         {0xC4, 0xFE, 0x14},
323         {0xC0 + 2, 0xBF, 0x40},
324         {0xBE, 0xDD, BIT5},
325         // HPET workaround
326         {0x54 + 3, 0xFC, BIT0 + BIT1},
327         {0x54 + 2, 0x7F, BIT7},
328         {0x54 + 2, 0x7F, 0x00},
329         {0xC4, ~(BIT2 + BIT4), BIT2 + BIT4},
330         {0xC0, 0, 0xF9},
331         {0xC0 + 1, 0x04, 0x03},
332         {0xC2, 0x20, 0x58},
333         {0xC2 + 1, 0, 0x40},
334         {0xC2, ~(BIT4), BIT4},
335         {0x74, 0x00, BIT0 + BIT1 + BIT2 + BIT4},
336         {0xDE + 1, ~(BIT0 + BIT1), BIT0 + BIT1},
337         {0xDE, ~BIT4, BIT4},
338         {0xBA, ~BIT3, BIT3},
339         {0xBA + 1, ~BIT6, BIT6},
340         {0xBC, ~BIT1, BIT1},
341         {0xED, ~(BIT0 + BIT1), 0},
342         {0xDC, 0x7C, BIT0},
343 //  {0xFF, 0xFF, 0xFF},
344 };
345
346 void sb800_lpc_port80(void)
347 {
348         u8 byte;
349         device_t dev;
350
351         /* Enable LPC controller */
352         byte = pmio_read(0xEC);
353         byte |= 1 << 0;
354         pmio_write(0xEC, byte);
355
356         /* Enable port 80 LPC decode in pci function 3 configuration space. */
357         dev = PCI_DEV(0, 0x14, 3);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
358         byte = pci_read_config8(dev, 0x4a);
359         byte |= 1 << 5;         /* enable port 80 */
360         pci_write_config8(dev, 0x4a, byte);
361 }
362
363 /* sbDevicesPorInitTable */
364 static void sb800_devices_por_init(void)
365 {
366         device_t dev;
367         u8 byte;
368
369         printk(BIOS_INFO, "sb800_devices_por_init()\n");
370         /* SMBus Device, BDF:0-20-0 */
371         printk(BIOS_INFO, "sb800_devices_por_init(): SMBus Device, BDF:0-20-0\n");
372         dev = PCI_DEV(0, 0x14, 0);//pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
373
374         if (dev == PCI_DEV_INVALID) {
375                 die("SMBUS controller not found\n");
376                 /* NOT REACHED */
377         }
378         printk(BIOS_INFO, "SMBus controller enabled, sb revision is A%x\n",
379                     get_sb800_revision());
380
381         /* sbPorAtStartOfTblCfg */
382         /* rpr 4.1.Set A-Link bridge access address.
383          * This is an I/O address. The I/O address must be on 16-byte boundry.  */
384         //pci_write_config32(dev, 0xf0, AB_INDX);
385         pmio_write(0xE0, AB_INDX & 0xFF);
386         pmio_write(0xE1, (AB_INDX >> 8) & 0xFF);
387         pmio_write(0xE2, (AB_INDX >> 16) & 0xFF);
388         pmio_write(0xE3, (AB_INDX >> 24) & 0xFF);
389
390         /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */
391         /* 4.2:Enables the SB800 to send transactions upstream over A-Link Express interface. */
392         axcfg_reg(0x04, 1 << 2, 1 << 2);
393         //axindxc_reg(0x21, 0xff, 0);
394
395         /* 4.15:Enabling Non-Posted Memory Write for the K8 Platform */
396         axindxc_reg(0x10, 1 << 9, 1 << 9);
397         /* END of sbPorAtStartOfTblCfg */
398
399         /* sbDevicesPorInitTables */
400         /* set smbus iobase */
401         //pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
402         /* The base address of SMBUS is set in a different way with sb700. */
403         byte = (SMBUS_IO_BASE & 0xFF) | 1;
404         pmio_write(0x2c, byte & 0xFF);
405         pmio_write(0x2d, SMBUS_IO_BASE >> 8);
406
407         /* AcpiMMioDecodeEn */
408         byte = pmio_read(0x24);
409         byte |= 1;
410         byte &= ~(1 << 1);
411         pmio_write(0x24, byte);
412         /* enable smbus controller interface */
413         //byte = pci_read_config8(dev, 0xd2);
414         //byte |= (1 << 0);
415         //pci_write_config8(dev, 0xd2, byte);
416
417         /* KB2RstEnable */
418         //pci_write_config8(dev, 0x40, 0x44);
419
420         /* Enable ISA Address 0-960K decoding */
421         //pci_write_config8(dev, 0x48, 0x0f);
422
423         /* Enable ISA  Address 0xC0000-0xDFFFF decode */
424         //pci_write_config8(dev, 0x49, 0xff);
425
426         /* Enable decode cycles to IO C50, C51, C52 GPM controls. */
427         //byte = pci_read_config8(dev, 0x41);
428         //byte &= 0x80;
429         //byte |= 0x33;
430         //pci_write_config8(dev, 0x41, byte);
431
432         /* Legacy DMA Prefetch Enhancement, CIM masked it. */
433         /* pci_write_config8(dev, 0x43, 0x1); */
434
435         /* clear any lingering errors, so the transaction will run */
436         outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
437
438         /* IDE Device, BDF:0-20-1 */
439         printk(BIOS_INFO, "sb800_devices_por_init(): IDE Device, BDF:0-20-1\n");
440         dev = PCI_DEV(0, 0x14, 1);//pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
441         /* Disable prefetch */
442         byte = pci_read_config8(dev, 0x63);
443         byte |= 0x1;
444         pci_write_config8(dev, 0x63, byte);
445
446         /* LPC Device, BDF:0-20-3 */
447         printk(BIOS_INFO, "sb800_devices_por_init(): LPC Device, BDF:0-20-3\n");
448         dev = PCI_DEV(0, 0x14, 3);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
449         /* DMA enable */
450         pci_write_config8(dev, 0x40, 0x04);
451
452         /* IO Port Decode Enable */
453         pci_write_config8(dev, 0x44, 0xFF);
454         pci_write_config8(dev, 0x45, 0xFF);
455         pci_write_config8(dev, 0x46, 0xC3);
456         pci_write_config8(dev, 0x47, 0xFF);
457
458         /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
459          *  Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
460          * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65).
461          * Enable bits for LPC ROM memory address range 1&2 for 1M ROM setting.*/
462         byte = pci_read_config8(dev, 0x48);
463         byte |= (1 << 1) | (1 << 0);    /* enable Super IO config port 2e-2h, 4e-4f */
464         byte |= (1 << 3) | (1 << 4);    /* enable for LPC ROM address range1&2, Enable 512KB rom access at 0xFFF80000 - 0xFFFFFFFF */
465         byte |= 1 << 6;         /* enable for RTC I/O range */
466         pci_write_config8(dev, 0x48, byte);
467         pci_write_config8(dev, 0x49, 0xFF);
468         /* Enable 0x480-0x4bf, 0x4700-0x470B */
469         byte = pci_read_config8(dev, 0x4A);
470         byte |= ((1 << 1) + (1 << 6));  /*0x42, save the configuraion for port 0x80. */
471         pci_write_config8(dev, 0x4A, byte);
472
473         /* Set LPC ROM size, it has been done in sb800_lpc_init().
474          * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB;
475          * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB
476          * pci_write_config16(dev, 0x68, 0x000e)
477          * pci_write_config16(dev, 0x6c, 0xfff0);*/
478
479         /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
480         pci_write_config8(dev, 0x7C, 0x05);
481
482         /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
483          */
484         printk(BIOS_INFO, "sb800_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
485         dev = PCI_DEV(0, 0x14, 4);//pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
486
487         /* Arbiter enable. */
488         pci_write_config8(dev, 0x43, 0xff);
489
490         /* Set PCDMA request into hight priority list. */
491         /* pci_write_config8(dev, 0x49, 0x1) */ ;
492
493         pci_write_config8(dev, 0x40, 0x26);
494
495         pci_write_config8(dev, 0x0d, 0x40);
496         pci_write_config8(dev, 0x1b, 0x40);
497         /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
498         pci_write_config8(dev, 0x50, 0x01);
499
500         /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
501         printk(BIOS_INFO, "sb800_devices_por_init(): SATA Device, BDF:0-18-0\n");
502         dev = PCI_DEV(0, 0x11, 0);//pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
503
504         /*PHY Global Control*/
505         pci_write_config16(dev, 0x86, 0x2C00);
506 }
507
508 /* sbPmioPorInitTable, Pre-initializing PMIO register space
509 * The power management (PM) block is resident in the PCI/LPC/ISA bridge.
510 * The PM regs are accessed via IO mapped regs 0xcd6 and 0xcd7.
511 * The index address is first programmed into IO reg 0xcd6.
512 * Read or write values are accessed through IO reg 0xcd7.
513 */
514 #if 0
515 static void sb800_pmio_por_init(void)
516 {
517         u8 byte, i;
518
519         printk(BIOS_INFO, "sb800_pmio_por_init()\n");
520
521         byte = pmio_read(0xD2);
522         byte |= 3 << 4;
523         pmio_write(0xD2, byte);
524
525         byte = pmio_read(0x5D);
526         byte &= 3;
527         byte |= 1;
528         pmio_write(0x5D, byte);
529
530         /* Watch Dog Timer Control
531          * Set watchdog time base to 0xfec000f0 to avoid SCSI card boot failure.
532          * But I don't find WDT is enabled in SMBUS 0x41 bit3 in CIM.
533          */
534         pmio_write(0x6c, 0xf0);
535         pmio_write(0x6d, 0x00);
536         pmio_write(0x6e, 0xc0);
537         pmio_write(0x6f, 0xfe);
538
539         /* rpr2.15: Enabling Spread Spectrum */
540         byte = pmio_read(0x42);
541         byte |= 1 << 7;
542         pmio_write(0x42, byte);
543         /* TODO: Check if it is necessary. IDE reset */
544         byte = pmio_read(0xB2);
545         byte |= 1 << 0;
546         pmio_write(0xB2, byte);
547
548         for (i=0; i<sizeof(pm_table)/sizeof(struct pm_entry); i++) {
549                 byte = pmio_read(pm_table[i].port);
550                 byte &= pm_table[i].mask;
551                 byte |= pm_table[i].bit;
552                 pmio_write(pm_table[i].port, byte);
553         }
554         pmio_write(0x00, 0x0E);
555         pmio_write(0x01, 0x00);
556         pmio_write(0x02, 0x4F);
557         pmio_write(0x03, 0x4A);
558 }
559 #endif
560
561 /*
562 * Add any south bridge setting.
563 */
564 static void sb800_pci_cfg(void)
565 {
566         device_t dev;
567         u8 byte;
568
569         /* SMBus Device, BDF:0-20-0 */
570         dev = PCI_DEV(0, 0x14, 0);//pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
571         /* Enable watchdog decode timer */
572         byte = pci_read_config8(dev, 0x41);
573         byte |= (1 << 3);
574         pci_write_config8(dev, 0x41, byte);
575
576         /* rpr 7.4. Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
577          * generated PCIRST#. */
578         byte = pmio_read(0xF0);
579         byte |= (1 << 2);
580         pmio_write(0xF0, byte);
581
582         /* IDE Device, BDF:0-20-1 */
583         dev = PCI_DEV(0, 0x14, 1);//pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
584         /* Enable IDE Explicit prefetch, 0x63[0] clear */
585         byte = pci_read_config8(dev, 0x63);
586         byte &= 0xfe;
587         pci_write_config8(dev, 0x63, byte);
588
589         /* LPC Device, BDF:0-20-3 */
590         /* The code below is ported from old chipset. It is not
591          * metioned in RPR. But I keep them. The registers and the
592          * comments are compatible. */
593         dev = PCI_DEV(0, 0x14, 3);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
594         /* Enabling LPC DMA function. */
595         byte = pci_read_config8(dev, 0x40);
596         byte |= (1 << 2);
597         pci_write_config8(dev, 0x40, byte);
598         /* Disabling LPC TimeOut. 0x48[7] clear. */
599         byte = pci_read_config8(dev, 0x48);
600         byte &= 0x7f;
601         pci_write_config8(dev, 0x48, byte);
602         /* Disabling LPC MSI Capability, 0x78[1] clear. */
603         byte = pci_read_config8(dev, 0x78);
604         byte &= 0xfd;
605         pci_write_config8(dev, 0x78, byte);
606
607         /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
608         dev = PCI_DEV(0, 0x11, 0);//pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
609         /* rpr7.12 SATA MSI and D3 Power State Capability. */
610         byte = pci_read_config8(dev, 0x40);
611         byte |= 1 << 0;
612         pci_write_config8(dev, 0x40, byte);
613         if (get_sb800_revision() <= 0x12)
614                 pci_write_config8(dev, 0x34, 0x70); /* set 0x61 to 0x70 if S1 is not supported. */
615         else
616                 pci_write_config8(dev, 0x34, 0x50); /* set 0x61 to 0x50 if S1 is not supported. */
617         byte &= ~(1 << 0);
618         pci_write_config8(dev, 0x40, byte);
619 }
620
621 /*
622 */
623 static void sb800_por_init(void)
624 {
625         /* sbDevicesPorInitTable + sbK8PorInitTable */
626         sb800_devices_por_init();
627
628         /* sbPmioPorInitTable + sbK8PmioPorInitTable */
629         //sb800_pmio_por_init();
630 }
631
632 /*
633 * It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
634 */
635 static void sb800_before_pci_init(void)
636 {
637         sb800_pci_cfg();
638 }
639
640 /*
641 * This function should be called after enable_sb800_smbus().
642 */
643 static void sb800_early_setup(void)
644 {
645         printk(BIOS_INFO, "sb800_early_setup()\n");
646         sb800_por_init();
647         sb800_acpi_init();
648 }
649
650 static int smbus_read_byte(u32 device, u32 address)
651 {
652         return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
653 }
654
655 int s3_save_nvram_early(u32 dword, int size, int  nvram_pos) {
656         int i;
657         printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
658
659         for (i = 0; i<size; i++) {
660                 outb(nvram_pos, BIOSRAM_INDEX);
661                 outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA);
662                 nvram_pos++;
663         }
664
665         return nvram_pos;
666 }
667
668 int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) {
669         u32 data = *old_dword;
670         int i;
671         for (i = 0; i<size; i++) {
672                 outb(nvram_pos, BIOSRAM_INDEX);
673                 data &= ~(0xff << (i * 8));
674                 data |= inb(BIOSRAM_DATA) << (i *8);
675                 nvram_pos++;
676         }
677         *old_dword = data;
678         printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", *old_dword, size,
679                 nvram_pos-size);
680         return nvram_pos;
681 }
682
683 #if CONFIG_HAVE_ACPI_RESUME == 1
684 static int acpi_is_wakeup_early(void) {
685         u16 tmp;
686         tmp = inw(ACPI_PM1_CNT_BLK);
687         printk(BIOS_DEBUG, "IN TEST WAKEUP %x\n", tmp);
688         return (((tmp & (7 << 10)) >> 10) == 3);
689 }
690 #endif
691
692 struct cbmem_entry *get_cbmem_toc(void) {
693         uint32_t xdata = 0;
694         int xnvram_pos = 0xfc, xi;
695         for (xi = 0; xi<4; xi++) {
696                 outb(xnvram_pos, BIOSRAM_INDEX);
697                 xdata &= ~(0xff << (xi * 8));
698                 xdata |= inb(BIOSRAM_DATA) << (xi *8);
699                 xnvram_pos++;
700         }
701         return (struct cbmem_entry *) xdata;
702 }
703
704 #endif