soc/intel/common/gpio: Rework PAD config macro to add lock support
This patch extends `struct pad_config` to add new variable for gpio lock action. Additionally, it creates new GPIO PAD configuration macros that perform GPIO pad configuration and pad lock configuration as well. List of new macros are: 1. PAD_CFG_NF_LOCK 2. PAD_CFG_GPO_LOCK 3. PAD_CFG_GPI_LOCK 4. PAD_CFG_GPI_TRIG_OWN_LOCK 5. PAD_CFG_GPI_GPIO_DRIVER_LOCK 6. PAD_CFG_GPI_INT_LOCK 7. PAD_CFG_GPI_APIC_LOCK 8. PAD_CFG_GPI_IRQ_WAKE_LOCK Mainboard users can use the above macros to lock the PAD after configuration. So far on IA chipset, the default GPIO pad lock configuration reset type is POWERGOOD hence, it's recommended as per GPIO BWG (doc: 630603) to configure the GPP PAD reset type the same as lock configuration reset type to avoid GPP reset value misconfiguration issue. BUG=b:211573253, b:211950520 Signed-off-by: Subrata Banik <subratabanik@google.com> Change-Id: Ibf8b0a845005ad545266d995449d0aa711f45a61 Reviewed-on: https://review.coreboot.org/c/coreboot/+/60774 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: EricR Lai <ericr_lai@compal.corp-partner.google.com> Reviewed-by: Nick Vaccaro <nvaccaro@google.com>
This commit is contained in:
parent
fe678cbd19
commit
7e8a0e61e7
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
@ -165,6 +168,15 @@
|
|||
.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
|
||||
|
@ -174,6 +186,7 @@
|
|||
.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_ */
|
||||
|
|
Loading…
Reference in New Issue