From 2269a3c328c335aa57d7094ca24a9d21ee6ade7d Mon Sep 17 00:00:00 2001 From: Chris Ching Date: Mon, 5 Feb 2018 16:46:41 -0700 Subject: [PATCH] soc/amd/stoneyridge: Add functions for GPIO interrupts Add a function to configure interrupt settings for a GPIO. This does not currently configure GEVENT signals. The second function returns the GPIO interrupt status and clears the flag if set. BUG=b:72838769 BRANCH=none TEST=Update and test interrupt settings for GPIO_9 on grunt Change-Id: I1addd3abcb6a57d916b1c93480bacb0450abddf2 Signed-off-by: Chris Ching Signed-off-by: Martin Roth Reviewed-on: https://review.coreboot.org/23624 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/amd/stoneyridge/Makefile.inc | 2 ++ src/soc/amd/stoneyridge/gpio.c | 29 ++++++++++++++++++++++ src/soc/amd/stoneyridge/include/soc/gpio.h | 23 +++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc index aae30eae3f..61704eaca6 100644 --- a/src/soc/amd/stoneyridge/Makefile.inc +++ b/src/soc/amd/stoneyridge/Makefile.inc @@ -40,6 +40,7 @@ subdirs-y += ../../../cpu/x86/smm bootblock-$(CONFIG_STONEYRIDGE_UART) += uart.c bootblock-y += BiosCallOuts.c bootblock-y += bootblock/bootblock.c +bootblock-y += gpio.c bootblock-y += i2c.c bootblock-y += monotonic_timer.c bootblock-y += pmutil.c @@ -66,6 +67,7 @@ romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c romstage-y += tsc_freq.c romstage-y += southbridge.c +verstage-y += gpio.c verstage-y += i2c.c verstage-y += monotonic_timer.c verstage-y += sb_util.c diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c index 59f283ed5c..088f1990d5 100644 --- a/src/soc/amd/stoneyridge/gpio.c +++ b/src/soc/amd/stoneyridge/gpio.c @@ -106,3 +106,32 @@ uint16_t gpio_acpi_pin(gpio_t gpio) { return gpio; } + +void gpio_set_interrupt(gpio_t gpio, uint32_t flags) +{ + uintptr_t gpio_address = gpio_get_address(gpio); + uint32_t reg = read32((void *)gpio_address); + + /* Clear registers that are being updated */ + reg &= ~(GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | GPIO_INTERRUPT_MASK); + + /* Clear any extra bits in the flags */ + flags &= (GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | GPIO_INTERRUPT_MASK); + + write32((void *)gpio_address, reg | flags); +} + +int gpio_interrupt_status(gpio_t gpio) +{ + uintptr_t gpio_address = gpio_get_address(gpio); + uint32_t reg = read32((void *)gpio_address); + + if (reg & GPIO_INT_STATUS) { + /* Clear interrupt status, preserve wake status */ + reg &= ~GPIO_WAKE_STATUS; + write32((void *)gpio_address, reg); + return 1; + } + + return 0; +} diff --git a/src/soc/amd/stoneyridge/include/soc/gpio.h b/src/soc/amd/stoneyridge/include/soc/gpio.h index 84a4e84a17..248171353b 100644 --- a/src/soc/amd/stoneyridge/include/soc/gpio.h +++ b/src/soc/amd/stoneyridge/include/soc/gpio.h @@ -23,6 +23,19 @@ #include #include +#define GPIO_EDGEL_TRIG (0 << 8) +#define GPIO_LEVEL_TRIG (1 << 8) +#define GPIO_TRIGGER_MASK (1 << 8) + +#define GPIO_ACTIVE_HIGH (0 << 9) +#define GPIO_ACTIVE_LOW (1 << 9) +#define GPIO_ACTIVE_BOTH (2 << 9) +#define GPIO_ACTIVE_MASK (3 << 9) + +#define GPIO_INT_STATUS_EN (1 << 11) +#define GPIO_INT_DELIVERY_EN (1 << 12) +#define GPIO_INTERRUPT_MASK (3 << 11) + #define GPIO_PIN_STS (1 << 16) #define GPIO_PULLUP_ENABLE (1 << 20) #define GPIO_PULLDOWN_ENABLE (1 << 21) @@ -30,6 +43,9 @@ #define GPIO_OUTPUT_MASK (1 << GPIO_OUTPUT_SHIFT) #define GPIO_OUTPUT_ENABLE (1 << 23) +#define GPIO_INT_STATUS (1 << 28) +#define GPIO_WAKE_STATUS (1 << 29) + /* * The definitions below should be used to make GPIO arrays compact and * easy to understand. @@ -143,5 +159,12 @@ #define GPIO_148 148 typedef uint32_t gpio_t; + +/* Update interrupt settings for given GPIO */ +void gpio_set_interrupt(gpio_t gpio, uint32_t flags); + +/* Return the interrupt status and clear if set. */ +int gpio_interrupt_status(gpio_t gpio); + #endif /* __ACPI__ */ #endif /* __STONEYRIDGE_GPIO_H__ */