diff options
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/common/block/gpio/gpio.c | 18 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/gpio.h | 20 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/gpio_defs.h | 78 |
3 files changed, 95 insertions, 21 deletions
diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 8d262fad18..dcec12a8f0 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -345,6 +345,8 @@ static void gpio_configure_pad(const struct pad_config *cfg) gpio_configure_owner(cfg, comm); gpi_enable_smi(cfg, comm); gpi_enable_nmi(cfg, comm); + if (cfg->lock_action) + gpio_lock_pad(cfg->pad, cfg->lock_action); } void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads) @@ -468,13 +470,13 @@ gpio_pad_config_lock_using_sbi(const struct gpio_lock_config *pad_info, .fid = 0, }; - if (!(pad_info->action & GPIO_LOCK_FULL)) { - printk(BIOS_ERR, "%s: Error: no action specified for pad %d!\n", + if (!(pad_info->lock_action & GPIO_LOCK_FULL)) { + printk(BIOS_ERR, "%s: Error: no lock_action specified for pad %d!\n", __func__, pad_info->pad); return; } - if ((pad_info->action & GPIO_LOCK_CONFIG) == GPIO_LOCK_CONFIG) { + if ((pad_info->lock_action & GPIO_LOCK_CONFIG) == GPIO_LOCK_CONFIG) { if (CONFIG(DEBUG_GPIO)) printk(BIOS_INFO, "%s: Locking pad %d configuration\n", __func__, pad_info->pad); @@ -484,7 +486,7 @@ gpio_pad_config_lock_using_sbi(const struct gpio_lock_config *pad_info, printk(BIOS_ERR, "Failed to lock GPIO PAD, response = %d\n", response); } - if ((pad_info->action & GPIO_LOCK_TX) == GPIO_LOCK_TX) { + if ((pad_info->lock_action & GPIO_LOCK_TX) == GPIO_LOCK_TX) { if (CONFIG(DEBUG_GPIO)) printk(BIOS_INFO, "%s: Locking pad %d Tx state\n", __func__, pad_info->pad); @@ -552,14 +554,14 @@ static void gpio_pad_config_lock_using_pcr(const struct gpio_lock_config *pad_info, uint8_t pid, uint16_t offset, const uint32_t bit_mask) { - if ((pad_info->action & GPIO_LOCK_CONFIG) == GPIO_LOCK_CONFIG) { + if ((pad_info->lock_action & GPIO_LOCK_CONFIG) == GPIO_LOCK_CONFIG) { if (CONFIG(DEBUG_GPIO)) printk(BIOS_INFO, "%s: Locking pad %d configuration\n", __func__, pad_info->pad); pcr_or32(pid, offset, bit_mask); } - if ((pad_info->action & GPIO_LOCK_TX) == GPIO_LOCK_TX) { + if ((pad_info->lock_action & GPIO_LOCK_TX) == GPIO_LOCK_TX) { if (CONFIG(DEBUG_GPIO)) printk(BIOS_INFO, "%s: Locking pad %d TX state\n", __func__, pad_info->pad); @@ -612,7 +614,7 @@ static int gpio_non_smm_lock_pad(const struct gpio_lock_config *pad_info) return 0; } -int gpio_lock_pad(const gpio_t pad, enum gpio_lock_action action) +int gpio_lock_pad(const gpio_t pad, enum gpio_lock_action lock_action) { /* Skip locking GPIO PAD in early stages */ if (ENV_ROMSTAGE_OR_BEFORE) @@ -620,7 +622,7 @@ int gpio_lock_pad(const gpio_t pad, enum gpio_lock_action action) const struct gpio_lock_config pads = { .pad = pad, - .action = action + .lock_action = lock_action }; if (!ENV_SMM && !CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS)) diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 700b975cf9..b37dd12c69 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -65,10 +65,18 @@ typedef uint32_t gpio_t; +enum gpio_lock_action { + GPIO_UNLOCK = 0x0, + GPIO_LOCK_CONFIG = 0x1, + GPIO_LOCK_TX = 0x2, + GPIO_LOCK_FULL = GPIO_LOCK_CONFIG | GPIO_LOCK_TX, +}; + struct pad_config { gpio_t pad;/* offset of pad within community */ uint32_t pad_config[GPIO_NUM_PAD_CFG_REGS];/* Pad config data corresponding to DW0, DW1,.... */ + enum gpio_lock_action lock_action; /* Pad lock configuration */ }; /* @@ -199,15 +207,9 @@ void gpio_configure_pads_with_override(const struct pad_config *base_cfg, */ void *gpio_dwx_address(const gpio_t pad); -enum gpio_lock_action { - GPIO_LOCK_CONFIG = 0x1, - GPIO_LOCK_TX = 0x2, - GPIO_LOCK_FULL = GPIO_LOCK_CONFIG | GPIO_LOCK_TX, -}; - struct gpio_lock_config { gpio_t pad; - enum gpio_lock_action action; + enum gpio_lock_action lock_action; }; /* @@ -227,14 +229,14 @@ struct gpio_lock_config { * function may only be called in SMM. * * @param pad: GPIO pad number - * @param action: Which register to lock. + * @param lock_action: Which register to lock. * @return 0 if successful, * 1 - unsuccessful * 2 - powered down * 3 - multi-cast mixed * -1 - sideband message failed or other error */ -int gpio_lock_pad(const gpio_t pad, enum gpio_lock_action action); +int gpio_lock_pad(const gpio_t pad, enum gpio_lock_action lock_action); /* * gpio_lock_pads() can be used to lock an array of gpio pads, avoiding diff --git a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h index d3249bcbbb..d9d882cc5f 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h @@ -3,6 +3,8 @@ #ifndef _SOC_BLOCK_GPIO_DEFS_H_ #define _SOC_BLOCK_GPIO_DEFS_H_ +#include <intelblocks/gpio.h> + #define PAD_CFG0_TX_STATE_BIT 0 #define PAD_CFG0_TX_STATE (1 << PAD_CFG0_TX_STATE_BIT) #define PAD_CFG0_RX_STATE_BIT 1 @@ -129,6 +131,7 @@ #define PAD_IRQ_ROUTE(value) PAD_CFG0_ROUTE_##value #define PAD_TRIG(value) PAD_CFG0_TRIG_##value #define PAD_PULL(value) PAD_CFG1_PULL_##value +#define PAD_LOCK(value) GPIO_##value /* Disable the input/output buffer of the pad */ #define PAD_CFG0_BUF_NO_DISABLE (0) @@ -161,19 +164,29 @@ #endif /* CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT */ #define _PAD_CFG_STRUCT(__pad, __config0, __config1) \ + { \ + .pad = __pad, \ + .pad_config[0] = __config0, \ + .pad_config[1] = __config1, \ + .lock_action = PAD_LOCK(UNLOCK), \ + } + +#define _PAD_CFG_STRUCT_LOCK(__pad, __config0, __config1, __action) \ { \ .pad = __pad, \ .pad_config[0] = __config0, \ .pad_config[1] = __config1, \ + .lock_action = __action, \ } #if GPIO_NUM_PAD_CFG_REGS > 2 #define _PAD_CFG_STRUCT_3(__pad, __config0, __config1, __config2) \ { \ - .pad = __pad, \ - .pad_config[0] = __config0, \ - .pad_config[1] = __config1, \ - .pad_config[2] = __config2, \ + .pad = __pad, \ + .pad_config[0] = __config0, \ + .pad_config[1] = __config1, \ + .pad_config[2] = __config2, \ + .lock_action = PAD_LOCK(UNLOCK), \ } #else #define _PAD_CFG_STRUCT_3(__pad, __config0, __config1, __config2) \ @@ -186,6 +199,13 @@ PAD_RESET(rst) | PAD_FUNC(func), \ PAD_PULL(pull) | PAD_IOSSTATE(TxLASTRxE)) +/* Native function configuration with lock */ +#define PAD_CFG_NF_LOCK(pad, pull, func, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_RESET(PWROK) | PAD_FUNC(func), \ + PAD_PULL(pull) | PAD_IOSSTATE(TxLASTRxE), \ + PAD_LOCK(lock_action)) + #if CONFIG(SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL) /* Native 1.8V tolerant pad, only applies to some pads like I2C/I2S Not applicable to all SOCs. Refer EDS @@ -230,6 +250,14 @@ PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | !!val, \ PAD_PULL(NONE) | PAD_IOSSTATE(TxLASTRxE)) +/* General purpose output with lock, no pullup/down. */ +#define PAD_CFG_GPO_LOCK(pad, val, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(PWROK) | \ + PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | !!val, \ + PAD_PULL(NONE) | PAD_IOSSTATE(TxLASTRxE), \ + PAD_LOCK(lock_action)) + /* General purpose output, with termination specified */ #define PAD_CFG_TERM_GPO(pad, val, pull, rst) \ _PAD_CFG_STRUCT(pad, \ @@ -258,6 +286,13 @@ PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_BUF(TX_DISABLE), \ PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE)) +/* General purpose input with lock */ +#define PAD_CFG_GPI_LOCK(pad, pull, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(PWROK) | PAD_BUF(TX_DISABLE), \ + PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE), \ + PAD_LOCK(lock_action)) + #define PAD_CFG_GPI_TRIG_IOSSTATE_OWN(pad, pull, rst, trig, iosstate, own) \ _PAD_CFG_STRUCT(pad, \ PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_TRIG(trig) | PAD_BUF(TX_DISABLE), \ @@ -279,12 +314,25 @@ PAD_TRIG(trig) | PAD_RX_POL(NONE) | PAD_BUF(TX_DISABLE), \ PAD_PULL(pull) | PAD_CFG_OWN_GPIO(own)) +#define PAD_CFG_GPI_TRIG_OWN_LOCK(pad, pull, rst, trig, own, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | \ + PAD_TRIG(trig) | PAD_RX_POL(NONE) | PAD_BUF(TX_DISABLE), \ + PAD_PULL(pull) | PAD_CFG_OWN_GPIO(own), PAD_LOCK(lock_action)) + #define PAD_CFG_GPI_GPIO_DRIVER(pad, pull, rst) \ _PAD_CFG_STRUCT(pad, \ PAD_FUNC(GPIO) | PAD_RESET(rst) | \ PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), \ PAD_PULL(pull) | PAD_CFG_OWN_GPIO(DRIVER) | PAD_IOSSTATE(TxDRxE)) +#define PAD_CFG_GPI_GPIO_DRIVER_LOCK(pad, pull, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(PWROK) | \ + PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), \ + PAD_PULL(pull) | PAD_CFG_OWN_GPIO(DRIVER) | PAD_IOSSTATE(TxDRxE), \ + PAD_LOCK(lock_action)) + #define PAD_CFG_GPIO_DRIVER_HI_Z(pad, pull, rst, iosstate, iosterm) \ _PAD_CFG_STRUCT(pad, \ PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_BUF(TX_RX_DISABLE), \ @@ -300,6 +348,10 @@ #define PAD_CFG_GPI_INT(pad, pull, rst, trig) \ PAD_CFG_GPI_TRIG_OWN(pad, pull, rst, trig, DRIVER) +/* GPIO Interrupt with lock */ +#define PAD_CFG_GPI_INT_LOCK(pad, pull, trig, lock_action) \ + PAD_CFG_GPI_TRIG_OWN_LOCK(pad, pull, PWROK, trig, DRIVER, lock_action) + /* * No Connect configuration for unconnected or unused pad. * Both TX and RX are disabled. RX disabling is done to avoid unnecessary @@ -319,6 +371,14 @@ PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \ PAD_IOSSTATE(TxDRxE)) +/* General purpose input with lock, routed to APIC */ +#define PAD_CFG_GPI_APIC_LOCK(pad, pull, trig, inv, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(PWROK) | PAD_BUF(TX_DISABLE) | \ + PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TxDRxE), \ + PAD_LOCK(lock_action)) + /* General purpose input, routed to APIC - with IOStandby Config*/ #define PAD_CFG_GPI_APIC_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \ _PAD_CFG_STRUCT(pad, \ @@ -406,9 +466,19 @@ PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv), \ PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE)) +#define PAD_CFG_GPI_DUAL_ROUTE_LOCK(pad, pull, rst, trig, inv, route1, route2, lock_action) \ + _PAD_CFG_STRUCT_LOCK(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_BUF(TX_DISABLE) | \ + PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv), \ + PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE), \ + PAD_LOCK(lock_action)) + #define PAD_CFG_GPI_IRQ_WAKE(pad, pull, rst, trig, inv) \ PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, IOAPIC, SCI) +#define PAD_CFG_GPI_IRQ_WAKE_LOCK(pad, pull, trig, inv, lock_action) \ + PAD_CFG_GPI_DUAL_ROUTE_LOCK(pad, pull, PWROK, trig, inv, IOAPIC, SCI, lock_action) + #endif /* CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT */ #endif /* _SOC_BLOCK_GPIO_DEFS_H_ */ |