diff options
Diffstat (limited to 'src/soc/intel/denverton_ns/gpio.c')
-rw-r--r-- | src/soc/intel/denverton_ns/gpio.c | 509 |
1 files changed, 0 insertions, 509 deletions
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 <stdint.h> -#include <string.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> - -#include <soc/iomap.h> -#include <soc/pcr.h> -#include <soc/soc_util.h> -#include <soc/gpio.h> - -// 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))); - } - } -} |