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
|
* I/O port address space
|
||||||
*/
|
*/
|
||||||
#define ACPI_BASE_ADDRESS 0x1000
|
#define GPE0_BASE_ADDRESS 0x2000
|
||||||
#define ACPI_BASE_SIZE 0x100
|
#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 LEGACY_GPIO_SIZE 0x80
|
||||||
|
|
||||||
#define IO_ADDRESS_VALID 0x80000000
|
#define IO_ADDRESS_VALID 0x80000000
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum {
|
||||||
GPIO_REGS,
|
GPIO_REGS,
|
||||||
PCIE_AFE_REGS,
|
PCIE_AFE_REGS,
|
||||||
PCIE_RESET,
|
PCIE_RESET,
|
||||||
|
GPE0_REGS,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -46,6 +47,27 @@ enum {
|
||||||
_REG_SCRIPT_ENCODE_RAW(REG_SCRIPT_COMMAND_##cmd_, SOC_TYPE, \
|
_REG_SCRIPT_ENCODE_RAW(REG_SCRIPT_COMMAND_##cmd_, SOC_TYPE, \
|
||||||
size_, reg_, mask_, value_, timeout_, reg_set_)
|
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 */
|
/* GPIO controller register access macros */
|
||||||
#define REG_GPIO_ACCESS(cmd_, reg_, mask_, value_, timeout_) \
|
#define REG_GPIO_ACCESS(cmd_, reg_, mask_, value_, timeout_) \
|
||||||
SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, 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. */
|
/* Get the normal PCI resources of this device. */
|
||||||
pci_dev_read_resources(dev);
|
pci_dev_read_resources(dev);
|
||||||
|
|
||||||
/* PMBASE */
|
/* GPE0 */
|
||||||
res = new_resource(dev, index++);
|
res = new_resource(dev, index++);
|
||||||
res->base = ACPI_BASE_ADDRESS;
|
res->base = GPE0_BASE_ADDRESS;
|
||||||
res->size = ACPI_BASE_SIZE;
|
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;
|
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,19 @@
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
#include <soc/ramstage.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)
|
static uint32_t *get_gpio_address(uint32_t reg_address)
|
||||||
{
|
{
|
||||||
uint32_t gpio_base_address;
|
uint32_t gpio_base_address;
|
||||||
|
@ -83,6 +96,18 @@ void mea_write(uint32_t reg_address)
|
||||||
& QNC_MEA_MASK);
|
& 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)
|
static uint32_t reg_gpio_read(uint32_t reg_address)
|
||||||
{
|
{
|
||||||
/* Read the GPIO register */
|
/* 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;
|
ctx->display_features = REG_SCRIPT_DISPLAY_NOTHING;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case GPE0_REGS:
|
||||||
|
ctx->display_prefix = "GPE0: ";
|
||||||
|
value = reg_gpe0_read(step->reg);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPIO_REGS:
|
case GPIO_REGS:
|
||||||
ctx->display_prefix = "GPIO: ";
|
ctx->display_prefix = "GPIO: ";
|
||||||
value = reg_gpio_read(step->reg);
|
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;
|
ctx->display_features = REG_SCRIPT_DISPLAY_NOTHING;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case GPE0_REGS:
|
||||||
|
ctx->display_prefix = "GPE0: ";
|
||||||
|
reg_gpe0_write(step->reg, (uint32_t)step->value);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPIO_REGS:
|
case GPIO_REGS:
|
||||||
ctx->display_prefix = "GPIO: ";
|
ctx->display_prefix = "GPIO: ";
|
||||||
reg_gpio_write(step->reg, (uint32_t)step->value);
|
reg_gpio_write(step->reg, (uint32_t)step->value);
|
||||||
|
|
|
@ -30,10 +30,22 @@
|
||||||
#include <soc/romstage.h>
|
#include <soc/romstage.h>
|
||||||
#include <soc/reg_access.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[] = {
|
static const struct reg_script legacy_gpio_init[] = {
|
||||||
/* Temporarily enable the legacy GPIO controller */
|
/* Temporarily enable the legacy GPIO controller */
|
||||||
REG_PCI_WRITE32(R_QNC_LPC_GBA_BASE, IO_ADDRESS_VALID
|
REG_PCI_WRITE32(R_QNC_LPC_GBA_BASE, IO_ADDRESS_VALID
|
||||||
| LEGACY_GPIO_BASE_ADDRESS),
|
| 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_PCI_OR8(PCI_COMMAND, PCI_COMMAND_IO),
|
||||||
REG_SCRIPT_END
|
REG_SCRIPT_END
|
||||||
};
|
};
|
||||||
|
@ -81,6 +93,7 @@ void soc_memory_init_params(struct romstage_params *params,
|
||||||
char *pdat_file;
|
char *pdat_file;
|
||||||
size_t pdat_file_len;
|
size_t pdat_file_len;
|
||||||
const struct soc_intel_quark_config *config;
|
const struct soc_intel_quark_config *config;
|
||||||
|
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
||||||
|
|
||||||
/* Locate the pdat.bin file */
|
/* Locate the pdat.bin file */
|
||||||
pdat_file = cbfs_boot_map_with_leak("pdat.bin", CBFS_TYPE_RAW,
|
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 */
|
/* Display the ROM shadow data */
|
||||||
hexdump((void *)0x000ffff0, 0x10);
|
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)
|
void soc_after_ram_init(struct romstage_params *params)
|
||||||
|
|
Loading…
Reference in New Issue