From ce026c93658d05c8cb7086c71153f357b4628dcf Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Fri, 27 May 2022 09:11:27 +0800 Subject: [PATCH] soc/intel/common/block/gpio: Add gpio pad based function Introduce three functions: - new_padbased_table: Returns the gpio pad number based table - gpio_padbased_override: Must pass the table with padbased table - gpio_configure_pads_with_padbased: Must pass the table with padbased table, will skip configures the unmapped pins by check pad and DW0 are 0. Some boards may have complex, SKU-based GPIO programming. This patch provides for a simpler pattern of controlling overrides of GPIO programming by providing a table of pad configuration indexed by pad number. Thus, pad state can be overwritten over multiple overrides until the final takes place, and then all GPIO programming is performed at once. Signed-off-by: Eric Lai Change-Id: I8b99127b73701b50a7f2e051dee9d12c9da9b741 Reviewed-on: https://review.coreboot.org/c/coreboot/+/64712 Reviewed-by: Kangheui Won Reviewed-by: Tim Wawrzynczak Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/gpio/gpio.c | 32 +++++++++++++++++++ .../common/block/include/intelblocks/gpio.h | 14 ++++++++ 2 files changed, 46 insertions(+) diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index baf0e168b8..4b27f3074c 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -432,6 +432,38 @@ void gpio_configure_pads_with_override(const struct pad_config *base_cfg, } } +struct pad_config *new_padbased_table(void) +{ + struct pad_config *padbased_table; + padbased_table = malloc(sizeof(struct pad_config) * TOTAL_PADS); + memset(padbased_table, 0, sizeof(struct pad_config) * TOTAL_PADS); + + return padbased_table; +} + +void gpio_padbased_override(struct pad_config *padbased_table, + const struct pad_config *override_cfg, + size_t override_num_pads) +{ + for (size_t i = 0; i < override_num_pads; i++) { + /* Prevent overflow hack */ + ASSERT(override_cfg[i].pad < TOTAL_PADS); + padbased_table[override_cfg[i].pad] = override_cfg[i]; + } +} + +void gpio_configure_pads_with_padbased(struct pad_config *padbased_table) +{ + size_t i; + const struct pad_config *cfg = padbased_table; + for (i = 0; i < TOTAL_PADS; i++) { + /* Consider unmapped pin as default setting, skip */ + if (cfg[i].pad == 0 && cfg[i].pad_config[0] == 0) + continue; + gpio_configure_pad(&cfg[i]); + } +} + void *gpio_dwx_address(const gpio_t pad) { /* Calculate Address of DW0 register for given GPIO diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 5043c84c2b..a7bb332344 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -324,5 +324,19 @@ bool gpio_get_vw_info(gpio_t pad, unsigned int *vw_index, unsigned int *vw_bit); /* Returns PCR port ID for this pad for the CPU; will be 0 if not available */ unsigned int gpio_get_pad_cpu_portid(gpio_t pad); +/* Return the gpio pad number based table */ +struct pad_config *new_padbased_table(void); + +/* Must pass the table with pad number based */ +void gpio_padbased_override(struct pad_config *padbased_table, + const struct pad_config *override_cfg, + size_t override_num_pads); + +/* + * Must pass the table with pad number based, will skip configures the unmapped + * pins by check pad and DW0 are 0. + */ +void gpio_configure_pads_with_padbased(struct pad_config *padbased_table); + #endif #endif /* _SOC_INTELBLOCKS_GPIO_H_ */