diff options
author | Subrata Banik <subrata.banik@intel.com> | 2018-12-17 16:53:33 +0530 |
---|---|---|
committer | Subrata Banik <subrata.banik@intel.com> | 2018-12-19 04:53:13 +0000 |
commit | da245353095d25ca9a8ee1a724135bd0ce5b5b1f (patch) | |
tree | 7a9fc8a72120faeb3832e08f0b8b73c626ab81ac | |
parent | e5e85e24f7aaa5cfec5699950d79abfcdefd8e89 (diff) |
soc/intel/icelake: Add GPIO group pad base for ACPI
commit msg copied from
commit id: 64c9f1584c63403207ee85b1d54ca594ae1fbedf
The GPIO drivers in Windows and Linux for the Icelake CPU
have a sparse GPIO map and do not allocate pins contiguously.
Each GPIO group is allocated as 32 pads regardless of whether
the hardware actually has that many in the group.
It appears this originated with a bug in Windows/UEFI and was
carried over to Linux in order to work with existing firmware:
https://lore.kernel.org/patchwork/patch/855244/
In order to support using ACPI GPIOs it is necessary for coreboot
to be compatible with this implementation. The GPIO groups that
are usable by the OS are declared with a pad base which is then
used to compute the number for ACPI GPIOs.
Change-Id: I94fafd8af13cf229f5c467de5179aed021465739
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/c/30276
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | src/soc/intel/icelake/gpio.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/soc/intel/icelake/gpio.c b/src/soc/intel/icelake/gpio.c index b244437503..53620054ce 100644 --- a/src/soc/intel/icelake/gpio.c +++ b/src/soc/intel/icelake/gpio.c @@ -32,34 +32,48 @@ static const struct reset_mapping rst_map_com0[] = { { .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 3U << 30 }, }; +/* + * The GPIO driver for Icelake on Windows/Linux expects 32 GPIOs per pad + * group, regardless of whether or not there is a physical pad for each + * exposed GPIO number. + * + * This results in the OS having a sparse GPIO map, and devices that need + * to export an ACPI GPIO must use the OS expected number. + * + * Not all pins are usable as GPIO and those groups do not have a pad base. + * + * This layout matches the Linux kernel pinctrl map for CNL-LP at: + * linux/drivers/pinctrl/intel/pinctrl-icelake.c + */ static const struct pad_group icl_community0_groups[] = { - INTEL_GPP(GPP_G0, GPP_G0, GPP_G7), /* GPP_G */ - INTEL_GPP(GPP_G0, GPP_B0, GPP_B23), /* GPP_B */ + INTEL_GPP_BASE(GPP_G0, GPP_G0, GPP_G7, 0), /* GPP_G */ + INTEL_GPP_BASE(GPP_G0, GPP_B0, GPP_B23, 32), /* GPP_B */ INTEL_GPP(GPP_G0, GPIO_RSVD_0, GPIO_RSVD_1), - INTEL_GPP(GPP_G0, GPP_A0, GPP_A23), /* GPP_A */ + INTEL_GPP_BASE(GPP_G0, GPP_A0, GPP_A23, 64), /* GPP_A */ }; static const struct pad_group icl_community1_groups[] = { - INTEL_GPP(GPP_H0, GPP_H0, GPP_H23), /* GPP_H */ - INTEL_GPP(GPP_H0, GPP_D0, GPIO_RSVD_2), /* GPP_D */ - INTEL_GPP(GPP_H0, GPP_F0, GPP_F19), /* GPP_F */ + INTEL_GPP_BASE(GPP_H0, GPP_H0, GPP_H23, 96), /* GPP_H */ + INTEL_GPP_BASE(GPP_H0, GPP_D0, GPIO_RSVD_2, 128), /* GPP_D */ + INTEL_GPP_BASE(GPP_H0, GPP_F0, GPP_F19, 160), /* GPP_F */ }; +/* This community is not visible to the OS */ static const struct pad_group icl_community2_groups[] = { INTEL_GPP(GPD0, GPD0, GPD11), /* GPD */ }; static const struct pad_group icl_community4_groups[] = { - INTEL_GPP(GPP_C0, GPP_C0, GPP_C23), /* GPP_C */ - INTEL_GPP(GPP_C0, GPP_E0, GPP_E23), /* GPP_E */ + INTEL_GPP_BASE(GPP_C0, GPP_C0, GPP_C23, 224), /* GPP_C */ + INTEL_GPP_BASE(GPP_C0, GPP_E0, GPP_E23, 256), /* GPP_E */ INTEL_GPP(GPP_C0, GPIO_RSVD_3, GPIO_RSVD_8), }; static const struct pad_group icl_community5_groups[] = { - INTEL_GPP(GPP_R0, GPP_R0, GPP_R7), /* GPP_R */ - INTEL_GPP(GPP_C0, GPP_S0, GPP_S7), /* GPP_S */ + INTEL_GPP_BASE(GPP_R0, GPP_R0, GPP_R7, 288), /* GPP_R */ + INTEL_GPP_BASE(GPP_C0, GPP_S0, GPP_S7, 320), /* GPP_S */ }; static const struct pad_community icl_communities[] = { |