diff options
-rw-r--r-- | src/mainboard/google/rambi/acpi_tables.c | 6 | ||||
-rw-r--r-- | src/soc/intel/baytrail/acpi.c | 61 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/acpi.h | 1 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/irq.h | 11 | ||||
-rw-r--r-- | src/soc/intel/baytrail/southcluster.c | 4 |
5 files changed, 77 insertions, 6 deletions
diff --git a/src/mainboard/google/rambi/acpi_tables.c b/src/mainboard/google/rambi/acpi_tables.c index f61db1d65f..a4754f1df6 100644 --- a/src/mainboard/google/rambi/acpi_tables.c +++ b/src/mainboard/google/rambi/acpi_tables.c @@ -78,11 +78,7 @@ unsigned long acpi_fill_madt(unsigned long current) current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2, IO_APIC_ADDR, 0); - /* INT_SRC_OVR */ - current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) - current, 0, 0, 2, 0); - current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) - current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH); + current = acpi_madt_irq_overrides(current); return current; } diff --git a/src/soc/intel/baytrail/acpi.c b/src/soc/intel/baytrail/acpi.c index e2e4937b21..ce7f5e45e6 100644 --- a/src/soc/intel/baytrail/acpi.c +++ b/src/soc/intel/baytrail/acpi.c @@ -20,14 +20,51 @@ #include <arch/acpi.h> #include <arch/acpigen.h> +#include <arch/io.h> +#include <arch/smp/mpspec.h> +#include <console/console.h> #include <cpu/x86/smm.h> #include <types.h> #include <string.h> #include <baytrail/acpi.h> #include <baytrail/iomap.h> +#include <baytrail/irq.h> #include <baytrail/pmc.h> +static int acpi_sci_irq(void) +{ + const unsigned long actl = ILB_BASE_ADDRESS + ACTL; + int scis; + static int sci_irq; + + if (sci_irq) + return sci_irq; + + /* Determine how SCI is routed. */ + scis = read32(actl) & SCIS_MASK; + switch (scis) { + case SCIS_IRQ9: + case SCIS_IRQ10: + case SCIS_IRQ11: + sci_irq = scis - SCIS_IRQ9 + 9; + break; + case SCIS_IRQ20: + case SCIS_IRQ21: + case SCIS_IRQ22: + case SCIS_IRQ23: + sci_irq = scis - SCIS_IRQ20 + 20; + break; + default: + printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n"); + sci_irq = 9; + break; + } + + printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq); + return sci_irq; +} + void acpi_create_intel_hpet(acpi_hpet_t * hpet) { acpi_header_t *header = &(hpet->header); @@ -70,7 +107,7 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) { const uint16_t pmbase = ACPI_BASE_ADDRESS; - fadt->sci_int = 0x9; + fadt->sci_int = acpi_sci_irq(); fadt->smi_cmd = APM_CNT; fadt->acpi_enable = APM_CNT_ACPI_ENABLE; fadt->acpi_disable = APM_CNT_ACPI_DISABLE; @@ -175,3 +212,25 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } + +unsigned long acpi_madt_irq_overrides(unsigned long current) +{ + int sci_irq = acpi_sci_irq(); + acpi_madt_irqoverride_t *irqovr; + uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL; + + /* INT_SRC_OVR */ + irqovr = (void *)current; + current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0); + + if (sci_irq >= 20) + sci_flags |= MP_IRQ_POLARITY_LOW; + else + sci_flags |= MP_IRQ_POLARITY_HIGH; + + irqovr = (void *)current; + current += acpi_create_madt_irqoverride(irqovr, 0, sci_irq, sci_irq, + sci_flags); + + return current; +} diff --git a/src/soc/intel/baytrail/baytrail/acpi.h b/src/soc/intel/baytrail/baytrail/acpi.h index bfb7d40d23..da5f4068ad 100644 --- a/src/soc/intel/baytrail/baytrail/acpi.h +++ b/src/soc/intel/baytrail/baytrail/acpi.h @@ -24,6 +24,7 @@ void acpi_create_intel_hpet(acpi_hpet_t * hpet); void acpi_fill_in_fadt(acpi_fadt_t *fadt); +unsigned long acpi_madt_irq_overrides(unsigned long current); #endif /* _BAYTRAIL_ACPI_H_ */ diff --git a/src/soc/intel/baytrail/baytrail/irq.h b/src/soc/intel/baytrail/baytrail/irq.h index d037b89059..646187848a 100644 --- a/src/soc/intel/baytrail/baytrail/irq.h +++ b/src/soc/intel/baytrail/baytrail/irq.h @@ -52,6 +52,17 @@ #define PIRQG 6 #define PIRQH 7 +/* These registers live behind the ILB_BASE_ADDRESS */ +#define ACTL 0x00 +# define SCIS_MASK 0x07 +# define SCIS_IRQ9 0x00 +# define SCIS_IRQ10 0x01 +# define SCIS_IRQ11 0x02 +# define SCIS_IRQ20 0x04 +# define SCIS_IRQ21 0x05 +# define SCIS_IRQ22 0x06 +# define SCIS_IRQ23 0x07 + /* In each mainbaord directory there should exist a header file irqroute.h that * defines the PCI_DEV_PIRQ_ROUTES and PIRQ_PIC_ROUTES macros which * consist of PCI_DEV_PIRQ_ROUTE and PIRQ_PIC entries. */ diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c index 10c0b896fb..b7cf4e5718 100644 --- a/src/soc/intel/baytrail/southcluster.c +++ b/src/soc/intel/baytrail/southcluster.c @@ -122,6 +122,7 @@ static void sc_init(device_t dev) int i; const unsigned long pr_base = ILB_BASE_ADDRESS + 0x08; const unsigned long ir_base = ILB_BASE_ADDRESS + 0x20; + const unsigned long actl = ILB_BASE_ADDRESS + ACTL; const struct baytrail_irq_route *ir = &global_baytrail_irq_route; /* Set up the PIRQ PIC routing based on static config. */ @@ -132,6 +133,9 @@ static void sc_init(device_t dev) for (i = 0; i < NUM_IR_DEVS; i++) { write16(ir_base + i*sizeof(ir->pcidev[i]), ir->pcidev[i]); } + + /* Route SCI to IRQ9 */ + write32(actl, (read32(actl) & ~SCIS_MASK) | SCIS_IRQ9); } /* |