summaryrefslogtreecommitdiff
path: root/src/soc/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd')
-rw-r--r--src/soc/amd/common/block/gpio_banks/gpio.c72
-rw-r--r--src/soc/amd/common/block/include/amdblocks/gpio_banks.h56
2 files changed, 46 insertions, 82 deletions
diff --git a/src/soc/amd/common/block/gpio_banks/gpio.c b/src/soc/amd/common/block/gpio_banks/gpio.c
index caf07c0192..883dcfa783 100644
--- a/src/soc/amd/common/block/gpio_banks/gpio.c
+++ b/src/soc/amd/common/block/gpio_banks/gpio.c
@@ -21,17 +21,6 @@ static int get_gpio_gevent(uint8_t gpio, const struct soc_amd_event *table,
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);
-}
-
static void program_smi(uint32_t flags, int gevent_num)
{
uint8_t level;
@@ -187,7 +176,6 @@ __weak void soc_gpio_hook(uint8_t gpio, uint8_t mux) {}
void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
{
- uint32_t *gpio_ptr;
uint32_t control, control_flags;
uint8_t mux, index, gpio;
int gevent_num;
@@ -219,51 +207,23 @@ void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
iomux_read8(gpio); /* Flush posted write */
soc_gpio_hook(gpio, mux);
+ __gpio_setbits32(gpio, PAD_CFG_MASK, control);
+
+ if (control_flags == 0)
+ continue;
+
+ gevent_num = get_gpio_gevent(gpio, gev_tbl, gev_items);
+ if (gevent_num < 0) {
+ printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n",
+ gpio);
+ continue;
+ }
- gpio_ptr = gpio_ctrl_ptr(gpio);
-
- if (control_flags & GPIO_FLAG_SPECIAL_MASK) {
- gevent_num = get_gpio_gevent(gpio, gev_tbl, gev_items);
- if (gevent_num < 0) {
- printk(BIOS_WARNING, "Warning: GPIO pin %d has"
- " no associated gevent!\n", gpio);
- continue;
- }
- switch (control_flags & GPIO_FLAG_SPECIAL_MASK) {
- case GPIO_FLAG_DEBOUNCE:
- mem_read_write32(gpio_ptr, control,
- GPIO_DEBOUNCE_MASK);
- break;
- case GPIO_FLAG_WAKE:
- mem_read_write32(gpio_ptr, control,
- INT_WAKE_MASK);
- break;
- case GPIO_FLAG_INT:
- mem_read_write32(gpio_ptr, control,
- AMD_GPIO_CONTROL_MASK);
- break;
- case GPIO_FLAG_SMI:
- mem_read_write32(gpio_ptr, control,
- INT_SCI_SMI_MASK);
-
- program_smi(control_flags, gevent_num);
- break;
- case GPIO_FLAG_SCI:
- mem_read_write32(gpio_ptr, control,
- INT_SCI_SMI_MASK);
-
- fill_sci_trigger(control_flags, gevent_num, &sci_trigger_cfg);
-
- soc_route_sci(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);
+ if (control_flags & GPIO_FLAG_SMI) {
+ program_smi(control_flags, gevent_num);
+ } else if (control_flags & GPIO_FLAG_SCI) {
+ fill_sci_trigger(control_flags, gevent_num, &sci_trigger_cfg);
+ soc_route_sci(gevent_num);
}
}
diff --git a/src/soc/amd/common/block/include/amdblocks/gpio_banks.h b/src/soc/amd/common/block/include/amdblocks/gpio_banks.h
index 546d55aa53..f02c8e86b4 100644
--- a/src/soc/amd/common/block/include/amdblocks/gpio_banks.h
+++ b/src/soc/amd/common/block/include/amdblocks/gpio_banks.h
@@ -74,6 +74,7 @@ struct soc_amd_event {
#define GPIO_INT_STATUS (1 << 28)
#define GPIO_WAKE_STATUS (1 << 29)
+#define GPIO_STATUS_MASK (3 << 28)
enum {
GEVENT_0,
@@ -118,7 +119,6 @@ enum {
#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
@@ -134,10 +134,6 @@ enum {
#define GPIO_FLAG_EVENT_ACTIVE_MASK (1 << 1)
#define GPIO_FLAG_SCI (1 << 2)
#define GPIO_FLAG_SMI (1 << 3)
-#define GPIO_FLAG_DEBOUNCE (1 << 4)
-#define GPIO_FLAG_WAKE (1 << 5)
-#define GPIO_FLAG_INT (1 << 6)
-#define GPIO_FLAG_SPECIAL_MASK (0x1f << 2)
/* Trigger configuration for GPIO SCI/SMI events. */
#define GPIO_FLAG_EVENT_TRIGGER_LEVEL_HIGH (GPIO_FLAG_EVENT_TRIGGER_LEVEL | \
@@ -169,11 +165,6 @@ static inline bool is_gpio_event_active_low(uint32_t flags)
return (flags & GPIO_FLAG_EVENT_ACTIVE_MASK) == GPIO_FLAG_EVENT_ACTIVE_LOW;
}
-#define GPIO_DEBOUNCE_MASK 0x000000ff
-#define INT_TRIGGER_MASK 0x00000700
-#define INT_WAKE_MASK 0x0000e700
-#define INT_SCI_SMI_MASK 0x00f40000
-
#define DEB_GLITCH_SHIFT 5
#define DEB_GLITCH_LOW 1
#define DEB_GLITCH_HIGH 2
@@ -200,18 +191,29 @@ static inline bool is_gpio_event_active_low(uint32_t flags)
#define GPIO_DEB_200mS (13 | GPIO_TIMEBASE_15560uS)
#define GPIO_DEB_500mS (8 | GPIO_TIMEBASE_62440uS)
+#define GPIO_DEB_MASK 0xff
+
#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)
+#define GPIO_WAKE_MASK (7 << 13)
+
+/*
+ * Mask used to reset bits in GPIO control register when configuring pad using `program_gpios()`
+ * Bits that are preserved/untouched:
+ * - Reserved bits
+ * - Drive strength bits
+ * - Read only bits
+ */
+#define PAD_CFG_MASK (GPIO_DEB_MASK | GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | \
+ GPIO_INT_ENABLE_MASK | GPIO_WAKE_MASK | GPIO_PULL_MASK | \
+ GPIO_OUTPUT_MASK | GPIO_STATUS_MASK)
/*
- * 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:
+ * Several macros are available to declare programming of GPIO pins. 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
@@ -230,19 +232,19 @@ static inline bool is_gpio_event_active_low(uint32_t flags)
* 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
+ * event 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
+ * event 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
+ * PAD_DEBOUNCE The input or interrupt will be debounced
* pin the pin to be programmed
+ * pull pull up, pull down or no pull
* debounce_type preserve low glitch, preserve high glitch, no glitch
* debounce_time the debounce time
*/
@@ -279,29 +281,31 @@ static inline bool is_gpio_event_active_low(uint32_t flags)
#define PAD_INT(pin, pull, trigger, action) \
PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, \
PAD_PULL(pull) | PAD_TRIGGER(trigger) | PAD_INT_ENABLE(action), \
- GPIO_FLAG_INT)
+ 0)
/* SCI pad configuration */
#define PAD_SCI(pin, pull, trigger) \
- PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, PAD_PULL(pull), \
+ PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, \
+ PAD_PULL(pull) | PAD_TRIGGER(LEVEL_HIGH), \
PAD_FLAG_EVENT_TRIGGER(trigger) | GPIO_FLAG_SCI)
/* SMI pad configuration */
#define PAD_SMI(pin, pull, trigger) \
- PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, PAD_PULL(pull), \
+ PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, \
+ PAD_PULL(pull) | PAD_TRIGGER(LEVEL_HIGH), \
PAD_FLAG_EVENT_TRIGGER(trigger) | GPIO_FLAG_SMI)
/* WAKE pad configuration */
#define PAD_WAKE(pin, pull, trigger, type) \
PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, \
PAD_PULL(pull) | PAD_TRIGGER(trigger) | PAD_WAKE_ENABLE(type), \
- GPIO_FLAG_WAKE)
+ 0)
/* pin debounce configuration */
-#define PAD_DEBOUNCE(pin, type, time) \
+#define PAD_DEBOUNCE(pin, pull, type, time) \
PAD_CFG_STRUCT(pin, pin ## _IOMUX_GPIOxx, \
- PAD_DEBOUNCE_CONFIG(type) | PAD_DEBOUNCE_CONFIG(time), \
- GPIO_FLAG_DEBOUNCE)
+ PAD_PULL(pull) | PAD_DEBOUNCE_CONFIG(type) | PAD_DEBOUNCE_CONFIG(time), \
+ 0)
typedef uint32_t gpio_t;