summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/google/rambi/acpi_tables.c6
-rw-r--r--src/soc/intel/baytrail/acpi.c61
-rw-r--r--src/soc/intel/baytrail/baytrail/acpi.h1
-rw-r--r--src/soc/intel/baytrail/baytrail/irq.h11
-rw-r--r--src/soc/intel/baytrail/southcluster.c4
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);
}
/*