diff options
-rw-r--r-- | src/mainboard/amd/gardenia/Makefile.inc | 3 | ||||
-rw-r--r-- | src/mainboard/amd/gardenia/bootblock/gpio.c (renamed from src/mainboard/amd/gardenia/bootblock/BiosCallOuts.c) | 26 | ||||
-rw-r--r-- | src/mainboard/google/kahlee/variants/baseboard/gpio.c | 31 | ||||
-rw-r--r-- | src/mainboard/google/kahlee/variants/kahlee/gpio.c | 25 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/gpio.h | 8 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/iomap.h | 4 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 30 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/southbridge.c | 26 |
8 files changed, 151 insertions, 2 deletions
diff --git a/src/mainboard/amd/gardenia/Makefile.inc b/src/mainboard/amd/gardenia/Makefile.inc index 4c637bbfbf..cceb84c48e 100644 --- a/src/mainboard/amd/gardenia/Makefile.inc +++ b/src/mainboard/amd/gardenia/Makefile.inc @@ -13,12 +13,13 @@ # GNU General Public License for more details. # -bootblock-y += bootblock/BiosCallOuts.c +bootblock-y += bootblock/gpio.c bootblock-y += bootblock/OemCustomize.c romstage-y += BiosCallOuts.c romstage-y += OemCustomize.c +ramstage-y += bootblock/gpio.c ramstage-y += BiosCallOuts.c ramstage-y += OemCustomize.c ramstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += fchec.c diff --git a/src/mainboard/amd/gardenia/bootblock/BiosCallOuts.c b/src/mainboard/amd/gardenia/bootblock/gpio.c index 7e60daee27..7b18618465 100644 --- a/src/mainboard/amd/gardenia/bootblock/BiosCallOuts.c +++ b/src/mainboard/amd/gardenia/bootblock/gpio.c @@ -17,6 +17,22 @@ #include <amdblocks/BiosCallOuts.h> #include <soc/southbridge.h> #include <stdlib.h> +#include <soc/gpio.h> + +/* + * As a rule of thumb, GPIO pins used by coreboot should be initialized at + * bootblock while GPIO pins used only by the OS should be initialized at + * ramstage. + */ +const struct soc_amd_stoneyridge_gpio gpio_set_stage_reset[] = { + /* NFC PU */ + {GPIO_64, Function0, FCH_GPIO_PULL_UP_ENABLE | OUTPUT_H }, +}; + +const struct soc_amd_stoneyridge_gpio gpio_set_stage_ram[] = { + /* BT radio disable */ + {GPIO_14, Function1, FCH_GPIO_PULL_UP_ENABLE | OUTPUT_H }, +}; static const GPIO_CONTROL oem_gardenia_gpio[] = { /* BT radio disable */ @@ -48,3 +64,13 @@ void platform_FchParams_reset(FCH_RESET_DATA_BLOCK *FchParams_reset) { FchParams_reset->EarlyOemGpioTable = (void *)oem_gardenia_gpio; } + +const struct soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size) +{ + if (GPIO_TABLE_BOOTBLOCK) { + *size = ARRAY_SIZE(gpio_set_stage_reset); + return gpio_set_stage_reset; + } + *size = ARRAY_SIZE(gpio_set_stage_ram); + return gpio_set_stage_ram; +} diff --git a/src/mainboard/google/kahlee/variants/baseboard/gpio.c b/src/mainboard/google/kahlee/variants/baseboard/gpio.c index 58d9473218..0566320e80 100644 --- a/src/mainboard/google/kahlee/variants/baseboard/gpio.c +++ b/src/mainboard/google/kahlee/variants/baseboard/gpio.c @@ -23,6 +23,26 @@ /* * 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 pins used by coreboot should be initialized at + * bootblock while GPIO pins used only by the OS should be initialized at + * ramstage. + */ +const static struct soc_amd_stoneyridge_gpio gpio_set_stage_reset[] = { + + /* GPIO_0 - EC_PCH_PWR_BTN_ODL */ + { GPIO_0, Function0, FCH_GPIO_PULL_UP_ENABLE | INPUT }, +}; + +const static struct soc_amd_stoneyridge_gpio gpio_set_stage_ram[] = { + + /* GPIO_2 - WLAN_PCIE_WAKE_3V3_ODL */ + { GPIO_2, Function0, FCH_GPIO_PULL_UP_ENABLE | INPUT }, +}; + +/* + * These settings were generated by a spreadsheet. If they need to be updated, + * update the spreadsheet shared with the Grunt development team. */ static const GPIO_CONTROL agesa_board_gpios[] = { @@ -260,6 +280,17 @@ const __attribute__((weak)) GPIO_CONTROL *get_gpio_table(void) return agesa_board_gpios; } +const __attribute__((weak)) const struct soc_amd_stoneyridge_gpio + *board_get_gpio(size_t *size) +{ + if (GPIO_TABLE_BOOTBLOCK) { + *size = ARRAY_SIZE(gpio_set_stage_reset); + return gpio_set_stage_reset; + } + *size = ARRAY_SIZE(gpio_set_stage_ram); + return gpio_set_stage_ram; +} + /* * 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 e5e15e610d..dda44afe7e 100644 --- a/src/mainboard/google/kahlee/variants/kahlee/gpio.c +++ b/src/mainboard/google/kahlee/variants/kahlee/gpio.c @@ -20,6 +20,21 @@ #include <stdlib.h> #include <variant/gpio.h> +/* + * As a rule of thumb, GPIO pins used by coreboot should be initialized at + * bootblock while GPIO pins used only by the OS should be initialized at + * ramstage. + */ +const struct soc_amd_stoneyridge_gpio gpio_set_stage_reset[] = { + /* AGPIO2, to become event generator */ + { GPIO_2, Function1, FCH_GPIO_PULL_UP_ENABLE | INPUT }, +}; + +const struct soc_amd_stoneyridge_gpio gpio_set_stage_ram[] = { + /* AGPIO 12 */ + { GPIO_12, Function2, FCH_GPIO_PULL_UP_ENABLE | INPUT }, +}; + static const GPIO_CONTROL agesa_board_gpios[] = { /* AGPIO2 PCIE/WLAN WAKE# SCI*/ {2, Function1, FCH_GPIO_PULL_UP_ENABLE }, @@ -104,6 +119,16 @@ const GPIO_CONTROL *get_gpio_table(void) return agesa_board_gpios; } +const struct soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size) +{ + if (GPIO_TABLE_BOOTBLOCK) { + *size = ARRAY_SIZE(gpio_set_stage_reset); + return gpio_set_stage_reset; + } + *size = ARRAY_SIZE(gpio_set_stage_ram); + return gpio_set_stage_ram; +} + /* * GPE setup table must match ACPI GPE ASL * { gevent, gpe, direction, level } diff --git a/src/soc/amd/stoneyridge/include/soc/gpio.h b/src/soc/amd/stoneyridge/include/soc/gpio.h index b3dddd4ed7..84a4e84a17 100644 --- a/src/soc/amd/stoneyridge/include/soc/gpio.h +++ b/src/soc/amd/stoneyridge/include/soc/gpio.h @@ -30,6 +30,14 @@ #define GPIO_OUTPUT_MASK (1 << GPIO_OUTPUT_SHIFT) #define GPIO_OUTPUT_ENABLE (1 << 23) +/* + * The definitions below should be used to make GPIO arrays compact and + * easy to understand. + */ +#define INPUT 0 +#define OUTPUT_H (FCH_GPIO_OUTPUT_ENABLE | FCH_GPIO_OUTPUT_VALUE) +#define OUTPUT_L FCH_GPIO_OUTPUT_ENABLE + /* GPIO_0 - GPIO_62 */ #define GPIO_BANK0_CONTROL(gpio) \ (AMD_SB_ACPI_MMIO_ADDR + 0x1500 + ((gpio) * 4)) diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 2d42ad9ad9..72a1e8c6f5 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -61,4 +61,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 7f1e210123..f77640e70d 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -24,6 +24,7 @@ #include <device/pci_def.h> #include <soc/iomap.h> #include "chip.h" +#include <rules.h> /* PSP at D8F0 */ #define PSP_MAILBOX_BAR PCI_BASE_ADDRESS_4 /* BKDG: "BAR3" */ @@ -265,7 +266,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 @@ -286,6 +286,20 @@ #define WIDEIO_RANGE_ERROR -1 #define TOTAL_WIDEIO_PORTS 3 +#define AMD_GPIO_MUX_MASK 0x03 + +#if ENV_BOOTBLOCK +#define GPIO_TABLE_BOOTBLOCK 1 +#else +#define GPIO_TABLE_BOOTBLOCK 0 +#endif +#define STR_GPIO_STAGE ENV_STRING + +struct soc_amd_stoneyridge_gpio { + uint8_t gpio; + uint8_t function; + uint8_t control; +}; void sb_enable_rom(void); void configure_stoneyridge_uart(void); @@ -331,6 +345,20 @@ void xhci_pm_write32(uint8_t reg, uint32_t value); uint32_t xhci_pm_read32(uint8_t reg); void bootblock_fch_early_init(void); /** + * @brief get table and table size to program GPIO + * + * @param size = pointer to variable where to return table size + * + * @return pointer to the desired table + */ +const struct soc_amd_stoneyridge_gpio *board_get_gpio(size_t *size); +/** + * @brief program a particular set of GPIO + * + * @return none + */ +void sb_program_gpio(void); +/** * @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 0af774bbf6..46906d09ab 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -155,6 +155,32 @@ const struct irq_idx_name *sb_get_apic_reg_association(size_t *size) return irq_association; } +void sb_program_gpio(void) +{ + void *tmp_ptr; + const struct soc_amd_stoneyridge_gpio *gpio_ptr; + size_t size; + uint8_t control, mux, index; + + printk(BIOS_SPEW, "GPIO programming stage %s\n", STR_GPIO_STAGE); + gpio_ptr = board_get_gpio(&size); + 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); + } + printk(BIOS_SPEW, "End GPIO programming\n"); +} + /** * @brief Find the size of a particular wide IO * |