aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/braswell/southcluster.c
diff options
context:
space:
mode:
authorFrans Hendriks <fhendriks@eltan.com>2019-04-02 15:06:29 +0200
committerPatrick Georgi <pgeorgi@google.com>2019-04-04 10:36:56 +0000
commit2c63017ca356bd245b3b09d1001586c019f5fa05 (patch)
treec1a694d89f4f6e1363948f9384fbc635672ce1e6 /src/soc/intel/braswell/southcluster.c
parente8fb3dfa6ca84976ad43563caa01a88eba9ba495 (diff)
soc/intel/braswell: Correct serial IRQ support
Serial IRQ was configured in quiet mode, but not enabled. Enable serial IRQ and use 'enum seriirq_mode' as a devicetree option. Function sc_enable_serial_irqs() is added to enabled serial IRQs. enable_serirq_quiet_mode() is renamed to sc_set_serial_irqs_mode(). This function use the 'serirq_mode' to set the mode. The call to this function is moved from finalize to init having serial IRQs enable in early stage. Serial IRQs must be enabled in continuous mode for at least one frame before switching into quiet mode. BUG=N/A TEST=Portwell PQ7-M107 Change-Id: I7844cad69dc0563fa6109d779d0afb7c2edd7245 Signed-off-by: Frans Hendriks <fhendriks@eltan.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/29398 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Diffstat (limited to 'src/soc/intel/braswell/southcluster.c')
-rw-r--r--src/soc/intel/braswell/southcluster.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/soc/intel/braswell/southcluster.c b/src/soc/intel/braswell/southcluster.c
index e79cb128a5..000790d9a6 100644
--- a/src/soc/intel/braswell/southcluster.c
+++ b/src/soc/intel/braswell/southcluster.c
@@ -28,6 +28,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
+#include <intelblocks/lpc_lib.h>
#include <pc80/isa-dma.h>
#include <pc80/i8254.h>
#include <pc80/i8259.h>
@@ -41,17 +42,23 @@
#include <soc/spi.h>
#include <spi-generic.h>
#include <stdint.h>
-#include <reg_script.h>
-static const struct reg_script ops[] = {
- REG_MMIO_RMW32(ILB_BASE_ADDRESS + SCNT,
- ~SCNT_MODE, 0), /* put LPC SERIRQ in Quiet Mode */
- REG_SCRIPT_END
-};
-
-static void enable_serirq_quiet_mode(void)
+static void sc_set_serial_irqs_mode(struct device *dev, enum serirq_mode mode)
{
- reg_script_run(ops);
+ u8 *ilb_base = (u8 *)(pci_read_config32(dev, IBASE) & ~0xF);
+
+ switch (mode) {
+ case SERIRQ_CONTINUOUS:
+ break;
+ case SERIRQ_OFF:
+ write32(ilb_base + ILB_OIC, read32(ilb_base + ILB_OIC) &
+ ~SIRQEN);
+ break;
+ case SERIRQ_QUIET:
+ default:
+ write8(ilb_base + SCNT, read8(ilb_base + SCNT) & ~SCNT_MODE);
+ break;
+ }
}
static inline void
@@ -85,6 +92,15 @@ static void sc_add_mmio_resources(struct device *dev)
#define LPC_DEFAULT_IO_RANGE_LOWER 0
#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
+static void sc_enable_serial_irqs(struct device *dev)
+{
+ u8 *ilb_base = (u8 *)(pci_read_config32(dev, IBASE) & ~0xF);
+
+ printk(BIOS_SPEW, "Enable serial irq\n");
+ write32(ilb_base + ILB_OIC, read32(ilb_base + ILB_OIC) | SIRQEN);
+ write8(ilb_base + SCNT, read8(ilb_base + SCNT) | SCNT_MODE);
+}
+
/*
* Write PCI config space IRQ assignments. PCI devices have the INT_LINE
* (0x3C) and INT_PIN (0x3D) registers which report interrupt routing
@@ -285,6 +301,8 @@ static void sc_init(struct device *dev)
isa_dma_init();
+ sc_enable_serial_irqs(dev);
+
/* Set up the PIRQ PIC routing based on static config. */
for (i = 0; i < NUM_PIRQS; i++)
write8((void *)(pr_base + i*sizeof(ir->pic[i])),
@@ -320,6 +338,9 @@ static void sc_init(struct device *dev)
/* Initialize i8254 timers */
setup_i8254();
+
+ sc_set_serial_irqs_mode(dev, config->serirq_mode);
+
}
/*
@@ -630,7 +651,6 @@ static void finalize_chipset(void *unused)
write32(spi + LVSCC, cfg.lvscc | VCL);
}
spi_init();
- enable_serirq_quiet_mode();
printk(BIOS_DEBUG, "Finalizing SMM.\n");
outb(APM_CNT_FINALIZE, APM_CNT);