Files
system76-coreboot/src/soc/amd/picasso/smi_util.c
Patrick Georgi 1c6d8a9cf4 soc: Remove copyright notices
They're listed in AUTHORS and often incorrect anyway, for example:
- What's a "Copyright $year-present"?
- Which incarnation of Google (Inc, LLC, ...) is the current
  copyright holder?
- People sometimes have their editor auto-add themselves to files even
  though they only deleted stuff
- Or they let the editor automatically update the copyright year,
  because why not?
- Who is the copyright holder "The coreboot project Authors"?
- Or "Generated Code"?

Sidestep all these issues by simply not putting these notices in
individual files, let's list all copyright holders in AUTHORS instead
and use the git history to deal with the rest.

Change-Id: I4c110f60b764c97fab2a29f6f04680196f156da5
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/39610
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: David Hendricks <david.hendricks@gmail.com>
2020-03-18 16:44:46 +00:00

138 lines
3.5 KiB
C

/*
* This file is part of the coreboot project.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* SMM utilities used in both SMM and normal mode
*/
#include <console/console.h>
#include <soc/southbridge.h>
#include <soc/smi.h>
#include <amdblocks/acpimmio.h>
void configure_smi(uint8_t smi_num, uint8_t mode)
{
uint8_t reg32_offset, bit_offset;
uint32_t reg32;
if (smi_num >= NUMBER_SMITYPES) {
printk(BIOS_WARNING, "BUG: Invalid SMI: %u\n", smi_num);
return;
}
/* 16 sources per register, 2 bits per source; registers are 4 bytes */
reg32_offset = (smi_num / 16) * 4;
bit_offset = (smi_num % 16) * 2;
reg32 = smi_read32(SMI_REG_CONTROL0 + reg32_offset);
reg32 &= ~(0x3 << (bit_offset));
reg32 |= (mode & 0x3) << bit_offset;
smi_write32(SMI_REG_CONTROL0 + reg32_offset, reg32);
}
/**
* Configure generation of interrupts for given GEVENT pin
*
* @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__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 >= SMI_GEVENTS) {
printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
return;
}
/* SMI0 source is GEVENT0 and so on */
configure_smi(gevent, mode);
/* And set set the trigger level */
reg32 = smi_read32(SMI_REG_SMITRIG0);
reg32 &= ~(1 << gevent);
reg32 |= (level & 0x1) << gevent;
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)
{
/* GEVENT pins range from [0:23] */
if (gevent > 23) {
printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
return;
}
/* SMI0 source is GEVENT0 and so on */
configure_smi(gevent, SMI_MODE_DISABLE);
}
uint16_t pm_acpi_smi_cmd_port(void)
{
return pm_read16(PM_ACPI_SMI_CMD);
}