1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <console/console.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <pc80/mc146818rtc.h>
26#include <pc80/isa-dma.h>
27#include <pc80/i8259.h>
28#include <arch/io.h>
29#include <arch/ioapic.h>
30#include <cpu/cpu.h>
31#include "i82801gx.h"
32
33#define NMI_OFF 0
34
35#define ENABLE_ACPI_MODE_IN_COREBOOT 0
36#define TEST_SMM_FLASH_LOCKDOWN 0
37
38typedef struct southbridge_intel_i82801gx_config config_t;
39
40static void i82801gx_enable_apic(struct device *dev)
41{
42 int i;
43 u32 reg32;
44 volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
45 volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
46
47
48
49
50 pci_write_config8(dev, ACPI_CNTL, 0x80);
51
52 *ioapic_index = 0;
53 *ioapic_data = (1 << 25);
54
55 *ioapic_index = 0;
56 reg32 = *ioapic_data;
57 printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", (reg32 >> 24) & 0x0f);
58 if (reg32 != (1 << 25))
59 die("APIC Error\n");
60
61 printk(BIOS_SPEW, "Dumping IOAPIC registers\n");
62 for (i=0; i<3; i++) {
63 *ioapic_index = i;
64 printk(BIOS_SPEW, " reg 0x%04x:", i);
65 reg32 = *ioapic_data;
66 printk(BIOS_SPEW, " 0x%08x\n", reg32);
67 }
68
69 *ioapic_index = 3;
70 *ioapic_data = 1;
71}
72
73static void i82801gx_enable_serial_irqs(struct device *dev)
74{
75
76 pci_write_config8(dev, SERIRQ_CNTL,
77 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
78}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101static void i82801gx_pirq_init(device_t dev)
102{
103 device_t irq_dev;
104
105 config_t *config = dev->chip_info;
106
107 pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
108 pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
109 pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
110 pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
111
112 pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
113 pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
114 pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
115 pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
116
117
118
119
120
121 for(irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
122 u8 int_pin=0, int_line=0;
123
124 if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
125 continue;
126
127 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
128
129 switch (int_pin) {
130 case 1: int_line = config->pirqa_routing; break;
131 case 2: int_line = config->pirqb_routing; break;
132 case 3: int_line = config->pirqc_routing; break;
133 case 4: int_line = config->pirqd_routing; break;
134 }
135
136 if (!int_line)
137 continue;
138
139 pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
140 }
141}
142
143static void i82801gx_gpi_routing(device_t dev)
144{
145
146 config_t *config = dev->chip_info;
147 u32 reg32 = 0;
148
149
150
151
152 reg32 |= (config->gpi0_routing & 0x03) << 0;
153 reg32 |= (config->gpi1_routing & 0x03) << 2;
154 reg32 |= (config->gpi2_routing & 0x03) << 4;
155 reg32 |= (config->gpi3_routing & 0x03) << 6;
156 reg32 |= (config->gpi4_routing & 0x03) << 8;
157 reg32 |= (config->gpi5_routing & 0x03) << 10;
158 reg32 |= (config->gpi6_routing & 0x03) << 12;
159 reg32 |= (config->gpi7_routing & 0x03) << 14;
160 reg32 |= (config->gpi8_routing & 0x03) << 16;
161 reg32 |= (config->gpi9_routing & 0x03) << 18;
162 reg32 |= (config->gpi10_routing & 0x03) << 20;
163 reg32 |= (config->gpi11_routing & 0x03) << 22;
164 reg32 |= (config->gpi12_routing & 0x03) << 24;
165 reg32 |= (config->gpi13_routing & 0x03) << 26;
166 reg32 |= (config->gpi14_routing & 0x03) << 28;
167 reg32 |= (config->gpi15_routing & 0x03) << 30;
168
169 pci_write_config32(dev, 0xb8, reg32);
170}
171
172extern u8 acpi_slp_type;
173
174static void i82801gx_power_options(device_t dev)
175{
176 u8 reg8;
177 u16 reg16, pmbase;
178 u32 reg32;
179 const char *state;
180
181 config_t *config = dev->chip_info;
182
183 int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
184 int nmi_option;
185
186
187
188
189
190
191
192 if (get_option(&pwr_on, "power_on_after_fail") < 0)
193 pwr_on = MAINBOARD_POWER_ON;
194
195 reg8 = pci_read_config8(dev, GEN_PMCON_3);
196 reg8 &= 0xfe;
197 switch (pwr_on) {
198 case MAINBOARD_POWER_OFF:
199 reg8 |= 1;
200 state = "off";
201 break;
202 case MAINBOARD_POWER_ON:
203 reg8 &= ~1;
204 state = "on";
205 break;
206 case MAINBOARD_POWER_KEEP:
207 reg8 &= ~1;
208 state = "state keep";
209 break;
210 default:
211 state = "undefined";
212 }
213
214 reg8 |= (3 << 4);
215 reg8 &= ~(1 << 3);
216
217 pci_write_config8(dev, GEN_PMCON_3, reg8);
218 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
219
220
221 reg8 = inb(0x61);
222 reg8 &= 0x0f;
223 reg8 &= ~(1 << 3);
224
225 reg8 |= (1 << 2);
226 outb(reg8, 0x61);
227
228 reg8 = inb(0x70);
229 nmi_option = NMI_OFF;
230 get_option(&nmi_option, "nmi");
231 if (nmi_option) {
232 printk(BIOS_INFO, "NMI sources enabled.\n");
233 reg8 &= ~(1 << 7);
234 } else {
235 printk(BIOS_INFO, "NMI sources disabled.\n");
236 reg8 |= ( 1 << 7);
237 }
238 outb(reg8, 0x70);
239
240
241 reg16 = pci_read_config16(dev, GEN_PMCON_1);
242 reg16 &= ~(3 << 0);
243 reg16 |= (1 << 2);
244 reg16 |= (1 << 3);
245 reg16 |= (1 << 5);
246
247
248 reg16 |= (1 << 10);
249#if DEBUG_PERIODIC_SMIS
250
251
252
253 reg16 |= (3 << 0);
254#endif
255 pci_write_config16(dev, GEN_PMCON_1, reg16);
256
257
258 i82801gx_gpi_routing(dev);
259
260 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
261
262 outl(config->gpe0_en, pmbase + GPE0_EN);
263 outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);
264
265
266 reg32 = inl(pmbase + 0x04);
267
268 reg32 &= ~(7 << 10);
269 reg32 |= (1 << 1);
270 reg32 |= (1 << 0);
271 outl(reg32, pmbase + 0x04);
272}
273
274static void i82801gx_configure_cstates(device_t dev)
275{
276 u8 reg8;
277
278 reg8 = pci_read_config8(dev, 0xa9);
279 reg8 |= (1 << 4) | (1 << 3) | (1 << 2);
280 pci_write_config8(dev, 0xa9, reg8);
281
282
283 reg8 = pci_read_config8(dev, 0xaa);
284 reg8 &= 0xf0;
285 reg8 |= (2 << 2);
286 reg8 |= (2 << 0);
287 pci_write_config8(dev, 0xaa, reg8);
288}
289
290static void i82801gx_rtc_init(struct device *dev)
291{
292 u8 reg8;
293 int rtc_failed;
294
295 reg8 = pci_read_config8(dev, GEN_PMCON_3);
296 rtc_failed = reg8 & RTC_BATTERY_DEAD;
297 if (rtc_failed) {
298 reg8 &= ~RTC_BATTERY_DEAD;
299 pci_write_config8(dev, GEN_PMCON_3, reg8);
300 }
301 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
302
303 rtc_init(rtc_failed);
304}
305
306static void enable_hpet(void)
307{
308 u32 reg32;
309
310
311 reg32 = RCBA32(HPTC);
312 reg32 |= (1 << 7);
313 reg32 &= ~(3 << 0);
314 RCBA32(HPTC) = reg32;
315}
316
317static void enable_clock_gating(void)
318{
319 u32 reg32;
320
321
322 reg32 = RCBA32(CG);
323 reg32 |= (1 << 31);
324 reg32 |= (1 << 30);
325
326 reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
327 reg32 |= (1 << 23);
328 reg32 |= (1 << 19);
329 reg32 |= (1 << 3) | (1 << 1);
330 reg32 |= (1 << 2);
331 reg32 &= ~(1 << 20);
332 reg32 &= ~( (1 << 29) | (1 << 28) );
333 RCBA32(CG) = reg32;
334}
335
336#if CONFIG_HAVE_SMI_HANDLER
337static void i82801gx_lock_smm(struct device *dev)
338{
339#if TEST_SMM_FLASH_LOCKDOWN
340 u8 reg8;
341#endif
342
343#if ENABLE_ACPI_MODE_IN_COREBOOT
344 printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n");
345 outb(0xe1, 0xb2);
346 printk(BIOS_DEBUG, "done.\n");
347#else
348 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
349 outb(0x1e, 0xb2);
350 printk(BIOS_DEBUG, "done.\n");
351#endif
352
353
354
355 smm_lock();
356
357#if TEST_SMM_FLASH_LOCKDOWN
358
359 printk(BIOS_DEBUG, "Locking BIOS to RO... ");
360 reg8 = pci_read_config8(dev, 0xdc);
361 printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
362 (reg8&1)?"rw":"ro");
363 reg8 &= ~(1 << 0);
364 pci_write_config8(dev, 0xdc, reg8);
365 reg8 |= (1 << 1);
366 pci_write_config8(dev, 0xdc, reg8);
367 printk(BIOS_DEBUG, "ok.\n");
368 reg8 = pci_read_config8(dev, 0xdc);
369 printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
370 (reg8&1)?"rw":"ro");
371
372 printk(BIOS_DEBUG, "Writing:\n");
373 *(volatile u8 *)0xfff00000 = 0x00;
374 printk(BIOS_DEBUG, "Testing:\n");
375 reg8 |= (1 << 0);
376 pci_write_config8(dev, 0xdc, reg8);
377
378 reg8 = pci_read_config8(dev, 0xdc);
379 printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
380 (reg8&1)?"rw":"ro");
381 printk(BIOS_DEBUG, "Done.\n");
382#endif
383}
384#endif
385
386#define SPIBASE 0x3020
387static void i82801gx_spi_init(void)
388{
389 u16 spicontrol;
390
391 spicontrol = RCBA16(SPIBASE + 2);
392 spicontrol &= ~(1 << 0);
393 RCBA16(SPIBASE + 2) = spicontrol;
394}
395
396static void i82801gx_fixups(struct device *dev)
397{
398
399 RCBA32(0x1d40) |= 1;
400
401
402
403
404
405 pci_write_config8(dev, 0xad, 0x3);
406}
407
408static void lpc_init(struct device *dev)
409{
410 printk(BIOS_DEBUG, "i82801gx: lpc_init\n");
411
412
413 pci_write_config16(dev, PCI_COMMAND, 0x000f);
414
415
416 i82801gx_enable_apic(dev);
417
418 i82801gx_enable_serial_irqs(dev);
419
420
421 i82801gx_pirq_init(dev);
422
423
424 i82801gx_power_options(dev);
425
426
427 i82801gx_configure_cstates(dev);
428
429
430
431
432
433 i82801gx_rtc_init(dev);
434
435
436 isa_dma_init();
437
438
439 enable_hpet();
440
441
442 enable_clock_gating();
443
444 setup_i8259();
445
446
447
448 i8259_configure_irq_trigger(9, 1);
449
450#if CONFIG_HAVE_SMI_HANDLER
451 i82801gx_lock_smm(dev);
452#endif
453
454 i82801gx_spi_init();
455
456 i82801gx_fixups(dev);
457}
458
459static void i82801gx_lpc_read_resources(device_t dev)
460{
461 struct resource *res;
462
463
464 pci_dev_read_resources(dev);
465
466
467 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
468 res->base = 0;
469 res->size = 0x1000;
470 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
471 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
472
473 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
474 res->base = 0xff800000;
475 res->size = 0x00800000;
476 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
477 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
478
479 res = new_resource(dev, 3);
480 res->base = IO_APIC_ADDR;
481 res->size = 0x00001000;
482 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
483}
484
485static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
486{
487 if (!vendor || !device) {
488 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
489 pci_read_config32(dev, PCI_VENDOR_ID));
490 } else {
491 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
492 ((device & 0xffff) << 16) | (vendor & 0xffff));
493 }
494}
495
496static struct pci_operations pci_ops = {
497 .set_subsystem = set_subsystem,
498};
499
500static struct device_operations device_ops = {
501 .read_resources = i82801gx_lpc_read_resources,
502 .set_resources = pci_dev_set_resources,
503 .enable_resources = pci_dev_enable_resources,
504 .init = lpc_init,
505 .scan_bus = scan_static_bus,
506 .enable = i82801gx_enable,
507 .ops_pci = &pci_ops,
508};
509
510
511static const struct pci_driver ich7_dh_lpc __pci_driver = {
512 .ops = &device_ops,
513 .vendor = PCI_VENDOR_ID_INTEL,
514 .device = 0x27b0,
515};
516
517
518static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
519 .ops = &device_ops,
520 .vendor = PCI_VENDOR_ID_INTEL,
521 .device = 0x27b8,
522};
523
524
525static const struct pci_driver ich7m_ich7u_lpc __pci_driver = {
526 .ops = &device_ops,
527 .vendor = PCI_VENDOR_ID_INTEL,
528 .device = 0x27b9,
529};
530
531
532static const struct pci_driver ich7m_dh_lpc __pci_driver = {
533 .ops = &device_ops,
534 .vendor = PCI_VENDOR_ID_INTEL,
535 .device = 0x27bd,
536};
537