soc/intel/skylake: Use common/block/gpio

Other than switch to use common gpio implementation for skylake based
platform, also apply the needed changes for purism board.

Change-Id: I06e06dbcb6d0d6fe277dfad57b82aca51f94b099
Signed-off-by: Hannah Williams <hannah.williams@intel.com>
Signed-off-by: Lijian Zhao <lijian.zhao@intel.com>
Reviewed-on: https://review.coreboot.org/19201
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Youness Alaoui <snifikino@gmail.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Hannah Williams 2017-04-06 20:54:11 -07:00 committed by Aaron Durbin
parent a05fdcb269
commit 1760cd3eb4
11 changed files with 216 additions and 821 deletions

View File

@ -21,72 +21,6 @@
#ifndef __ACPI__
/* Redefine PAD_CFG_NF_1V8 using DRIVE0 RXEVCFG value */
#undef PAD_CFG_NF_1V8
#define PAD_CFG_NF_1V8(pad_, term_, rst_, func_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, DRIVE0, NO, NO, \
NO, NO, NO, NO, func_, YES, YES), PAD_FIELD(PAD_TOL, 1V8))
/* Redefine PAD_CFG_GPI using DRIVE0 RXEVCFG value */
#undef PAD_CFG_GPI
#define PAD_CFG_GPI(pad_, term_, rst_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, DRIVE0, NO, NO, NO, NO, NO, NO, \
GPIO, NO, YES), PAD_FIELD(HOSTSW, GPIO))
/* Redefine PAD_CFG_GPO using DRIVE0 RXEVCFG value */
#undef PAD_CFG_TERM_GPO
#define PAD_CFG_TERM_GPO(pad_, val_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, DRIVE0, NO, NO, NO, NO, NO, NO, \
GPIO, YES, NO) | PAD_FIELD_VAL(GPIOTXSTATE, val_))
/* Create new macro PAD_CFG_NF_EVCFG to allow specifying the RXEVCFG value */
#define PAD_CFG_NF_EVCFG(pad_, term_, rst_, func_, evcfg_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, evcfg_, NO, NO, NO, NO, NO, NO, \
func_, YES, YES))
/* Redefine PAD_CFG_NF using DRIVE0 RXEVCFG value */
#undef PAD_CFG_NF
#define PAD_CFG_NF(pad_, term_, rst_, func_) \
PAD_CFG_NF_EVCFG(pad_, term_, rst_, func_, DRIVE0)
/* Define new PAD_CFG_NC_EVCFG macro which sets NC pad with custom RXEVCFG */
#define PAD_CFG_NC_EVCFG(pad_, evcfg_, val_) \
_PAD_CFG(pad_, NONE, \
_DW0_VALS(DEEP, RAW, NO, evcfg_, NO, NO, NO, NO, NO, NO, \
GPIO, YES, YES) | PAD_FIELD_VAL(GPIOTXSTATE, val_))
/* Define new PAD_CFG_NC_RXINV macro which enables the RXINV value */
#define PAD_CFG_NC_RXINV(pad_, evcfg_) \
_PAD_CFG(pad_, NONE, \
_DW0_VALS(DEEP, RAW, NO, evcfg_, NO, YES, NO, NO, NO, NO, \
GPIO, YES, YES))
/* Redefine PAD_CFG_NC using DRIVE0 RXEVCFG value */
#undef PAD_CFG_NC
#define PAD_CFG_NC(pad_) \
PAD_CFG_NC_EVCFG(pad_, DRIVE0, 0)
/* Define new PAD_CFG_NC_1 macro which sets GPIOTXSTATE to 1*/
#define PAD_CFG_NC_1(pad_) \
PAD_CFG_NC_EVCFG(pad_, DRIVE0, 1)
/* Define new NC pad with 1v8 pad voltage tolerance */
#define PAD_CFG_NC_1V8(pad_) \
_PAD_CFG_ATTRS(pad_, NONE, \
_DW0_VALS(DEEP, RAW, NO, DRIVE0, NO, NO, NO, NO, NO, NO, \
GPIO, YES, YES), PAD_FIELD(PAD_TOL, 1V8))
/* Define new PAD_CFG_GPIO_APIC macro which enables both RX and TX */
#define PAD_CFG_GPIO_APIC(pad_, val_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, \
GPIO, NO, NO) | PAD_FIELD_VAL(GPIOTXSTATE, val_))
/* Pad configuration in ramstage. */
static const struct pad_config gpio_table[] = {
/* RCIN# */ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1),
@ -96,30 +30,30 @@ static const struct pad_config gpio_table[] = {
/* LAD3 */ PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1),
/* LFRAME# */ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1),
/* SERIRQ */ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1),
/* PIRQA# */ PAD_CFG_NC_1(GPP_A7),
/* PIRQA# */ PAD_CFG_NC(GPP_A7),
/* CLKRUN# */ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1),
/* CLKOUT_LPC0 */ PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1),
/* CLKOUT_LPC1 */ PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1),
/* PME# */ PAD_CFG_NC_EVCFG(GPP_A11, LEVEL, 0),
/* BM_BUSY# */ PAD_CFG_NC_1(GPP_A12),
/* PME# */ PAD_CFG_NC(GPP_A11),
/* BM_BUSY# */ PAD_CFG_NC(GPP_A12),
/* SUSWARN# */ PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),
/* SUS_STAT# */ PAD_CFG_NF(GPP_A14, NONE, DEEP, NF1),
/* SUSACK# */ PAD_CFG_NF(GPP_A15, 20K_PD, DEEP, NF1),
/* SUSACK# */ PAD_CFG_NF(GPP_A15, DN_20K, DEEP, NF1),
/* SD_1P8_SEL */ PAD_CFG_NC(GPP_A16),
/* SD_PWR_EN# */ PAD_CFG_NF(GPP_A17, NONE, DEEP, NF1),
/* ISH_GP0 */ PAD_CFG_NC(GPP_A18),
/* ISH_GP1 */ PAD_CFG_NC(GPP_A19),
/* ISH_GP2 */ PAD_CFG_NC(GPP_A20),
/* ISH_GP3 */ PAD_CFG_NC(GPP_A21),
/* ISH_GP4 */ PAD_CFG_NC_1(GPP_A22),
/* ISH_GP5 */ PAD_CFG_NC_EVCFG(GPP_A23, LEVEL, 0),
/* ISH_GP4 */ PAD_CFG_NC(GPP_A22),
/* ISH_GP5 */ PAD_CFG_NC(GPP_A23),
/* CORE_VID0 */ PAD_CFG_NC(GPP_B0),
/* CORE_VID1 */ PAD_CFG_NC(GPP_B1),
/* VRALERT# */ PAD_CFG_NC(GPP_B2),
/* CPU_GP2 */ PAD_CFG_NC_EVCFG(GPP_B3, LEVEL, 0),
/* CPU_GP3 */ PAD_CFG_NC_1(GPP_B4),
/* SRCCLKREQ0# */ PAD_CFG_NF_EVCFG(GPP_B5, NONE, DEEP, NF1, LEVEL),
/* CPU_GP2 */ PAD_CFG_NC(GPP_B3),
/* CPU_GP3 */ PAD_CFG_NC(GPP_B4),
/* SRCCLKREQ0# */ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1),
/* SRCCLKREQ1# */ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1),
/* SRCCLKREQ2# */ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1),
/* SRCCLKREQ3# */ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1),
@ -128,24 +62,24 @@ static const struct pad_config gpio_table[] = {
/* EXT_PWR_GATE# */ PAD_CFG_NC(GPP_B11),
/* SLP_S0# */ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1),
/* PLTRST# */ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1),
/* SPKR */ PAD_CFG_TERM_GPO(GPP_B14, 1, 20K_PD, DEEP),
/* SPKR */ PAD_CFG_TERM_GPO(GPP_B14, 1, DN_20K, DEEP),
/* GSPI0_CS# */ PAD_CFG_NC(GPP_B15),
/* GSPI0_CLK */ PAD_CFG_NC_RXINV(GPP_B16, LEVEL),
/* GSPI0_MISO */ PAD_CFG_NC_RXINV(GPP_B17, EDGE),
/* GSPI0_MOSI */ PAD_CFG_GPI_ACPI_SCI_LEVEL(GPP_B18, 20K_PU,
PLTRST, YES),
/* GSPI0_CLK */ PAD_CFG_NC(GPP_B16),
/* GSPI0_MISO */ PAD_CFG_NC(GPP_B17),
/* GSPI0_MOSI */ PAD_CFG_GPI_SCI(GPP_B18, UP_20K, PLTRST, LEVEL,
INVERT),
/* GSPI1_CS# */ PAD_CFG_NC(GPP_B19),
/* GSPI1_CLK */ PAD_CFG_NC(GPP_B20),
/* GSPI1_MISO */ PAD_CFG_NC(GPP_B21),
/* GSPI1_MOSI */ PAD_CFG_NF(GPP_B22, 20K_PD, DEEP, NF1),
/* SM1ALERT# */ PAD_CFG_TERM_GPO(GPP_B23, 1, 20K_PD, DEEP),
/* GSPI1_MOSI */ PAD_CFG_NF(GPP_B22, DN_20K, DEEP, NF1),
/* SM1ALERT# */ PAD_CFG_TERM_GPO(GPP_B23, 1, DN_20K, DEEP),
/* SMBCLK */ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1),
/* SMBDATA */ PAD_CFG_NF(GPP_C1, 20K_PD, DEEP, NF1),
/* SMBALERT# */ PAD_CFG_TERM_GPO(GPP_C2, 1, 20K_PD, DEEP),
/* SMBDATA */ PAD_CFG_NF(GPP_C1, DN_20K, DEEP, NF1),
/* SMBALERT# */ PAD_CFG_TERM_GPO(GPP_C2, 1, DN_20K, DEEP),
/* SML0CLK */ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1),
/* SML0DATA */ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1),
/* SML0ALERT# */ PAD_CFG_GPI_APIC_INVERT(GPP_C5, 20K_PD, DEEP),
/* SML0ALERT# */ PAD_CFG_GPI_APIC_INVERT(GPP_C5, DN_20K, DEEP),
/* SML1CLK */ PAD_CFG_NC(GPP_C6), /* RESERVED */
/* SML1DATA */ PAD_CFG_NC(GPP_C7), /* RESERVED */
/* UART0_RXD */ PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1),
@ -174,10 +108,10 @@ static const struct pad_config gpio_table[] = {
/* ISH_I2C0_SCL */ PAD_CFG_NC(GPP_D6),
/* ISH_I2C1_SDA */ PAD_CFG_NC(GPP_D7),
/* ISH_I2C1_SCL */ PAD_CFG_NC(GPP_D8),
/* ISH_SPI_CS# */ PAD_CFG_NC_EVCFG(GPP_D9, LEVEL, 0),
/* ISH_SPI_CLK */ PAD_CFG_NC_EVCFG(GPP_D10, LEVEL, 0),
/* ISH_SPI_MISO */ PAD_CFG_NC_EVCFG(GPP_D11, LEVEL, 0),
/* ISH_SPI_MOSI */ PAD_CFG_NC_EVCFG(GPP_D12, LEVEL, 0),
/* ISH_SPI_CS# */ PAD_CFG_NC(GPP_D9),
/* ISH_SPI_CLK */ PAD_CFG_NC(GPP_D10),
/* ISH_SPI_MISO */ PAD_CFG_NC(GPP_D11),
/* ISH_SPI_MOSI */ PAD_CFG_NC(GPP_D12),
/* ISH_UART0_RXD */ PAD_CFG_NC(GPP_D13),
/* ISH_UART0_TXD */ PAD_CFG_NC(GPP_D14),
/* ISH_UART0_RTS# */ PAD_CFG_NC(GPP_D15),
@ -190,10 +124,10 @@ static const struct pad_config gpio_table[] = {
/* SPI1_IO3 */ PAD_CFG_NC(GPP_D22),
/* I2S_MCLK */ PAD_CFG_NC(GPP_D23),
/* SATAXPCI0 */ PAD_CFG_NC_EVCFG(GPP_E0, EDGE, 0),
/* SATAXPCI0 */ PAD_CFG_NC(GPP_E0),
/* SATAXPCIE1 */ PAD_CFG_NC(GPP_E1),
/* SATAXPCIE2 */ PAD_CFG_NF(GPP_E2, 20K_PU, DEEP, NF1),
/* CPU_GP0 */ PAD_CFG_NC_1(GPP_E3),
/* SATAXPCIE2 */ PAD_CFG_NF(GPP_E2, UP_20K, DEEP, NF1),
/* CPU_GP0 */ PAD_CFG_NC(GPP_E3),
/* SATA_DEVSLP0 */ PAD_CFG_NC(GPP_E4),
/* SATA_DEVSLP1 */ PAD_CFG_NC(GPP_E5),
/* SATA_DEVSLP2 */ PAD_CFG_NC(GPP_E6),
@ -205,28 +139,28 @@ static const struct pad_config gpio_table[] = {
/* USB2_OC3# */ PAD_CFG_NC(GPP_E12),
/* DDPB_HPD0 */ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1),
/* DDPC_HPD1 */ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1),
/* DDPD_HPD2 */ PAD_CFG_NC_RXINV(GPP_E15, EDGE),
/* DDPE_HPD3 */ PAD_CFG_GPI_ACPI_SCI(GPP_E16, NONE, PLTRST, NO),
/* DDPD_HPD2 */ PAD_CFG_NC(GPP_E15),
/* DDPE_HPD3 */ PAD_CFG_GPI_ACPI_SCI(GPP_E16, NONE, PLTRST, NONE),
/* EDP_HPD */ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1),
/* DDPB_CTRLCLK */ PAD_CFG_NF(GPP_E18, NONE, DEEP, NF1),
/* DDPB_CTRLDATA */ PAD_CFG_NF(GPP_E19, 20K_PD, DEEP, NF1),
/* DDPB_CTRLDATA */ PAD_CFG_NF(GPP_E19, DN_20K, DEEP, NF1),
/* DDPC_CTRLCLK */ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1),
/* DDPC_CTRLDATA */ PAD_CFG_NF(GPP_E21, 20K_PD, DEEP, NF1),
/* DDPD_CTRLCLK */ PAD_CFG_GPIO_APIC(GPP_E22, 0, NONE, DEEP),
/* DDPD_CTRLDATA */ PAD_CFG_TERM_GPO(GPP_E23, 1, 20K_PD, DEEP),
/* DDPC_CTRLDATA */ PAD_CFG_NF(GPP_E21, DN_20K, DEEP, NF1),
/* DDPD_CTRLCLK */ PAD_CFG_GPI_APIC(GPP_E22, NONE, DEEP),
/* DDPD_CTRLDATA */ PAD_CFG_TERM_GPO(GPP_E23, 1, DN_20K, DEEP),
/* I2S2_SCLK */ PAD_CFG_NC(GPP_F0),
/* I2S2_SFRM */ PAD_CFG_NC(GPP_F1),
/* I2S2_TXD */ PAD_CFG_NC(GPP_F2),
/* I2S2_RXD */ PAD_CFG_NC(GPP_F3),
/* I2C2_SDA */ PAD_CFG_NC_1V8(GPP_F4),
/* I2C2_SCL */ PAD_CFG_NC_1V8(GPP_F5),
/* I2C3_SDA */ PAD_CFG_NC_1V8(GPP_F6),
/* I2C3_SCL */ PAD_CFG_NC_1V8(GPP_F7),
/* I2C2_SDA */ PAD_CFG_NC(GPP_F4),
/* I2C2_SCL */ PAD_CFG_NC(GPP_F5),
/* I2C3_SDA */ PAD_CFG_NC(GPP_F6),
/* I2C3_SCL */ PAD_CFG_NC(GPP_F7),
/* I2C4_SDA */ PAD_CFG_NF_1V8(GPP_F8, NONE, DEEP, NF1),
/* I2C4_SCL */ PAD_CFG_NF_1V8(GPP_F9, NONE, DEEP, NF1),
/* I2C5_SDA */ PAD_CFG_NC_1V8(GPP_F10),
/* I2C5_SCL */ PAD_CFG_NC_1V8(GPP_F11),
/* I2C5_SDA */ PAD_CFG_NC(GPP_F10),
/* I2C5_SCL */ PAD_CFG_NC(GPP_F11),
/* EMMC_CMD */ PAD_CFG_NC(GPP_F12),
/* EMMC_DATA0 */ PAD_CFG_NC(GPP_F13),
/* EMMC_DATA1 */ PAD_CFG_NC(GPP_F14),
@ -238,7 +172,7 @@ static const struct pad_config gpio_table[] = {
/* EMMC_DATA7 */ PAD_CFG_NC(GPP_F20),
/* EMMC_RCLK */ PAD_CFG_NC(GPP_F21),
/* EMMC_CLK */ PAD_CFG_NC(GPP_F22),
/* RSVD */ PAD_CFG_NC_EVCFG(GPP_F23, LEVEL, 0),
/* RSVD */ PAD_CFG_NC(GPP_F23),
/* SD_CMD */ PAD_CFG_NF(GPP_G0, NONE, DEEP, NF1),
/* SD_DATA0 */ PAD_CFG_NF(GPP_G1, NONE, DEEP, NF1),
@ -247,19 +181,19 @@ static const struct pad_config gpio_table[] = {
/* SD_DATA3 */ PAD_CFG_NF(GPP_G4, NONE, DEEP, NF1),
/* SD_CD# */ PAD_CFG_NF(GPP_G5, NONE, DEEP, NF1),
/* SD_CLK */ PAD_CFG_NF(GPP_G6, NONE, DEEP, NF1),
/* SD_WP */ PAD_CFG_NF(GPP_G7, 20K_PU, DEEP, NF1),
/* SD_WP */ PAD_CFG_NF(GPP_G7, UP_20K, DEEP, NF1),
/* BATLOW# */ PAD_CFG_NC(GPD0),
/* ACPRESENT */ PAD_CFG_NF(GPD1, NONE, DSW_PWROK, NF1),
/* LAN_WAKE# */ PAD_CFG_NC_EVCFG(GPD2, LEVEL, 0),
/* PWRBTN# */ PAD_CFG_NF(GPD3, 20K_PU, DSW_PWROK, NF1),
/* SLP_S3# */ PAD_CFG_NF(GPD4, NONE, DSW_PWROK, NF1),
/* SLP_S4# */ PAD_CFG_NF(GPD5, NONE, DSW_PWROK, NF1),
/* SLP_A# */ PAD_CFG_NF(GPD6, NONE, DSW_PWROK, NF1),
/* RSVD */ PAD_CFG_NC_1(GPD7),
/* SUSCLK */ PAD_CFG_NF(GPD8, NONE, DSW_PWROK, NF1),
/* SLP_WLAN# */ PAD_CFG_NF(GPD9, NONE, DSW_PWROK, NF1),
/* SLP_S5# */ PAD_CFG_NF(GPD10, NONE, DSW_PWROK, NF1),
/* ACPRESENT */ PAD_CFG_NF(GPD1, NONE, PWROK, NF1),
/* LAN_WAKE# */ PAD_CFG_NC(GPD2),
/* PWRBTN# */ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1),
/* SLP_S3# */ PAD_CFG_NF(GPD4, NONE, PWROK, NF1),
/* SLP_S4# */ PAD_CFG_NF(GPD5, NONE, PWROK, NF1),
/* SLP_A# */ PAD_CFG_NF(GPD6, NONE, PWROK, NF1),
/* RSVD */ PAD_CFG_NC(GPD7),
/* SUSCLK */ PAD_CFG_NF(GPD8, NONE, PWROK, NF1),
/* SLP_WLAN# */ PAD_CFG_NF(GPD9, NONE, PWROK, NF1),
/* SLP_S5# */ PAD_CFG_NF(GPD10, NONE, PWROK, NF1),
/* LANPHYC */ PAD_CFG_NF(GPD11, NONE, DEEP, NF1),
};

