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