[coreboot-gerrit] Patch set updated for coreboot: soc/intel/quark: Clear SMI interrupts and wake events

Leroy P Leahy (leroy.p.leahy@intel.com) gerrit at coreboot.org
Tue May 31 02:26:36 CEST 2016


Leroy P Leahy (leroy.p.leahy at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14945

-gerrit

commit 9b14de6046752f8e9cf73a2f416e15a1660c03b2
Author: Lee Leahy <leroy.p.leahy at intel.com>
Date:   Sun May 22 11:52:28 2016 -0700

    soc/intel/quark: Clear SMI interrupts and wake events
    
    Migrate the clearing of the SMI interrupts and wake events from FSP into
    coreboot.
    
    TEST=Build and run on Galileo Gen2
    
    Change-Id: Ia369801da87a16bc00fb2c05475831ebe8a315f8
    Signed-off-by: Lee Leahy <leroy.p.leahy at intel.com>
---
 src/soc/intel/quark/include/soc/iomap.h      |  9 ++++---
 src/soc/intel/quark/include/soc/reg_access.h | 22 +++++++++++++++++
 src/soc/intel/quark/lpc.c                    | 18 +++++++++++---
 src/soc/intel/quark/reg_access.c             | 35 ++++++++++++++++++++++++++++
 src/soc/intel/quark/romstage/romstage.c      | 19 +++++++++++++++
 5 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/src/soc/intel/quark/include/soc/iomap.h b/src/soc/intel/quark/include/soc/iomap.h
index ce92676..61773d5 100644
--- a/src/soc/intel/quark/include/soc/iomap.h
+++ b/src/soc/intel/quark/include/soc/iomap.h
@@ -30,10 +30,13 @@
 /*
  * I/O port address space
  */
-#define ACPI_BASE_ADDRESS		0x1000
-#define ACPI_BASE_SIZE			0x100
+#define GPE0_BASE_ADDRESS		0x2000
+#define GPE0_SIZE			0x40
 
-#define LEGACY_GPIO_BASE_ADDRESS	0x1080
+#define PM1BLK_BASE_ADDRESS		0x2040
+#define PM1BLK_SIZE			0x10
+
+#define LEGACY_GPIO_BASE_ADDRESS	0x2080
 #define LEGACY_GPIO_SIZE		0x80
 
 #define IO_ADDRESS_VALID		0x80000000
diff --git a/src/soc/intel/quark/include/soc/reg_access.h b/src/soc/intel/quark/include/soc/reg_access.h
index 580400c..e7a8963 100644
--- a/src/soc/intel/quark/include/soc/reg_access.h
+++ b/src/soc/intel/quark/include/soc/reg_access.h
@@ -35,6 +35,7 @@ enum {
 	GPIO_REGS,
 	PCIE_AFE_REGS,
 	PCIE_RESET,
+	GPE0_REGS,
 };
 
 enum {
@@ -46,6 +47,27 @@ enum {
 	_REG_SCRIPT_ENCODE_RAW(REG_SCRIPT_COMMAND_##cmd_, SOC_TYPE,        \
 			       size_, reg_, mask_, value_, timeout_, reg_set_)
 
+/* GPE0 controller register access macros */
+#define REG_GPE0_ACCESS(cmd_, reg_, mask_, value_, timeout_) \
+	SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, mask_, value_, timeout_, \
+		GPE0_REGS)
+#define REG_GPE0_READ(reg_) \
+	REG_GPE0_ACCESS(READ, reg_, 0, 0, 0)
+#define REG_GPE0_WRITE(reg_, value_) \
+	REG_GPE0_ACCESS(WRITE, reg_, 0, value_, 0)
+#define REG_GPE0_AND(reg_, value_) \
+	REG_GPE0_RMW(reg_, value_, 0)
+#define REG_GPE0_RMW(reg_, mask_, value_) \
+	REG_GPE0_ACCESS(RMW, reg_, mask_, value_, 0)
+#define REG_GPE0_RXW(reg_, mask_, value_) \
+	REG_GPE0_ACCESS(RXW, reg_, mask_, value_, 0)
+#define REG_GPE0_OR(reg_, value_) \
+	REG_GPE0_RMW(reg_, 0xffffffff, value_)
+#define REG_GPE0_POLL(reg_, mask_, value_, timeout_) \
+	REG_GPE0_ACCESS(POLL, reg_, mask_, value_, timeout_)
+#define REG_GPE0_XOR(reg_, value_) \
+	REG_GPE0_RXW(reg_, 0xffffffff, value_)
+
 /* GPIO controller register access macros */
 #define REG_GPIO_ACCESS(cmd_, reg_, mask_, value_, timeout_) \
 	SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, mask_, value_, timeout_, \
diff --git a/src/soc/intel/quark/lpc.c b/src/soc/intel/quark/lpc.c
index fbed935..e57b717 100644
--- a/src/soc/intel/quark/lpc.c
+++ b/src/soc/intel/quark/lpc.c
@@ -30,10 +30,22 @@ static void pmc_read_resources(device_t dev)
 	/* Get the normal PCI resources of this device. */
 	pci_dev_read_resources(dev);
 
-	/* PMBASE */
+	/* GPE0 */
 	res = new_resource(dev, index++);
-	res->base = ACPI_BASE_ADDRESS;
-	res->size = ACPI_BASE_SIZE;
+	res->base = GPE0_BASE_ADDRESS;
+	res->size = GPE0_SIZE;
+	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	/* PM1BLK */
+	res = new_resource(dev, index++);
+	res->base = PM1BLK_BASE_ADDRESS;
+	res->size = PM1BLK_SIZE;
+	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	/* Legacy GPIO */
+	res = new_resource(dev, index++);
+	res->base = LEGACY_GPIO_BASE_ADDRESS;
+	res->size = LEGACY_GPIO_SIZE;
 	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 }
 
diff --git a/src/soc/intel/quark/reg_access.c b/src/soc/intel/quark/reg_access.c
index f7820e9..30cc7db 100644
--- a/src/soc/intel/quark/reg_access.c
+++ b/src/soc/intel/quark/reg_access.c
@@ -19,6 +19,19 @@
 #include <soc/pci_devs.h>
 #include <soc/ramstage.h>
 
+static uint16_t get_gpe0_address(uint32_t reg_address)
+{
+	uint32_t gpe0_base_address;
+
+	/* Get the GPE0 base address */
+	gpe0_base_address = pci_read_config32(LPC_BDF, R_QNC_LPC_GPE0BLK);
+	ASSERT (gpe0_base_address >= 0x80000000);
+	gpe0_base_address &= B_QNC_LPC_GPE0BLK_MASK;
+
+	/* Return the GPE0 register address */
+	return (uint16_t)(gpe0_base_address + reg_address);
+}
+
 static uint32_t *get_gpio_address(uint32_t reg_address)
 {
 	uint32_t gpio_base_address;
@@ -83,6 +96,18 @@ void mea_write(uint32_t reg_address)
 		& QNC_MEA_MASK);
 }
 