View File

@ -56,6 +56,9 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
select SOC_INTEL_COMMON_BLOCK_EBDA
select SOC_INTEL_COMMON_BLOCK_FAST_SPI
select SOC_INTEL_COMMON_BLOCK_GPIO
select SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL
select SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS
select SOC_INTEL_COMMON_BLOCK_GSPI
select SOC_INTEL_COMMON_BLOCK_ITSS
select SOC_INTEL_COMMON_BLOCK_I2C

View File

@ -13,7 +13,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <soc/gpio_defs.h>
#include <soc/gpio.h>
#define GPIOTXSTATE_MASK 0x1
#define GPIORXSTATE_MASK 0x1
Device (GPIO)
{
@ -51,7 +54,7 @@ Device (GPIO)
Store (GPIO_BASE_SIZE, LEN3)
CreateDWordField (^RBUF, ^GIRQ._INT, IRQN)
And (^^PCRR (PID_GPIOCOM0, MISCCFG_OFFSET),
And (^^PCRR (PID_GPIOCOM0, GPIO_MISCCFG),
GPIO_DRIVER_IRQ_ROUTE_MASK, Local0)
If (LEqual (Local0, GPIO_DRIVER_IRQ_ROUTE_IRQ14)) {
@ -115,7 +118,7 @@ Method (GADD, 1, NotSerialized)
}
#endif /* CONFIG_SKYLAKE_SOC_PCH_H */
Store (PCRB (Local0), Local2)
Add (Local2, PAD_CFG_DW_OFFSET, Local2)
Add (Local2, PAD_CFG_BASE, Local2)
Return (Add (Local2, Multiply (Local1, 8)))
}
@ -130,7 +133,7 @@ Method (GRXS, 1, Serialized)
{
VAL0, 32
}
And (GPIORXSTATE_MASK, ShiftRight (VAL0, GPIORXSTATE_SHIFT), Local0)
And (GPIORXSTATE_MASK, ShiftRight (VAL0, PAD_CFG0_RX_STATE_BIT), Local0)
Return (Local0)
}
@ -146,7 +149,7 @@ Method (GTXS, 1, Serialized)
{
VAL0, 32
}
And (GPIOTXSTATE_MASK, ShiftRight (VAL0, GPIOTXSTATE_SHIFT), Local0)
And (GPIOTXSTATE_MASK, ShiftRight (VAL0, PAD_CFG0_TX_STATE_BIT), Local0)
Return (Local0)
}

