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/mmio.h>
8 #include <device/pci_ops.h>
9 #include <arch/ioapic.h>
10 #include <acpi/acpi.h>
11 #include <cpu/x86/smm.h>
12 #include <bootstate.h>
15 #include <soc/pci_devs.h>
16 #include <soc/ramstage.h>
17 #include <soc/iomap.h>
24 /* PCH I/O APIC redirection entries */
25 #define PCH_REDIR_ETR 120
28 * Set miscellaneous static southbridge features.
30 * @param dev PCI device with I/O APIC control registers
32 static void pch_enable_ioapic(struct device
*dev
)
34 /* affirm full set of redirection table entries ("write once") */
35 ioapic_set_max_vectors(IO_APIC_ADDR
, PCH_REDIR_ETR
);
37 register_new_ioapic_gsi0(IO_APIC_ADDR
);
40 /* interrupt router lookup for internal devices */
47 #define DEVFN(dev, fn) ((dev << 3) | (fn))
49 static const struct dnv_ir_lut dnv_ir_lut
[] = {
50 {.devfn
= DEVFN(0x05, 0), .ir
= 3}, /* RCEC */
51 {.devfn
= DEVFN(0x06, 0), .ir
= 4}, /* Virtual RP to QAT */
52 {.devfn
= DEVFN(0x09, 0), .ir
= 7}, /* PCIe RP0 */
53 {.devfn
= DEVFN(0x0a, 0), .ir
= 7}, /* PCIe RP1 */
54 {.devfn
= DEVFN(0x0b, 0), .ir
= 7}, /* PCIe RP2 */
55 {.devfn
= DEVFN(0x0c, 0), .ir
= 7}, /* PCIe RP3 */
56 {.devfn
= DEVFN(0x0e, 0), .ir
= 8}, /* PCIe RP4 */
57 {.devfn
= DEVFN(0x0f, 0), .ir
= 8}, /* PCIe RP5 */
58 {.devfn
= DEVFN(0x10, 0), .ir
= 8}, /* PCIe RP6 */
59 {.devfn
= DEVFN(0x11, 0), .ir
= 8}, /* PCIe RP7 */
60 {.devfn
= DEVFN(0x12, 0), .ir
= 10}, /* SMBus - Host */
61 {.devfn
= DEVFN(0x13, 0), .ir
= 6}, /* AHCI0 */
62 {.devfn
= DEVFN(0x14, 0), .ir
= 11}, /* AHCI1 */
63 {.devfn
= DEVFN(0x15, 0), .ir
= 9}, /* USB */
64 {.devfn
= DEVFN(0x16, 0), .ir
= 1}, /* Virtual RP to LAN0 */
65 {.devfn
= DEVFN(0x17, 0), .ir
= 2}, /* Virtual RP to LAN1 */
66 {.devfn
= DEVFN(0x18, 0), .ir
= 5}, /* ME HECI1 */
67 {.devfn
= DEVFN(0x18, 1), .ir
= 5}, /* ME HECI1 */
68 {.devfn
= DEVFN(0x18, 2), .ir
= 5}, /* ME PTIO-IDER */
69 {.devfn
= DEVFN(0x18, 3), .ir
= 5}, /* ME PTIO-KT */
70 {.devfn
= DEVFN(0x18, 4), .ir
= 5}, /* ME HECI3 */
71 {.devfn
= DEVFN(0x1a, 0), .ir
= 10}, /* HSUART0 */
72 {.devfn
= DEVFN(0x1a, 1), .ir
= 10}, /* HSUART1 */
73 {.devfn
= DEVFN(0x1a, 2), .ir
= 10}, /* HSUART2 */
74 {.devfn
= DEVFN(0x1b, 0), .ir
= 12}, /* IE HECI1 */
75 {.devfn
= DEVFN(0x1b, 1), .ir
= 12}, /* IE HECI1 */
76 {.devfn
= DEVFN(0x1b, 2), .ir
= 12}, /* IE PTIO-IDER */
77 {.devfn
= DEVFN(0x1b, 3), .ir
= 12}, /* IE PTIO-KT */
78 {.devfn
= DEVFN(0x1b, 4), .ir
= 12}, /* IE HECI3 */
79 {.devfn
= DEVFN(0x1c, 0), .ir
= 12}, /* SDHCI */
80 {.devfn
= DEVFN(0x1f, 0), .ir
= 0}, /* LPC */
81 {.devfn
= DEVFN(0x1f, 1), .ir
= 0}, /* PS2B */
82 {.devfn
= DEVFN(0x1f, 4), .ir
= 0}, /* SMBus - Legacy */
83 {.devfn
= DEVFN(0x1f, 7), .ir
= 0}, /* Trace Hub */
87 * Only 6 of the 8 root ports have swizzling, return '1' if this bdf is one of
90 static int is_dnv_swizzled_rp(uint16_t bdf
)
106 * Figure out which upstream interrupt pin a downstream device gets swizzled to
108 * config - pointer to chip_info containing routing info
109 * devfn - device/function of root port to check swizzling for
110 * pin - interrupt pin 1-4 = A-D
112 * Return new pin mapping, 0 if invalid pin
114 static int dnv_get_swizzled_pin(config_t
*config
, u8 devfn
, u8 pin
)
116 if (pin
< 1 || pin
> 4)
125 return ((pin
- 1 + devfn
) % 4) + 1;
129 * Figure out which upstream interrupt pin a downstream device gets swizzled to
131 * config - pointer to chip_info containing routing info
132 * devfn - device/function of root port to check swizzling for
133 * pin - interrupt pin 1-4 = A-D
135 * Return new pin mapping, 0 if invalid pin
137 static int dnv_get_ir(config_t
*config
, u8 devfn
, u8 pin
)
143 /* The only valid pin values are 1-4 for A-D */
144 if (pin
< 1 || pin
> 4) {
145 printk(BIOS_WARNING
, "%s: pin %d is invalid\n", __func__
, pin
);
146 goto dnv_get_ir_done
;
149 for (i
= 0; i
< ARRAY_SIZE(dnv_ir_lut
); i
++) {
150 if (dnv_ir_lut
[i
].devfn
== devfn
)
154 if (i
== ARRAY_SIZE(dnv_ir_lut
)) {
155 printk(BIOS_WARNING
, "%s: no entry\n", __func__
);
156 goto dnv_get_ir_done
;
159 switch (dnv_ir_lut
[i
].ir
) {
161 ir
= config
->ir00_routing
;
164 ir
= config
->ir01_routing
;
167 ir
= config
->ir02_routing
;
170 ir
= config
->ir03_routing
;
173 ir
= config
->ir04_routing
;
176 ir
= config
->ir05_routing
;
179 ir
= config
->ir06_routing
;
182 ir
= config
->ir07_routing
;
185 ir
= config
->ir08_routing
;
188 ir
= config
->ir09_routing
;
191 ir
= config
->ir10_routing
;
194 ir
= config
->ir11_routing
;
197 ir
= config
->ir12_routing
;
200 printk(BIOS_ERR
, "%s: invalid ir %d for entry %d\n", __func__
, dnv_ir_lut
[i
].ir
,
202 goto dnv_get_ir_done
;
205 ir
>>= (pin
- 1) * 4;
209 line
= config
->pirqa_routing
;
212 line
= config
->pirqb_routing
;
215 line
= config
->pirqc_routing
;
218 line
= config
->pirqd_routing
;
221 line
= config
->pirqe_routing
;
224 line
= config
->pirqf_routing
;
227 line
= config
->pirqg_routing
;
230 line
= config
->pirqh_routing
;
233 printk(BIOS_ERR
, "%s: invalid ir pirq %d for entry %d\n", __func__
, ir
, i
);
242 * PCI devices have the INT_LINE (0x3C) and INT_PIN (0x3D) registers which
243 * report interrupt routing information to operating systems and drivers. The
244 * INT_PIN register is generally read only and reports which interrupt pin
245 * A - D it uses. The INT_LINE register is configurable and reports which IRQ
246 * (generally the PIC IRQs 1 - 15) it will use. This needs to take interrupt
247 * pin swizzling on devices that are downstream on a PCI bridge into account.
249 static u8
dnv_get_int_line(struct device
*irq_dev
)
252 struct device
*targ_dev
= NULL
;
253 uint16_t parent_bdf
= 0;
254 int8_t original_int_pin
= 0, new_int_pin
= 0, swiz_int_pin
= 0;
255 uint8_t int_line
= 0xff;
257 if (!is_enabled_pci(irq_dev
)) {
258 printk(BIOS_ERR
, "%s for non pci device?\n", __func__
);
259 goto dnv_get_int_line_done
;
263 * Get the INT_PIN swizzled up to the root port if necessary
264 * using the existing coreboot pci_device code
266 original_int_pin
= pci_read_config8(irq_dev
, PCI_INTERRUPT_PIN
);
267 new_int_pin
= get_pci_irq_pins(irq_dev
, &targ_dev
);
268 if (targ_dev
== NULL
|| new_int_pin
< 1)
269 goto dnv_get_int_line_done
;
271 printk(BIOS_DEBUG
, "%s: irq_dev %s, targ_dev %s:\n", __func__
, dev_path(irq_dev
),
273 printk(BIOS_DEBUG
, "%s: std swizzle %s from %c to %c\n", __func__
, dev_path(targ_dev
),
274 '@' + original_int_pin
, '@' + new_int_pin
);
276 /* Swizzle this device if needed */
277 config
= targ_dev
->chip_info
;
278 parent_bdf
= targ_dev
->path
.pci
.devfn
| targ_dev
->upstream
->secondary
<< 8;
279 if (is_dnv_swizzled_rp(parent_bdf
) && irq_dev
!= targ_dev
) {
280 swiz_int_pin
= dnv_get_swizzled_pin(config
, parent_bdf
, new_int_pin
);
281 printk(BIOS_DEBUG
, "%s: dnv swizzle %s from %c to %c\n", __func__
,
282 dev_path(targ_dev
), '@' + new_int_pin
, '@' + swiz_int_pin
);
284 swiz_int_pin
= new_int_pin
;
287 /* Look up the routing for the pin */
288 int_line
= dnv_get_ir(config
, parent_bdf
, swiz_int_pin
);
290 dnv_get_int_line_done
:
291 printk(BIOS_DEBUG
, "\tINT_LINE\t\t: %d\n", int_line
);
295 /* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
296 * 0x00 - 0000 = Reserved
297 * 0x01 - 0001 = Reserved
298 * 0x02 - 0010 = Reserved
304 * 0x08 - 1000 = Reserved
306 * 0x0A - 1010 = IRQ10
307 * 0x0B - 1011 = IRQ11
308 * 0x0C - 1100 = IRQ12
309 * 0x0D - 1101 = Reserved
310 * 0x0E - 1110 = IRQ14
311 * 0x0F - 1111 = IRQ15
312 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
313 * 0x80 - The PIRQ is not routed.
316 static void pch_pirq_init(struct device
*dev
)
318 struct device
*irq_dev
;
319 /* Get the chip configuration */
320 config_t
*config
= config_of(dev
);
322 /* Initialize PIRQ Routings */
323 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQA_ROUT
),
324 config
->pirqa_routing
);
325 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQB_ROUT
),
326 config
->pirqb_routing
);
327 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQC_ROUT
),
328 config
->pirqc_routing
);
329 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQD_ROUT
),
330 config
->pirqd_routing
);
332 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQE_ROUT
),
333 config
->pirqe_routing
);
334 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQF_ROUT
),
335 config
->pirqf_routing
);
336 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQG_ROUT
),
337 config
->pirqg_routing
);
338 write8((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIRQH_ROUT
),
339 config
->pirqh_routing
);
341 /* Initialize device's Interrupt Routings */
342 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR00
),
343 config
->ir00_routing
);
344 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR01
),
345 config
->ir01_routing
);
346 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR02
),
347 config
->ir02_routing
);
348 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR03
),
349 config
->ir03_routing
);
350 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR04
),
351 config
->ir04_routing
);
352 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR05
),
353 config
->ir05_routing
);
354 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR06
),
355 config
->ir06_routing
);
356 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR07
),
357 config
->ir07_routing
);
358 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR08
),
359 config
->ir08_routing
);
360 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR09
),
361 config
->ir09_routing
);
362 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR10
),
363 config
->ir10_routing
);
364 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR11
),
365 config
->ir11_routing
);
366 write16((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCR_ITSS_PIR12
),
367 config
->ir12_routing
);
369 /* Initialize device's Interrupt Polarity Control */
370 write32((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCH_PCR_ITSS_IPC0
),
372 write32((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCH_PCR_ITSS_IPC1
),
374 write32((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCH_PCR_ITSS_IPC2
),
376 write32((void *)PCH_PCR_ADDRESS(PID_ITSS
, PCH_PCR_ITSS_IPC3
),
379 for (irq_dev
= all_devices
; irq_dev
; irq_dev
= irq_dev
->next
) {
380 int devfn
= irq_dev
->path
.pci
.devfn
;
381 u8 int_pin
= 0, int_line
= 0;
383 if (!is_enabled_pci(irq_dev
))
386 int_pin
= pci_read_config8(irq_dev
, PCI_INTERRUPT_PIN
);
388 int_line
= dnv_get_int_line(irq_dev
);
389 printk(BIOS_DEBUG
, "%s: %02x:%02x.%d pin %d int line %d\n", __func__
,
390 irq_dev
->upstream
->secondary
, devfn
>> 3, devfn
& 0x7, int_pin
, int_line
);
392 pci_write_config8(irq_dev
, PCI_INTERRUPT_LINE
, int_line
);
396 static void pci_p2sb_read_resources(struct device
*dev
)
398 struct resource
*res
;
401 * Use 0xda as an unused index for PCR BAR.
403 res
= new_resource(dev
, 0xda);
404 res
->base
= DEFAULT_PCR_BASE
;
405 res
->size
= 16 * 1024 * 1024; /* 16MB PCR config space */
406 res
->flags
= IORESOURCE_MEM
| IORESOURCE_FIXED
| IORESOURCE_STORED
|
410 * Use 0xdb as an unused index for IOAPIC.
412 res
= new_resource(dev
, 0xdb); /* IOAPIC */
413 res
->base
= IO_APIC_ADDR
;
414 res
->size
= 0x00001000;
415 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
418 static void pch_enable_serial_irqs(struct device
*dev
)
420 /* Set packet length and toggle silent mode bit for one frame. */
421 pci_write_config8(dev
, SERIRQ_CNTL
,
422 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
423 #if !CONFIG(SERIRQ_CONTINUOUS_MODE)
424 pci_write_config8(dev
, SERIRQ_CNTL
,
425 (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
429 static void lpc_init(struct device
*dev
)
431 printk(BIOS_DEBUG
, "pch: %s\n", __func__
);
433 /* Get the base address */
435 /* Set the value for PCI command register. */
436 pci_write_config16(dev
, PCI_COMMAND
,
437 PCI_COMMAND_SPECIAL
| PCI_COMMAND_MASTER
|
438 PCI_COMMAND_MEMORY
| PCI_COMMAND_IO
);
440 /* Serial IRQ initialization. */
441 pch_enable_serial_irqs(dev
);
443 /* IO APIC initialization. */
444 pch_enable_ioapic(dev
);
446 /* Setup the PIRQ. */
450 static void pch_lpc_add_mmio_resources(struct device
*dev
) { /* TODO */ }
452 static void pch_lpc_add_io_resources(struct device
*dev
)
454 struct resource
*res
;
457 /* Add an extra subtractive resource for both memory and I/O. */
458 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
461 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
462 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
464 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(io_index
++, 0));
465 res
->base
= 0xff000000;
466 res
->size
= 0x01000000; /* 16 MB for flash */
467 res
->flags
= IORESOURCE_MEM
| IORESOURCE_SUBTRACTIVE
|
468 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
471 static void lpc_read_resources(struct device
*dev
)
473 /* Get the normal PCI resources of this device. */
474 pci_dev_read_resources(dev
);
476 /* Add non-standard MMIO resources. */
477 pch_lpc_add_mmio_resources(dev
);
479 /* Add IO resources. */
480 pch_lpc_add_io_resources(dev
);
482 /* Add MMIO resource for IOAPIC. */
483 pci_p2sb_read_resources(dev
);
486 static void pch_decode_init(struct device
*dev
) { /* TODO */ }
488 static void lpc_enable_resources(struct device
*dev
)
490 pch_decode_init(dev
);
491 pci_dev_enable_resources(dev
);
494 /* Set bit in Function Disable register to hide this device */
495 static void pch_hide_devfn(uint32_t devfn
) { /* TODO */ }
497 void southcluster_enable_dev(struct device
*dev
)
502 printk(BIOS_DEBUG
, "%s: Disabling device\n", dev_path(dev
));
504 /* Ensure memory, io, and bus master are all disabled */
505 reg16
= pci_read_config16(dev
, PCI_COMMAND
);
506 reg16
&= ~(PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
|
508 pci_write_config16(dev
, PCI_COMMAND
, reg16
);
510 /* Hide this device if possible */
511 pch_hide_devfn(dev
->path
.pci
.devfn
);
514 pci_or_config16(dev
, PCI_COMMAND
, PCI_COMMAND_SERR
);
518 static struct device_operations device_ops
= {
519 .read_resources
= lpc_read_resources
,
520 .set_resources
= pci_dev_set_resources
,
521 #if CONFIG(HAVE_ACPI_TABLES)
522 .write_acpi_tables
= southcluster_write_acpi_tables
,
524 .enable_resources
= lpc_enable_resources
,
526 .enable
= southcluster_enable_dev
,
527 .scan_bus
= scan_static_bus
,
528 .ops_pci
= &soc_pci_ops
,
531 static const struct pci_driver lpc_driver __pci_driver
= {
533 .vendor
= PCI_VID_INTEL
,
534 .device
= PCI_DID_INTEL_DNV_LPC
,
537 static void finalize_chipset(void *unused
)
539 apm_control(APM_CNT_FINALIZE
);
542 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME
, BS_ON_ENTRY
, finalize_chipset
, NULL
);
543 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD
, BS_ON_EXIT
, finalize_chipset
, NULL
);