From 7ebb6b0f00ed6b8f92749cc4b035f02c001197e7 Mon Sep 17 00:00:00 2001 From: Julien Viard de Galbert Date: Thu, 1 Mar 2018 16:03:31 +0100 Subject: soc/intel/denverton_ns + mb: Rename gpio configuration In order to use the shared code in intelblock, this patch renames the denverton specific implementation to not use the same names (for files and types). - rename pad_config to remove conflict with soc/.../intelblocks/gpio.h - rename gpio.c, soc/gpio.h to not conflict with intelblock Note: There is no functional change in this patch. Change-Id: Id3f4e2dc0a118e8c864a96a435fa22e32bbe684f Signed-off-by: Julien Viard de Galbert Reviewed-on: https://review.coreboot.org/24926 Reviewed-by: Philipp Deppenwiese Tested-by: build bot (Jenkins) --- src/soc/intel/denverton_ns/Makefile.inc | 2 +- src/soc/intel/denverton_ns/gpio.c | 509 ---------------------- src/soc/intel/denverton_ns/gpio_dnv.c | 509 ++++++++++++++++++++++ src/soc/intel/denverton_ns/include/soc/gpio.h | 309 ------------- src/soc/intel/denverton_ns/include/soc/gpio_dnv.h | 309 +++++++++++++ 5 files changed, 819 insertions(+), 819 deletions(-) delete mode 100644 src/soc/intel/denverton_ns/gpio.c create mode 100644 src/soc/intel/denverton_ns/gpio_dnv.c delete mode 100644 src/soc/intel/denverton_ns/include/soc/gpio.h create mode 100644 src/soc/intel/denverton_ns/include/soc/gpio_dnv.h (limited to 'src/soc/intel') diff --git a/src/soc/intel/denverton_ns/Makefile.inc b/src/soc/intel/denverton_ns/Makefile.inc index 798ca83b9e..712b21c39e 100644 --- a/src/soc/intel/denverton_ns/Makefile.inc +++ b/src/soc/intel/denverton_ns/Makefile.inc @@ -39,7 +39,7 @@ romstage-y += memmap.c romstage-y += reset.c romstage-y += romstage.c romstage-y += tsc_freq.c -romstage-y += gpio.c +romstage-y += gpio_dnv.c romstage-y += soc_util.c romstage-y += spi.c romstage-y += fiamux.c diff --git a/src/soc/intel/denverton_ns/gpio.c b/src/soc/intel/denverton_ns/gpio.c deleted file mode 100644 index 1921b13806..0000000000 --- a/src/soc/intel/denverton_ns/gpio.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 - 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -// Community PadOwnOffset HostOwnOffset -// GpiIsOffset -// GpiIeOffset GpiGpeStsOffset GpiGpeEnOffset -// SmiStsOffset -// SmiEnOffset NmiStsOffset NmiEnOffset -// PadCfgLockOffset -// PadCfgLockTxOffset PadCfgOffset PadPerGroup -static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = { - {PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN, - R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE, - R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN, - R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN, - R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN, - R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX, - R_PCH_PCR_GPIO_NC_PADCFG_OFFSET, - V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL - {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN, - R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS, - R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS, - R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY, - NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, - NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK, - R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX, - R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET, - V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX - {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN, - R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS, - R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS, - R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS, - R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS, - R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK, - R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET, - V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0 - {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN, - R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS, - R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS, - R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS, - R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS, - R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK, - R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET, - V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1 -}; - -/* Retrieve address and length of GPIO info table */ -static struct GPIO_GROUP_INFO * -GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength) -{ - *GpioGroupInfoTableLength = - sizeof(mGpioGroupInfo) / sizeof(struct GPIO_GROUP_INFO); - return (struct GPIO_GROUP_INFO *)mGpioGroupInfo; -} - -/* Get Gpio Pad Ownership */ -static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal) -{ - uint32_t Mask; - uint32_t RegOffset; - uint32_t GroupIndex; - uint32_t PadNumber; - struct GPIO_GROUP_INFO *GpioGroupInfo; - uint32_t GpioGroupInfoLength; - uint32_t PadOwnRegValue; - - GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad); - PadNumber = GPIO_GET_PAD_NUMBER(GpioPad); - - GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); - - // - // Check if group argument exceeds GPIO GROUP INFO array - // - if ((uint32_t)GroupIndex >= GpioGroupInfoLength) { - printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO " - "group range\n", - GroupIndex); - return; - } - - // - // Check if legal pin number - // - if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { - printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible " - "range for this group\n", - PadNumber); - return; - } - // - // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. - // One DWord register contains information for 8 pads. - // - RegOffset = - GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4; - - // - // Calculate pad bit position within DWord register - // - PadNumber %= 8; - Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4); - - PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS( - GpioGroupInfo[GroupIndex].Community, RegOffset)); - - *PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4)); -} - -void gpio_configure_pads(const struct pad_config *gpio, size_t num) -{ - /* Return if gpio not valid */ - if ((gpio == NULL) || (num == 0)) - return; - - uint32_t Index; - uint32_t Dw0Reg; - uint32_t Dw0RegMask; - uint32_t Dw1Reg; - uint32_t Dw1RegMask; - uint32_t PadCfgReg; - uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX]; - uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX]; - uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX]; - uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX]; - struct GPIO_GROUP_INFO *GpioGroupInfo; - uint32_t GpioGroupInfoLength; - GPIO_PAD GpioGroupOffset; - uint32_t NumberOfGroups; - GPIO_PAD_OWN PadOwnVal; - struct pad_config *GpioData; - GPIO_PAD Group; - uint32_t GroupIndex; - uint32_t PadNumber; - uint32_t FinalValue; - uint32_t Data32; - uint32_t PadMode1, PadMode2; - - PadOwnVal = GpioPadOwnHost; - - memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg)); - memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask)); - memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg)); - memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask)); - - GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); - - GpioGroupOffset = GPIO_DNV_GROUP_MIN; - NumberOfGroups = V_PCH_GPIO_GROUP_MAX; - - for (Index = 0; Index < (uint32_t)num; Index++) { - - Dw0RegMask = 0; - Dw0Reg = 0; - Dw1RegMask = 0; - Dw1Reg = 0; - - GpioData = (struct pad_config *)&(gpio[Index]); - - Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad); - GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad); - PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad); - - // - // Check if group index argument exceeds GPIO group index range - // - if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) { - printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index " - "(GroupIndex=%d, Pad=%d)!\n", - GroupIndex, PadNumber); - continue; - } - - // - // Check if group argument exceeds GPIO group range - // - if ((Group < GpioGroupOffset) || - (Group >= NumberOfGroups + GpioGroupOffset)) { - printk(BIOS_ERR, - "GPIO ERROR: Invalid Group (Group=%d)!\n", - Group); - return; - } - - // - // Check if legal pin number - // - if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { - printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber " - "(PadNumber=%d)!\n", - PadNumber); - return; - } - - // - // Check if selected GPIO Pad is not owned by CSME/ISH - // - GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal); - - if (PadOwnVal != GpioPadOwnHost) { - printk(BIOS_ERR, "GPIO WARNING: Accessing pad not " - "owned by host (Group=%d, Pad=%d)!", - GroupIndex, PadNumber); - if (PadOwnVal == GpioPadOwnCsme) - printk(BIOS_ERR, "The owner is CSME\n"); - else if (PadOwnVal == GpioPadOwnIsh) - printk(BIOS_ERR, "The owner is ISH\n"); - printk(BIOS_ERR, "** Please make sure the GPIO usage " - "in sync between CSME/ISH and Host IA " - "FW configuration.\n"); - printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH " - "should not do any configuration by " - "Host IA FW.\n"); - continue; - } - - // - // Configure Reset Type (PadRstCfg) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.PowerConfig & - GPIO_CONF_RESET_MASK) >> - GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_RST_CONF); - Dw0Reg |= (((GpioData->GpioConfig.PowerConfig & - GPIO_CONF_RESET_MASK) >> - (GPIO_CONF_RESET_BIT_POS + 1)) - << N_PCH_GPIO_RST_CONF); - - // - // Configure how interrupt is triggered (RxEvCfg) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.InterruptConfig & - GPIO_CONF_INT_TRIG_MASK) >> - GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_RX_LVL_EDG); - Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & - GPIO_CONF_INT_TRIG_MASK) >> - (GPIO_CONF_INT_TRIG_BIT_POS + 1)) - << N_PCH_GPIO_RX_LVL_EDG); - - // - // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.InterruptConfig & - GPIO_CONF_INT_ROUTE_MASK) >> - GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : (B_PCH_GPIO_RX_NMI_ROUTE | - B_PCH_GPIO_RX_SCI_ROUTE | - B_PCH_GPIO_RX_SMI_ROUTE | - B_PCH_GPIO_RX_APIC_ROUTE)); - Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & - GPIO_CONF_INT_ROUTE_MASK) >> - (GPIO_CONF_INT_ROUTE_BIT_POS + 1)) - << N_PCH_GPIO_RX_NMI_ROUTE); - - // If CFIO is not Working as GPIO mode, Don't move TxDisable and - // RxDisable - if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) { - // - // Configure GPIO direction (GPIORxDis and GPIOTxDis) - // - Dw0RegMask |= ((((GpioData->GpioConfig.Direction & - GPIO_CONF_DIR_MASK) >> - GPIO_CONF_DIR_BIT_POS) == - GpioHardwareDefault) - ? 0x0 - : (B_PCH_GPIO_RXDIS | - B_PCH_GPIO_TXDIS)); - Dw0Reg |= (((GpioData->GpioConfig.Direction & - GPIO_CONF_DIR_MASK) >> - (GPIO_CONF_DIR_BIT_POS + 1)) - << N_PCH_GPIO_TXDIS); - } - - // - // Configure GPIO input inversion (RXINV) - // - Dw0RegMask |= ((((GpioData->GpioConfig.Direction & - GPIO_CONF_INV_MASK) >> - GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_RXINV); - Dw0Reg |= (((GpioData->GpioConfig.Direction & - GPIO_CONF_INV_MASK) >> - (GPIO_CONF_INV_BIT_POS + 1)) - << N_PCH_GPIO_RXINV); - - // - // Configure GPIO output state (GPIOTxState) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.OutputState & - GPIO_CONF_OUTPUT_MASK) >> - GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_TX_STATE); - Dw0Reg |= (((GpioData->GpioConfig.OutputState & - GPIO_CONF_OUTPUT_MASK) >> - (GPIO_CONF_OUTPUT_BIT_POS + 1)) - << N_PCH_GPIO_TX_STATE); - - // - // Configure GPIO RX raw override to '1' (RXRAW1) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.OtherSettings & - GPIO_CONF_RXRAW_MASK) >> - GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_RX_RAW1); - Dw0Reg |= (((GpioData->GpioConfig.OtherSettings & - GPIO_CONF_RXRAW_MASK) >> - (GPIO_CONF_RXRAW_BIT_POS + 1)) - << N_PCH_GPIO_RX_RAW1); - - // - // Configure GPIO Pad Mode (PMode) - // - Dw0RegMask |= - ((((GpioData->GpioConfig.PadMode & - GPIO_CONF_PAD_MODE_MASK) >> - GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_PAD_MODE); - Dw0Reg |= (((GpioData->GpioConfig.PadMode & - GPIO_CONF_PAD_MODE_MASK) >> - (GPIO_CONF_PAD_MODE_BIT_POS + 1)) - << N_PCH_GPIO_PAD_MODE); - - // - // Configure GPIO termination (Term) - // - Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig & - GPIO_CONF_TERM_MASK) >> - GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_TERM); - Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & - GPIO_CONF_TERM_MASK) >> - (GPIO_CONF_TERM_BIT_POS + 1)) - << N_PCH_GPIO_TERM); - - // - // Configure GPIO pad tolerance (padtol) - // - Dw1RegMask |= - ((((GpioData->GpioConfig.ElectricalConfig & - GPIO_CONF_PADTOL_MASK) >> - GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault) - ? 0x0 - : B_PCH_GPIO_PADTOL); - Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & - GPIO_CONF_PADTOL_MASK) >> - (GPIO_CONF_PADTOL_BIT_POS + 1)) - << N_PCH_GPIO_PADTOL); - - // - // Check for additional requirements on setting PADCFG register - // - - // - // Create PADCFG register offset using group and pad number - // - PadCfgReg = 0x8 * PadNumber + - GpioGroupInfo[GroupIndex].PadCfgOffset; - Data32 = read32((void *)PCH_PCR_ADDRESS( - GpioGroupInfo[GroupIndex].Community, PadCfgReg)); - - FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg); - - PadMode1 = - (Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; - PadMode2 = - (Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; - - if (((Data32 & B_PCH_GPIO_PAD_MODE) != - (FinalValue & B_PCH_GPIO_PAD_MODE)) || - (PadMode2 == 0)) { - printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: " - "0x%x PadModeP1: %d P2: %d ", - GpioGroupInfo[GroupIndex].Community, PadCfgReg, - PadMode1, PadMode2); - printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32, - FinalValue); - // - // Write PADCFG DW0 register`` - // - mmio_andthenor32( - (void *)(uint32_t)PCH_PCR_ADDRESS( - GpioGroupInfo[GroupIndex].Community, - PadCfgReg), - ~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg); - } - - Data32 = read32((void *)PCH_PCR_ADDRESS( - GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4)); - FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg); - if (Data32 != FinalValue) { - // - // Write PADCFG DW1 register - // - mmio_andthenor32( - (void *)(uint32_t)PCH_PCR_ADDRESS( - GpioGroupInfo[GroupIndex].Community, - PadCfgReg + 0x4), - ~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg); - } - - // - // Update value to be programmed in HOSTSW_OWN register - // - HostSoftOwnRegMask[GroupIndex] |= LShiftU64( - (uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1, - PadNumber); - HostSoftOwnReg[GroupIndex] |= LShiftU64( - (uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1, - PadNumber); - - // - // Update value to be programmed in GPI_GPE_EN register - // - GpiGpeEnRegMask[GroupIndex] |= LShiftU64( - (uint64_t)(GpioData->GpioConfig.InterruptConfig & 0x1), - PadNumber); - GpiGpeEnReg[GroupIndex] |= LShiftU64( - (uint64_t)(GpioData->GpioConfig.InterruptConfig & - GpioIntSci) >> - 3, - PadNumber); - } - - for (Index = 0; Index < NumberOfGroups; Index++) { - // - // Write HOSTSW_OWN registers - // - if (GpioGroupInfo[Index].HostOwnOffset != - NO_REGISTER_FOR_PROPERTY) { - mmio_andthenor32( - (void *)PCH_PCR_ADDRESS( - GpioGroupInfo[Index].Community, - GpioGroupInfo[Index].HostOwnOffset), - ~(uint32_t)(HostSoftOwnRegMask[Index] & - 0xFFFFFFFF), - (uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF)); - mmio_andthenor32( - (void *)PCH_PCR_ADDRESS( - GpioGroupInfo[Index].Community, - GpioGroupInfo[Index].HostOwnOffset + - 0x4), - ~(uint32_t)(RShiftU64(HostSoftOwnRegMask[Index], - 32)), - (uint32_t)( - RShiftU64(HostSoftOwnReg[Index], 32))); - } - - // - // Write GPI_GPE_EN registers - // - if (GpioGroupInfo[Index].GpiGpeEnOffset != - NO_REGISTER_FOR_PROPERTY) { - mmio_andthenor32( - (void *)PCH_PCR_ADDRESS( - GpioGroupInfo[Index].Community, - GpioGroupInfo[Index].GpiGpeEnOffset), - ~(uint32_t)(GpiGpeEnRegMask[Index] & - 0xFFFFFFFF), - (uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF)); - mmio_andthenor32( - (void *)PCH_PCR_ADDRESS( - GpioGroupInfo[Index].Community, - GpioGroupInfo[Index].GpiGpeEnOffset + - 0x4), - ~(uint32_t)( - RShiftU64(GpiGpeEnRegMask[Index], 32)), - (uint32_t)(RShiftU64(GpiGpeEnReg[Index], 32))); - } - } -} diff --git a/src/soc/intel/denverton_ns/gpio_dnv.c b/src/soc/intel/denverton_ns/gpio_dnv.c new file mode 100644 index 0000000000..b8576ae357 --- /dev/null +++ b/src/soc/intel/denverton_ns/gpio_dnv.c @@ -0,0 +1,509 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 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 + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// Community PadOwnOffset HostOwnOffset +// GpiIsOffset +// GpiIeOffset GpiGpeStsOffset GpiGpeEnOffset +// SmiStsOffset +// SmiEnOffset NmiStsOffset NmiEnOffset +// PadCfgLockOffset +// PadCfgLockTxOffset PadCfgOffset PadPerGroup +static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = { + {PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN, + R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE, + R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN, + R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN, + R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN, + R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX, + R_PCH_PCR_GPIO_NC_PADCFG_OFFSET, + V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN, + R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS, + R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY, + NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, + NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK, + R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX, + R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET, + V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN, + R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS, + R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS, + R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS, + R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK, + R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET, + V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0 + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN, + R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS, + R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS, + R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS, + R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK, + R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET, + V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1 +}; + +/* Retrieve address and length of GPIO info table */ +static struct GPIO_GROUP_INFO * +GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength) +{ + *GpioGroupInfoTableLength = + sizeof(mGpioGroupInfo) / sizeof(struct GPIO_GROUP_INFO); + return (struct GPIO_GROUP_INFO *)mGpioGroupInfo; +} + +/* Get Gpio Pad Ownership */ +static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal) +{ + uint32_t Mask; + uint32_t RegOffset; + uint32_t GroupIndex; + uint32_t PadNumber; + struct GPIO_GROUP_INFO *GpioGroupInfo; + uint32_t GpioGroupInfoLength; + uint32_t PadOwnRegValue; + + GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad); + PadNumber = GPIO_GET_PAD_NUMBER(GpioPad); + + GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); + + // + // Check if group argument exceeds GPIO GROUP INFO array + // + if ((uint32_t)GroupIndex >= GpioGroupInfoLength) { + printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO " + "group range\n", + GroupIndex); + return; + } + + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible " + "range for this group\n", + PadNumber); + return; + } + // + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. + // One DWord register contains information for 8 pads. + // + RegOffset = + GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4; + + // + // Calculate pad bit position within DWord register + // + PadNumber %= 8; + Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4); + + PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, RegOffset)); + + *PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4)); +} + +void gpio_configure_dnv_pads(const struct dnv_pad_config *gpio, size_t num) +{ + /* Return if gpio not valid */ + if ((gpio == NULL) || (num == 0)) + return; + + uint32_t Index; + uint32_t Dw0Reg; + uint32_t Dw0RegMask; + uint32_t Dw1Reg; + uint32_t Dw1RegMask; + uint32_t PadCfgReg; + uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX]; + uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX]; + uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX]; + uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX]; + struct GPIO_GROUP_INFO *GpioGroupInfo; + uint32_t GpioGroupInfoLength; + GPIO_PAD GpioGroupOffset; + uint32_t NumberOfGroups; + GPIO_PAD_OWN PadOwnVal; + struct dnv_pad_config *GpioData; + GPIO_PAD Group; + uint32_t GroupIndex; + uint32_t PadNumber; + uint32_t FinalValue; + uint32_t Data32; + uint32_t PadMode1, PadMode2; + + PadOwnVal = GpioPadOwnHost; + + memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg)); + memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask)); + memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg)); + memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask)); + + GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); + + GpioGroupOffset = GPIO_DNV_GROUP_MIN; + NumberOfGroups = V_PCH_GPIO_GROUP_MAX; + + for (Index = 0; Index < (uint32_t)num; Index++) { + + Dw0RegMask = 0; + Dw0Reg = 0; + Dw1RegMask = 0; + Dw1Reg = 0; + + GpioData = (struct dnv_pad_config *)&(gpio[Index]); + + Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad); + GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad); + PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad); + + // + // Check if group index argument exceeds GPIO group index range + // + if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) { + printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index " + "(GroupIndex=%d, Pad=%d)!\n", + GroupIndex, PadNumber); + continue; + } + + // + // Check if group argument exceeds GPIO group range + // + if ((Group < GpioGroupOffset) || + (Group >= NumberOfGroups + GpioGroupOffset)) { + printk(BIOS_ERR, + "GPIO ERROR: Invalid Group (Group=%d)!\n", + Group); + return; + } + + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber " + "(PadNumber=%d)!\n", + PadNumber); + return; + } + + // + // Check if selected GPIO Pad is not owned by CSME/ISH + // + GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal); + + if (PadOwnVal != GpioPadOwnHost) { + printk(BIOS_ERR, "GPIO WARNING: Accessing pad not " + "owned by host (Group=%d, Pad=%d)!", + GroupIndex, PadNumber); + if (PadOwnVal == GpioPadOwnCsme) + printk(BIOS_ERR, "The owner is CSME\n"); + else if (PadOwnVal == GpioPadOwnIsh) + printk(BIOS_ERR, "The owner is ISH\n"); + printk(BIOS_ERR, "** Please make sure the GPIO usage " + "in sync between CSME/ISH and Host IA " + "FW configuration.\n"); + printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH " + "should not do any configuration by " + "Host IA FW.\n"); + continue; + } + + // + // Configure Reset Type (PadRstCfg) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.PowerConfig & + GPIO_CONF_RESET_MASK) >> + GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RST_CONF); + Dw0Reg |= (((GpioData->GpioConfig.PowerConfig & + GPIO_CONF_RESET_MASK) >> + (GPIO_CONF_RESET_BIT_POS + 1)) + << N_PCH_GPIO_RST_CONF); + + // + // Configure how interrupt is triggered (RxEvCfg) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_TRIG_MASK) >> + GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RX_LVL_EDG); + Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_TRIG_MASK) >> + (GPIO_CONF_INT_TRIG_BIT_POS + 1)) + << N_PCH_GPIO_RX_LVL_EDG); + + // + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_ROUTE_MASK) >> + GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : (B_PCH_GPIO_RX_NMI_ROUTE | + B_PCH_GPIO_RX_SCI_ROUTE | + B_PCH_GPIO_RX_SMI_ROUTE | + B_PCH_GPIO_RX_APIC_ROUTE)); + Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_ROUTE_MASK) >> + (GPIO_CONF_INT_ROUTE_BIT_POS + 1)) + << N_PCH_GPIO_RX_NMI_ROUTE); + + // If CFIO is not Working as GPIO mode, Don't move TxDisable and + // RxDisable + if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) { + // + // Configure GPIO direction (GPIORxDis and GPIOTxDis) + // + Dw0RegMask |= ((((GpioData->GpioConfig.Direction & + GPIO_CONF_DIR_MASK) >> + GPIO_CONF_DIR_BIT_POS) == + GpioHardwareDefault) + ? 0x0 + : (B_PCH_GPIO_RXDIS | + B_PCH_GPIO_TXDIS)); + Dw0Reg |= (((GpioData->GpioConfig.Direction & + GPIO_CONF_DIR_MASK) >> + (GPIO_CONF_DIR_BIT_POS + 1)) + << N_PCH_GPIO_TXDIS); + } + + // + // Configure GPIO input inversion (RXINV) + // + Dw0RegMask |= ((((GpioData->GpioConfig.Direction & + GPIO_CONF_INV_MASK) >> + GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RXINV); + Dw0Reg |= (((GpioData->GpioConfig.Direction & + GPIO_CONF_INV_MASK) >> + (GPIO_CONF_INV_BIT_POS + 1)) + << N_PCH_GPIO_RXINV); + + // + // Configure GPIO output state (GPIOTxState) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.OutputState & + GPIO_CONF_OUTPUT_MASK) >> + GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_TX_STATE); + Dw0Reg |= (((GpioData->GpioConfig.OutputState & + GPIO_CONF_OUTPUT_MASK) >> + (GPIO_CONF_OUTPUT_BIT_POS + 1)) + << N_PCH_GPIO_TX_STATE); + + // + // Configure GPIO RX raw override to '1' (RXRAW1) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.OtherSettings & + GPIO_CONF_RXRAW_MASK) >> + GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RX_RAW1); + Dw0Reg |= (((GpioData->GpioConfig.OtherSettings & + GPIO_CONF_RXRAW_MASK) >> + (GPIO_CONF_RXRAW_BIT_POS + 1)) + << N_PCH_GPIO_RX_RAW1); + + // + // Configure GPIO Pad Mode (PMode) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.PadMode & + GPIO_CONF_PAD_MODE_MASK) >> + GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_PAD_MODE); + Dw0Reg |= (((GpioData->GpioConfig.PadMode & + GPIO_CONF_PAD_MODE_MASK) >> + (GPIO_CONF_PAD_MODE_BIT_POS + 1)) + << N_PCH_GPIO_PAD_MODE); + + // + // Configure GPIO termination (Term) + // + Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_TERM_MASK) >> + GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_TERM); + Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_TERM_MASK) >> + (GPIO_CONF_TERM_BIT_POS + 1)) + << N_PCH_GPIO_TERM); + + // + // Configure GPIO pad tolerance (padtol) + // + Dw1RegMask |= + ((((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_PADTOL_MASK) >> + GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_PADTOL); + Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_PADTOL_MASK) >> + (GPIO_CONF_PADTOL_BIT_POS + 1)) + << N_PCH_GPIO_PADTOL); + + // + // Check for additional requirements on setting PADCFG register + // + + // + // Create PADCFG register offset using group and pad number + // + PadCfgReg = 0x8 * PadNumber + + GpioGroupInfo[GroupIndex].PadCfgOffset; + Data32 = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, PadCfgReg)); + + FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg); + + PadMode1 = + (Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; + PadMode2 = + (Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; + + if (((Data32 & B_PCH_GPIO_PAD_MODE) != + (FinalValue & B_PCH_GPIO_PAD_MODE)) || + (PadMode2 == 0)) { + printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: " + "0x%x PadModeP1: %d P2: %d ", + GpioGroupInfo[GroupIndex].Community, PadCfgReg, + PadMode1, PadMode2); + printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32, + FinalValue); + // + // Write PADCFG DW0 register`` + // + mmio_andthenor32( + (void *)(uint32_t)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, + PadCfgReg), + ~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg); + } + + Data32 = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4)); + FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg); + if (Data32 != FinalValue) { + // + // Write PADCFG DW1 register + // + mmio_andthenor32( + (void *)(uint32_t)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, + PadCfgReg + 0x4), + ~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg); + } + + // + // Update value to be programmed in HOSTSW_OWN register + // + HostSoftOwnRegMask[GroupIndex] |= LShiftU64( + (uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1, + PadNumber); + HostSoftOwnReg[GroupIndex] |= LShiftU64( + (uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1, + PadNumber); + + // + // Update value to be programmed in GPI_GPE_EN register + // + GpiGpeEnRegMask[GroupIndex] |= LShiftU64( + (uint64_t)(GpioData->GpioConfig.InterruptConfig & 0x1), + PadNumber); + GpiGpeEnReg[GroupIndex] |= LShiftU64( + (uint64_t)(GpioData->GpioConfig.InterruptConfig & + GpioIntSci) >> + 3, + PadNumber); + } + + for (Index = 0; Index < NumberOfGroups; Index++) { + // + // Write HOSTSW_OWN registers + // + if (GpioGroupInfo[Index].HostOwnOffset != + NO_REGISTER_FOR_PROPERTY) { + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].HostOwnOffset), + ~(uint32_t)(HostSoftOwnRegMask[Index] & + 0xFFFFFFFF), + (uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF)); + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].HostOwnOffset + + 0x4), + ~(uint32_t)(RShiftU64(HostSoftOwnRegMask[Index], + 32)), + (uint32_t)( + RShiftU64(HostSoftOwnReg[Index], 32))); + } + + // + // Write GPI_GPE_EN registers + // + if (GpioGroupInfo[Index].GpiGpeEnOffset != + NO_REGISTER_FOR_PROPERTY) { + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].GpiGpeEnOffset), + ~(uint32_t)(GpiGpeEnRegMask[Index] & + 0xFFFFFFFF), + (uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF)); + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].GpiGpeEnOffset + + 0x4), + ~(uint32_t)( + RShiftU64(GpiGpeEnRegMask[Index], 32)), + (uint32_t)(RShiftU64(GpiGpeEnReg[Index], 32))); + } + } +} diff --git a/src/soc/intel/denverton_ns/include/soc/gpio.h b/src/soc/intel/denverton_ns/include/soc/gpio.h deleted file mode 100644 index 964b5e0715..0000000000 --- a/src/soc/intel/denverton_ns/include/soc/gpio.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 - 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _DENVERTON_NS_GPIO_H_ -#define _DENVERTON_NS_GPIO_H_ - -#define RShiftU64(Operand, Count) (Operand >> Count) -#define LShiftU64(Operand, Count) (Operand << Count) - -#include - -#ifndef __ACPI__ -#include -#include - -// -// Structure for storing information about registers offset, community, -// maximal pad number for available groups -// -struct GPIO_GROUP_INFO { - uint32_t Community; - uint32_t PadOwnOffset; - uint32_t HostOwnOffset; - uint32_t GpiIsOffset; - uint32_t GpiIeOffset; - uint32_t GpiGpeStsOffset; - uint32_t GpiGpeEnOffset; - uint32_t SmiStsOffset; - uint32_t SmiEnOffset; - uint32_t NmiStsOffset; - uint32_t NmiEnOffset; - uint32_t PadCfgLockOffset; - uint32_t PadCfgLockTxOffset; - uint32_t PadCfgOffset; - uint32_t PadPerGroup; -}; - -// -// If in GPIO_GROUP_INFO structure certain register doesn't exist -// it will have value equal to NO_REGISTER_FOR_PROPERTY -// -#define NO_REGISTER_FOR_PROPERTY (~0u) - -// -// Below defines are based on GPIO_CONFIG structure fields -// -#define GPIO_CONF_PAD_MODE_MASK 0xF -#define GPIO_CONF_PAD_MODE_BIT_POS 0 -#define GPIO_CONF_HOST_OWN_MASK 0x3 -#define GPIO_CONF_HOST_OWN_BIT_POS 0 -#define GPIO_CONF_DIR_MASK 0x7 -#define GPIO_CONF_DIR_BIT_POS 0 -#define GPIO_CONF_INV_MASK 0x18 -#define GPIO_CONF_INV_BIT_POS 3 -#define GPIO_CONF_OUTPUT_MASK 0x3 -#define GPIO_CONF_OUTPUT_BIT_POS 0 -#define GPIO_CONF_INT_ROUTE_MASK 0x1F -#define GPIO_CONF_INT_ROUTE_BIT_POS 0 -#define GPIO_CONF_INT_TRIG_MASK 0xE0 -#define GPIO_CONF_INT_TRIG_BIT_POS 5 -#define GPIO_CONF_RESET_MASK 0x7 -#define GPIO_CONF_RESET_BIT_POS 0 -#define GPIO_CONF_TERM_MASK 0x1F -#define GPIO_CONF_TERM_BIT_POS 0 -#define GPIO_CONF_PADTOL_MASK 0x60 -#define GPIO_CONF_PADTOL_BIT_POS 5 -#define GPIO_CONF_LOCK_MASK 0x7 -#define GPIO_CONF_LOCK_BIT_POS 0 -#define GPIO_CONF_RXRAW_MASK 0x3 -#define GPIO_CONF_RXRAW_BIT_POS 0 - -/** -GPIO configuration structure used for pin programming. -Structure contains fields that can be used to configure pad. -**/ -struct GPIO_CONFIG { - /** - Pad Mode - Pad can be set as GPIO or one of its native functions. - When in native mode setting Direction (except Inversion), OutputState, - InterruptConfig and Host Software Pad Ownership are unnecessary. - Refer to definition of GPIO_PAD_MODE. - Refer to EDS for each native mode according to the pad. - **/ - uint32_t PadMode : 4; - /** - Host Software Pad Ownership - Set pad to ACPI mode or GPIO Driver Mode. - Refer to definition of GPIO_HOSTSW_OWN. - **/ - uint32_t HostSoftPadOwn : 2; - /** - GPIO Direction - Can choose between In, In with inversion Out, both In and Out, both In - with inversion and out or disabling both. - Refer to definition of GPIO_DIRECTION for supported settings. - **/ - uint32_t Direction : 5; - /** - Output State - Set Pad output value. - Refer to definition of GPIO_OUTPUT_STATE for supported settings. - This setting takes place when output is enabled. - **/ - uint32_t OutputState : 2; - /** - GPIO Interrupt Configuration - Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI). This setting - is applicable only if GPIO is in input mode. - If GPIO is set to cause an SCI then also Gpe is enabled for this pad. - Refer to definition of GPIO_INT_CONFIG for supported settings. - **/ - uint32_t InterruptConfig : 8; - /** - GPIO Power Configuration. - This setting controls Pad Reset Configuration. - Refer to definition of GPIO_RESET_CONFIG for supported settings. - **/ - uint32_t PowerConfig : 4; - - /** - GPIO Electrical Configuration - This setting controls pads termination and voltage tolerance. - Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings. - **/ - uint32_t ElectricalConfig : 7; - - /** - GPIO Lock Configuration - This setting controls pads lock. - Refer to definition of GPIO_LOCK_CONFIG for supported settings. - **/ - uint32_t LockConfig : 3; - /** - Additional GPIO configuration - Refer to definition of GPIO_OTHER_CONFIG for supported settings. - **/ - uint32_t OtherSettings : 2; - uint32_t RsvdBits : 27; ///< Reserved bits for future extension -} __attribute__((packed)); - -typedef enum { GpioHardwareDefault = 0x0 } GPIO_HARDWARE_DEFAULT; - -/// -/// GPIO Pad Mode -/// -typedef enum { - GpioPadModeGpio = 0x1, - GpioPadModeNative1 = 0x3, - GpioPadModeNative2 = 0x5, - GpioPadModeNative3 = 0x7, - GpioPadModeNative4 = 0x9 -} GPIO_PAD_MODE; - -/// -/// Host Software Pad Ownership modes -/// -typedef enum { - GpioHostOwnDefault = 0x0, ///< Leave ownership value unmodified - GpioHostOwnAcpi = 0x1, ///< Set HOST ownership to ACPI - GpioHostOwnGpio = 0x3 ///< Set HOST ownership to GPIO -} GPIO_HOSTSW_OWN; - -/// -/// GPIO Direction -/// -typedef enum { - GpioDirDefault = 0x0, ///< Leave pad direction setting unmodified - GpioDirInOut = - (0x1 | (0x1 << 3)), ///< Set pad for both output and input - GpioDirInInvOut = (0x1 | (0x3 << 3)), ///< Set pad for both output and - ///input with inversion - GpioDirIn = (0x3 | (0x1 << 3)), ///< Set pad for input only - GpioDirInInv = (0x3 | (0x3 << 3)), ///< Set pad for input with inversion - GpioDirOut = 0x5, ///< Set pad for output only - GpioDirNone = 0x7 ///< Disable both output and input -} GPIO_DIRECTION; - -/// -/// GPIO Output State -/// -typedef enum { - GpioOutDefault = 0x0, ///< Leave output value unmodified - GpioOutLow = 0x1, ///< Set output to low - GpioOutHigh = 0x3 ///< Set output to high -} GPIO_OUTPUT_STATE; - -/// -/// GPIO interrupt configuration -/// This setting is applicable only if GPIO is in input mode. -/// GPIO_INT_CONFIG allows to choose which interrupt is generated -/// (IOxAPIC/SCI/SMI/NMI) -/// and how it is triggered (edge or level). -/// Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to -/// GpioIntBothEdgecan -/// to describe an interrupt e.g. GpioIntApic | GpioIntLevel -/// If GPIO is set to cause an SCI then also Gpe is enabled for this pad. -/// Not all GPIO are capable of generating an SMI or NMI interrupt -/// - -typedef enum { - GpioIntDefault = 0x0, ///< Leave value of interrupt routing unmodified - GpioIntDis = 0x1, ///< Disable IOxAPIC/SCI/SMI/NMI interrupt generation - GpioIntNmi = 0x3, ///< Enable NMI interrupt only - GpioIntSmi = 0x5, ///< Enable SMI interrupt only - GpioIntSci = 0x9, ///< Enable SCI interrupt only - GpioIntApic = 0x11, ///< Enable IOxAPIC interrupt only - GpioIntLevel = (0x1 << 5), ///< Set interrupt as level triggered - GpioIntEdge = (0x3 << 5), ///< Set interrupt as edge triggered (type of - ///edge depends on input inversion) - GpioIntLvlEdgDis = (0x5 << 5), ///< Disable interrupt trigger - GpioIntBothEdge = (0x7 << 5) ///< Set interrupt as both edge triggered -} GPIO_INT_CONFIG; - -/// -/// GPIO Power Configuration -/// GPIO_RESET_CONFIG allows to set GPIO Reset (used to reset the specified -/// Pad Register fields). -/// -typedef enum { - GpioResetDefault = 0x0, ///< Leave value of pad reset unmodified - GpioResetPwrGood = 0x1, ///< Powergood reset - GpioResetDeep = 0x3, ///< Deep GPIO Reset - GpioResetNormal = 0x5, ///< GPIO Reset - GpioResetResume = 0x7 ///< Resume Reset (applicable only for GPD group) -} GPIO_RESET_CONFIG; - -/// -/// GPIO Electrical Configuration -/// Set GPIO termination and Pad Tolerance (applicable only for some pads) -/// Field from GpioTermDefault to GpioTermNative can be OR'ed with -/// GpioTolerance1v8. -/// -typedef enum { - GpioTermDefault = 0x0, ///< Leave termination setting unmodified - GpioTermNone = 0x1, ///< none - GpioTermWpd5K = 0x5, ///< 5kOhm weak pull-down - GpioTermWpd20K = 0x9, ///< 20kOhm weak pull-down - GpioTermWpu1K = 0x13, ///< 1kOhm weak pull-up - GpioTermWpu2K = 0x17, ///< 2kOhm weak pull-up - GpioTermWpu5K = 0x15, ///< 5kOhm weak pull-up - GpioTermWpu20K = 0x19, ///< 20kOhm weak pull-up - GpioTermWpu1K2K = 0x1B, ///< 1kOhm & 2kOhm weak pull-up - GpioTermNative = 0x1F, ///< Native function controls pads termination - GpioNoTolerance1v8 = (0x1 << 5), ///< Disable 1.8V pad tolerance - GpioTolerance1v8 = (0x3 << 5) ///< Enable 1.8V pad tolerance -} GPIO_ELECTRICAL_CONFIG; - -/// -/// GPIO LockConfiguration -/// Set GPIO configuration lock and output state lock -/// GpioLockPadConfig and GpioLockOutputState can be OR'ed -/// -typedef enum { - GpioLockDefault = 0x0, ///< Leave lock setting unmodified - GpioPadConfigLock = 0x3, ///< Lock Pad Configuration - GpioOutputStateLock = 0x5 ///< Lock GPIO pad output value -} GPIO_LOCK_CONFIG; - -/// -/// Other GPIO Configuration -/// GPIO_OTHER_CONFIG is used for less often settings and for future extensions -/// Supported settings: -/// - RX raw override to '1' - allows to override input value to '1' -/// This setting is applicable only if in input mode (both in GPIO and -/// native usage). -/// The override takes place at the internal pad state directly from buffer -/// and before the RXINV. -/// -typedef enum { - GpioRxRaw1Default = 0x0, ///< Use default input override value - GpioRxRaw1Dis = 0x1, ///< Don't override input - GpioRxRaw1En = 0x3 ///< Override input to '1' -} GPIO_OTHER_CONFIG; - -// -// Possible values of Pad Ownership -// -typedef enum { - GpioPadOwnHost = 0x0, - GpioPadOwnCsme = 0x1, - GpioPadOwnIsh = 0x2, -} GPIO_PAD_OWN; - -typedef uint32_t GPIO_PAD; - -struct pad_config { - GPIO_PAD GpioPad; - struct GPIO_CONFIG GpioConfig; -}; - -/* Configure GPIOs with mainboard provided settings */ -void gpio_configure_pads(const struct pad_config *gpio, size_t num); - -#endif /* __ACPI__ */ -#endif /* _DENVERTON_NS_GPIO_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/gpio_dnv.h b/src/soc/intel/denverton_ns/include/soc/gpio_dnv.h new file mode 100644 index 0000000000..c1c1d65e60 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/gpio_dnv.h @@ -0,0 +1,309 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 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 + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_GPIO_H_ +#define _DENVERTON_NS_GPIO_H_ + +#define RShiftU64(Operand, Count) (Operand >> Count) +#define LShiftU64(Operand, Count) (Operand << Count) + +#include + +#ifndef __ACPI__ +#include +#include + +// +// Structure for storing information about registers offset, community, +// maximal pad number for available groups +// +struct GPIO_GROUP_INFO { + uint32_t Community; + uint32_t PadOwnOffset; + uint32_t HostOwnOffset; + uint32_t GpiIsOffset; + uint32_t GpiIeOffset; + uint32_t GpiGpeStsOffset; + uint32_t GpiGpeEnOffset; + uint32_t SmiStsOffset; + uint32_t SmiEnOffset; + uint32_t NmiStsOffset; + uint32_t NmiEnOffset; + uint32_t PadCfgLockOffset; + uint32_t PadCfgLockTxOffset; + uint32_t PadCfgOffset; + uint32_t PadPerGroup; +}; + +// +// If in GPIO_GROUP_INFO structure certain register doesn't exist +// it will have value equal to NO_REGISTER_FOR_PROPERTY +// +#define NO_REGISTER_FOR_PROPERTY (~0u) + +// +// Below defines are based on GPIO_CONFIG structure fields +// +#define GPIO_CONF_PAD_MODE_MASK 0xF +#define GPIO_CONF_PAD_MODE_BIT_POS 0 +#define GPIO_CONF_HOST_OWN_MASK 0x3 +#define GPIO_CONF_HOST_OWN_BIT_POS 0 +#define GPIO_CONF_DIR_MASK 0x7 +#define GPIO_CONF_DIR_BIT_POS 0 +#define GPIO_CONF_INV_MASK 0x18 +#define GPIO_CONF_INV_BIT_POS 3 +#define GPIO_CONF_OUTPUT_MASK 0x3 +#define GPIO_CONF_OUTPUT_BIT_POS 0 +#define GPIO_CONF_INT_ROUTE_MASK 0x1F +#define GPIO_CONF_INT_ROUTE_BIT_POS 0 +#define GPIO_CONF_INT_TRIG_MASK 0xE0 +#define GPIO_CONF_INT_TRIG_BIT_POS 5 +#define GPIO_CONF_RESET_MASK 0x7 +#define GPIO_CONF_RESET_BIT_POS 0 +#define GPIO_CONF_TERM_MASK 0x1F +#define GPIO_CONF_TERM_BIT_POS 0 +#define GPIO_CONF_PADTOL_MASK 0x60 +#define GPIO_CONF_PADTOL_BIT_POS 5 +#define GPIO_CONF_LOCK_MASK 0x7 +#define GPIO_CONF_LOCK_BIT_POS 0 +#define GPIO_CONF_RXRAW_MASK 0x3 +#define GPIO_CONF_RXRAW_BIT_POS 0 + +/** +GPIO configuration structure used for pin programming. +Structure contains fields that can be used to configure pad. +**/ +struct GPIO_CONFIG { + /** + Pad Mode + Pad can be set as GPIO or one of its native functions. + When in native mode setting Direction (except Inversion), OutputState, + InterruptConfig and Host Software Pad Ownership are unnecessary. + Refer to definition of GPIO_PAD_MODE. + Refer to EDS for each native mode according to the pad. + **/ + uint32_t PadMode : 4; + /** + Host Software Pad Ownership + Set pad to ACPI mode or GPIO Driver Mode. + Refer to definition of GPIO_HOSTSW_OWN. + **/ + uint32_t HostSoftPadOwn : 2; + /** + GPIO Direction + Can choose between In, In with inversion Out, both In and Out, both In + with inversion and out or disabling both. + Refer to definition of GPIO_DIRECTION for supported settings. + **/ + uint32_t Direction : 5; + /** + Output State + Set Pad output value. + Refer to definition of GPIO_OUTPUT_STATE for supported settings. + This setting takes place when output is enabled. + **/ + uint32_t OutputState : 2; + /** + GPIO Interrupt Configuration + Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI). This setting + is applicable only if GPIO is in input mode. + If GPIO is set to cause an SCI then also Gpe is enabled for this pad. + Refer to definition of GPIO_INT_CONFIG for supported settings. + **/ + uint32_t InterruptConfig : 8; + /** + GPIO Power Configuration. + This setting controls Pad Reset Configuration. + Refer to definition of GPIO_RESET_CONFIG for supported settings. + **/ + uint32_t PowerConfig : 4; + + /** + GPIO Electrical Configuration + This setting controls pads termination and voltage tolerance. + Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings. + **/ + uint32_t ElectricalConfig : 7; + + /** + GPIO Lock Configuration + This setting controls pads lock. + Refer to definition of GPIO_LOCK_CONFIG for supported settings. + **/ + uint32_t LockConfig : 3; + /** + Additional GPIO configuration + Refer to definition of GPIO_OTHER_CONFIG for supported settings. + **/ + uint32_t OtherSettings : 2; + uint32_t RsvdBits : 27; ///< Reserved bits for future extension +} __attribute__((packed)); + +typedef enum { GpioHardwareDefault = 0x0 } GPIO_HARDWARE_DEFAULT; + +/// +/// GPIO Pad Mode +/// +typedef enum { + GpioPadModeGpio = 0x1, + GpioPadModeNative1 = 0x3, + GpioPadModeNative2 = 0x5, + GpioPadModeNative3 = 0x7, + GpioPadModeNative4 = 0x9 +} GPIO_PAD_MODE; + +/// +/// Host Software Pad Ownership modes +/// +typedef enum { + GpioHostOwnDefault = 0x0, ///< Leave ownership value unmodified + GpioHostOwnAcpi = 0x1, ///< Set HOST ownership to ACPI + GpioHostOwnGpio = 0x3 ///< Set HOST ownership to GPIO +} GPIO_HOSTSW_OWN; + +/// +/// GPIO Direction +/// +typedef enum { + GpioDirDefault = 0x0, ///< Leave pad direction setting unmodified + GpioDirInOut = + (0x1 | (0x1 << 3)), ///< Set pad for both output and input + GpioDirInInvOut = (0x1 | (0x3 << 3)), ///< Set pad for both output and + ///input with inversion + GpioDirIn = (0x3 | (0x1 << 3)), ///< Set pad for input only + GpioDirInInv = (0x3 | (0x3 << 3)), ///< Set pad for input with inversion + GpioDirOut = 0x5, ///< Set pad for output only + GpioDirNone = 0x7 ///< Disable both output and input +} GPIO_DIRECTION; + +/// +/// GPIO Output State +/// +typedef enum { + GpioOutDefault = 0x0, ///< Leave output value unmodified + GpioOutLow = 0x1, ///< Set output to low + GpioOutHigh = 0x3 ///< Set output to high +} GPIO_OUTPUT_STATE; + +/// +/// GPIO interrupt configuration +/// This setting is applicable only if GPIO is in input mode. +/// GPIO_INT_CONFIG allows to choose which interrupt is generated +/// (IOxAPIC/SCI/SMI/NMI) +/// and how it is triggered (edge or level). +/// Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to +/// GpioIntBothEdgecan +/// to describe an interrupt e.g. GpioIntApic | GpioIntLevel +/// If GPIO is set to cause an SCI then also Gpe is enabled for this pad. +/// Not all GPIO are capable of generating an SMI or NMI interrupt +/// + +typedef enum { + GpioIntDefault = 0x0, ///< Leave value of interrupt routing unmodified + GpioIntDis = 0x1, ///< Disable IOxAPIC/SCI/SMI/NMI interrupt generation + GpioIntNmi = 0x3, ///< Enable NMI interrupt only + GpioIntSmi = 0x5, ///< Enable SMI interrupt only + GpioIntSci = 0x9, ///< Enable SCI interrupt only + GpioIntApic = 0x11, ///< Enable IOxAPIC interrupt only + GpioIntLevel = (0x1 << 5), ///< Set interrupt as level triggered + GpioIntEdge = (0x3 << 5), ///< Set interrupt as edge triggered (type of + ///edge depends on input inversion) + GpioIntLvlEdgDis = (0x5 << 5), ///< Disable interrupt trigger + GpioIntBothEdge = (0x7 << 5) ///< Set interrupt as both edge triggered +} GPIO_INT_CONFIG; + +/// +/// GPIO Power Configuration +/// GPIO_RESET_CONFIG allows to set GPIO Reset (used to reset the specified +/// Pad Register fields). +/// +typedef enum { + GpioResetDefault = 0x0, ///< Leave value of pad reset unmodified + GpioResetPwrGood = 0x1, ///< Powergood reset + GpioResetDeep = 0x3, ///< Deep GPIO Reset + GpioResetNormal = 0x5, ///< GPIO Reset + GpioResetResume = 0x7 ///< Resume Reset (applicable only for GPD group) +} GPIO_RESET_CONFIG; + +/// +/// GPIO Electrical Configuration +/// Set GPIO termination and Pad Tolerance (applicable only for some pads) +/// Field from GpioTermDefault to GpioTermNative can be OR'ed with +/// GpioTolerance1v8. +/// +typedef enum { + GpioTermDefault = 0x0, ///< Leave termination setting unmodified + GpioTermNone = 0x1, ///< none + GpioTermWpd5K = 0x5, ///< 5kOhm weak pull-down + GpioTermWpd20K = 0x9, ///< 20kOhm weak pull-down + GpioTermWpu1K = 0x13, ///< 1kOhm weak pull-up + GpioTermWpu2K = 0x17, ///< 2kOhm weak pull-up + GpioTermWpu5K = 0x15, ///< 5kOhm weak pull-up + GpioTermWpu20K = 0x19, ///< 20kOhm weak pull-up + GpioTermWpu1K2K = 0x1B, ///< 1kOhm & 2kOhm weak pull-up + GpioTermNative = 0x1F, ///< Native function controls pads termination + GpioNoTolerance1v8 = (0x1 << 5), ///< Disable 1.8V pad tolerance + GpioTolerance1v8 = (0x3 << 5) ///< Enable 1.8V pad tolerance +} GPIO_ELECTRICAL_CONFIG; + +/// +/// GPIO LockConfiguration +/// Set GPIO configuration lock and output state lock +/// GpioLockPadConfig and GpioLockOutputState can be OR'ed +/// +typedef enum { + GpioLockDefault = 0x0, ///< Leave lock setting unmodified + GpioPadConfigLock = 0x3, ///< Lock Pad Configuration + GpioOutputStateLock = 0x5 ///< Lock GPIO pad output value +} GPIO_LOCK_CONFIG; + +/// +/// Other GPIO Configuration +/// GPIO_OTHER_CONFIG is used for less often settings and for future extensions +/// Supported settings: +/// - RX raw override to '1' - allows to override input value to '1' +/// This setting is applicable only if in input mode (both in GPIO and +/// native usage). +/// The override takes place at the internal pad state directly from buffer +/// and before the RXINV. +/// +typedef enum { + GpioRxRaw1Default = 0x0, ///< Use default input override value + GpioRxRaw1Dis = 0x1, ///< Don't override input + GpioRxRaw1En = 0x3 ///< Override input to '1' +} GPIO_OTHER_CONFIG; + +// +// Possible values of Pad Ownership +// +typedef enum { + GpioPadOwnHost = 0x0, + GpioPadOwnCsme = 0x1, + GpioPadOwnIsh = 0x2, +} GPIO_PAD_OWN; + +typedef uint32_t GPIO_PAD; + +struct dnv_pad_config { + GPIO_PAD GpioPad; + struct GPIO_CONFIG GpioConfig; +}; + +/* Configure GPIOs with mainboard provided settings */ +void gpio_configure_dnv_pads(const struct dnv_pad_config *gpio, size_t num); + +#endif /* __ACPI__ */ +#endif /* _DENVERTON_NS_GPIO_H_ */ -- cgit v1.2.3