View File

@ -19,7 +19,7 @@
#include <intelblocks/pcr.h>
#include <soc/iomap.h>
#include <soc/irq.h>
#include <soc/gpio_defs.h>
#include <soc/itss.h>
#include <soc/gpe.h>
#include <soc/pcr_ids.h>

View File

@ -24,8 +24,8 @@
#include <intelblocks/gspi.h>
#include <intelblocks/lpss_i2c.h>
#include <stdint.h>
#include <soc/gpio_defs.h>
#include <soc/gpe.h>
#include <soc/gpio.h>
#include <soc/irq.h>
#include <soc/pci_devs.h>
#include <soc/pmc.h>

View File

@ -2,7 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Google Inc.
* Copyright (C) 2015 Intel Corporation.
* Copyright (C) 2015 - 2017 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,422 +14,116 @@
* GNU General Public License for more details.
*/
#include <stdint.h>
#include <string.h>
#include <arch/io.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <gpio.h>
#include <assert.h>
#include <intelblocks/gpio.h>
#include <intelblocks/pcr.h>
#include <soc/pcr_ids.h>
#include <soc/iomap.h>
#include <soc/pm.h>
static const int gpio_debug = 0;
/* There are 4 communities with 8 GPIO groups (GPP_[A:G] and GPD) */
struct gpio_community {
int port_id;
/* Inclusive pads within the community. */
gpio_t min;
gpio_t max;
static const struct reset_mapping rst_map[] = {
{ .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 0U << 30},
{ .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30},
{ .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30},
};
/* This is ordered to match ACPI and OS driver. */
static const struct gpio_community communities[] = {
static const struct reset_mapping rst_map_com2[] = {
{ .logical = PAD_CFG0_LOGICAL_RESET_PWROK, .chipset = 0U << 30},
{ .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30},
{ .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30},
{ .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 3U << 30},
};
static const struct pad_community skl_gpio_communities[] = {
{
.port_id = PID_GPIOCOM0,
.min = GPP_A0,
.max = GPP_B23,
},
{
.port_id = PID_GPIOCOM1,
.min = GPP_C0,
.port = PID_GPIOCOM0,
.first_pad = GPP_A0,
.last_pad = GPP_B23,
.num_gpi_regs = NUM_GPIO_COM0_GPI_REGS,
.pad_cfg_base = PAD_CFG_BASE,
.host_own_reg_0 = HOSTSW_OWN_REG_0,
.gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_COM0",
.acpi_path = "\\_SB.PCI0.GPIO",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
}, {
.port = PID_GPIOCOM1,
.first_pad = GPP_C0,
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
.max = GPP_H23,
.last_pad = GPP_H23,
#else
.max = GPP_E23,
.last_pad = GPP_E23,
#endif
},
{
.port_id = PID_GPIOCOM3,
.num_gpi_regs = NUM_GPIO_COM1_GPI_REGS,
.pad_cfg_base = PAD_CFG_BASE,
.host_own_reg_0 = HOSTSW_OWN_REG_0,
.gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_COM1",
.acpi_path = "\\_SB.PCI0.GPIO",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
}, {
.port = PID_GPIOCOM3,
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
.min = GPP_I0,
.max = GPP_I10,
.first_pad = GPP_I0,
.last_pad = GPP_I10,
#else
.min = GPP_F0,
.max = GPP_G7,
.first_pad = GPP_F0,
.last_pad = GPP_G7,
#endif
},
{
.port_id = PID_GPIOCOM2,
.min = GPD0,
.max = GPD11,
},
.num_gpi_regs = NUM_GPIO_COM3_GPI_REGS,
.pad_cfg_base = PAD_CFG_BASE,
.host_own_reg_0 = HOSTSW_OWN_REG_0,
.gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_COM3",
.acpi_path = "\\_SB.PCI0.GPIO",
.reset_map = rst_map,
.num_reset_vals = ARRAY_SIZE(rst_map),
}, {
.port = PID_GPIOCOM2,
.first_pad = GPD0,
.last_pad = GPD11,
.num_gpi_regs = NUM_GPIO_COM2_GPI_REGS,
.pad_cfg_base = PAD_CFG_BASE,
.host_own_reg_0 = HOSTSW_OWN_REG_0,
.gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
.gpi_smi_en_reg_0 = GPI_SMI_EN_0,
.max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
.name = "GPIO_COM2",
.acpi_path = "\\_SB.PCI0.GPIO",
.reset_map = rst_map_com2,
.num_reset_vals = ARRAY_SIZE(rst_map_com2),
}
};
static const char *gpio_group_names[GPIO_NUM_GROUPS] = {
"GPP_A",
"GPP_B",
"GPP_C",
"GPP_D",
"GPP_E",
"GPP_F",
"GPP_G",
const struct pad_community *soc_gpio_get_community(size_t *num_communities)
{
*num_communities = ARRAY_SIZE(skl_gpio_communities);
return skl_gpio_communities;
}
const struct pmc_to_gpio_route *soc_pmc_gpio_routes(size_t *num)
{
static const struct pmc_to_gpio_route routes[] = {
{ GPP_A, GPP_A},
{ GPP_B, GPP_B},
{ GPP_C, GPP_C},
{ GPP_D, GPP_D},
{ GPP_E, GPP_E},
{ GPP_F, GPP_F},
{ GPP_G, GPP_G},
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
"GPP_H",
"GPP_I",
{ GPP_H, GPP_H},
{ GPP_I, GPP_I},
#endif
"GPD",
};
static inline void *gpio_community_regs(int port_id)
{
return pcr_reg_address(port_id, 0);
}
static inline size_t gpios_in_community(const struct gpio_community *comm)
{
/* max is inclusive */
return comm->max - comm->min + 1;
}
static inline size_t groups_in_community(const struct gpio_community *comm)
{
size_t n = gpios_in_community(comm) + GPIO_MAX_NUM_PER_GROUP - 1;
return n / GPIO_MAX_NUM_PER_GROUP;
}
static inline int gpio_index_gpd(gpio_t gpio)
{
if (gpio >= GPD0 && gpio <= GPD11)
return 1;
return 0;
}
static const struct gpio_community *gpio_get_community(gpio_t pad)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(communities); i++) {
const struct gpio_community *c = &communities[i];
if (pad >= c->min && pad <= c->max)
return c;
}
return NULL;
}
static size_t community_clr_get_smi_sts(const struct gpio_community *comm,
uint32_t *sts)
{
uint8_t *regs;
size_t i;
uint32_t *gpi_status_reg;
uint32_t *gpi_en_reg;
const size_t num_grps = groups_in_community(comm);
/* Not all groups can be routed to SMI. However, the registers
* read as 0. In order to simplify the logic read everything from
* each community. */
regs = gpio_community_regs(comm->port_id);
gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
for (i = 0; i < num_grps; i++) {
sts[i] = read32(gpi_status_reg + i) & read32(gpi_en_reg + i);
/* Clear the enabled and set status bits. */
write32(gpi_status_reg + i, sts[i]);
}
return num_grps;
}
static void print_gpi_status(uint32_t status, const char *grp_name)
{
int i;
if (!status)
return;
for (i = 31; i >= 0; i--) {
if (status & (1 << i))
printk(BIOS_DEBUG, "%s%d ", grp_name, i);
}
}
void gpi_clear_get_smi_status(struct gpi_status *sts)
{
int i;
int do_print;
size_t sts_index = 0;
for (i = 0; i < ARRAY_SIZE(communities); i++) {
const struct gpio_community *comm = &communities[i];
sts_index += community_clr_get_smi_sts(comm,
&sts->grp[sts_index]);
}
do_print = 0;
for (i = 0; i < ARRAY_SIZE(sts->grp); i++) {
if (sts->grp[i] == 0)
continue;
do_print = 1;
break;
}
if (!do_print)
return;
printk(BIOS_DEBUG, "GPI_SMI_STS: ");
for (i = 0; i < ARRAY_SIZE(sts->grp); i++)
print_gpi_status(sts->grp[i], gpio_group_names[i]);
printk(BIOS_DEBUG, "\n");
}
int gpi_status_get(const struct gpi_status *sts, gpio_t gpi)
{
const uint32_t *gpi_sts;
/* Check if valid gpi */
if (gpio_get_community(gpi) == NULL)
return 0;
/* If not in GPD group the index is a linear function based on
* GPI number and GPIO_MAX_NUM_PER_GROUP. */
if (gpio_index_gpd(gpi))
gpi_sts = &sts->grp[GPD];
else
gpi_sts = &sts->grp[gpi / GPIO_MAX_NUM_PER_GROUP];
return !!(*gpi_sts & (1 << (gpi % GPIO_MAX_NUM_PER_GROUP)));
}
void gpio_route_gpe(uint16_t gpe0_route)
{
int i;
uint32_t misc_cfg;
const uint32_t misc_cfg_reg_mask = GPE_DW_MASK;
misc_cfg = (uint32_t)gpe0_route << GPE_DW_SHIFT;
misc_cfg &= misc_cfg_reg_mask;
for (i = 0; i < ARRAY_SIZE(communities); i++) {
uint8_t *regs;
uint32_t reg;
const struct gpio_community *comm = &communities[i];
regs = gpio_community_regs(comm->port_id);
reg = read32(regs + MISCCFG_OFFSET);
reg &= ~misc_cfg_reg_mask;
reg |= misc_cfg;
write32(regs + MISCCFG_OFFSET, reg);
}
}
static void *gpio_dw_regs(gpio_t pad)
{
const struct gpio_community *comm;
uint8_t *regs;
size_t pad_relative;
comm = gpio_get_community(pad);
if (comm == NULL)
return NULL;
regs = gpio_community_regs(comm->port_id);
pad_relative = pad - comm->min;
/* DW0 and DW1 regs are 4 bytes each. */
return &regs[PAD_CFG_DW_OFFSET + pad_relative *
GPIO_DWx_SIZE(GPIO_DWx_COUNT)];
}
static void *gpio_hostsw_reg(gpio_t pad, size_t *bit)
{
const struct gpio_community *comm;
uint8_t *regs;
size_t pad_relative;
comm = gpio_get_community(pad);
if (comm == NULL)
return NULL;
regs = gpio_community_regs(comm->port_id);
pad_relative = pad - comm->min;
/* Update the bit for this pad. */
*bit = (pad_relative % HOSTSW_OWN_PADS_PER);
/* HostSw regs are 4 bytes each. */
regs = &regs[HOSTSW_OWN_REG_OFFSET];
return &regs[(pad_relative / HOSTSW_OWN_PADS_PER) * 4];
}
static void gpio_handle_pad_mode(const struct pad_config *cfg)
{
size_t bit;
uint32_t *hostsw_own_reg;
uint32_t reg;
bit = 0;
hostsw_own_reg = gpio_hostsw_reg(cfg->pad, &bit);
if (hostsw_own_reg == NULL)
return;
reg = read32(hostsw_own_reg);
reg &= ~(1U << bit);
if ((cfg->attrs & PAD_FIELD(HOSTSW, GPIO)) == PAD_FIELD(HOSTSW, GPIO))
reg |= (HOSTSW_GPIO << bit);
else
reg |= (HOSTSW_ACPI << bit);
write32(hostsw_own_reg, reg);
}
static void gpi_enable_smi(gpio_t pad)
{
const struct gpio_community *comm;
uint8_t *regs;
uint32_t *gpi_status_reg;
uint32_t *gpi_en_reg;
size_t group_offset;
uint32_t pad_mask;
comm = gpio_get_community(pad);
if (comm == NULL)
return;
regs = gpio_community_regs(comm->port_id);
gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
/* Offset of SMI STS/EN for this pad's group within the community. */
group_offset = (pad - comm->min) / GPIO_MAX_NUM_PER_GROUP;
/* Clear status then set enable. */
pad_mask = 1 << ((pad - comm->min) % GPIO_MAX_NUM_PER_GROUP);
write32(&gpi_status_reg[group_offset], pad_mask);
write32(&gpi_en_reg[group_offset],
read32(&gpi_en_reg[group_offset]) | pad_mask);
}
static void gpio_configure_pad(const struct pad_config *cfg)
{
uint32_t *dw_regs;
uint32_t reg;
uint32_t dw0;
uint32_t mask;
dw_regs = gpio_dw_regs(cfg->pad);
if (dw_regs == NULL)
return;
dw0 = cfg->dw0;
write32(&dw_regs[0], dw0);
reg = read32(&dw_regs[1]);
/* Apply termination field */
mask = PAD_TERM_MASK << PAD_TERM_SHIFT;
reg &= ~mask;
reg |= cfg->attrs & mask;
/* Apply voltage tolerance field */
mask = PAD_TOL_MASK << PAD_TOL_SHIFT;
reg &= ~mask;
reg |= cfg->attrs & mask;
write32(&dw_regs[1], reg);
gpio_handle_pad_mode(cfg);
if ((dw0 & PAD_FIELD(GPIROUTSMI, MASK)) == PAD_FIELD(GPIROUTSMI, YES))
gpi_enable_smi(cfg->pad);
if (gpio_debug)
printk(BIOS_DEBUG,
"Write Pad: Base(%p) - conf0 = %x conf1= %x pad # = %d\n",
&dw_regs[0], dw0, reg, cfg->pad);
}
void gpio_configure_pads(const struct pad_config *cfgs, size_t num)
{
size_t i;
for (i = 0; i < num; i++)
gpio_configure_pad(&cfgs[i]);
}
void gpio_input_pulldown(gpio_t gpio)
{
struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PD, DEEP);
gpio_configure_pad(&cfg);
}
void gpio_input_pullup(gpio_t gpio)
{
struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PU, DEEP);
gpio_configure_pad(&cfg);
}
void gpio_input(gpio_t gpio)
{
struct pad_config cfg = PAD_CFG_GPI(gpio, NONE, DEEP);
gpio_configure_pad(&cfg);
}
void gpio_output(gpio_t gpio, int value)
{
struct pad_config cfg = PAD_CFG_GPO(gpio, value, DEEP);
gpio_configure_pad(&cfg);
}
int gpio_get(gpio_t gpio_num)
{
uint32_t *dw_regs;
uint32_t reg;
dw_regs = gpio_dw_regs(gpio_num);
if (dw_regs == NULL)
return -1;
reg = read32(&dw_regs[0]);
return (reg >> GPIORXSTATE_SHIFT) & GPIORXSTATE_MASK;
}
void gpio_set(gpio_t gpio_num, int value)
{
uint32_t *dw_regs;
uint32_t reg;
dw_regs = gpio_dw_regs(gpio_num);
if (dw_regs == NULL)
return;
reg = read32(&dw_regs[0]);
reg &= ~PAD_FIELD(GPIOTXSTATE, MASK);
reg |= PAD_FIELD_VAL(GPIOTXSTATE, value);
write32(&dw_regs[0], reg);
/* GPIO port ids support posted write semantics. */
}
const char *gpio_acpi_path(gpio_t gpio_num)
{
return "\\_SB.PCI0.GPIO";
}
uint16_t gpio_acpi_pin(gpio_t gpio_num)
{
return gpio_num;
{ GPD, GPD},
};
*num = ARRAY_SIZE(routes);
return routes;
}

