1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ids.h>
7 #include <device/pci_ops.h>
9 #include <pc80/isa-dma.h>
10 #include <pc80/i8259.h>
12 #include <arch/ioapic.h>
13 #include <acpi/acpi.h>
14 #include <acpi/acpigen.h>
15 #include <cpu/x86/smm.h>
19 #include <northbridge/intel/sandybridge/sandybridge.h>
20 #include <southbridge/intel/common/pciehp.h>
21 #include <southbridge/intel/common/acpi_pirq_gen.h>
22 #include <southbridge/intel/common/pmutil.h>
23 #include <southbridge/intel/common/rcba_pirq.h>
24 #include <southbridge/intel/common/rtc.h>
25 #include <southbridge/intel/common/spi.h>
30 typedef struct southbridge_intel_bd82x6x_config config_t
;
33 * Set miscellaneous static southbridge features.
35 * @param dev PCI device with I/O APIC control registers
37 static void pch_enable_ioapic(struct device
*dev
)
39 /* Assign unique bus/dev/fn for I/O APIC */
40 pci_write_config16(dev
, LPC_IBDF
,
41 PCH_IOAPIC_PCI_BUS
<< 8 | PCH_IOAPIC_PCI_SLOT
<< 3);
43 /* affirm full set of redirection table entries ("write once") */
44 ioapic_lock_max_vectors(IO_APIC_ADDR
);
46 register_new_ioapic_gsi0(IO_APIC_ADDR
);
49 static void pch_enable_serial_irqs(struct device
*dev
)
51 /* Set packet length and toggle silent mode bit for one frame. */
52 pci_write_config8(dev
, SERIRQ_CNTL
,
53 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
54 #if !CONFIG(SERIRQ_CONTINUOUS_MODE)
55 pci_write_config8(dev
, SERIRQ_CNTL
,
56 (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
60 /* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
61 * 0x00 - 0000 = Reserved
62 * 0x01 - 0001 = Reserved
63 * 0x02 - 0010 = Reserved
69 * 0x08 - 1000 = Reserved
74 * 0x0D - 1101 = Reserved
77 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
78 * 0x80 - The PIRQ is not routed.
81 static void pch_pirq_init(struct device
*dev
)
83 struct device
*irq_dev
;
84 /* Interrupt 11 is not used by legacy devices and so can always be used for
85 PCI interrupts. Full legacy IRQ routing is complicated and hard to
86 get right. Fortunately all modern OS use MSI and so it's not that big of
87 an issue anyway. Still we have to provide a reasonable default. Using
88 interrupt 11 for it everywhere is a working default. ACPI-aware OS can
89 move it to any interrupt and others will just leave them at default.
91 const u8 pirq_routing
= 11;
93 pci_write_config8(dev
, PIRQA_ROUT
, pirq_routing
);
94 pci_write_config8(dev
, PIRQB_ROUT
, pirq_routing
);
95 pci_write_config8(dev
, PIRQC_ROUT
, pirq_routing
);
96 pci_write_config8(dev
, PIRQD_ROUT
, pirq_routing
);
98 pci_write_config8(dev
, PIRQE_ROUT
, pirq_routing
);
99 pci_write_config8(dev
, PIRQF_ROUT
, pirq_routing
);
100 pci_write_config8(dev
, PIRQG_ROUT
, pirq_routing
);
101 pci_write_config8(dev
, PIRQH_ROUT
, pirq_routing
);
103 for (irq_dev
= all_devices
; irq_dev
; irq_dev
= irq_dev
->next
) {
106 if (!is_enabled_pci(irq_dev
))
109 int_pin
= pci_read_config8(irq_dev
, PCI_INTERRUPT_PIN
);
114 pci_write_config8(irq_dev
, PCI_INTERRUPT_LINE
, pirq_routing
);
118 static void pch_gpi_routing(struct device
*dev
)
120 /* Get the chip configuration */
121 config_t
*config
= dev
->chip_info
;
124 /* An array would be much nicer here, or some
125 * other method of doing this.
127 reg32
|= (config
->gpi0_routing
& 0x03) << 0;
128 reg32
|= (config
->gpi1_routing
& 0x03) << 2;
129 reg32
|= (config
->gpi2_routing
& 0x03) << 4;
130 reg32
|= (config
->gpi3_routing
& 0x03) << 6;
131 reg32
|= (config
->gpi4_routing
& 0x03) << 8;
132 reg32
|= (config
->gpi5_routing
& 0x03) << 10;
133 reg32
|= (config
->gpi6_routing
& 0x03) << 12;
134 reg32
|= (config
->gpi7_routing
& 0x03) << 14;
135 reg32
|= (config
->gpi8_routing
& 0x03) << 16;
136 reg32
|= (config
->gpi9_routing
& 0x03) << 18;
137 reg32
|= (config
->gpi10_routing
& 0x03) << 20;
138 reg32
|= (config
->gpi11_routing
& 0x03) << 22;
139 reg32
|= (config
->gpi12_routing
& 0x03) << 24;
140 reg32
|= (config
->gpi13_routing
& 0x03) << 26;
141 reg32
|= (config
->gpi14_routing
& 0x03) << 28;
142 reg32
|= (config
->gpi15_routing
& 0x03) << 30;
144 pci_write_config32(dev
, GPIO_ROUT
, reg32
);
147 static void pch_power_options(struct device
*dev
)
153 /* Get the chip configuration */
154 config_t
*config
= dev
->chip_info
;
156 /* Which state do we want to goto after g3 (power restored)?
160 * If the option is not existent (Laptops), use Kconfig setting.
162 const unsigned int pwr_on
= get_uint_option("power_on_after_fail",
163 CONFIG_MAINBOARD_POWER_FAILURE_STATE
);
165 reg16
= pci_read_config16(dev
, GEN_PMCON_3
);
168 case MAINBOARD_POWER_OFF
:
172 case MAINBOARD_POWER_ON
:
176 case MAINBOARD_POWER_KEEP
:
178 state
= "state keep";
184 reg16
&= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */
185 reg16
|= (1 << 3); /* SLP_S4# Assertion Stretch Enable */
188 reg16
|= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */
190 reg16
|= (1 << 12); /* Disable SLP stretch after SUS well */
192 pci_write_config16(dev
, GEN_PMCON_3
, reg16
);
193 printk(BIOS_INFO
, "Set power %s after power failure.\n", state
);
195 /* Set up NMI on errors. */
197 reg8
&= 0x0f; /* Higher Nibble must be 0 */
198 reg8
&= ~(1 << 3); /* IOCHK# NMI Enable */
199 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
200 reg8
|= (1 << 2); /* PCI SERR# Disable for now */
204 const unsigned int nmi_option
= get_uint_option("nmi", NMI_OFF
);
206 printk(BIOS_INFO
, "NMI sources enabled.\n");
207 reg8
&= ~(1 << 7); /* Set NMI. */
209 printk(BIOS_INFO
, "NMI sources disabled.\n");
210 reg8
|= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
214 /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
215 reg16
= pci_read_config16(dev
, GEN_PMCON_1
);
216 reg16
&= ~(3 << 0); // SMI# rate 1 minute
217 reg16
&= ~(1 << 10); // Disable BIOS_PCI_EXP_EN for native PME
218 if (CONFIG(DEBUG_PERIODIC_SMI
))
219 reg16
|= (3 << 0); // Periodic SMI every 8s
220 pci_write_config16(dev
, GEN_PMCON_1
, reg16
);
222 // Set the board's GPI routing.
223 pch_gpi_routing(dev
);
225 pmbase
= pci_read_config16(dev
, 0x40) & 0xfffe;
227 outl(config
->gpe0_en
, pmbase
+ GPE0_EN
);
228 outw(config
->alt_gp_smi_en
, pmbase
+ ALT_GP_SMI_EN
);
230 /* Set up power management block and determine sleep mode */
231 reg32
= inl(pmbase
+ 0x04); // PM1_CNT
232 reg32
&= ~(7 << 10); // SLP_TYP
233 reg32
|= (1 << 0); // SCI_EN
234 outl(reg32
, pmbase
+ 0x04);
236 /* Clear magic status bits to prevent unexpected wake */
237 reg32
= RCBA32(PRSTS
);
238 reg32
|= (1 << 4)|(1 << 5)|(1 << 0);
239 RCBA32(PRSTS
) = reg32
;
241 reg32
= RCBA32(0x3f02);
243 RCBA32(0x3f02) = reg32
;
246 /* CougarPoint PCH Power Management init */
247 static void cpt_pm_init(struct device
*dev
)
249 printk(BIOS_DEBUG
, "CougarPoint PM init\n");
250 pci_write_config8(dev
, 0xa9, 0x47);
251 RCBA32_AND_OR(CIR30
, ~0U, (1 << 6)|(1 << 0));
252 RCBA32_AND_OR(CIR5
, ~0U, (1 << 0));
253 RCBA16_AND_OR(CIR3
, ~0U, (1 << 13)|(1 << 14));
254 RCBA16_AND_OR(CIR2
, ~0U, (1 << 14));
255 RCBA32(DMC
) = 0xc0388400;
256 RCBA32_AND_OR(CIR6
, ~0U, (1 << 5)|(1 << 18));
257 RCBA32_AND_OR(CIR9
, ~0U, (1 << 15)|(1 << 1));
258 RCBA32_AND_OR(CIR7
, ~0x1f, 0xf);
259 RCBA32(PM_CFG
) = 0x050f0000;
260 RCBA32(CIR8
) = 0x04000000;
261 RCBA32_AND_OR(CIR10
, ~0U, 0xfffff);
262 RCBA32_AND_OR(CIR11
, ~0U, (1 << 1));
263 RCBA32(CIR12
) = 0x0001c000;
264 RCBA32(CIR14
) = 0x00061100;
265 RCBA32(CIR15
) = 0x7f8fdfff;
266 RCBA32(CIR13
) = 0x000003fc;
267 RCBA32(CIR16
) = 0x00001000;
268 RCBA32(CIR18
) = 0x0001c000;
269 RCBA32(CIR17
) = 0x00000800;
270 RCBA32(CIR23
) = 0x00001000;
271 RCBA32(CIR19
) = 0x00093900;
272 RCBA32(CIR20
) = 0x24653002;
273 RCBA32(CIR21
) = 0x062108fe;
274 RCBA32_AND_OR(CIR22
, 0xf000f000, 0x00670060);
275 RCBA32(CIR24
) = 0x01010000;
276 RCBA32(CIR25
) = 0x01010404;
277 RCBA32(CIR27
) = 0x01041041;
278 RCBA32_AND_OR(CIR28
, ~0x0000ffff, 0x00001001);
279 RCBA32_AND_OR(CIR28
, ~0UL, (1 << 24)); /* SATA 2/3 disabled */
280 RCBA32_AND_OR(CIR29
, ~0UL, (1 << 0)); /* SATA 4/5 disabled */
281 RCBA32(CIR26
) = 0x00000001;
282 RCBA32_AND_OR(0x2344, 0x00ffff00, 0xff00000c);
283 RCBA32_AND_OR(0x80c, ~(0xff << 20), 0x11 << 20);
284 RCBA32(PMSYNC_CFG
) = 0;
285 RCBA32_AND_OR(0x21b0, ~0UL, 0xf);
288 /* PantherPoint PCH Power Management init */
289 static void ppt_pm_init(struct device
*dev
)
291 printk(BIOS_DEBUG
, "PantherPoint PM init\n");
292 pci_write_config8(dev
, 0xa9, 0x47);
293 RCBA32_AND_OR(CIR30
, ~0UL, (1 << 0));
294 RCBA32_AND_OR(CIR5
, ~0UL, (1 << 0));
295 RCBA16_AND_OR(CIR3
, ~0UL, (1 << 13)|(1 << 14));
296 RCBA16_AND_OR(CIR2
, ~0UL, (1 << 14));
297 RCBA32(DMC
) = 0xc03b8400;
298 RCBA32_AND_OR(CIR6
, ~0UL, (1 << 5)|(1 << 18));
299 RCBA32_AND_OR(CIR9
, ~0UL, (1 << 15)|(1 << 1));
300 RCBA32_AND_OR(CIR7
, ~0x1f, 0xf);
301 RCBA32(PM_CFG
) = 0x054f0000;
302 RCBA32(CIR8
) = 0x04000000;
303 RCBA32_AND_OR(CIR10
, ~0UL, 0xfffff);
304 RCBA32_AND_OR(CIR11
, ~0UL, (1 << 1)|(1 << 0));
305 RCBA32(CIR12
) = 0x0001c000;
306 RCBA32(CIR14
) = 0x00061100;
307 RCBA32(CIR15
) = 0x7f8fdfff;
308 RCBA32(CIR13
) = 0x000003fd;
309 RCBA32(CIR16
) = 0x00001000;
310 RCBA32(CIR18
) = 0x0001c000;
311 RCBA32(CIR17
) = 0x00000800;
312 RCBA32(CIR23
) = 0x00001000;
313 RCBA32(CIR19
) = 0x00093900;
314 RCBA32(CIR20
) = 0x24653002;
315 RCBA32(CIR21
) = 0x067388fe;
316 RCBA32_AND_OR(CIR22
, 0xf000f000, 0x00670060);
317 RCBA32(CIR24
) = 0x01010000;
318 RCBA32(CIR25
) = 0x01010404;
319 RCBA32(CIR27
) = 0x01040000;
320 RCBA32_AND_OR(CIR28
, ~0x0000ffff, 0x00001001);
321 RCBA32_AND_OR(CIR28
, ~0UL, (1 << 24)); /* SATA 2/3 disabled */
322 RCBA32_AND_OR(CIR29
, ~0UL, (1 << 0)); /* SATA 4/5 disabled */
323 RCBA32(CIR26
) = 0x00000001;
324 RCBA32_AND_OR(0x2344, 0x00ffff00, 0xff00000c);
325 RCBA32_AND_OR(0x80c, ~(0xff << 20), 0x11 << 20);
326 RCBA32_AND_OR(0x33a4, ~0UL, (1 << 0));
327 RCBA32(PMSYNC_CFG
) = 0;
328 RCBA32_AND_OR(0x21b0, ~0UL, 0xf);
331 static void enable_hpet(struct device
*const dev
)
336 /* Assign unique bus/dev/fn for each HPET */
337 for (i
= 0; i
< 8; ++i
)
338 pci_write_config16(dev
, LPC_HnBDF(i
),
339 PCH_HPET_PCI_BUS
<< 8 | PCH_HPET_PCI_SLOT
<< 3 | i
);
341 /* Move HPET to default address 0xfed00000 and enable it */
342 reg32
= RCBA32(HPTC
);
343 reg32
|= (1 << 7); // HPET Address Enable
345 RCBA32(HPTC
) = reg32
;
348 static void enable_clock_gating(struct device
*dev
)
353 RCBA32_AND_OR(DMIC
, ~0UL, 0xf);
355 reg16
= pci_read_config16(dev
, GEN_PMCON_1
);
356 reg16
&= ~(3 << 2); /* Clear CLKRUN bits for mobile and desktop */
357 if (get_platform_type() == PLATFORM_MOBILE
)
358 reg16
|= (1 << 2); /* CLKRUN_EN for mobile */
359 else if (get_platform_type() == PLATFORM_DESKTOP_SERVER
)
360 reg16
|= (1 << 3); /* PSEUDO_CLKRUN_EN for desktop */
362 pci_write_config16(dev
, GEN_PMCON_1
, reg16
);
364 pch_iobp_update(0xEB007F07, ~0U, (1 << 31));
365 pch_iobp_update(0xEB004000, ~0U, (1 << 7));
366 pch_iobp_update(0xEC007F07, ~0U, (1 << 31));
367 pch_iobp_update(0xEC004000, ~0U, (1 << 7));
371 reg32
|= (1 << 29) | (1 << 28);
372 reg32
|= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
384 RCBA32_OR(0x38c0, 0x7);
385 RCBA32_OR(0x36d4, 0x6680c004);
386 RCBA32_OR(0x3564, 0x3);
389 static void pch_set_acpi_mode(void)
391 if (!acpi_is_wakeup_s3()) {
392 apm_control(APM_CNT_ACPI_DISABLE
);
396 static void pch_fixups(struct device
*dev
)
398 /* Indicate DRAM init done for MRC S3 to know it can resume */
399 pci_or_config8(dev
, GEN_PMCON_2
, 1 << 7);
402 * Enable DMI ASPM in the PCH
404 RCBA32_AND_OR(DMC
, ~(1 << 10), 0);
405 RCBA32_OR(LCAP
, (1 << 11)|(1 << 10));
406 RCBA32_OR(LCTL
, 0x3);
409 static void pch_spi_init(const struct device
*const dev
)
411 const config_t
*const config
= dev
->chip_info
;
413 printk(BIOS_DEBUG
, "%s\n", __func__
);
415 if (config
->spi_uvscc
)
416 RCBA32(0x3800 + 0xc8) = config
->spi_uvscc
;
417 if (config
->spi_lvscc
)
418 RCBA32(0x3800 + 0xc4) = config
->spi_lvscc
;
420 if (config
->spi_uvscc
|| config
->spi_lvscc
)
421 RCBA32_OR(0x3800 + 0xc4, 1 << 23); /* lock both UVSCC + LVSCC */
424 static const struct {
426 const char *dev_name
;
428 /* 6-series PCI ids from
429 * Intel® 6 Series Chipset and
430 * Intel® C200 Series Chipset
431 * Specification Update - NDA
435 {PCI_DID_INTEL_6_SERIES_MOBILE_SFF
, "SFF Sample"},
436 {PCI_DID_INTEL_6_DESKTOP_SAMPLE
, "Desktop Sample"},
437 {PCI_DID_INTEL_6_SERIES_MOBILE
, "Mobile Sample"},
438 {PCI_DID_INTEL_6_SERIES_Z68
, "Z68"},
439 {PCI_DID_INTEL_6_SERIES_P67
, "P67"},
440 {PCI_DID_INTEL_6_SERIES_UM67
, "UM67"},
441 {PCI_DID_INTEL_6_SERIES_HM65
, "HM65"},
442 {PCI_DID_INTEL_6_SERIES_H67
, "H67"},
443 {PCI_DID_INTEL_6_SERIES_HM67
, "HM67"},
444 {PCI_DID_INTEL_6_SERIES_Q65
, "Q65"},
445 {PCI_DID_INTEL_6_SERIES_QS67
, "QS67"},
446 {PCI_DID_INTEL_6_SERIES_Q67
, "Q67"},
447 {PCI_DID_INTEL_6_SERIES_QM67
, "QM67"},
448 {PCI_DID_INTEL_6_SERIES_B65
, "B65"},
449 {PCI_DID_INTEL_6_SERIES_C202
, "C202"},
450 {PCI_DID_INTEL_6_SERIES_C204
, "C204"},
451 {PCI_DID_INTEL_6_SERIES_C206
, "C206"},
452 {PCI_DID_INTEL_6_SERIES_H61
, "H61"},
454 /* 7-series PCI ids from Intel document 472178 */
455 {PCI_DID_INTEL_7_SERIES_DESKTOP_SAMPLE
, "Desktop Sample"},
456 {PCI_DID_INTEL_7_SERIES_MOBILE
, "Mobile Sample"},
457 {PCI_DID_INTEL_7_SERIES_MOBILE_SFF
, "SFF Sample"},
458 {PCI_DID_INTEL_7_SERIES_Z77
, "Z77"},
459 {PCI_DID_INTEL_7_SERIES_H71
, "H71"},
460 {PCI_DID_INTEL_7_SERIES_Z75
, "Z75"},
461 {PCI_DID_INTEL_7_SERIES_Q77
, "Q77"},
462 {PCI_DID_INTEL_7_SERIES_Q75
, "Q75"},
463 {PCI_DID_INTEL_7_SERIES_B75
, "B75"},
464 {PCI_DID_INTEL_7_SERIES_H77
, "H77"},
465 {PCI_DID_INTEL_7_SERIES_C216
, "C216"},
466 {PCI_DID_INTEL_7_SERIES_QM77
, "QM77"},
467 {PCI_DID_INTEL_7_SERIES_QS77
, "QS77"},
468 {PCI_DID_INTEL_7_SERIES_UM77
, "UM77"},
469 {PCI_DID_INTEL_7_SERIES_HM77
, "HM77"},
470 {PCI_DID_INTEL_7_SERIES_HM76
, "HM76"},
471 {PCI_DID_INTEL_7_SERIES_HM75
, "HM75"},
472 {PCI_DID_INTEL_7_SERIES_HM70
, "HM70"},
473 {PCI_DID_INTEL_7_SERIES_NM70
, "NM70"},
476 static void report_pch_info(struct device
*dev
)
478 const u16 dev_id
= pci_read_config16(dev
, PCI_DEVICE_ID
);
481 const char *pch_type
= "Unknown";
482 for (i
= 0; i
< ARRAY_SIZE(pch_table
); i
++) {
483 if (pch_table
[i
].dev_id
== dev_id
) {
484 pch_type
= pch_table
[i
].dev_name
;
488 printk(BIOS_INFO
, "PCH: detected %s, device id: 0x%x, rev id 0x%x\n",
489 pch_type
, dev_id
, pci_read_config8(dev
, PCI_CLASS_REVISION
));
492 static void lpc_init(struct device
*dev
)
494 printk(BIOS_DEBUG
, "pch: %s\n", __func__
);
496 /* Print detected platform */
497 report_pch_info(dev
);
499 /* IO APIC initialization. */
500 pch_enable_ioapic(dev
);
502 pch_enable_serial_irqs(dev
);
504 /* Setup the PIRQ. */
507 /* Setup power options. */
508 pch_power_options(dev
);
510 /* Initialize power management */
511 switch (pch_silicon_type()) {
512 case PCH_TYPE_CPT
: /* CougarPoint */
515 case PCH_TYPE_PPT
: /* PantherPoint */
519 printk(BIOS_ERR
, "Unknown Chipset: 0x%04x\n", dev
->device
);
522 /* Initialize the real time clock. */
525 /* Initialize ISA DMA. */
528 /* Initialize the High Precision Event Timers, if present. */
531 /* Initialize Clock Gating */
532 enable_clock_gating(dev
);
536 /* The OS should do this? */
537 /* Interrupt 9 should be level triggered (SCI) */
538 i8259_configure_irq_trigger(9, 1);
547 static void pch_lpc_read_resources(struct device
*dev
)
549 struct resource
*res
;
550 config_t
*config
= dev
->chip_info
;
553 /* Get the normal PCI resources of this device. */
554 pci_dev_read_resources(dev
);
556 /* Add an extra subtractive resource for both memory and I/O. */
557 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
560 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
561 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
563 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
564 res
->base
= 0xff000000;
565 /* Some systems (e.g. X230) have 12 MiB flash.
566 SPI controller supports up to 2 x 16 MiB of flash but
567 address map limits this to 16MiB. */
568 res
->size
= 0x01000000; /* 16 MB for flash */
569 res
->flags
= IORESOURCE_MEM
| IORESOURCE_SUBTRACTIVE
|
570 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
572 res
= new_resource(dev
, 3); /* IOAPIC */
573 res
->base
= IO_APIC_ADDR
;
574 res
->size
= 0x00001000;
575 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
577 /* Set PCH IO decode ranges if required.*/
578 if ((config
->gen1_dec
& 0xFFFC) > 0x1000) {
579 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
580 res
->base
= config
->gen1_dec
& 0xFFFC;
581 res
->size
= (config
->gen1_dec
>> 16) & 0xFC;
582 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
583 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
586 if ((config
->gen2_dec
& 0xFFFC) > 0x1000) {
587 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
588 res
->base
= config
->gen2_dec
& 0xFFFC;
589 res
->size
= (config
->gen2_dec
>> 16) & 0xFC;
590 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
591 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
594 if ((config
->gen3_dec
& 0xFFFC) > 0x1000) {
595 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
596 res
->base
= config
->gen3_dec
& 0xFFFC;
597 res
->size
= (config
->gen3_dec
>> 16) & 0xFC;
598 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
599 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
602 if ((config
->gen4_dec
& 0xFFFC) > 0x1000) {
603 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
604 res
->base
= config
->gen4_dec
& 0xFFFC;
605 res
->size
= (config
->gen4_dec
>> 16) & 0xFC;
606 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
607 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
611 static void pch_lpc_enable(struct device
*dev
)
613 /* Enable PCH Display Port */
614 RCBA16(DISPBDF
) = 0x0010;
615 RCBA32_OR(FD2
, PCH_ENABLE_DBDF
);
620 static const char *lpc_acpi_name(const struct device
*dev
)
625 static void southbridge_fill_ssdt(const struct device
*device
)
627 struct device
*dev
= pcidev_on_root(0x1f, 0);
628 config_t
*chip
= dev
->chip_info
;
630 intel_acpi_pcie_hotplug_generator(chip
->pcie_hotplug_map
, 8);
631 intel_acpi_gen_def_acpi_pirq(dev
);
634 static void lpc_final(struct device
*dev
)
638 /* Call SMM finalize() handlers before resume */
639 if (CONFIG(INTEL_CHIPSET_LOCKDOWN
) ||
640 acpi_is_wakeup_s3()) {
641 apm_control(APM_CNT_FINALIZE
);
645 void intel_southbridge_override_spi(
646 struct intel_swseq_spi_config
*spi_config
)
648 struct device
*dev
= pcidev_on_root(0x1f, 0);
652 /* Devicetree may override defaults. */
653 const config_t
*const config
= dev
->chip_info
;
658 if (config
->spi
.ops
[0].op
!= 0)
659 memcpy(spi_config
, &config
->spi
, sizeof(*spi_config
));
662 struct device_operations bd82x6x_lpc_bridge_ops
= {
663 .read_resources
= pch_lpc_read_resources
,
664 .set_resources
= pci_dev_set_resources
,
665 .enable_resources
= pci_dev_enable_resources
,
666 .write_acpi_tables
= acpi_write_hpet
,
667 .acpi_fill_ssdt
= southbridge_fill_ssdt
,
668 .acpi_name
= lpc_acpi_name
,
671 .enable
= pch_lpc_enable
,
672 .scan_bus
= scan_static_bus
,
673 .ops_pci
= &pci_dev_ops_pci
,