summaryrefslogtreecommitdiff
path: root/src/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel')
-rw-r--r--src/soc/intel/common/block/gpio/gpio.c18
-rw-r--r--src/soc/intel/common/block/include/intelblocks/gpio.h20
-rw-r--r--src/soc/intel/common/block/include/intelblocks/gpio_defs.h78
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_ */