sb/intel/ibexpeak: Use common final SPI OPs setup
[coreboot.git] / src / southbridge / intel / ibexpeak / lpc.c
blobfa1ca92d783d4d7641e753cb9a91bd2c15dd7b57
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2013 Vladimir Serbinenko
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <console/console.h>
19 #include <device/device.h>
20 #include <device/pci.h>
21 #include <device/pci_ids.h>
22 #include <pc80/mc146818rtc.h>
23 #include <pc80/isa-dma.h>
24 #include <pc80/i8259.h>
25 #include <arch/io.h>
26 #include <device/mmio.h>
27 #include <device/pci_ops.h>
28 #include <arch/ioapic.h>
29 #include <arch/acpi.h>
30 #include <arch/cpu.h>
31 #include <elog.h>
32 #include <arch/acpigen.h>
33 #include <drivers/intel/gma/i915.h>
34 #include <cbmem.h>
35 #include <string.h>
36 #include <cpu/x86/smm.h>
37 #include "pch.h"
38 #include "nvs.h"
39 #include <southbridge/intel/common/pciehp.h>
40 #include <southbridge/intel/common/acpi_pirq_gen.h>
41 #include <southbridge/intel/common/spi.h>
43 #define NMI_OFF 0
45 #define ENABLE_ACPI_MODE_IN_COREBOOT 0
47 typedef struct southbridge_intel_ibexpeak_config config_t;
49 /**
50 * Set miscellanous static southbridge features.
52 * @param dev PCI device with I/O APIC control registers
54 static void pch_enable_ioapic(struct device *dev)
56 u32 reg32;
58 /* Enable ACPI I/O range decode */
59 pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
61 set_ioapic_id(VIO_APIC_VADDR, 0x01);
62 /* affirm full set of redirection table entries ("write once") */
63 reg32 = io_apic_read(VIO_APIC_VADDR, 0x01);
64 io_apic_write(VIO_APIC_VADDR, 0x01, reg32);
67 * Select Boot Configuration register (0x03) and
68 * use Processor System Bus (0x01) to deliver interrupts.
70 io_apic_write(VIO_APIC_VADDR, 0x03, 0x01);
73 static void pch_enable_serial_irqs(struct device *dev)
75 /* Set packet length and toggle silent mode bit for one frame. */
76 pci_write_config8(dev, SERIRQ_CNTL,
77 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
78 #if !CONFIG(SERIRQ_CONTINUOUS_MODE)
79 pci_write_config8(dev, SERIRQ_CNTL,
80 (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
81 #endif
84 /* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
85 * 0x00 - 0000 = Reserved
86 * 0x01 - 0001 = Reserved
87 * 0x02 - 0010 = Reserved
88 * 0x03 - 0011 = IRQ3
89 * 0x04 - 0100 = IRQ4
90 * 0x05 - 0101 = IRQ5
91 * 0x06 - 0110 = IRQ6
92 * 0x07 - 0111 = IRQ7
93 * 0x08 - 1000 = Reserved
94 * 0x09 - 1001 = IRQ9
95 * 0x0A - 1010 = IRQ10
96 * 0x0B - 1011 = IRQ11
97 * 0x0C - 1100 = IRQ12
98 * 0x0D - 1101 = Reserved
99 * 0x0E - 1110 = IRQ14
100 * 0x0F - 1111 = IRQ15
101 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
102 * 0x80 - The PIRQ is not routed.
105 static void pch_pirq_init(struct device *dev)
107 struct device *irq_dev;
108 /* Interrupt 11 is not used by legacy devices and so can always be used for
109 PCI interrupts. Full legacy IRQ routing is complicated and hard to
110 get right. Fortunately all modern OS use MSI and so it's not that big of
111 an issue anyway. Still we have to provide a reasonable default. Using
112 interrupt 11 for it everywhere is a working default. ACPI-aware OS can
113 move it to any interrupt and others will just leave them at default.
115 const u8 pirq_routing = 11;
117 pci_write_config8(dev, PIRQA_ROUT, pirq_routing);
118 pci_write_config8(dev, PIRQB_ROUT, pirq_routing);
119 pci_write_config8(dev, PIRQC_ROUT, pirq_routing);
120 pci_write_config8(dev, PIRQD_ROUT, pirq_routing);
122 pci_write_config8(dev, PIRQE_ROUT, pirq_routing);
123 pci_write_config8(dev, PIRQF_ROUT, pirq_routing);
124 pci_write_config8(dev, PIRQG_ROUT, pirq_routing);
125 pci_write_config8(dev, PIRQH_ROUT, pirq_routing);
127 for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
128 u8 int_pin=0;
130 if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
131 continue;
133 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
135 if (int_pin == 0)
136 continue;
138 pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, pirq_routing);
142 static void pch_gpi_routing(struct device *dev)
144 /* Get the chip configuration */
145 config_t *config = dev->chip_info;
146 u32 reg32 = 0;
148 /* An array would be much nicer here, or some
149 * other method of doing this.
151 reg32 |= (config->gpi0_routing & 0x03) << 0;
152 reg32 |= (config->gpi1_routing & 0x03) << 2;
153 reg32 |= (config->gpi2_routing & 0x03) << 4;
154 reg32 |= (config->gpi3_routing & 0x03) << 6;
155 reg32 |= (config->gpi4_routing & 0x03) << 8;
156 reg32 |= (config->gpi5_routing & 0x03) << 10;
157 reg32 |= (config->gpi6_routing & 0x03) << 12;
158 reg32 |= (config->gpi7_routing & 0x03) << 14;
159 reg32 |= (config->gpi8_routing & 0x03) << 16;
160 reg32 |= (config->gpi9_routing & 0x03) << 18;
161 reg32 |= (config->gpi10_routing & 0x03) << 20;
162 reg32 |= (config->gpi11_routing & 0x03) << 22;
163 reg32 |= (config->gpi12_routing & 0x03) << 24;
164 reg32 |= (config->gpi13_routing & 0x03) << 26;
165 reg32 |= (config->gpi14_routing & 0x03) << 28;
166 reg32 |= (config->gpi15_routing & 0x03) << 30;
168 pci_write_config32(dev, GPIO_ROUT, reg32);
171 static void pch_power_options(struct device *dev)
173 u8 reg8;
174 u16 reg16, pmbase;
175 u32 reg32;
176 const char *state;
177 /* Get the chip configuration */
178 config_t *config = dev->chip_info;
180 int pwr_on = CONFIG_MAINBOARD_POWER_FAILURE_STATE;
181 int nmi_option;
183 /* Which state do we want to goto after g3 (power restored)?
184 * 0 == S0 Full On
185 * 1 == S5 Soft Off
187 * If the option is not existent (Laptops), use Kconfig setting.
189 get_option(&pwr_on, "power_on_after_fail");
191 reg16 = pci_read_config16(dev, GEN_PMCON_3);
192 reg16 &= 0xfffe;
193 switch (pwr_on) {
194 case MAINBOARD_POWER_OFF:
195 reg16 |= 1;
196 state = "off";
197 break;
198 case MAINBOARD_POWER_ON:
199 reg16 &= ~1;
200 state = "on";
201 break;
202 case MAINBOARD_POWER_KEEP:
203 reg16 &= ~1;
204 state = "state keep";
205 break;
206 default:
207 state = "undefined";
210 reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */
211 reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */
213 reg16 &= ~(1 << 10);
214 reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */
216 reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */
218 pci_write_config16(dev, GEN_PMCON_3, reg16);
219 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
221 /* Set up NMI on errors. */
222 reg8 = inb(0x61);
223 reg8 &= 0x0f; /* Higher Nibble must be 0 */
224 reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
225 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
226 reg8 |= (1 << 2); /* PCI SERR# Disable for now */
227 outb(reg8, 0x61);
229 reg8 = inb(0x70);
230 nmi_option = NMI_OFF;
231 get_option(&nmi_option, "nmi");
232 if (nmi_option) {
233 printk(BIOS_INFO, "NMI sources enabled.\n");
234 reg8 &= ~(1 << 7); /* Set NMI. */
235 } else {
236 printk(BIOS_INFO, "NMI sources disabled.\n");
237 reg8 |= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
239 outb(reg8, 0x70);
241 /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
242 reg16 = pci_read_config16(dev, GEN_PMCON_1);
243 reg16 &= ~(3 << 0); // SMI# rate 1 minute
244 reg16 &= ~(1 << 10); // Disable BIOS_PCI_EXP_EN for native PME
245 #if DEBUG_PERIODIC_SMIS
246 /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using
247 * periodic SMIs.
249 reg16 |= (3 << 0); // Periodic SMI every 8s
250 #endif
251 pci_write_config16(dev, GEN_PMCON_1, reg16);
253 // Set the board's GPI routing.
254 pch_gpi_routing(dev);
256 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
258 outl(config->gpe0_en, pmbase + GPE0_EN);
259 outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);
261 /* Set up power management block and determine sleep mode */
262 reg32 = inl(pmbase + 0x04); // PM1_CNT
263 reg32 &= ~(7 << 10); // SLP_TYP
264 reg32 |= (1 << 0); // SCI_EN
265 outl(reg32, pmbase + 0x04);
267 /* Clear magic status bits to prevent unexpected wake */
268 reg32 = RCBA32(0x3310);
269 reg32 |= (1 << 4)|(1 << 5)|(1 << 0);
270 RCBA32(0x3310) = reg32;
272 reg32 = RCBA32(0x3f02);
273 reg32 &= ~0xf;
274 RCBA32(0x3f02) = reg32;
277 static void pch_rtc_init(struct device *dev)
279 u8 reg8;
280 int rtc_failed;
282 reg8 = pci_read_config8(dev, GEN_PMCON_3);
283 rtc_failed = reg8 & RTC_BATTERY_DEAD;
284 if (rtc_failed) {
285 reg8 &= ~RTC_BATTERY_DEAD;
286 pci_write_config8(dev, GEN_PMCON_3, reg8);
287 #if CONFIG(ELOG)
288 elog_add_event(ELOG_TYPE_RTC_RESET);
289 #endif
291 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
293 cmos_init(rtc_failed);
296 static void mobile5_pm_init(struct device *dev)
298 int i;
300 printk(BIOS_DEBUG, "Mobile 5 PM init\n");
301 pci_write_config8(dev, 0xa9, 0x47);
303 RCBA32 (0x1d44) = 0x00000000;
304 (void) RCBA32 (0x1d44);
305 RCBA32 (0x1d48) = 0x00030000;
306 (void) RCBA32 (0x1d48);
307 RCBA32 (0x1e80) = 0x000c0801;
308 (void) RCBA32 (0x1e80);
309 RCBA32 (0x1e84) = 0x000200f0;
310 (void) RCBA32 (0x1e84);
312 const u32 rcba2010[] =
314 /* 2010: */ 0x00188200, 0x14000016, 0xbc4abcb5, 0x00000000,
315 /* 2020: */ 0xf0c9605b, 0x13683040, 0x04c8f16e, 0x09e90170
317 for (i = 0; i < sizeof(rcba2010) / sizeof(rcba2010[0]); i++)
319 RCBA32 (0x2010 + 4 * i) = rcba2010[i];
320 RCBA32 (0x2010 + 4 * i);
323 RCBA32 (0x2100) = 0x00000000;
324 (void) RCBA32 (0x2100);
325 RCBA32 (0x2104) = 0x00000757;
326 (void) RCBA32 (0x2104);
327 RCBA32 (0x2108) = 0x00170001;
328 (void) RCBA32 (0x2108);
330 RCBA32 (0x211c) = 0x00000000;
331 (void) RCBA32 (0x211c);
332 RCBA32 (0x2120) = 0x00010000;
333 (void) RCBA32 (0x2120);
335 RCBA32 (0x21fc) = 0x00000000;
336 (void) RCBA32 (0x21fc);
337 RCBA32 (0x2200) = 0x20000044;
338 (void) RCBA32 (0x2200);
339 RCBA32 (0x2204) = 0x00000001;
340 (void) RCBA32 (0x2204);
341 RCBA32 (0x2208) = 0x00003457;
342 (void) RCBA32 (0x2208);
344 const u32 rcba2210[] =
346 /* 2210 */ 0x00000000, 0x00000001, 0xa0fff210, 0x0000df00,
347 /* 2220 */ 0x00e30880, 0x00000070, 0x00004000, 0x00000000,
348 /* 2230 */ 0x00e30880, 0x00000070, 0x00004000, 0x00000000,
349 /* 2240 */ 0x00002301, 0x36000000, 0x00010107, 0x00160000,
350 /* 2250 */ 0x00001b01, 0x36000000, 0x00010107, 0x00160000,
351 /* 2260 */ 0x00000601, 0x16000000, 0x00010107, 0x00160000,
352 /* 2270 */ 0x00001c01, 0x16000000, 0x00010107, 0x00160000
355 for (i = 0; i < sizeof(rcba2210) / sizeof(rcba2210[0]); i++)
357 RCBA32 (0x2210 + 4 * i) = rcba2210[i];
358 RCBA32 (0x2210 + 4 * i);
361 const u32 rcba2300[] =
363 /* 2300: */ 0x00000000, 0x40000000, 0x4646827b, 0x6e803131,
364 /* 2310: */ 0x32c77887, 0x00077733, 0x00007447, 0x00000040,
365 /* 2320: */ 0xcccc0cfc, 0x0fbb0fff
368 for (i = 0; i < sizeof(rcba2300) / sizeof(rcba2300[0]); i++)
370 RCBA32 (0x2300 + 4 * i) = rcba2300[i];
371 RCBA32 (0x2300 + 4 * i);
374 RCBA32 (0x37fc) = 0x00000000;
375 (void) RCBA32 (0x37fc);
376 RCBA32 (0x3dfc) = 0x00000000;
377 (void) RCBA32 (0x3dfc);
378 RCBA32 (0x3e7c) = 0xffffffff;
379 (void) RCBA32 (0x3e7c);
380 RCBA32 (0x3efc) = 0x00000000;
381 (void) RCBA32 (0x3efc);
382 RCBA32 (0x3f00) = 0x0000010b;
383 (void) RCBA32 (0x3f00);
386 static void enable_hpet(void)
388 u32 reg32;
390 /* Move HPET to default address 0xfed00000 and enable it */
391 reg32 = RCBA32(HPTC);
392 reg32 |= (1 << 7); // HPET Address Enable
393 reg32 &= ~(3 << 0);
394 RCBA32(HPTC) = reg32;
396 write32((u32 *)0xfed00010, read32((u32 *)0xfed00010) | 1);
399 static void enable_clock_gating(struct device *dev)
401 u32 reg32;
402 u16 reg16;
404 RCBA32_AND_OR(0x2234, ~0UL, 0xf);
406 reg16 = pci_read_config16(dev, GEN_PMCON_1);
407 reg16 |= (1 << 2) | (1 << 11);
408 pci_write_config16(dev, GEN_PMCON_1, reg16);
410 pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
411 pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
412 pch_iobp_update(0xEC007F07, ~0UL, (1 << 31));
413 pch_iobp_update(0xEC004000, ~0UL, (1 << 7));
415 reg32 = RCBA32(CG);
416 reg32 |= (1 << 31);
417 reg32 |= (1 << 29) | (1 << 28);
418 reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
419 reg32 |= (1 << 16);
420 reg32 |= (1 << 17);
421 reg32 |= (1 << 18);
422 reg32 |= (1 << 22);
423 reg32 |= (1 << 23);
424 reg32 &= ~(1 << 20);
425 reg32 |= (1 << 19);
426 reg32 |= (1 << 0);
427 reg32 |= (0xf << 1);
428 RCBA32(CG) = reg32;
430 RCBA32_OR(0x38c0, 0x7);
431 RCBA32_OR(0x36d4, 0x6680c004);
432 RCBA32_OR(0x3564, 0x3);
435 static void pch_set_acpi_mode(void)
437 if (!acpi_is_wakeup_s3() && CONFIG(HAVE_SMI_HANDLER)) {
438 #if ENABLE_ACPI_MODE_IN_COREBOOT
439 printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n");
440 outb(APM_CNT_ACPI_ENABLE, APM_CNT); // Enable ACPI mode
441 printk(BIOS_DEBUG, "done.\n");
442 #else
443 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
444 outb(APM_CNT_ACPI_DISABLE, APM_CNT); // Disable ACPI mode
445 printk(BIOS_DEBUG, "done.\n");
446 #endif
450 static void pch_disable_smm_only_flashing(struct device *dev)
452 u8 reg8;
454 printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... ");
455 reg8 = pci_read_config8(dev, BIOS_CNTL);
456 reg8 &= ~(1 << 5);
457 pci_write_config8(dev, BIOS_CNTL, reg8);
460 static void pch_fixups(struct device *dev)
463 * Enable DMI ASPM in the PCH
465 RCBA32_AND_OR(0x2304, ~(1 << 10), 0);
466 RCBA32_OR(0x21a4, (1 << 11)|(1 << 10));
467 RCBA32_OR(0x21a8, 0x3);
470 static void pch_decode_init(struct device *dev)
472 config_t *config = dev->chip_info;
474 printk(BIOS_DEBUG, "pch_decode_init\n");
476 pci_write_config32(dev, LPC_GEN1_DEC, config->gen1_dec);
477 pci_write_config32(dev, LPC_GEN2_DEC, config->gen2_dec);
478 pci_write_config32(dev, LPC_GEN3_DEC, config->gen3_dec);
479 pci_write_config32(dev, LPC_GEN4_DEC, config->gen4_dec);
482 static void lpc_init(struct device *dev)
484 printk(BIOS_DEBUG, "pch: lpc_init\n");
486 /* Set the value for PCI command register. */
487 pci_write_config16(dev, PCI_COMMAND, 0x000f);
489 /* IO APIC initialization. */
490 pch_enable_ioapic(dev);
492 pch_enable_serial_irqs(dev);
494 /* Setup the PIRQ. */
495 pch_pirq_init(dev);
497 /* Setup power options. */
498 pch_power_options(dev);
500 /* Initialize power management */
501 switch (pch_silicon_type()) {
502 case PCH_TYPE_MOBILE5:
503 mobile5_pm_init (dev);
504 break;
505 default:
506 printk(BIOS_ERR, "Unknown Chipset: 0x%04x\n", dev->device);
509 /* Set the state of the GPIO lines. */
510 //gpio_init(dev);
512 /* Initialize the real time clock. */
513 pch_rtc_init(dev);
515 /* Initialize ISA DMA. */
516 isa_dma_init();
518 /* Initialize the High Precision Event Timers, if present. */
519 enable_hpet();
521 /* Initialize Clock Gating */
522 enable_clock_gating(dev);
524 setup_i8259();
526 /* The OS should do this? */
527 /* Interrupt 9 should be level triggered (SCI) */
528 i8259_configure_irq_trigger(9, 1);
530 pch_disable_smm_only_flashing(dev);
532 pch_set_acpi_mode();
534 pch_fixups(dev);
537 static void pch_lpc_read_resources(struct device *dev)
539 struct resource *res;
540 config_t *config = dev->chip_info;
541 u8 io_index = 0;
543 /* Get the normal PCI resources of this device. */
544 pci_dev_read_resources(dev);
546 /* Add an extra subtractive resource for both memory and I/O. */
547 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
548 res->base = 0;
549 res->size = 0x1000;
550 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
551 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
553 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
554 res->base = 0xff800000;
555 res->size = 0x00800000; /* 8 MB for flash */
556 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
557 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
559 res = new_resource(dev, 3); /* IOAPIC */
560 res->base = IO_APIC_ADDR;
561 res->size = 0x00001000;
562 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
564 /* Set PCH IO decode ranges if required.*/
565 if ((config->gen1_dec & 0xFFFC) > 0x1000) {
566 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
567 res->base = config->gen1_dec & 0xFFFC;
568 res->size = (config->gen1_dec >> 16) & 0xFC;
569 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
570 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
573 if ((config->gen2_dec & 0xFFFC) > 0x1000) {
574 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
575 res->base = config->gen2_dec & 0xFFFC;
576 res->size = (config->gen2_dec >> 16) & 0xFC;
577 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
578 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
581 if ((config->gen3_dec & 0xFFFC) > 0x1000) {
582 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
583 res->base = config->gen3_dec & 0xFFFC;
584 res->size = (config->gen3_dec >> 16) & 0xFC;
585 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
586 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
589 if ((config->gen4_dec & 0xFFFC) > 0x1000) {
590 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
591 res->base = config->gen4_dec & 0xFFFC;
592 res->size = (config->gen4_dec >> 16) & 0xFC;
593 res->flags = IORESOURCE_IO| IORESOURCE_SUBTRACTIVE |
594 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
598 static void pch_lpc_enable_resources(struct device *dev)
600 pch_decode_init(dev);
601 return pci_dev_enable_resources(dev);
604 static void pch_lpc_enable(struct device *dev)
606 /* Enable PCH Display Port */
607 RCBA16(DISPBDF) = 0x0010;
608 RCBA32_OR(FD2, PCH_ENABLE_DBDF);
610 pch_enable(dev);
613 static void southbridge_inject_dsdt(struct device *dev)
615 global_nvs_t *gnvs = cbmem_add (CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
617 if (gnvs) {
618 const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
619 memset(gnvs, 0, sizeof(*gnvs));
621 acpi_create_gnvs(gnvs);
623 gnvs->apic = 1;
624 gnvs->mpen = 1; /* Enable Multi Processing */
625 gnvs->pcnt = dev_count_cpu();
627 if (gfx) {
628 gnvs->ndid = gfx->ndid;
629 memcpy(gnvs->did, gfx->did, sizeof(gnvs->did));
632 /* And tell SMI about it */
633 smm_setup_structures(gnvs, NULL, NULL);
635 /* Add it to SSDT. */
636 acpigen_write_scope("\\");
637 acpigen_write_name_dword("NVSA", (u32) gnvs);
638 acpigen_pop_len();
642 void acpi_fill_fadt(acpi_fadt_t *fadt)
644 struct device *dev = pcidev_on_root(0x1f, 0);
645 config_t *chip = dev->chip_info;
646 u16 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
647 int c2_latency;
649 fadt->reserved = 0;
651 fadt->sci_int = 0x9;
652 fadt->smi_cmd = APM_CNT;
653 fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
654 fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
655 fadt->s4bios_req = 0x0;
656 fadt->pstate_cnt = 0;
658 fadt->pm1a_evt_blk = pmbase;
659 fadt->pm1b_evt_blk = 0x0;
660 fadt->pm1a_cnt_blk = pmbase + 0x4;
661 fadt->pm1b_cnt_blk = 0x0;
662 fadt->pm2_cnt_blk = pmbase + 0x50;
663 fadt->pm_tmr_blk = pmbase + 0x8;
664 fadt->gpe0_blk = pmbase + 0x20;
665 fadt->gpe1_blk = 0;
667 fadt->pm1_evt_len = 4;
668 fadt->pm1_cnt_len = 2;
669 fadt->pm2_cnt_len = 1;
670 fadt->pm_tmr_len = 4;
671 fadt->gpe0_blk_len = 16;
672 fadt->gpe1_blk_len = 0;
673 fadt->gpe1_base = 0;
674 fadt->cst_cnt = 0;
675 c2_latency = chip->c2_latency;
676 if (!c2_latency) {
677 c2_latency = 101; /* c2 unsupported */
679 fadt->p_lvl2_lat = c2_latency;
680 fadt->p_lvl3_lat = 87;
681 fadt->flush_size = 1024;
682 fadt->flush_stride = 16;
683 fadt->duty_offset = 1;
684 if (chip->p_cnt_throttling_supported) {
685 fadt->duty_width = 3;
686 } else {
687 fadt->duty_width = 0;
689 fadt->day_alrm = 0xd;
690 fadt->mon_alrm = 0x00;
691 fadt->century = 0x32;
692 fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
694 fadt->flags = ACPI_FADT_WBINVD |
695 ACPI_FADT_C1_SUPPORTED |
696 ACPI_FADT_SLEEP_BUTTON |
697 ACPI_FADT_RESET_REGISTER |
698 ACPI_FADT_S4_RTC_WAKE |
699 ACPI_FADT_PLATFORM_CLOCK;
700 if (chip->docking_supported) {
701 fadt->flags |= ACPI_FADT_DOCKING_SUPPORTED;
703 if (c2_latency < 100) {
704 fadt->flags |= ACPI_FADT_C2_MP_SUPPORTED;
707 fadt->reset_reg.space_id = 1;
708 fadt->reset_reg.bit_width = 8;
709 fadt->reset_reg.bit_offset = 0;
710 fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
711 fadt->reset_reg.addrl = 0xcf9;
712 fadt->reset_reg.addrh = 0;
714 fadt->reset_value = 6;
716 fadt->x_pm1a_evt_blk.space_id = 1;
717 fadt->x_pm1a_evt_blk.bit_width = 32;
718 fadt->x_pm1a_evt_blk.bit_offset = 0;
719 fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
720 fadt->x_pm1a_evt_blk.addrl = pmbase;
721 fadt->x_pm1a_evt_blk.addrh = 0x0;
723 fadt->x_pm1b_evt_blk.space_id = 1;
724 fadt->x_pm1b_evt_blk.bit_width = 0;
725 fadt->x_pm1b_evt_blk.bit_offset = 0;
726 fadt->x_pm1b_evt_blk.access_size = 0;
727 fadt->x_pm1b_evt_blk.addrl = 0x0;
728 fadt->x_pm1b_evt_blk.addrh = 0x0;
730 fadt->x_pm1a_cnt_blk.space_id = 1;
731 fadt->x_pm1a_cnt_blk.bit_width = 16;
732 fadt->x_pm1a_cnt_blk.bit_offset = 0;
733 fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
734 fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
735 fadt->x_pm1a_cnt_blk.addrh = 0x0;
737 fadt->x_pm1b_cnt_blk.space_id = 1;
738 fadt->x_pm1b_cnt_blk.bit_width = 0;
739 fadt->x_pm1b_cnt_blk.bit_offset = 0;
740 fadt->x_pm1b_cnt_blk.access_size = 0;
741 fadt->x_pm1b_cnt_blk.addrl = 0x0;
742 fadt->x_pm1b_cnt_blk.addrh = 0x0;
744 fadt->x_pm2_cnt_blk.space_id = 1;
745 fadt->x_pm2_cnt_blk.bit_width = 8;
746 fadt->x_pm2_cnt_blk.bit_offset = 0;
747 fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
748 fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
749 fadt->x_pm2_cnt_blk.addrh = 0x0;
751 fadt->x_pm_tmr_blk.space_id = 1;
752 fadt->x_pm_tmr_blk.bit_width = 32;
753 fadt->x_pm_tmr_blk.bit_offset = 0;
754 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
755 fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
756 fadt->x_pm_tmr_blk.addrh = 0x0;
758 fadt->x_gpe0_blk.space_id = 1;
759 fadt->x_gpe0_blk.bit_width = 128;
760 fadt->x_gpe0_blk.bit_offset = 0;
761 fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
762 fadt->x_gpe0_blk.addrl = pmbase + 0x20;
763 fadt->x_gpe0_blk.addrh = 0x0;
765 fadt->x_gpe1_blk.space_id = 1;
766 fadt->x_gpe1_blk.bit_width = 0;
767 fadt->x_gpe1_blk.bit_offset = 0;
768 fadt->x_gpe1_blk.access_size = 0;
769 fadt->x_gpe1_blk.addrl = 0x0;
770 fadt->x_gpe1_blk.addrh = 0x0;
773 static const char *lpc_acpi_name(const struct device *dev)
775 return "LPCB";
778 static void southbridge_fill_ssdt(struct device *device)
780 struct device *dev = pcidev_on_root(0x1f, 0);
781 config_t *chip = dev->chip_info;
783 intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
784 intel_acpi_gen_def_acpi_pirq(dev);
787 static void lpc_final(struct device *dev)
789 spi_finalize_ops();
791 /* Call SMM finalize() handlers before resume */
792 if (CONFIG(HAVE_SMI_HANDLER)) {
793 if (CONFIG(INTEL_CHIPSET_LOCKDOWN) ||
794 acpi_is_wakeup_s3()) {
795 outb(APM_CNT_FINALIZE, APM_CNT);
800 static struct pci_operations pci_ops = {
801 .set_subsystem = pci_dev_set_subsystem,
804 static struct device_operations device_ops = {
805 .read_resources = pch_lpc_read_resources,
806 .set_resources = pci_dev_set_resources,
807 .enable_resources = pch_lpc_enable_resources,
808 .acpi_inject_dsdt_generator = southbridge_inject_dsdt,
809 .acpi_fill_ssdt_generator = southbridge_fill_ssdt,
810 .acpi_name = lpc_acpi_name,
811 .write_acpi_tables = acpi_write_hpet,
812 .init = lpc_init,
813 .final = lpc_final,
814 .enable = pch_lpc_enable,
815 .scan_bus = scan_lpc_bus,
816 .ops_pci = &pci_ops,
820 static const unsigned short pci_device_ids[] = { 0x3b07, 0x3b09, 0 };
822 static const struct pci_driver pch_lpc __pci_driver = {
823 .ops = &device_ops,
824 .vendor = PCI_VENDOR_ID_INTEL,
825 .devices = pci_device_ids,