+static uint32_t reg_gpe0_read(uint32_t reg_address)
+{
+	/* Read the GPE0 register */
+	return inl(get_gpe0_address(reg_address));
+}
+
+static void reg_gpe0_write(uint32_t reg_address, uint32_t value)
+{
+	/* Write the GPE0 register */
+	outl(get_gpe0_address(reg_address), value);
+}
+
 static uint32_t reg_gpio_read(uint32_t reg_address)
 {
 	/* Read the GPIO register */
@@ -190,6 +215,11 @@ static uint64_t reg_read(struct reg_script_context *ctx)
 		ctx->display_features = REG_SCRIPT_DISPLAY_NOTHING;
 		return 0;
 
+	case GPE0_REGS:
+		ctx->display_prefix = "GPE0: ";
+		value = reg_gpe0_read(step->reg);
+		break;
+
 	case GPIO_REGS:
 		ctx->display_prefix = "GPIO: ";
 		value = reg_gpio_read(step->reg);
@@ -234,6 +264,11 @@ static void reg_write(struct reg_script_context *ctx)
 		ctx->display_features = REG_SCRIPT_DISPLAY_NOTHING;
 		return;
 
+	case GPE0_REGS:
+		ctx->display_prefix = "GPE0: ";
+		reg_gpe0_write(step->reg, (uint32_t)step->value);
+		break;
+
 	case GPIO_REGS:
 		ctx->display_prefix = "GPIO: ";
 		reg_gpio_write(step->reg, (uint32_t)step->value);
diff --git a/src/soc/intel/quark/romstage/romstage.c b/src/soc/intel/quark/romstage/romstage.c
index 4ed5863..c4f9844 100644
--- a/src/soc/intel/quark/romstage/romstage.c
+++ b/src/soc/intel/quark/romstage/romstage.c
@@ -30,10 +30,22 @@
 #include <soc/romstage.h>
 #include <soc/reg_access.h>
 
+static const struct reg_script clear_smi_and_wake_events[] = {
+	/* Clear any SMI or wake events */
+	REG_GPE0_READ(R_QNC_GPE0BLK_GPE0S),
+	REG_GPE0_READ(R_QNC_GPE0BLK_SMIS),
+	REG_GPE0_OR(R_QNC_GPE0BLK_GPE0S, B_QNC_GPE0BLK_GPE0S_ALL),
+	REG_GPE0_OR(R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_ALL),
+	REG_SCRIPT_END
+};
+
 static const struct reg_script legacy_gpio_init[] = {
 	/* Temporarily enable the legacy GPIO controller */
 	REG_PCI_WRITE32(R_QNC_LPC_GBA_BASE, IO_ADDRESS_VALID
 		| LEGACY_GPIO_BASE_ADDRESS),
+	/* Temporarily enable the GPE controller */
+	REG_PCI_WRITE32(R_QNC_LPC_GPE0BLK, IO_ADDRESS_VALID
+		| GPE0_BASE_ADDRESS),
 	REG_PCI_OR8(PCI_COMMAND, PCI_COMMAND_IO),
 	REG_SCRIPT_END
 };
@@ -81,6 +93,7 @@ void soc_memory_init_params(struct romstage_params *params,
 	char *pdat_file;
 	size_t pdat_file_len;
 	const struct soc_intel_quark_config *config;
+	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
 
 	/* Locate the pdat.bin file */
 	pdat_file = cbfs_boot_map_with_leak("pdat.bin", CBFS_TYPE_RAW,
@@ -104,6 +117,12 @@ void soc_memory_init_params(struct romstage_params *params,
 
 	/* Display the ROM shadow data */
 	hexdump((void *)0x000ffff0, 0x10);
+
+	/* Clear SMI and wake events */
+	if (ps->prev_sleep_state != 3) {
+		printk(BIOS_SPEW, "Clearing SMI interrupts and wake events\n");
+		reg_script_run_on_dev(LPC_BDF, clear_smi_and_wake_events);
+	}
 }
 
 void soc_after_ram_init(struct romstage_params *params)



More information about the coreboot-gerrit mailing list