diff options
author | Richard Spiegel <richard.spiegel@amd.corp-partner.google.com> | 2018-04-20 16:50:12 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2018-05-27 01:03:28 +0000 |
commit | 2db06bba0fdeb2465108da487b0b2d1ecedef985 (patch) | |
tree | 49591ccccf5f171fd4e984cd517615ec8886b748 /src/soc/amd/stoneyridge/include | |
parent | 2aa13eff9d5df7c19898acecbcdb2fda1ec00d44 (diff) | |
download | coreboot-2db06bba0fdeb2465108da487b0b2d1ecedef985.tar.xz |
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>
Diffstat (limited to 'src/soc/amd/stoneyridge/include')
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/gpio.h | 233 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 16 |
2 files changed, 220 insertions, 29 deletions
diff --git a/src/soc/amd/stoneyridge/include/soc/gpio.h b/src/soc/amd/stoneyridge/include/soc/gpio.h index cbc99e4d31..e43f2c7306 100644 --- a/src/soc/amd/stoneyridge/include/soc/gpio.h +++ b/src/soc/amd/stoneyridge/include/soc/gpio.h @@ -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); diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 0a23fcacd4..10b1f4328b 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -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; @@ -443,15 +436,6 @@ uint32_t get_uma_size(void); */ 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 * * @param index = index of desired wide IO |