diff options
Diffstat (limited to 'src/soc/amd/stoneyridge/smi_util.c')
-rw-r--r-- | src/soc/amd/stoneyridge/smi_util.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/soc/amd/stoneyridge/smi_util.c b/src/soc/amd/stoneyridge/smi_util.c index 96e9d6156b..7b176dee30 100644 --- a/src/soc/amd/stoneyridge/smi_util.c +++ b/src/soc/amd/stoneyridge/smi_util.c @@ -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) { |