View File

@ -18,184 +18,8 @@
#define _SOC_GPIO_H_
#include <soc/gpio_defs.h>
#define GPIO_DWx_SIZE(x) (sizeof(uint32_t) * (x))
#include <intelblocks/gpio.h> /* intelblocks/gpio.h depends on definitions in
soc/gpio_defs.h */
#define CROS_GPIO_DEVICE_NAME "INT344B:00"
#ifndef __ACPI__
#include <stdint.h>
#include <stddef.h>
typedef uint32_t gpio_t;
/* Structure to represent GPI status for GPE and SMI. Use helper
* functions for interrogating particular GPIs. */
struct gpi_status {
uint32_t grp[GPIO_NUM_GROUPS];
};
/*
* Clear GPI SMI status and fill in the structure representing enabled
* and set status.
*/
void gpi_clear_get_smi_status(struct gpi_status *sts);
/* Return 1 if gpio is set in the gpi_status struct. Otherwise 0. */
int gpi_status_get(const struct gpi_status *sts, gpio_t gpi);
/*
* Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted
* as the packed configuration for GPE0_DW[2:0]:
* dw0 = gpe0_route[3:0]
* dw1 = gpe0_route[7:4]
* dw2 = gpe0_route[11:8].
*/
void gpio_route_gpe(uint16_t gpe0_route);
/* Configure the pads according to the pad_config array. */
struct pad_config;
void gpio_configure_pads(const struct pad_config *cfgs, size_t num);
#define PAD_FIELD_VAL(field_, val_) \
(((val_) & field_ ## _MASK) << field_ ## _SHIFT)
#define PAD_FIELD(field_, setting_) \
PAD_FIELD_VAL(field_, field_ ## _ ## setting_)
/*
* This encodes all the fields found within the dw0 register for each
* pad. It directly follows the register specification:
* rst - reset type when pad configuration is reset
* rxst - native function routing: raw buffer or internal buffer
* rxraw1 - drive fixed '1' for Rx buffer
* rxev - event filtering for pad value: level, edge, drive '0'
* rxgf - glitch filter enable
* rxinv - invert the internal pad state
* gpiioapic - route to IOxAPIC
* gpisci - route for SCI
* gpismi - route for SMI
* gpinmi - route for NMI
* mode - GPIO vs native function
* rxdis - disable Rx buffer
* txdis - disable Tx buffer
*/
#define _DW0_VALS(rst, rxst, rxraw1, rxev, rxgf, rxinv, gpiioapic, gpisci, \
gpismi, gpinmi, mode, rxdis, txdis) \
(PAD_FIELD(PADRSTCFG, rst) | \
PAD_FIELD(RXPADSTSEL, rxst) | \
PAD_FIELD(RXRAW1, rxraw1) | \
PAD_FIELD(RXEVCFG, rxev) | \
PAD_FIELD(PREGFRXSEL, rxgf) | \
PAD_FIELD(RXINV, rxinv) | \
PAD_FIELD(GPIROUTIOXAPIC, gpiioapic) | \
PAD_FIELD(GPIROUTSCI, gpisci) | \
PAD_FIELD(GPIROUTSMI, gpismi) | \
PAD_FIELD(GPIROUTNMI, gpinmi) | \
PAD_FIELD(PMODE, mode) | \
PAD_FIELD(GPIORXDIS, rxdis) | \
PAD_FIELD(GPIOTXDIS, txdis))
#define _PAD_CFG_ATTRS(pad_, term_, dw0_, attrs_) \
{ \
.pad = pad_, \
.attrs = PAD_FIELD(PAD_TERM, term_) | attrs_, \
.dw0 = dw0_, \
}
/* Default to ACPI owned. Ownership only matters for GPI pads. */
#define _PAD_CFG(pad_, term_, dw0_) \
_PAD_CFG_ATTRS(pad_, term_, dw0_, PAD_FIELD(HOSTSW, ACPI))
/* Native Function - No Rx buffer manipulation */
#define PAD_CFG_NF(pad_, term_, rst_, func_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, func_, NO, NO))
/* Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. */
#define PAD_CFG_NF_1V8(pad_, term_, rst_, func_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, \
NO, NO, NO, NO, func_, NO, NO), PAD_FIELD(PAD_TOL, 1V8))
/* Unused PINS will be controlled by GPIO controller (PMODE = GPIO) and
GPIO TX/RX will be disabled. */
#define PAD_CFG_NC(pad_) \
_PAD_CFG(pad_, NONE, \
_DW0_VALS(DEEP, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, YES))
/* General purpose output with termination. */
#define PAD_CFG_TERM_GPO(pad_, val_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, NO) \
| PAD_FIELD_VAL(GPIOTXSTATE, val_))
/* General purpose output. By default no termination. */
#define PAD_CFG_GPO(pad_, val_, rst_) \
PAD_CFG_TERM_GPO(pad_, val_, NONE, rst_)
/* General purpose input with no special IRQ routing. */
#define PAD_CFG_GPI(pad_, term_, rst_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
PAD_FIELD(HOSTSW, GPIO))
/* General purpose input passed through to GPIO interrupt */
#define PAD_CFG_GPI_INT(pad_, term_, rst_, trig_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, trig_, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
PAD_FIELD(HOSTSW, GPIO))
/* General purpose input passed through to IOxAPIC. Assume APIC logic can
* handle polarity/edge/level constraints. */
#define PAD_CFG_GPI_APIC(pad_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
/* General purpose input passed through to IOxAPIC as inverted input. */
#define PAD_CFG_GPI_APIC_INVERT(pad_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, YES, YES, NO, NO, NO, GPIO, NO, \
YES))
/* General purpose input passed through to IOxAPIC. This assumes edge
* triggered events. */
#define PAD_CFG_GPI_APIC_EDGE(pad_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, EDGE, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
/* General purpose input routed to SCI. This assumes edge triggered events. */
#define PAD_CFG_GPI_ACPI_SCI(pad_, term_, rst_, inv_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
#define PAD_CFG_GPI_ACPI_SCI_LEVEL(pad_, term_, rst_, inv_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, inv_, \
NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
/* General purpose input routed to SMI. This assumes edge triggered events. */
#define PAD_CFG_GPI_ACPI_SMI(pad_, term_, rst_, inv_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
NO, NO, YES, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
/*
* The 'attrs' field carries the termination in bits 13:10 and tolerance in bit
* 25 to match up with thd DW1 pad configuration register. Additionally, other
* attributes can be applied such as the ones below. Bit allocation matters.
*/
#define HOSTSW_SHIFT 0
#define HOSTSW_MASK 1
#define HOSTSW_ACPI HOSTSW_OWN_ACPI
#define HOSTSW_GPIO HOSTSW_OWN_GPIO
struct pad_config {
uint16_t pad;
uint32_t attrs;
uint32_t dw0;
};
#endif /* __ACPI__ */
#endif

