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@intel.com> Reviewed-on: https://review.coreboot.org/14945 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
773ee2bb17
commit
7f4b053980
|
@ -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
|
||||
|
|
|
@ -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_, \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue