summaryrefslogtreecommitdiff
path: root/src/soc/intel/baytrail/acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/baytrail/acpi.c')
-rw-r--r--src/soc/intel/baytrail/acpi.c61
1 files changed, 60 insertions, 1 deletions
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;
+}