View File

@ -15,13 +15,31 @@
#ifndef _SOC_GPIO_DEFS_H_
#define _SOC_GPIO_DEFS_H_
#ifndef __ACPI__
#include <stddef.h>
#endif
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
# include <soc/gpio_pch_h_defs.h>
#else
# include <soc/gpio_soc_defs.h>
#endif
#define GPIO_NUM_PAD_CFG_REGS 2 /* DW0, DW1 */
#define NUM_GPIO_COMx_GPI_REGS(n) \
(ALIGN_UP((n), GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
#define NUM_GPIO_COM0_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM0_PADS)
#define NUM_GPIO_COM1_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM1_PADS)
#define NUM_GPIO_COM2_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM2_PADS)
#define NUM_GPIO_COM3_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM3_PADS)
#define NUM_GPI_STATUS_REGS \
((NUM_GPIO_COM0_GPI_REGS) +\
(NUM_GPIO_COM1_GPI_REGS) +\
(NUM_GPIO_COM3_GPI_REGS) +\
(NUM_GPIO_COM2_GPI_REGS))
/*
* IOxAPIC IRQs for the GPIOs
*/
@ -76,6 +94,7 @@
#define GPP_B21_IRQ 0x45
#define GPP_B22_IRQ 0x46
#define GPP_B23_IRQ 0x47
/* Group C */
#define GPP_C0_IRQ 0x48
#define GPP_C1_IRQ 0x49
@ -200,121 +219,13 @@
#define GPD11_IRQ 0x5b
/* Register defines. */
#define MISCCFG_OFFSET 0x10
#define GPIO_MISCCFG 0x10
#define GPIO_DRIVER_IRQ_ROUTE_MASK 8
#define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0
#define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8
#define GPE_DW_SHIFT 8
#define GPE_DW_MASK 0xfff00
#define PAD_OWN_REG_OFFSET 0x20
#define PAD_OWN_PADS_PER 8
#define PAD_OWN_WIDTH_PER 4
#define PAD_OWN_MASK 0x03
#define PAD_OWN_HOST 0x00
#define PAD_OWN_ME 0x01
#define PAD_OWN_ISH 0x02
#define HOSTSW_OWN_REG_OFFSET 0xd0
#define HOSTSW_OWN_PADS_PER 24
#define HOSTSW_OWN_ACPI 0
#define HOSTSW_OWN_GPIO 1
#define PAD_CFG_DW_OFFSET 0x400
/* PADRSTCFG - when to reset the pad config */
#define PADRSTCFG_SHIFT 30
#define PADRSTCFG_MASK 0x3
#define PADRSTCFG_DSW_PWROK 0
#define PADRSTCFG_DEEP 1
#define PADRSTCFG_PLTRST 2
#define PADRSTCFG_RSMRST 3
/* RXPADSTSEL - raw signal or internal state */
#define RXPADSTSEL_SHIFT 29
#define RXPADSTSEL_MASK 0x1
#define RXPADSTSEL_RAW 0
#define RXPADSTSEL_INTERNAL 1
/* RXRAW1 - drive 1 instead instead of pad value */
#define RXRAW1_SHIFT 28
#define RXRAW1_MASK 0x1
#define RXRAW1_NO 0
#define RXRAW1_YES 1
/* RXEVCFG - Interrupt and wake types */
#define RXEVCFG_SHIFT 25
#define RXEVCFG_MASK 0x3
#define RXEVCFG_LEVEL 0
#define RXEVCFG_EDGE 1
#define RXEVCFG_DRIVE0 2
/* PREGFRXSEL - use filtering on Rx pad */
#define PREGFRXSEL_SHIFT 24
#define PREGFRXSEL_MASK 0x1
#define PREGFRXSEL_NO 0
#define PREGFRXSEL_YES 1
/* RXINV - invert signal to SMI, SCI, NMI, or IRQ routing. */
#define RXINV_SHIFT 23
#define RXINV_MASK 0x1
#define RXINV_NO 0
#define RXINV_YES 1
/* GPIROUTIOXAPIC - route to io-xapic or not */
#define GPIROUTIOXAPIC_SHIFT 20
#define GPIROUTIOXAPIC_MASK 0x1
#define GPIROUTIOXAPIC_NO 0
#define GPIROUTIOXAPIC_YES 1
/* GPIROUTSCI - route to SCI */
#define GPIROUTSCI_SHIFT 19
#define GPIROUTSCI_MASK 0x1
#define GPIROUTSCI_NO 0
#define GPIROUTSCI_YES 1
/* GPIROUTSMI - route to SMI */
#define GPIROUTSMI_SHIFT 18
#define GPIROUTSMI_MASK 0x1
#define GPIROUTSMI_NO 0
#define GPIROUTSMI_YES 1
/* GPIROUTNMI - route to NMI */
#define GPIROUTNMI_SHIFT 17
#define GPIROUTNMI_MASK 0x1
#define GPIROUTNMI_NO 0
#define GPIROUTNMI_YES 1
/* PMODE - mode of pad */
#define PMODE_SHIFT 10
#define PMODE_MASK 0x3
#define PMODE_GPIO 0
#define PMODE_NF1 1
#define PMODE_NF2 2
#define PMODE_NF3 3
/* GPIORXDIS - Disable Rx */
#define GPIORXDIS_SHIFT 9
#define GPIORXDIS_MASK 0x1
#define GPIORXDIS_NO 0
#define GPIORXDIS_YES 1
/* GPIOTXDIS - Disable Tx */
#define GPIOTXDIS_SHIFT 8
#define GPIOTXDIS_MASK 0x1
#define GPIOTXDIS_NO 0
#define GPIOTXDIS_YES 1
/* GPIORXSTATE - Internal state after glitch filter */
#define GPIORXSTATE_SHIFT 1
#define GPIORXSTATE_MASK 0x1
/* GPIOTXSTATE - Drive value onto pad */
#define GPIOTXSTATE_SHIFT 0
#define GPIOTXSTATE_MASK 0x1
/* TERM - termination control */
#define PAD_TERM_SHIFT 10
#define PAD_TERM_MASK 0xf
#define PAD_TERM_NONE 0
#define PAD_TERM_5K_PD 2
#define PAD_TERM_20K_PD 4
#define PAD_TERM_1K_PU 9
#define PAD_TERM_2K_PU 11
#define PAD_TERM_5K_PU 10
#define PAD_TERM_20K_PU 12
#define PAD_TERM_667_PU 13
#define PAD_TERM_NATIVE 15
/* TOL - voltage tolerance */
#define PAD_TOL_SHIFT 25
#define PAD_TOL_MASK 0x1
#define PAD_TOL_3V3 0 /* 3.3V default */
#define PAD_TOL_1V8 1 /* 1.8V tolerant */
#define GPI_GPE_STS_OFFSET 0x140
#define GPI_GPE_EN_OFFSET 0x160
#define GPI_SMI_STS_OFFSET 0x180
#define GPI_SMI_EN_OFFSET 0x1a0
#define HOSTSW_OWN_REG_0 0xd0
#define PAD_CFG_BASE 0x400
#define GPI_SMI_STS_0 0x180
#define GPI_SMI_EN_0 0x1a0
#endif /* _SOC_GPIO_DEFS_H_ */

View File

@ -90,6 +90,9 @@
#define GPP_B21 45
#define GPP_B22 46
#define GPP_B23 47
#define NUM_GPIO_COM0_PADS (GPP_B23 - GPP_A0 + 1)
/* Group C */
#define GPP_C0 48
#define GPP_C1 49
@ -229,6 +232,9 @@
#define GPP_H21 178
#define GPP_H22 179
#define GPP_H23 180
#define NUM_GPIO_COM1_PADS (GPP_H23 - GPP_C0 + 1)
/* Group I */
#define GPP_I0 181
#define GPP_I1 182
@ -241,6 +247,9 @@
#define GPP_I8 189
#define GPP_I9 190
#define GPP_I10 191
#define NUM_GPIO_COM3_PADS (GPP_I10 - GPP_I0 + 1)
/* Group GPD */
#define GPD0 192
#define GPD1 193
@ -254,4 +263,7 @@
#define GPD9 201
#define GPD10 202
#define GPD11 203
#define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1)
#endif /* _SOC_GPIO_PCH_H_DEFS_H_ */

View File

@ -88,6 +88,9 @@
#define GPP_B21 45
#define GPP_B22 46
#define GPP_B23 47
#define NUM_GPIO_COM0_PADS (GPP_B23 - GPP_A0 + 1)
/* Group C */
#define GPP_C0 48
#define GPP_C1 49
@ -163,6 +166,9 @@
#define GPP_E21 117
#define GPP_E22 118
#define GPP_E23 119
#define NUM_GPIO_COM1_PADS (GPP_E23 - GPP_C0 + 1)
/* Group F */
#define GPP_F0 120
#define GPP_F1 121
@ -197,6 +203,9 @@
#define GPP_G5 149
#define GPP_G6 150
#define GPP_G7 151
#define NUM_GPIO_COM3_PADS (GPP_G7 - GPP_F0 + 1)
/* Group GPD */
#define GPD0 152
#define GPD1 153
@ -211,4 +220,7 @@
#define GPD10 162
#define GPD11 163
#define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1)
#endif /* _SOC_GPIO_SOC_DEFS_H_ */

View File

@ -536,7 +536,9 @@ void pmc_gpe_init(void)
write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
/* Set the routes in the GPIO communities as well. */
gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
gpio_route_gpe((gpio_cfg_reg >> GPE0_DW0_SHIFT) & GPE0_DWX_MASK,
(gpio_cfg_reg >> GPE0_DW1_SHIFT) & GPE0_DWX_MASK,
(gpio_cfg_reg >> GPE0_DW2_SHIFT) & GPE0_DWX_MASK);
/* Set GPE enables based on devictree. */
enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,