stoneyridge GPIO: Create and use PAD_INT for interrupt pins
The default interrupt control for GPIO pins within stoneyridge is for edge triggered, high. However, sometimes these need to change, or maybe the interrupt needs to be reported or delivered. This was the case of platform grunt, where the interrupt related bits were being changed afterwards. Ideally all the bits should be programmed through the same procedure. Create several PAD_INT definitions (for general configuration, for trigger configuration and for interrupt type configuration) and change function sb_program_gpios() to accept the output from PAD_INT_XX and program all the necessary bits while keeping compatibility with other PAD_XX definitions. BUG=b:72875858 TEST=Add code to report GPIO and interrupt configuration, build grunt and record a baseline. Add new code, rebuild grunt and record a test output. Compare baseline against test, there should be no change in GPIO or interrupt programming. Remove code that reports GPIO/interrupt configuration. Change-Id: I3457543bdf64ec757fd82df53c83fdc1d03c1f22 Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com> Reviewed-on: https://review.coreboot.org/25758 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
2aa13eff9d
commit
2db06bba0f
|
@ -50,11 +50,4 @@ void bootblock_mainboard_init(void)
|
|||
|
||||
/* Setup TPM decode before verstage */
|
||||
sb_tpm_decode_spi();
|
||||
|
||||
/* Configure cr50 interrupt pin for use in polling tpm status */
|
||||
if (IS_ENABLED(CONFIG_MAINBOARD_HAS_TPM_CR50)) {
|
||||
const uint32_t flags = GPIO_EDGE_TRIG | GPIO_ACTIVE_LOW |
|
||||
GPIO_INT_STATUS_EN;
|
||||
gpio_set_interrupt(H1_PCH_INT, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,15 @@ static void mainboard_init(void *chip_info)
|
|||
gpios = variant_gpio_table(&num_gpios);
|
||||
sb_program_gpios(gpios, num_gpios);
|
||||
|
||||
/*
|
||||
* Some platforms use SCI not generated by a GPIO pin (event above 23).
|
||||
* For these boards, gpe_configure_sci() is still needed, but all GPIO
|
||||
* generated events (23-0) must be removed from gpe_table[].
|
||||
* For boards that only have GPIO generated events, table gpe_table[]
|
||||
* must be removed, and get_gpe_table() should return NULL.
|
||||
*/
|
||||
gpes = get_gpe_table(&num);
|
||||
if (gpes != NULL)
|
||||
gpe_configure_sci(gpes, num);
|
||||
|
||||
/* Initialize i2c busses that were not initialized in bootblock */
|
||||
|
|
|
@ -32,16 +32,17 @@ static const struct soc_amd_gpio gpio_set_stage_reset_old[] = {
|
|||
PAD_GPO(GPIO_4, HIGH),
|
||||
|
||||
/* GPIO_6 - APU_RST_L / EC_SMI_ODL, SMI */
|
||||
PAD_GPI(GPIO_6, PULL_UP),
|
||||
PAD_SMI(GPIO_6, PULL_UP, LEVEL_LOW),
|
||||
|
||||
/* GPIO_9 - H1_PCH_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_9, PULL_UP),
|
||||
PAD_INT(GPIO_9, PULL_UP, EDGE_LOW, STATUS),
|
||||
PAD_SCI(GPIO_9, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_15 - EC_IN_RW_OD */
|
||||
PAD_GPI(GPIO_15, PULL_UP),
|
||||
|
||||
/* GPIO_22 - EC_SCI_ODL, SCI */
|
||||
PAD_GPI(GPIO_22, PULL_UP),
|
||||
PAD_SCI(GPIO_22, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_26 - APU_PCIE_RST_L */
|
||||
PAD_NF(GPIO_26, PCIE_RST_L, PULL_NONE),
|
||||
|
@ -85,16 +86,17 @@ static const struct soc_amd_gpio gpio_set_stage_reset[] = {
|
|||
PAD_GPO(GPIO_4, HIGH),
|
||||
|
||||
/* GPIO_6 - APU_RST_L / EC_SMI_ODL, SMI */
|
||||
PAD_GPI(GPIO_6, PULL_UP),
|
||||
PAD_SMI(GPIO_6, PULL_UP, LEVEL_LOW),
|
||||
|
||||
/* GPIO_9 - H1_PCH_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_9, PULL_UP),
|
||||
PAD_INT(GPIO_9, PULL_UP, EDGE_LOW, STATUS),
|
||||
PAD_SCI(GPIO_9, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_15 - EC_IN_RW_OD */
|
||||
PAD_GPI(GPIO_15, PULL_UP),
|
||||
|
||||
/* GPIO_22 - EC_SCI_ODL, SCI */
|
||||
PAD_GPI(GPIO_22, PULL_UP),
|
||||
PAD_SCI(GPIO_22, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_24 - EC_PCH_WAKE_L */
|
||||
PAD_GPI(GPIO_24, PULL_UP),
|
||||
|
@ -150,7 +152,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram_old[] = {
|
|||
PAD_GPI(GPIO_3, PULL_UP),
|
||||
|
||||
/* GPIO_5 - PCH_TRACKPAD_INT_3V3_ODL, SCI */
|
||||
PAD_GPI(GPIO_5, PULL_UP),
|
||||
PAD_SCI(GPIO_5, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_7 - APU_PWROK_OD (currently not used) */
|
||||
PAD_GPI(GPIO_7, PULL_UP),
|
||||
|
@ -162,7 +164,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram_old[] = {
|
|||
PAD_NF(GPIO_10, S0A3_GPIO, PULL_UP),
|
||||
|
||||
/* GPIO_11 - TOUCHSCREEN_INT_3V3_ODL, SCI */
|
||||
PAD_GPI(GPIO_11, PULL_UP),
|
||||
PAD_SCI(GPIO_11, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_12 - Unused (TP126) */
|
||||
PAD_GPI(GPIO_12, PULL_UP),
|
||||
|
@ -171,7 +173,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram_old[] = {
|
|||
PAD_GPI(GPIO_13, PULL_UP),
|
||||
|
||||
/* GPIO_14 - APU_HP_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_14, PULL_UP),
|
||||
PAD_SCI(GPIO_14, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_16 - USB_C0_OC_L */
|
||||
PAD_NF(GPIO_16, USB_OC0_L, PULL_UP),
|
||||
|
@ -189,7 +191,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram_old[] = {
|
|||
PAD_NF(GPIO_20, I2C3_SDA, PULL_UP),
|
||||
|
||||
/* GPIO_21 - APU_PEN_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_21, PULL_UP),
|
||||
PAD_SCI(GPIO_21, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_24 - USB_A1_OC_ODL */
|
||||
PAD_NF(GPIO_24, USB_OC3_L, PULL_UP),
|
||||
|
@ -314,7 +316,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram[] = {
|
|||
PAD_GPI(GPIO_3, PULL_UP),
|
||||
|
||||
/* GPIO_5 - PCH_TRACKPAD_INT_3V3_ODL, SCI */
|
||||
PAD_GPI(GPIO_5, PULL_UP),
|
||||
PAD_SCI(GPIO_5, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_7 - APU_PWROK_OD (currently not used) */
|
||||
PAD_GPI(GPIO_7, PULL_UP),
|
||||
|
@ -326,7 +328,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram[] = {
|
|||
PAD_NF(GPIO_10, S0A3_GPIO, PULL_UP),
|
||||
|
||||
/* GPIO_11 - TOUCHSCREEN_INT_3V3_ODL, SCI */
|
||||
PAD_GPI(GPIO_11, PULL_UP),
|
||||
PAD_SCI(GPIO_11, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_12 - EN_PP3300_TRACKPAD */
|
||||
PAD_GPO(GPIO_12, HIGH),
|
||||
|
@ -335,7 +337,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram[] = {
|
|||
PAD_GPI(GPIO_13, PULL_UP),
|
||||
|
||||
/* GPIO_14 - APU_HP_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_14, PULL_UP),
|
||||
PAD_SCI(GPIO_14, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_16 - USB_C0_OC_L */
|
||||
PAD_NF(GPIO_16, USB_OC0_L, PULL_UP),
|
||||
|
@ -353,7 +355,7 @@ static const struct soc_amd_gpio gpio_set_stage_ram[] = {
|
|||
PAD_NF(GPIO_20, I2C3_SDA, PULL_UP),
|
||||
|
||||
/* GPIO_21 - APU_PEN_INT_ODL, SCI */
|
||||
PAD_GPI(GPIO_21, PULL_UP),
|
||||
PAD_SCI(GPIO_21, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* GPIO_25 - SD_CD */
|
||||
PAD_NF(GPIO_25, SD0_CD, PULL_UP),
|
||||
|
@ -486,73 +488,15 @@ struct soc_amd_gpio *variant_gpio_table(size_t *size)
|
|||
}
|
||||
|
||||
/*
|
||||
* GPE setup table must match ACPI GPE ASL
|
||||
* { gevent, gpe, direction, level }
|
||||
* This function is still needed for boards that sets gevents above 23
|
||||
* that will generate SCI or SMI, such as kahlee. Normally this function
|
||||
* points to a table of gevents and what needs to be set. The code that
|
||||
* calls it was modified so that when this function returns NULL then the
|
||||
* caller does nothing.
|
||||
*/
|
||||
static const struct sci_source gpe_table[] = {
|
||||
|
||||
/* PCH_TRACKPAD_INT_3V3_ODL */
|
||||
{
|
||||
.scimap = 7,
|
||||
.gpe = 7,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* EC_PCH_WAKE_L */
|
||||
{
|
||||
.scimap = EC_WAKE_GPI,
|
||||
.gpe = EC_WAKE_GPI,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* H1_PCH_INT_ODL */
|
||||
{
|
||||
.scimap = 22,
|
||||
.gpe = 22,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* TOUCHSCREEN_INT_3V3_ODL */
|
||||
{
|
||||
.scimap = 18,
|
||||
.gpe = 18,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
|
||||
/* APU_HP_INT_ODL */
|
||||
{
|
||||
.scimap = 6,
|
||||
.gpe = 6,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* APU_PEN_INT_ODL */
|
||||
{
|
||||
.scimap = 5,
|
||||
.gpe = 5,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* EC_SCI_ODL */
|
||||
{
|
||||
.scimap = 3,
|
||||
.gpe = 3,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
};
|
||||
|
||||
const __weak struct sci_source *get_gpe_table(size_t *num)
|
||||
{
|
||||
*num = ARRAY_SIZE(gpe_table);
|
||||
return gpe_table;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int __weak variant_get_xhci_oc_map(uint16_t *map)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
static const struct soc_amd_gpio gpio_set_stage_reset[] = {
|
||||
/* AGPIO2, to become event generator */
|
||||
PAD_GPI(GPIO_2, PULL_UP),
|
||||
PAD_SCI(GPIO_2, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* SER_TX */
|
||||
PAD_NF(GPIO_8, SerPortTX_OUT, PULL_UP),
|
||||
|
@ -44,7 +44,7 @@ static const struct soc_amd_gpio gpio_set_stage_reset[] = {
|
|||
PAD_NF(GPIO_20, I2C3_SDA, PULL_UP),
|
||||
|
||||
/* AGPIO22 EC_SCI */
|
||||
PAD_GPI(GPIO_22, PULL_UP),
|
||||
PAD_SCI(GPIO_22, PULL_UP, EDGE_LOW),
|
||||
|
||||
/* SPI_TPM_CS_L */
|
||||
PAD_NF(GPIO_76, SPI_TPM_CS_L, PULL_DOWN),
|
||||
|
@ -120,22 +120,6 @@ const struct soc_amd_gpio *variant_gpio_table(size_t *size)
|
|||
*/
|
||||
static const struct sci_source gpe_table[] = {
|
||||
|
||||
/* EC AGPIO22/Gevent3 -> GPE 3 */
|
||||
{
|
||||
.scimap = 3,
|
||||
.gpe = 3,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_EDG,
|
||||
},
|
||||
|
||||
/* PCIE/WLAN AGPIO2/Gevent8 -> GPE8 */
|
||||
{
|
||||
.scimap = 8,
|
||||
.gpe = 8,
|
||||
.direction = SMI_SCI_LVL_LOW,
|
||||
.level = SMI_SCI_LVL,
|
||||
},
|
||||
|
||||
/* EHCI USB_PME -> GPE24 */
|
||||
{
|
||||
.scimap = 24,
|
||||
|
|
|
@ -50,6 +50,7 @@ bootblock-y += tsc_freq.c
|
|||
bootblock-y += southbridge.c
|
||||
bootblock-y += nb_util.c
|
||||
bootblock-$(CONFIG_SPI_FLASH) += spi.c
|
||||
bootblock-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
|
||||
|
||||
romstage-y += BiosCallOuts.c
|
||||
romstage-y += i2c.c
|
||||
|
@ -69,6 +70,7 @@ romstage-y += tsc_freq.c
|
|||
romstage-y += southbridge.c
|
||||
romstage-y += nb_util.c
|
||||
romstage-$(CONFIG_SPI_FLASH) += spi.c
|
||||
romstage-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
|
||||
|
||||
verstage-y += gpio.c
|
||||
verstage-y += i2c.c
|
||||
|
|
|
@ -19,6 +19,110 @@
|
|||
#include <console/console.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <assert.h>
|
||||
#include <compiler.h>
|
||||
|
||||
static const struct soc_amd_event gpio_event_table[] = {
|
||||
{ GPIO_1, GEVENT_19 },
|
||||
{ GPIO_2, GEVENT_8 },
|
||||
{ GPIO_3, GEVENT_2 },
|
||||
{ GPIO_4, GEVENT_4 },
|
||||
{ GPIO_5, GEVENT_7 },
|
||||
{ GPIO_6, GEVENT_10 },
|
||||
{ GPIO_7, GEVENT_11 },
|
||||
{ GPIO_8, GEVENT_23 },
|
||||
{ GPIO_9, GEVENT_22 },
|
||||
{ GPIO_11, GEVENT_18 },
|
||||
{ GPIO_13, GEVENT_21 },
|
||||
{ GPIO_14, GEVENT_6 },
|
||||
{ GPIO_15, GEVENT_20 },
|
||||
{ GPIO_16, GEVENT_12 },
|
||||
{ GPIO_17, GEVENT_13 },
|
||||
{ GPIO_18, GEVENT_14 },
|
||||
{ GPIO_21, GEVENT_5 },
|
||||
{ GPIO_22, GEVENT_3 },
|
||||
{ GPIO_23, GEVENT_16 },
|
||||
{ GPIO_24, GEVENT_15 },
|
||||
{ GPIO_65, GEVENT_0 },
|
||||
{ GPIO_66, GEVENT_1 },
|
||||
{ GPIO_68, GEVENT_9 },
|
||||
{ GPIO_69, GEVENT_17 },
|
||||
};
|
||||
|
||||
static int get_gpio_gevent(uint8_t gpio)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gpio_event_table); i++) {
|
||||
if (gpio_event_table[i].gpio == gpio)
|
||||
return (int)gpio_event_table[i].event;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void mem_read_write32(uint32_t *address, uint32_t value, uint32_t mask)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
value &= mask;
|
||||
reg32 = read32(address);
|
||||
reg32 &= ~mask;
|
||||
reg32 |= value;
|
||||
write32(address, reg32);
|
||||
}
|
||||
|
||||
__weak void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
|
||||
{
|
||||
printk(BIOS_WARNING, "Warning: SMI disabled!\n");
|
||||
}
|
||||
|
||||
static void program_smi(uint32_t flag, int gevent_num)
|
||||
{
|
||||
uint32_t trigger;
|
||||
|
||||
trigger = flag & FLAGS_TRIGGER_MASK;
|
||||
/*
|
||||
* Only level trigger is allowed for SMI. Trigger values are 0
|
||||
* through 3, with 0-1 being level trigger and 2-3 being edge
|
||||
* trigger. GPIO_TRIGGER_EDGE_LOW is 2, so trigger has to be
|
||||
* less than GPIO_TRIGGER_EDGE_LOW.
|
||||
*/
|
||||
assert(trigger < GPIO_TRIGGER_EDGE_LOW);
|
||||
|
||||
if (trigger == GPIO_TRIGGER_LEVEL_HIGH)
|
||||
configure_gevent_smi(gevent_num, SMI_MODE_SMI,
|
||||
SMI_SCI_LVL_HIGH);
|
||||
if (trigger == GPIO_TRIGGER_LEVEL_LOW)
|
||||
configure_gevent_smi(gevent_num, SMI_MODE_SMI,
|
||||
SMI_SCI_LVL_LOW);
|
||||
}
|
||||
|
||||
static void get_sci_config_bits(uint32_t flag, uint32_t *edge, uint32_t *level)
|
||||
{
|
||||
uint32_t trigger;
|
||||
|
||||
trigger = flag & FLAGS_TRIGGER_MASK;
|
||||
switch (trigger) {
|
||||
case GPIO_TRIGGER_LEVEL_LOW:
|
||||
*edge = SCI_TRIGGER_LEVEL;
|
||||
*level = 0;
|
||||
break;
|
||||
case GPIO_TRIGGER_LEVEL_HIGH:
|
||||
*edge = SCI_TRIGGER_LEVEL;
|
||||
*level = 1;
|
||||
break;
|
||||
case GPIO_TRIGGER_EDGE_LOW:
|
||||
*edge = SCI_TRIGGER_EDGE;
|
||||
*level = 0;
|
||||
break;
|
||||
case GPIO_TRIGGER_EDGE_HIGH:
|
||||
*edge = SCI_TRIGGER_EDGE;
|
||||
*level = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uintptr_t gpio_get_address(gpio_t gpio_num)
|
||||
{
|
||||
|
@ -108,18 +212,79 @@ uint16_t gpio_acpi_pin(gpio_t gpio)
|
|||
return gpio;
|
||||
}
|
||||
|
||||
void gpio_set_interrupt(gpio_t gpio, uint32_t flags)
|
||||
void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
|
||||
{
|
||||
uintptr_t gpio_address = gpio_get_address(gpio);
|
||||
uint32_t reg = read32((void *)gpio_address);
|
||||
uint8_t *mux_ptr;
|
||||
uint32_t *gpio_ptr;
|
||||
uint32_t control, control_flags, edge_level, direction;
|
||||
uint32_t mask, bit_edge, bit_level;
|
||||
uint8_t mux, index, gpio;
|
||||
int gevent_num;
|
||||
|
||||
/* Clear registers that are being updated */
|
||||
reg &= ~(GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | GPIO_INTERRUPT_MASK);
|
||||
direction = 0;
|
||||
edge_level = 0;
|
||||
mask = 0;
|
||||
for (index = 0; index < size; index++) {
|
||||
gpio = gpio_list_ptr[index].gpio;
|
||||
mux = gpio_list_ptr[index].function;
|
||||
control = gpio_list_ptr[index].control;
|
||||
control_flags = gpio_list_ptr[index].flags;
|
||||
|
||||
/* Clear any extra bits in the flags */
|
||||
flags &= (GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | GPIO_INTERRUPT_MASK);
|
||||
mux_ptr = (uint8_t *)(uintptr_t)(gpio + AMD_GPIO_MUX);
|
||||
write8(mux_ptr, mux & AMD_GPIO_MUX_MASK);
|
||||
gpio_ptr = (uint32_t *)gpio_get_address(gpio);
|
||||
|
||||
write32((void *)gpio_address, reg | flags);
|
||||
if (control_flags & GPIO_SPECIAL_FLAG) {
|
||||
gevent_num = get_gpio_gevent(gpio);
|
||||
if (gevent_num < 0) {
|
||||
printk(BIOS_WARNING, "Warning: GPIO pin %d has"
|
||||
" no associated gevent!\n", gpio);
|
||||
continue;
|
||||
}
|
||||
switch (control_flags & GPIO_SPECIAL_MASK) {
|
||||
case GPIO_DEBOUNCE_FLAG:
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
GPIO_DEBOUNCE_MASK);
|
||||
break;
|
||||
case GPIO_WAKE_FLAG:
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
INT_WAKE_MASK);
|
||||
break;
|
||||
case GPIO_INT_FLAG:
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
AMD_GPIO_CONTROL_MASK);
|
||||
break;
|
||||
case GPIO_SMI_FLAG:
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
INT_SCI_SMI_MASK);
|
||||
program_smi(control_flags, gevent_num);
|
||||
break;
|
||||
case GPIO_SCI_FLAG:
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
INT_SCI_SMI_MASK);
|
||||
get_sci_config_bits(control_flags, &bit_edge,
|
||||
&bit_level);
|
||||
edge_level |= bit_edge << gevent_num;
|
||||
direction |= bit_level << gevent_num;
|
||||
mask |= (1 << gevent_num);
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_WARNING, "Error, flags 0x%08x\n",
|
||||
control_flags);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mem_read_write32(gpio_ptr, control,
|
||||
AMD_GPIO_CONTROL_MASK);
|
||||
}
|
||||
}
|
||||
/* Set all SCI trigger direction (high/low) */
|
||||
mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_TRIG),
|
||||
direction, mask);
|
||||
|
||||
/* Set all SCI trigger level (edge/level) */
|
||||
mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_LEVEL),
|
||||
edge_level, mask);
|
||||
}
|
||||
|
||||
int gpio_interrupt_status(gpio_t gpio)
|
||||
|
|
|
@ -21,8 +21,21 @@
|
|||
|
||||
#ifndef __ACPI__
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/smi.h>
|
||||
#include <types.h>
|
||||
|
||||
struct soc_amd_gpio {
|
||||
uint8_t gpio;
|
||||
uint8_t function;
|
||||
uint32_t control;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct soc_amd_event {
|
||||
uint8_t gpio;
|
||||
uint8_t event;
|
||||
};
|
||||
|
||||
#define GPIO_EDGE_TRIG (0 << 8)
|
||||
#define GPIO_LEVEL_TRIG (1 << 8)
|
||||
#define GPIO_TRIGGER_MASK (1 << 8)
|
||||
|
@ -35,12 +48,16 @@
|
|||
#define GPIO_INT_STATUS_EN (1 << 11)
|
||||
#define GPIO_INT_DELIVERY_EN (1 << 12)
|
||||
#define GPIO_INTERRUPT_MASK (3 << 11)
|
||||
#define GPIO_S0I3_WAKE_EN (1 << 13)
|
||||
#define GPIO_S3_WAKE_EN (1 << 14)
|
||||
#define GPIO_S4_S5_WAKE_EN (1 << 15)
|
||||
|
||||
#define GPIO_PIN_STS (1 << 16)
|
||||
#define GPIO_PULLUP_ENABLE (1 << 20)
|
||||
#define GPIO_PULLDOWN_ENABLE (1 << 21)
|
||||
#define GPIO_OUTPUT_SHIFT 22
|
||||
#define GPIO_OUTPUT_MASK (1 << GPIO_OUTPUT_SHIFT)
|
||||
#define GPIO_OUTPUT_VALUE (1 << GPIO_OUTPUT_SHIFT)
|
||||
#define GPIO_OUTPUT_ENABLE (1 << 23)
|
||||
|
||||
#define GPIO_INT_STATUS (1 << 28)
|
||||
|
@ -325,38 +342,228 @@
|
|||
#define GPIO_148_IOMUX_I2C1_SDA 0
|
||||
#define GPIO_148_IOMUX_GPIOxx 1
|
||||
|
||||
#define GPIO_ENABLE_OUTPUT BIT(7)
|
||||
#define GPIO_OUTPUT_VALUE BIT(6)
|
||||
#define GPIO_PULL_DOWN_ENABLE BIT(5)
|
||||
#define GPIO_PULL_UP_ENABLE BIT(4)
|
||||
enum {
|
||||
GEVENT_0,
|
||||
GEVENT_1,
|
||||
GEVENT_2,
|
||||
GEVENT_3,
|
||||
GEVENT_4,
|
||||
GEVENT_5,
|
||||
GEVENT_6,
|
||||
GEVENT_7,
|
||||
GEVENT_8,
|
||||
GEVENT_9,
|
||||
GEVENT_10,
|
||||
GEVENT_11,
|
||||
GEVENT_12,
|
||||
GEVENT_13,
|
||||
GEVENT_14,
|
||||
GEVENT_15,
|
||||
GEVENT_16,
|
||||
GEVENT_17,
|
||||
GEVENT_18,
|
||||
GEVENT_19,
|
||||
GEVENT_20,
|
||||
GEVENT_21,
|
||||
GEVENT_22,
|
||||
GEVENT_23,
|
||||
};
|
||||
|
||||
#define GPIO_OUTPUT_OUT_HIGH (GPIO_ENABLE_OUTPUT | GPIO_OUTPUT_VALUE)
|
||||
#define GPIO_OUTPUT_OUT_LOW GPIO_ENABLE_OUTPUT
|
||||
#define GPIO_OUTPUT_OUT_HIGH (GPIO_OUTPUT_ENABLE | GPIO_OUTPUT_VALUE)
|
||||
#define GPIO_OUTPUT_OUT_LOW GPIO_OUTPUT_ENABLE
|
||||
|
||||
#define GPIO_PULL_PULL_UP GPIO_PULL_UP_ENABLE
|
||||
#define GPIO_PULL_PULL_DOWN GPIO_PULL_DOWN_ENABLE
|
||||
#define GPIO_PULL_PULL_UP GPIO_PULLUP_ENABLE
|
||||
#define GPIO_PULL_PULL_DOWN GPIO_PULLDOWN_ENABLE
|
||||
#define GPIO_PULL_PULL_NONE 0
|
||||
|
||||
#define AMD_GPIO_CONTROL_MASK 0x00f4ff00
|
||||
#define AMD_GPIO_MUX_MASK 0x03
|
||||
|
||||
/* Definitions for PAD_INT. */
|
||||
#define GPIO_INT_EDGE_HIGH (GPIO_ACTIVE_HIGH | GPIO_EDGE_TRIG)
|
||||
#define GPIO_INT_EDGE_LOW (GPIO_ACTIVE_LOW | GPIO_EDGE_TRIG)
|
||||
#define GPIO_INT_BOTH_EDGES (GPIO_ACTIVE_BOTH | GPIO_EDGE_TRIG)
|
||||
#define GPIO_INT_LEVEL_HIGH (GPIO_ACTIVE_HIGH | GPIO_LEVEL_TRIG)
|
||||
#define GPIO_INT_LEVEL_LOW (GPIO_ACTIVE_LOW | GPIO_LEVEL_TRIG)
|
||||
|
||||
enum {
|
||||
GPIO_TRIGGER_LEVEL_LOW,
|
||||
GPIO_TRIGGER_LEVEL_HIGH,
|
||||
GPIO_TRIGGER_EDGE_LOW,
|
||||
GPIO_TRIGGER_EDGE_HIGH,
|
||||
};
|
||||
|
||||
#define GPIO_TRIGGER_INVALID -1
|
||||
#define SCI_TRIGGER_EDGE 0
|
||||
#define SCI_TRIGGER_LEVEL 1
|
||||
|
||||
#define GPIO_SPECIAL_FLAG (1 << 31)
|
||||
#define GPIO_DEBOUNCE_FLAG (1 << 30)
|
||||
#define GPIO_WAKE_FLAG (1 << 29)
|
||||
#define GPIO_INT_FLAG (1 << 28)
|
||||
#define GPIO_SMI_FLAG (1 << 27)
|
||||
#define GPIO_SCI_FLAG (1 << 26)
|
||||
#define GPIO_FLAG_DEBOUNCE (GPIO_SPECIAL_FLAG | GPIO_DEBOUNCE_FLAG)
|
||||
#define GPIO_FLAG_WAKE (GPIO_SPECIAL_FLAG | GPIO_WAKE_FLAG)
|
||||
#define GPIO_FLAG_INT (GPIO_SPECIAL_FLAG | GPIO_INT_FLAG)
|
||||
#define GPIO_FLAG_SCI (GPIO_SPECIAL_FLAG | GPIO_SCI_FLAG)
|
||||
#define GPIO_FLAG_SMI (GPIO_SPECIAL_FLAG | GPIO_SMI_FLAG)
|
||||
|
||||
#define FLAGS_TRIGGER_MASK 0x00000003
|
||||
#define GPIO_SPECIAL_MASK 0x7c000000
|
||||
#define GPIO_DEBOUNCE_MASK 0x000000ff
|
||||
#define INT_TRIGGER_MASK 0x00000700
|
||||
#define INT_WAKE_MASK 0x0000e700
|
||||
#define INT_SCI_SMI_MASK 0x00f40000
|
||||
|
||||
#define IN_GLITCH_SHIFT 5
|
||||
#define GLITCH_LOW 1
|
||||
#define GLITCH_HIGH 2
|
||||
#define GLITCH_NONE 3
|
||||
#define GPIO_IN_PRESERVE_LOW_GLITCH (GLITCH_LOW << IN_GLITCH_SHIFT)
|
||||
#define GPIO_IN_PRESERVE_HIGH_GLITCH (GLITCH_HIGH << IN_GLITCH_SHIFT)
|
||||
#define GPIO_IN_REMOVE_GLITCH (GLITCH_NONE << IN_GLITCH_SHIFT)
|
||||
|
||||
#define GPIO_TIMEBASE_61uS 0
|
||||
#define GPIO_TIMEBASE_183uS (1 << 4)
|
||||
#define GPIO_TIMEBASE_15560uS (1 << 7)
|
||||
#define GPIO_TIMEBASE_62440uS (GPIO_TIMEBASE_183uS | \
|
||||
GPIO_TIMEBASE_15560uS)
|
||||
#define GPIO_IN_60uS (1 | GPIO_TIMEBASE_61uS)
|
||||
#define GPIO_IN_120uS (2 | GPIO_TIMEBASE_61uS)
|
||||
#define GPIO_IN_200uS (3 | GPIO_TIMEBASE_61uS)
|
||||
#define GPIO_IN_500uS (8 | GPIO_TIMEBASE_61uS)
|
||||
#define GPIO_IN_1mS (5 | GPIO_TIMEBASE_183uS)
|
||||
#define GPIO_IN_2mS (11 | GPIO_TIMEBASE_183uS)
|
||||
#define GPIO_IN_15mS (1 | GPIO_TIMEBASE_15560uS)
|
||||
#define GPIO_IN_50mS (3 | GPIO_TIMEBASE_15560uS)
|
||||
#define GPIO_IN_100mS (6 | GPIO_TIMEBASE_15560uS)
|
||||
#define GPIO_IN_200mS (13 | GPIO_TIMEBASE_15560uS)
|
||||
#define GPIO_IN_500mS (8 | GPIO_TIMEBASE_62440uS)
|
||||
|
||||
#define GPIO_IN_NO_DEBOUNCE (DEBOUNCE_NONE << IN_GLITCH_SHIFT)
|
||||
#define GPIO_IN_PRESERVE_LOW_GLITCH (GLITCH_LOW << IN_GLITCH_SHIFT)
|
||||
#define GPIO_IN_PRESERVE_HIGH_GLITCH (GLITCH_HIGH << IN_GLITCH_SHIFT)
|
||||
#define GPIO_IN_REMOVE_GLITCH (GLITCH_NONE << IN_GLITCH_SHIFT)
|
||||
|
||||
#define GPIO_EVENT_INT_STATUS GPIO_INT_STATUS_EN
|
||||
#define GPIO_EVENT_INT_DELIVER GPIO_INT_DELIVERY_EN
|
||||
#define GPIO_EVENT_INT_STATUS_DELIVER (GPIO_INT_STATUS_EN | \
|
||||
GPIO_INT_DELIVERY_EN)
|
||||
#define GPIO_WAKE_S0i3 (1 << 13)
|
||||
#define GPIO_WAKE_S3 (1 << 14)
|
||||
#define GPIO_WAKE_S4_S5 (1 << 15)
|
||||
#define GPIO_WAKE_S0i3_S4_S5 (GPIO_WAKE_S0i3 | GPIO_WAKE_S4_S5)
|
||||
#define GPIO_WAKE_S3_S4_S5 (GPIO_WAKE_S3 | GPIO_WAKE_S4_S5)
|
||||
|
||||
/*
|
||||
* Several macros are available to declare programming of GPIO pins, and if
|
||||
* needed more than 1 macro can be used for any pin. However, some macros
|
||||
* will have no effect if combined. For example debounce only affects input
|
||||
* or one of the interrupts. Some macros should not be combined, such as SMI
|
||||
* and regular interrupt. The defined macros and their parameters are:
|
||||
* PAD_NF Define native alternate function for the pin.
|
||||
* pin the pin to be programmed
|
||||
* function the native function
|
||||
* pull pull up, pull down or no pull
|
||||
* PAD_GPI The pin is a GPIO input
|
||||
* pin the pin to be programmed
|
||||
* pull pull up, pull down or no pull
|
||||
* PAD_GPO The pin is a GPIO output
|
||||
* pin the pin to be programmed
|
||||
* direction high or low
|
||||
* PAD_INT The pin is regular interrupt that works while booting
|
||||
* pin the pin to be programmed
|
||||
* pull pull up, pull down or no pull
|
||||
* trigger LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, EDGE_HIGH, BOTH_EDGES
|
||||
* action STATUS, DELIVER, STATUS_DELIVER
|
||||
* PAD_SCI The pin is a SCI source
|
||||
* pin the pin to be programmed
|
||||
* pull pull up, pull down or no pull
|
||||
* trigger LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, EDGE_HIGH
|
||||
* PAD_SMI The pin is a SMI source
|
||||
* pin the pin to be programmed
|
||||
* pull pull up, pull down or no pull
|
||||
* trigger LEVEL_LOW, LEVEL_HIGH
|
||||
* PAD_WAKE The pin can wake, use after PAD_INT or PAD_SCI
|
||||
* pin the pin to be programmed
|
||||
* pull pull up, pull down or no pull
|
||||
* trigger LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, EDGE_HIGH, BOTH_EDGES
|
||||
* type S0i3, S3, S4_S5 or S4_S5 combinations (S0i3_S3 invalid)
|
||||
* PAD_DEBOUNCE The input or interrupt will be debounced, invalid after
|
||||
* PAD_NF
|
||||
* pin the pin to be programmed
|
||||
* debounce_type preserve low glitch, preserve high glitch, no glitch
|
||||
* debounce_time the debounce time
|
||||
*/
|
||||
|
||||
/* Native function pad configuration */
|
||||
#define PAD_NF(pin, func, pull) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## func, \
|
||||
.control = GPIO_PULL ## _ ## pull }
|
||||
.control = GPIO_PULL ## _ ## pull, \
|
||||
.flags = 0 }
|
||||
/* General purpose input pad configuration */
|
||||
#define PAD_GPI(pin, pull) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = GPIO_PULL ## _ ## pull }
|
||||
.control = GPIO_PULL ## _ ## pull, \
|
||||
.flags = 0 }
|
||||
/* General purpose output pad configuration */
|
||||
#define PAD_GPO(pin, direction) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = GPIO_OUTPUT ## _OUT_ ## direction }
|
||||
.control = GPIO_OUTPUT ## _OUT_ ## direction, \
|
||||
.flags = 0 }
|
||||
/* Auxiliary macro for legacy interrupt and wake */
|
||||
#define PAD_AUX1(pull, trigger) (GPIO_PULL ## _ ## pull | \
|
||||
GPIO_INT ## _ ## trigger)
|
||||
/* Legacy interrupt pad configuration */
|
||||
#define PAD_INT(pin, pull, trigger, action) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = (PAD_AUX1(pull, trigger) | \
|
||||
GPIO_EVENT_INT ## _ ## action), \
|
||||
.flags = GPIO_FLAG_INT }
|
||||
/* Auxiliary macro for SCI and SMI */
|
||||
#define PAD_AUX2(trigger, flag) (GPIO_TRIGGER ## _ ## trigger | flag)
|
||||
/* SCI pad configuration */
|
||||
#define PAD_SCI(pin, pull, trigger) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = GPIO_PULL ## _ ## pull, \
|
||||
.flags = PAD_AUX2(trigger, GPIO_FLAG_SCI) }
|
||||
/* SMI pad configuration */
|
||||
#define PAD_SMI(pin, pull, trigger) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = GPIO_PULL ## _ ## pull, \
|
||||
.flags = PAD_AUX2(trigger, GPIO_FLAG_SMI) }
|
||||
/* WAKE pad configuration */
|
||||
#define PAD_WAKE(pin, pull, trigger, type) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = (PAD_AUX1(pull, trigger) | \
|
||||
GPIO_WAKE ## _ ## type), \
|
||||
.flags = GPIO_FLAG_WAKE }
|
||||
/* pin debounce configuration */
|
||||
#define PAD_DEBOUNCE(pin, type, time) \
|
||||
{ .gpio = (pin), \
|
||||
.function = pin ## _IOMUX_ ## GPIOxx, \
|
||||
.control = (GPIO_IN ## _ ## type | GPIO_IN ## _ ## time), \
|
||||
.flags = GPIO_FLAG_DEBOUNCE }
|
||||
|
||||
typedef uint32_t gpio_t;
|
||||
|
||||
/* Update interrupt settings for given GPIO */
|
||||
void gpio_set_interrupt(gpio_t gpio, uint32_t flags);
|
||||
/**
|
||||
* @brief program a particular set of GPIO
|
||||
*
|
||||
* @param gpio_list_ptr = pointer to array of gpio configurations
|
||||
* @param size = number of entries in array
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size);
|
||||
|
||||
/* Return the interrupt status and clear if set. */
|
||||
int gpio_interrupt_status(gpio_t gpio);
|
||||
|
|
|
@ -306,7 +306,6 @@
|
|||
|
||||
#define WIDEIO_RANGE_ERROR -1
|
||||
#define TOTAL_WIDEIO_PORTS 3
|
||||
#define AMD_GPIO_MUX_MASK 0x03
|
||||
|
||||
#if ENV_BOOTBLOCK
|
||||
#define GPIO_TABLE_BOOTBLOCK 1
|
||||
|
@ -354,12 +353,6 @@
|
|||
#define FCH_AOAC_STAT0 BIT(6)
|
||||
#define FCH_AOAC_STAT1 BIT(7)
|
||||
|
||||
struct soc_amd_gpio {
|
||||
uint8_t gpio;
|
||||
uint8_t function;
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct stoneyridge_aoac {
|
||||
int enable;
|
||||
int status;
|
||||
|
@ -442,15 +435,6 @@ uint32_t get_uma_size(void);
|
|||
* @return 64bit base address
|
||||
*/
|
||||
uint64_t get_uma_base(void);
|
||||
/**
|
||||
* @brief program a particular set of GPIO
|
||||
*
|
||||
* @param gpio_ptr = pointer to array of gpio configurations
|
||||
* @param size = number of entries in array
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void sb_program_gpios(const struct soc_amd_gpio *gpio_ptr, size_t size);
|
||||
/**
|
||||
* @brief Find the size of a particular wide IO
|
||||
*
|
||||
|
|
|
@ -173,27 +173,6 @@ const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
|
|||
return irq_association;
|
||||
}
|
||||
|
||||
void sb_program_gpios(const struct soc_amd_gpio *gpio_ptr, size_t size)
|
||||
{
|
||||
void *tmp_ptr;
|
||||
uint8_t control, mux, index;
|
||||
|
||||
for (index = 0; index < size; index++) {
|
||||
mux = gpio_ptr[index].function;
|
||||
control = gpio_ptr[index].control;
|
||||
tmp_ptr = (void *)(gpio_ptr[index].gpio + AMD_GPIO_MUX);
|
||||
write8(tmp_ptr, mux & AMD_GPIO_MUX_MASK);
|
||||
|
||||
/*
|
||||
* Get the address of AMD_GPIO_CONTROL (dword) relative
|
||||
* to the desired pin and program bits 16-23.
|
||||
*/
|
||||
tmp_ptr = (void *)(gpio_ptr[index].gpio * sizeof(uint32_t) +
|
||||
AMD_GPIO_CONTROL + 2);
|
||||
write8(tmp_ptr, control);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the size of a particular wide IO
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue