Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/22986
Change subject: soc/amd/stoneyridge/southbridge.c: Create a GPIO programming function ......................................................................
soc/amd/stoneyridge/southbridge.c: Create a GPIO programming function
Create a GPIO programming function that can be called from multiple stages (bootblock, romstage and ramstage) that will program only the GPIO specific to the particular stage.
Add dummy table to kahlee to be able to test a build.
BUG=b:64140392 TEST=Build kahlee.
Change-Id: I88d65c78a186bed9739bc208d5711a31aa3c3bb6 Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/mainboard/google/kahlee/variants/baseboard/gpio.c M src/mainboard/google/kahlee/variants/kahlee/gpio.c M src/soc/amd/stoneyridge/include/soc/iomap.h M src/soc/amd/stoneyridge/include/soc/southbridge.h M src/soc/amd/stoneyridge/southbridge.c 5 files changed, 112 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/86/22986/1
diff --git a/src/mainboard/google/kahlee/variants/baseboard/gpio.c b/src/mainboard/google/kahlee/variants/baseboard/gpio.c index 250fcc1..35b35d1 100644 --- a/src/mainboard/google/kahlee/variants/baseboard/gpio.c +++ b/src/mainboard/google/kahlee/variants/baseboard/gpio.c @@ -21,6 +21,30 @@ #include <stdlib.h>
/* + * The definitions bellow are valid only within this file, with the sole + * purpose of making the array below compact and easy to understand. + */ +#define PULL_UP FCH_GPIO_PULL_UP_ENABLE +#define PULL_DOWN FCH_GPIO_PULL_DOWN_ENABLE +#define INPUT 0 +#define OUTPUT_H (FCH_GPIO_OUTPUT_ENABLE | FCH_GPIO_OUTPUT_VALUE) +#define OUTPUT_L FCH_GPIO_OUTPUT_ENABLE + +/* + * These settings were generated by a spreadsheet. If they need to be updated, + * update the spreadsheet shared with the Grunt development team. + * + * As a rule of thumb, GPIO used by coreboot should be initialized at + * STAGE_RESET while GPIO used only by the OS should be initialized at + * STAGE_INIT_LATE. + */ +const static struct soc_amd_stoneyridge_gpio gpio_set_stage[] = { + + /* GPIO_0 - EC_PCH_PWR_BTN_ODL */ + { GPIO_0, Function0, PULL_UP | INPUT, STAGE_RESET } +}; + +/* * These settings were generated by a spreadsheet. If they need to be updated, * update the spreadsheet shared with the Grunt development team. */ @@ -260,6 +284,14 @@ return agesa_board_gpios; }
+const __attribute__((weak)) const struct + soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size) +{ + *size = ARRAY_SIZE(gpio_set_stage); + return gpio_set_stage; +} + + /* * GPE setup table must match ACPI GPE ASL * { gevent, gpe, direction, level } diff --git a/src/mainboard/google/kahlee/variants/kahlee/gpio.c b/src/mainboard/google/kahlee/variants/kahlee/gpio.c index e5e15e6..8d76ee9 100644 --- a/src/mainboard/google/kahlee/variants/kahlee/gpio.c +++ b/src/mainboard/google/kahlee/variants/kahlee/gpio.c @@ -20,6 +20,26 @@ #include <stdlib.h> #include <variant/gpio.h>
+/* + * The definitions bellow are valid only within this file, with the sole + * purpose of making the array below compact and easy to understand. + */ +#define PULL_UP FCH_GPIO_PULL_UP_ENABLE +#define PULL_DOWN FCH_GPIO_PULL_DOWN_ENABLE +#define INPUT 0 +#define OUTPUT_H (FCH_GPIO_OUTPUT_ENABLE | FCH_GPIO_OUTPUT_VALUE) +#define OUTPUT_L FCH_GPIO_OUTPUT_ENABLE + +/* + * As a rule of thumb, GPIO used by coreboot should be initialized at + * STAGE_RESET while GPIO used only by the OS should be initialized at + * STAGE_INIT_LATE. + */ +const struct soc_amd_stoneyridge_gpio gpio_set_stage[] = { + /* AGPIO2, to become event generator */ + { GPIO_2, Function1, PULL_UP | INPUT, STAGE_RESET } +}; + static const GPIO_CONTROL agesa_board_gpios[] = { /* AGPIO2 PCIE/WLAN WAKE# SCI*/ {2, Function1, FCH_GPIO_PULL_UP_ENABLE }, @@ -104,6 +124,12 @@ return agesa_board_gpios; }
+const struct soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size) +{ + *size = ARRAY_SIZE(gpio_set_stage); + return gpio_set_stage; +} + /* * GPE setup table must match ACPI GPE ASL * { gevent, gpe, direction, level } diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 64a9b30..9df1e6b 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -50,4 +50,8 @@ #define AB_DATA (AB_INDX+4) #define SYS_RESET 0xcf9
+/* GPIO control and mux access */ +#define AMD_GPIO_MUX (AMD_SB_ACPI_MMIO_ADDR + 0x00000d00) +#define AMD_GPIO_CONTROL (AMD_SB_ACPI_MMIO_ADDR + 0x00001500) + #endif /* __SOC_STONEYRIDGE_IOMAP_H__ */ diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index bbf6344..1d03822 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -271,7 +271,6 @@ #define XHCI_PM_INDIRECT_INDEX 0x48 #define XHCI_PM_INDIRECT_DATA 0x4C #define XHCI_OVER_CURRENT_CONTROL 0x30 - #define EHCI_OVER_CURRENT_CONTROL 0x70
#define USB_OC0 0 @@ -293,6 +292,18 @@ #define WIDEIO_RANGE_ERROR -1 #define TOTAL_WIDEIO_PORTS 3
+#define GPIO_CONTROL_MASK 0x00f00000 +#define GPIO_UNKNOWN_BIT 0x00040000 /* cleared by AGESA */ +struct soc_amd_stoneyridge_gpio { + uint8_t gpio; + uint8_t function; + uint8_t control; + enum { + STAGE_RESET, + STAGE_INIT_LATE + } stage; +}; + static inline int sb_sata_enable(void) { /* True if IDE or AHCI. */ @@ -346,6 +357,8 @@ int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos); int s3_save_nvram_early(u32 dword, int size, int nvram_pos); void bootblock_fch_early_init(void); +const struct soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size); +void sb_program_gpio(int stage); /** * @brief Find the size of a particular wide IO * diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 1357257..77a424b 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -142,6 +142,42 @@ return irq_association; }
+void sb_program_gpio(int stage) +{ + uint32_t *control_ptr; + uint8_t *mux_ptr; + const struct soc_amd_stoneyridge_gpio *gpio_ptr; + uint32_t ptr_build, control_value; + int gpio = 0; + size_t size; + uint8_t control, mux, index; + + printk(BIOS_DEBUG, "GPIO programming stage %s\n", + (stage == STAGE_RESET) ? "reset" : "init late"); + gpio_ptr = board_get_gpio(&size); + for (index = 0; index < size; index++) { + if (gpio_ptr[index].stage == stage) { + mux = gpio_ptr[index].function; + control = gpio_ptr[index].control; + gpio = gpio_ptr[index].gpio; + mux_ptr = (uint8_t *) gpio + AMD_GPIO_MUX; + *mux_ptr = (mux & 0x03); /* clear reserved bits */ + ptr_build = gpio * 4; + ptr_build += AMD_GPIO_CONTROL; + control_ptr = (uint32_t *)ptr_build; + control_value = *control_ptr; + control_value &= ~(GPIO_CONTROL_MASK | + GPIO_UNKNOWN_BIT); + control_value |= ((control << 16) & GPIO_CONTROL_MASK); + *control_ptr = control_value; + printk(BIOS_DEBUG, "GPIO%-3d function%d set to" + " 0x%08x\n", + gpio, mux, *control_ptr); + } + } + printk(BIOS_DEBUG, "End GPIO programming\n"); +} + /** * @brief Find the size of a particular wide IO *