summaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/gpio/gpio.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2017-07-19 13:16:51 -0600
committerAaron Durbin <adurbin@chromium.org>2017-07-20 21:08:35 +0000
commit65943e1670ebc2bd7717730acfb1137a6f5fe09f (patch)
tree103ff5de9990997f3cd6b011fe7dfef1c456196d /src/soc/intel/common/block/gpio/gpio.c
parentac8e4db246861b917513133aaf02a668cdfd0915 (diff)
downloadcoreboot-65943e1670ebc2bd7717730acfb1137a6f5fe09f.tar.xz
soc/intel/common/gpio: add helpers for relative pin calcuations
The gpio numbers are global, but they have their respective place within each community and the group within their community. For all the calculations open coding this calculation convert them to use the helpers. Change-Id: I0423490ae1740ef59225a70fea80a7d91ac2a39a Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/20653 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Diffstat (limited to 'src/soc/intel/common/block/gpio/gpio.c')
-rw-r--r--src/soc/intel/common/block/gpio/gpio.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c
index ce867ceadc..f77f88f3e0 100644
--- a/src/soc/intel/common/block/gpio/gpio.c
+++ b/src/soc/intel/common/block/gpio/gpio.c
@@ -55,6 +55,37 @@
#define GPI_SMI_EN_OFFSET(comm, group) ((comm)->gpi_smi_en_reg_0 + \
((group) * sizeof(uint32_t)))
+static inline size_t relative_pad_in_comm(const struct pad_community *comm,
+ gpio_t gpio)
+{
+ return gpio - comm->first_pad;
+}
+
+static inline size_t gpio_group_index_scaled(const struct pad_community *comm,
+ unsigned int relative_pad, size_t scale)
+{
+ return (relative_pad / comm->max_pads_per_group) * scale;
+}
+
+static inline size_t gpio_group_index(const struct pad_community *comm,
+ unsigned int relative_pad)
+{
+ return gpio_group_index_scaled(comm, relative_pad, 1);
+}
+
+static inline size_t gpio_within_group(const struct pad_community *comm,
+ unsigned int relative_pad)
+{
+ return relative_pad % comm->max_pads_per_group;
+}
+
+static inline uint32_t gpio_bitmask_within_group(
+ const struct pad_community *comm,
+ unsigned int relative_pad)
+{
+ return 1U << gpio_within_group(comm, relative_pad);
+}
+
static const struct pad_community *gpio_get_community(gpio_t pad)
{
size_t gpio_communities;
@@ -76,7 +107,7 @@ static void gpio_configure_owner(const struct pad_config *cfg,
uint16_t hostsw_reg;
int pin;
- pin = cfg->pad - comm->first_pad;
+ pin = relative_pad_in_comm(comm, cfg->pad);
/* The 4th bit in pad_config 1 (RO) is used to indicate if the pad
* needs GPIO driver ownership.
@@ -87,10 +118,9 @@ static void gpio_configure_owner(const struct pad_config *cfg,
/* Based on the gpio pin number configure the corresponding bit in
* HOSTSW_OWN register. Value of 0x1 indicates GPIO Driver onwership.
*/
- hostsw_reg = comm->host_own_reg_0 + ((pin / comm->max_pads_per_group) *
- sizeof(uint32_t));
- pcr_or32(comm->port, hostsw_reg, (1 << (pin %
- comm->max_pads_per_group)));
+ hostsw_reg = comm->host_own_reg_0;
+ hostsw_reg += gpio_group_index_scaled(comm, pin, sizeof(uint32_t));
+ pcr_or32(comm->port, hostsw_reg, gpio_bitmask_within_group(comm, pin));
}
static void gpi_enable_smi(const struct pad_config *cfg,
@@ -105,8 +135,8 @@ static void gpi_enable_smi(const struct pad_config *cfg,
if (((cfg->pad_config[0]) & PAD_CFG0_ROUTE_SMI) != PAD_CFG0_ROUTE_SMI)
return;
- pin = cfg->pad - comm->first_pad;
- group = pin / comm->max_pads_per_group;
+ pin = relative_pad_in_comm(comm, cfg->pad);
+ group = gpio_group_index(comm, pin);
sts_reg = GPI_SMI_STS_OFFSET(comm, group);
value = pcr_read32(comm->port, sts_reg);
@@ -115,7 +145,7 @@ static void gpi_enable_smi(const struct pad_config *cfg,
/* Set enable bits */
en_reg = GPI_SMI_EN_OFFSET(comm, group);
- pcr_or32(comm->port, en_reg, (1 << (pin % comm->max_pads_per_group)));
+ pcr_or32(comm->port, en_reg, gpio_bitmask_within_group(comm, pin));
}
static void gpio_configure_itss(const struct pad_config *cfg, uint16_t port,
@@ -159,7 +189,7 @@ static uint16_t pad_config_offset(const struct pad_community *comm, gpio_t pad)
{
size_t offset;
- offset = pad - comm->first_pad;
+ offset = relative_pad_in_comm(comm, pad);
offset *= GPIO_DWx_SIZE(GPIO_NUM_PAD_CFG_REGS);
return offset + comm->pad_cfg_base;
}
@@ -210,11 +240,9 @@ static void gpio_configure_pad(const struct pad_config *cfg)
if (IS_ENABLED(CONFIG_DEBUG_SOC_COMMON_BLOCK_GPIO))
printk(BIOS_DEBUG,
- "gpio_padcfg [0x%02x, %02d] DW%d [0x%08x : 0x%08x"
+ "gpio_padcfg [0x%02x, %02zd] DW%d [0x%08x : 0x%08x"
" : 0x%08x]\n",
- comm->port,
- (cfg->pad - comm->first_pad),
- i,
+ comm->port, relative_pad_in_comm(comm, cfg->pad), i,
pad_conf,/* old value */
cfg->pad_config[i],/* value passed from gpio table */
soc_pad_conf);/*new value*/
@@ -305,13 +333,10 @@ void gpio_set(gpio_t gpio_num, int value)
uint16_t gpio_acpi_pin(gpio_t gpio_num)
{
- const struct pad_community *comm;
-
if (!IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES))
return gpio_num;
- comm = gpio_get_community(gpio_num);
- return gpio_num - comm->first_pad;
+ return relative_pad_in_comm(gpio_get_community(gpio_num), gpio_num);
}
static void print_gpi_status(const struct gpi_status *sts)
@@ -383,12 +408,11 @@ int gpi_status_get(const struct gpi_status *sts, gpio_t pad)
uint8_t sts_index;
const struct pad_community *comm = gpio_get_community(pad);
- pad = pad - comm->first_pad;
+ pad = relative_pad_in_comm(comm, pad);
sts_index = comm->gpi_status_offset;
- sts_index += pad / comm->max_pads_per_group;
+ sts_index += gpio_group_index(comm, pad);
- return !!(sts->grp[sts_index] &
- (1 << pad % comm->max_pads_per_group));
+ return !!(sts->grp[sts_index] & gpio_bitmask_within_group(comm, pad));
}
static int gpio_route_pmc_gpio_gpe(int pmc_gpe_num)