stoneyridge: Add SCI/GPE configuration
Add functions for configuring the GPE ACPI SCI events. BUG=b:63268311 BRANCH=none TEST=With the Kahlee GPE setup patch, test lidswitch powers the device on and off at the login screen. Change-Id: I5c282268edbd7b92a3f2ca7c72896406c8f8512f Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/22095 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
f1c8ea35b3
commit
e8e72bd0ca
|
@ -20,7 +20,18 @@
|
|||
|
||||
#include <arch/io.h>
|
||||
|
||||
#define SMI_GEVENTS 24
|
||||
#define SCIMAPS 58
|
||||
#define SCI_GPES 32
|
||||
|
||||
#define SMI_EVENT_STATUS 0x0
|
||||
#define SMI_EVENT_ENABLE 0x04
|
||||
#define SMI_SCI_TRIG 0x08
|
||||
#define SMI_SCI_LEVEL 0x0c
|
||||
#define SMI_SCI_STATUS 0x10
|
||||
#define SMI_SCI_EN 0x14
|
||||
#define SMI_SCI_MAP0 0x40
|
||||
# define SMI_SCI_MAP(X) (SMI_SCI_MAP0 + (X))
|
||||
|
||||
/* SMI source and status */
|
||||
#define SMITYPE_AGPIO65 0
|
||||
|
@ -189,9 +200,21 @@ enum smi_mode {
|
|||
SMI_MODE_IRQ13 = 3,
|
||||
};
|
||||
|
||||
enum smi_lvl {
|
||||
SMI_LVL_LOW = 0,
|
||||
SMI_LVL_HIGH = 1,
|
||||
enum smi_sci_type {
|
||||
NONE,
|
||||
SCI,
|
||||
SMI,
|
||||
BOTH,
|
||||
};
|
||||
|
||||
enum smi_sci_lvl {
|
||||
SMI_SCI_LVL_LOW,
|
||||
SMI_SCI_LVL_HIGH,
|
||||
};
|
||||
|
||||
enum smi_sci_dir {
|
||||
SMI_SCI_EDG,
|
||||
SMI_SCI_LVL,
|
||||
};
|
||||
|
||||
struct smi_sources_t {
|
||||
|
@ -199,10 +222,19 @@ struct smi_sources_t {
|
|||
void (*handler)(void);
|
||||
};
|
||||
|
||||
struct sci_source {
|
||||
uint8_t scimap; /* SCIMAP 0-57 */
|
||||
uint8_t gpe; /* 32 GPEs */
|
||||
uint8_t direction; /* Active High or Low, smi_sci_lvl */
|
||||
uint8_t level; /* Edge or Level, smi_sci_dir */
|
||||
};
|
||||
|
||||
uint16_t pm_acpi_smi_cmd_port(void);
|
||||
void configure_smi(uint8_t smi_num, uint8_t mode);
|
||||
void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level);
|
||||
void configure_scimap(const struct sci_source *sci);
|
||||
void disable_gevent_smi(uint8_t gevent);
|
||||
void gpe_configure_sci(const struct sci_source *scis, size_t num_gpes);
|
||||
|
||||
#ifndef __SMM__
|
||||
void enable_smi_generation(void);
|
||||
|
|
|
@ -276,8 +276,10 @@ u32 pm_read32(u8 reg);
|
|||
void pm_write8(u8 reg, u8 value);
|
||||
void pm_write16(u8 reg, u16 value);
|
||||
void pm_write32(u8 reg, u32 value);
|
||||
u8 smi_read8(u8 reg);
|
||||
u16 smi_read16(u8 reg);
|
||||
u32 smi_read32(u8 reg);
|
||||
void smi_write8(u8 reg, u8 value);
|
||||
void smi_write16(u8 reg, u16 value);
|
||||
void smi_write32(u8 reg, u32 value);
|
||||
uint16_t pm_acpi_pm_cnt_blk(void);
|
||||
|
|
|
@ -65,6 +65,16 @@ void smi_write16(uint8_t offset, uint16_t value)
|
|||
write16((void *)(APU_SMI_BASE + offset), value);
|
||||
}
|
||||
|
||||
uint8_t smi_read8(uint8_t offset)
|
||||
{
|
||||
return read8((void *)(APU_SMI_BASE + offset));
|
||||
}
|
||||
|
||||
void smi_write8(uint8_t offset, uint8_t value)
|
||||
{
|
||||
write8((void *)(APU_SMI_BASE + offset), value);
|
||||
}
|
||||
|
||||
uint16_t pm_acpi_pm_cnt_blk(void)
|
||||
{
|
||||
return pm_read16(PM1_CNT_BLK);
|
||||
|
|
|
@ -35,13 +35,13 @@ void configure_smi(uint8_t smi_num, uint8_t mode)
|
|||
* @param gevent The GEVENT pin number. Valid values are 0 thru 23
|
||||
* @param mode The type of event this pin should generate. Note that only
|
||||
* SMI_MODE_SMI generates an SMI. SMI_MODE_DISABLE disables events.
|
||||
* @param level SMI_LVL_LOW or SMI_LVL_HIGH
|
||||
* @param level SMI__SCI_LVL_LOW or SMI_SCI_LVL_HIGH
|
||||
*/
|
||||
void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
|
||||
{
|
||||
uint32_t reg32;
|
||||
/* GEVENT pins range from [0:23] */
|
||||
if (gevent > 23) {
|
||||
if (gevent >= SMI_GEVENTS) {
|
||||
printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
|
||||
return;
|
||||
}
|
||||
|
@ -56,6 +56,55 @@ void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
|
|||
smi_write32(SMI_REG_SMITRIG0, reg32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure generation of SCIs.
|
||||
*/
|
||||
void configure_scimap(const struct sci_source *sci)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
/* GEVENT pins range */
|
||||
if (sci->scimap >= SCIMAPS) {
|
||||
printk(BIOS_WARNING, "BUG: Invalid SCIMAP: %u\n",
|
||||
sci->scimap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GPEs range from [0:31] */
|
||||
if (sci->gpe >= SCI_GPES) {
|
||||
printk(BIOS_WARNING, "BUG: Invalid SCI GPE: %u\n", sci->gpe);
|
||||
return;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "SCIMAP %u maps to GPE %u (active %s, %s trigger)\n",
|
||||
sci->scimap, sci->gpe,
|
||||
(!!sci->direction) ? "high" : "low",
|
||||
(!!sci->level) ? "level" : "edge");
|
||||
|
||||
/* Map Gevent to SCI GPE# */
|
||||
smi_write8(SMI_SCI_MAP(sci->scimap), sci->gpe);
|
||||
|
||||
/* Set the trigger direction (high/low) */
|
||||
reg32 = smi_read32(SMI_SCI_TRIG);
|
||||
reg32 &= ~(1 << sci->gpe);
|
||||
reg32 |= !!sci->direction << sci->gpe;
|
||||
smi_write32(SMI_SCI_TRIG, reg32);
|
||||
|
||||
/* Set the trigger level (edge/level) */
|
||||
reg32 = smi_read32(SMI_SCI_LEVEL);
|
||||
reg32 &= ~(1 << sci->gpe);
|
||||
reg32 |= !!sci->level << sci->gpe;
|
||||
smi_write32(SMI_SCI_LEVEL, reg32);
|
||||
}
|
||||
|
||||
void gpe_configure_sci(const struct sci_source *scis, size_t num_gpes)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num_gpes; i++)
|
||||
configure_scimap(scis + i);
|
||||
}
|
||||
|
||||
/** Disable events from given GEVENT pin */
|
||||
void disable_gevent_smi(uint8_t gevent)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue