summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@google.com>2018-12-10 11:27:47 -0800
committerDuncan Laurie <dlaurie@chromium.org>2018-12-14 18:30:46 +0000
commit64c9f1584c63403207ee85b1d54ca594ae1fbedf (patch)
tree0d8e1cdccc7837dc85fae9aa4dc7af7cba0bff1c
parent6217e9beff16d805ca833e79a2931bcdb3d02a44 (diff)
soc/intel/cannonlake: Add GPIO group pad base for ACPI
The GPIO drivers in Windows and Linux for the Cannonlake 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. BUG=b:120686247 TEST=tested with write protect GPIO on sarien board. Before this change the ACPI pin number was 220 which did not correspond to the pin number in Linux. After this change the ACPI number is 303, which maps to the correct GPIO in Linux. Now the GPIO value reported by the kernel changes when the WP pin is toggled in hardware. Change-Id: I4f1a9e118d7e48f2445ccbb62a12a22e9a832c51 Signed-off-by: Duncan Laurie <dlaurie@google.com> Reviewed-on: https://review.coreboot.org/c/30133 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/soc/intel/cannonlake/gpio.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/soc/intel/cannonlake/gpio.c b/src/soc/intel/cannonlake/gpio.c
index 2705bcf144..701eb0bf4e 100644
--- a/src/soc/intel/cannonlake/gpio.c
+++ b/src/soc/intel/cannonlake/gpio.c
@@ -32,34 +32,49 @@ static const struct reset_mapping rst_map_com0[] = {
{ .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 3U << 30 },
};
+/*
+ * The GPIO driver for Cannonlake 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-cannonlake.c
+ */
static const struct pad_group cnl_community0_groups[] = {
- INTEL_GPP(GPP_A0, GPP_A0, GPIO_RSVD_0), /* GPP_A */
- INTEL_GPP(GPP_A0, GPP_B0, GPIO_RSVD_2), /* GPP_B */
- INTEL_GPP(GPP_A0, GPP_G0, GPP_G7), /* GPP_G */
- INTEL_GPP(GPP_A0, GPIO_RSVD_3, GPIO_RSVD_11), /* SPI */
+ INTEL_GPP_BASE(GPP_A0, GPP_A0, GPIO_RSVD_0, 0), /* GPP_A */
+ INTEL_GPP_BASE(GPP_A0, GPP_B0, GPIO_RSVD_2, 32), /* GPP_B */
+ INTEL_GPP_BASE(GPP_A0, GPP_G0, GPP_G7, 64), /* GPP_G */
+ INTEL_GPP(GPP_A0, GPIO_RSVD_3, GPIO_RSVD_11), /* SPI */
};
static const struct pad_group cnl_community1_groups[] = {
- INTEL_GPP(GPP_D0, GPP_D0, GPIO_RSVD_12), /* GPP_D */
- INTEL_GPP(GPP_D0, GPP_F0, GPP_F23), /* GPP_F */
- INTEL_GPP(GPP_D0, GPP_H0, GPP_H23), /* GPP_H */
- INTEL_GPP(GPP_D0, GPIO_RSVD_13, GPIO_RSVD_52), /* VGPIO */
+ INTEL_GPP_BASE(GPP_D0, GPP_D0, GPIO_RSVD_12, 96), /* GPP_D */
+ INTEL_GPP_BASE(GPP_D0, GPP_F0, GPP_F23, 128), /* GPP_F */
+ INTEL_GPP_BASE(GPP_D0, GPP_H0, GPP_H23, 160), /* GPP_H */
+ INTEL_GPP_BASE(GPP_D0, GPIO_RSVD_13, GPIO_RSVD_52, 192),/* VGPIO */
};
+/* This community is not visible to the OS */
static const struct pad_group cnl_community2_groups[] = {
- INTEL_GPP(GPD0, GPD0, GPD11), /* GPD */
+ INTEL_GPP(GPD0, GPD0, GPD11), /* GPD */
};
+/* This community is not visible to the OS */
static const struct pad_group cnl_community3_groups[] = {
INTEL_GPP(HDA_BCLK, HDA_BCLK, SSP1_TXD), /* AZA */
INTEL_GPP(HDA_BCLK, GPIO_RSVD_68, GPIO_RSVD_78), /* CPU */
};
static const struct pad_group cnl_community4_groups[] = {
- INTEL_GPP(GPP_C0, GPP_C0, GPP_C23), /* GPP_C */
- INTEL_GPP(GPP_C0, GPP_E0, GPP_E23), /* GPP_E */
- INTEL_GPP(GPP_C0, GPIO_RSVD_53, GPIO_RSVD_61), /* JTAG */
- INTEL_GPP(GPP_C0, GPIO_RSVD_62, GPIO_RSVD_67), /* HVMOS */
+ INTEL_GPP_BASE(GPP_C0, GPP_C0, GPP_C23, 256), /* GPP_C */
+ INTEL_GPP_BASE(GPP_C0, GPP_E0, GPP_E23, 288), /* GPP_E */
+ INTEL_GPP(GPP_C0, GPIO_RSVD_53, GPIO_RSVD_61), /* JTAG */
+ INTEL_GPP(GPP_C0, GPIO_RSVD_62, GPIO_RSVD_67), /* HVMOS */
};
static const struct pad_community cnl_communities[] = {