summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/google/kahlee/bootblock/bootblock.c7
-rw-r--r--src/mainboard/google/kahlee/mainboard.c10
-rw-r--r--src/mainboard/google/kahlee/variants/baseboard/gpio.c100
-rw-r--r--src/mainboard/google/kahlee/variants/kahlee/gpio.c20
-rw-r--r--src/soc/amd/stoneyridge/Makefile.inc2
-rw-r--r--src/soc/amd/stoneyridge/gpio.c181
-rw-r--r--src/soc/amd/stoneyridge/include/soc/gpio.h233
-rw-r--r--src/soc/amd/stoneyridge/include/soc/southbridge.h16
-rw-r--r--src/soc/amd/stoneyridge/southbridge.c21
9 files changed, 428 insertions, 162 deletions
diff --git a/src/mainboard/google/kahlee/bootblock/bootblock.c b/src/mainboard/google/kahlee/bootblock/bootblock.c
index aac1d955d9..8f124b36ff 100644
--- a/src/mainboard/google/kahlee/bootblock/bootblock.c
+++ b/src/mainboard/google/kahlee/bootblock/bootblock.c
@@ -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);
- }
}
diff --git a/src/mainboard/google/kahlee/mainboard.c b/src/mainboard/google/kahlee/mainboard.c
index a01ae0acf5..e090401ddf 100644
--- a/src/mainboard/google/kahlee/mainboard.c
+++ b/src/mainboard/google/kahlee/mainboard.c
@@ -169,8 +169,16 @@ 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);
- gpe_configure_sci(gpes, num);
+ if (gpes != NULL)
+ gpe_configure_sci(gpes, num);
/* Initialize i2c busses that were not initialized in bootblock */
i2c_soc_init();
diff --git a/src/mainboard/google/kahlee/variants/baseboard/gpio.c b/src/mainboard/google/kahlee/variants/baseboard/gpio.c
index ff6141e525..c7bd6a5be9 100644
--- a/src/mainboard/google/kahlee/variants/baseboard/gpio.c
+++ b/src/mainboard/google/kahlee/variants/baseboard/gpio.c
@@ -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)
diff --git a/src/mainboard/google/kahlee/variants/kahlee/gpio.c b/src/mainboard/google/kahlee/variants/kahlee/gpio.c
index 8f30e4b40e..30723508db 100644
--- a/src/mainboard/google/kahlee/variants/kahlee/gpio.c
+++ b/src/mainboard/google/kahlee/variants/kahlee/gpio.c
@@ -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,
diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc
index 54b1198b32..c2d48d5f6d 100644
--- a/src/soc/amd/stoneyridge/Makefile.inc
+++ b/src/soc/amd/stoneyridge/Makefile.inc
@@ -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
diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c
index 4520df7a6f..1b7f0557df 100644
--- a/src/soc/amd/stoneyridge/gpio.c
+++ b/src/soc/amd/stoneyridge/gpio.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;
+
+ 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 registers that are being updated */
- reg &= ~(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);
- /* Clear any extra bits in the flags */
- flags &= (GPIO_TRIGGER_MASK | GPIO_ACTIVE_MASK | GPIO_INTERRUPT_MASK);
+ 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);
- write32((void *)gpio_address, reg | flags);
+ /* 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)
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
diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c
index 5a3a442415..cc21601c3e 100644
--- a/src/soc/amd/stoneyridge/southbridge.c
+++ b/src/soc/amd/stoneyridge/southbridge.c
@@ -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
*