+++ /dev/null
-/** @file\r
-Helper routines with common PEI / DXE implementation.\r
-\r
-Copyright (c) 2013-2016 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "CommonHeader.h"\r
-#include <Library/I2cLib.h>\r
-\r
-CHAR16 *mPlatTypeNameTable[] = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION };\r
-UINTN mPlatTypeNameTableLen = ((sizeof(mPlatTypeNameTable)) / sizeof (CHAR16 *));\r
-\r
-//\r
-// Routines defined in other source modules of this component.\r
-//\r
-\r
-//\r
-// Routines local to this source module.\r
-//\r
-\r
-//\r
-// Routines shared with other souce modules in this component.\r
-//\r
-\r
-EFI_STATUS\r
-WriteFirstFreeSpiProtect (\r
- IN CONST UINT32 PchRootComplexBar,\r
- IN CONST UINT32 DirectValue,\r
- IN CONST UINT32 BaseAddress,\r
- IN CONST UINT32 Length,\r
- OUT UINT32 *OffsetPtr\r
- )\r
-{\r
- UINT32 RegVal;\r
- UINT32 Offset;\r
- UINT32 StepLen;\r
-\r
- ASSERT (PchRootComplexBar > 0);\r
-\r
- Offset = 0;\r
- if (OffsetPtr != NULL) {\r
- *OffsetPtr = Offset;\r
- }\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) == 0) {\r
- Offset = R_QNC_RCRB_SPIPBR0;\r
- } else {\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1) == 0) {\r
- Offset = R_QNC_RCRB_SPIPBR1;\r
- } else {\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2) == 0) {\r
- Offset = R_QNC_RCRB_SPIPBR2;\r
- }\r
- }\r
- }\r
- if (Offset != 0) {\r
- if (DirectValue == 0) {\r
- StepLen = ALIGN_VALUE (Length,SIZE_4KB); // Bring up to 4K boundary.\r
- RegVal = BaseAddress + StepLen - 1;\r
- RegVal &= 0x00FFF000; // Set EDS Protected Range Limit (PRL).\r
- RegVal |= ((BaseAddress >> 12) & 0xfff); // or in EDS Protected Range Base (PRB).\r
- } else {\r
- RegVal = DirectValue;\r
- }\r
- //\r
- // Enable protection.\r
- //\r
- RegVal |= B_QNC_RCRB_SPIPBRn_WPE;\r
- MmioWrite32 (PchRootComplexBar + Offset, RegVal);\r
- if (RegVal == MmioRead32 (PchRootComplexBar + Offset)) {\r
- if (OffsetPtr != NULL) {\r
- *OffsetPtr = Offset;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_DEVICE_ERROR;\r
- }\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-//\r
-// Routines exported by this component.\r
-//\r
-\r
-/**\r
- Clear SPI Protect registers.\r
-\r
- @retval EFI_SUCCESS SPI protect registers cleared.\r
- @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.\r
-**/\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PlatformClearSpiProtect (\r
- VOID\r
- )\r
-{\r
- UINT32 PchRootComplexBar;\r
-\r
- PchRootComplexBar = QNC_RCRB_BASE;\r
- //\r
- // Check if the SPI interface has been locked-down.\r
- //\r
- if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0, 0);\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1, 0);\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2, 0);\r
- if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Determine if an SPI address range is protected.\r
-\r
- @param SpiBaseAddress Base of SPI range.\r
- @param Length Length of SPI range.\r
-\r
- @retval TRUE Range is protected.\r
- @retval FALSE Range is not protected.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-PlatformIsSpiRangeProtected (\r
- IN CONST UINT32 SpiBaseAddress,\r
- IN CONST UINT32 Length\r
- )\r
-{\r
- UINT32 RegVal;\r
- UINT32 Offset;\r
- UINT32 Limit;\r
- UINT32 ProtectedBase;\r
- UINT32 ProtectedLimit;\r
- UINT32 PchRootComplexBar;\r
-\r
- PchRootComplexBar = QNC_RCRB_BASE;\r
-\r
- if (Length > 0) {\r
- Offset = R_QNC_RCRB_SPIPBR0;\r
- Limit = SpiBaseAddress + (Length - 1);\r
- do {\r
- RegVal = MmioRead32 (PchRootComplexBar + Offset);\r
- if ((RegVal & B_QNC_RCRB_SPIPBRn_WPE) != 0) {\r
- ProtectedBase = (RegVal & 0xfff) << 12;\r
- ProtectedLimit = (RegVal & 0x00fff000) + 0xfff;\r
- if (SpiBaseAddress >= ProtectedBase && Limit <= ProtectedLimit) {\r
- return TRUE;\r
- }\r
- }\r
- if (Offset == R_QNC_RCRB_SPIPBR0) {\r
- Offset = R_QNC_RCRB_SPIPBR1;\r
- } else if (Offset == R_QNC_RCRB_SPIPBR1) {\r
- Offset = R_QNC_RCRB_SPIPBR2;\r
- } else {\r
- break;\r
- }\r
- } while (TRUE);\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Set Legacy GPIO Level\r
-\r
- @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
- @param GpioNum GPIO bit to change.\r
- @param HighLevel If TRUE set GPIO High else Set GPIO low.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformLegacyGpioSetLevel (\r
- IN CONST UINT32 LevelRegOffset,\r
- IN CONST UINT32 GpioNum,\r
- IN CONST BOOLEAN HighLevel\r
- )\r
-{\r
- UINT32 RegValue;\r
- UINT32 GpioBaseAddress;\r
- UINT32 GpioNumMask;\r
-\r
- GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
- ASSERT (GpioBaseAddress > 0);\r
-\r
- RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
- GpioNumMask = (1 << GpioNum);\r
- if (HighLevel) {\r
- RegValue |= (GpioNumMask);\r
- } else {\r
- RegValue &= ~(GpioNumMask);\r
- }\r
- IoWrite32 (GpioBaseAddress + LevelRegOffset, RegValue);\r
-}\r
-\r
-/**\r
- Get Legacy GPIO Level\r
-\r
- @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
- @param GpioNum GPIO bit to check.\r
-\r
- @retval TRUE If bit is SET.\r
- @retval FALSE If bit is CLEAR.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-PlatformLegacyGpioGetLevel (\r
- IN CONST UINT32 LevelRegOffset,\r
- IN CONST UINT32 GpioNum\r
- )\r
-{\r
- UINT32 RegValue;\r
- UINT32 GpioBaseAddress;\r
- UINT32 GpioNumMask;\r
-\r
- GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
- RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
- GpioNumMask = (1 << GpioNum);\r
- return ((RegValue & GpioNumMask) != 0);\r
-}\r
-\r
-\r
-BOOLEAN\r
-Pcal9555GetPortRegBit (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum,\r
- IN CONST UINT8 RegBase\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN ReadLength;\r
- UINTN WriteLength;\r
- UINT8 Data[2];\r
- EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
- EFI_I2C_ADDR_MODE I2cAddrMode;\r
- UINT8 *RegValuePtr;\r
- UINT8 GpioNumMask;\r
- UINT8 SubAddr;\r
-\r
- I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
- I2cAddrMode = EfiI2CSevenBitAddrMode;\r
-\r
- if (GpioNum < 8) {\r
- SubAddr = RegBase;\r
- GpioNumMask = (UINT8)(1 << GpioNum);\r
- } else {\r
- SubAddr = RegBase + 1;\r
- GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
- }\r
-\r
- //\r
- // Output port value always at 2nd byte in Data variable.\r
- //\r
- RegValuePtr = &Data[1];\r
-\r
- //\r
- // On read entry sub address at 2nd byte, on read exit output\r
- // port value in 2nd byte.\r
- //\r
- Data[1] = SubAddr;\r
- WriteLength = 1;\r
- ReadLength = 1;\r
- Status = I2cReadMultipleByte (\r
- I2cDeviceAddr,\r
- I2cAddrMode,\r
- &WriteLength,\r
- &ReadLength,\r
- &Data[1]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Adjust output port bit given callers request.\r
- //\r
- return ((*RegValuePtr & GpioNumMask) != 0);\r
-}\r
-\r
-VOID\r
-Pcal9555SetPortRegBit (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum,\r
- IN CONST UINT8 RegBase,\r
- IN CONST BOOLEAN LogicOne\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN ReadLength;\r
- UINTN WriteLength;\r
- UINT8 Data[2];\r
- EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
- EFI_I2C_ADDR_MODE I2cAddrMode;\r
- UINT8 *RegValuePtr;\r
- UINT8 GpioNumMask;\r
- UINT8 SubAddr;\r
-\r
- I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
- I2cAddrMode = EfiI2CSevenBitAddrMode;\r
-\r
- if (GpioNum < 8) {\r
- SubAddr = RegBase;\r
- GpioNumMask = (UINT8)(1 << GpioNum);\r
- } else {\r
- SubAddr = RegBase + 1;\r
- GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
- }\r
-\r
- //\r
- // Output port value always at 2nd byte in Data variable.\r
- //\r
- RegValuePtr = &Data[1];\r
-\r
- //\r
- // On read entry sub address at 2nd byte, on read exit output\r
- // port value in 2nd byte.\r
- //\r
- Data[1] = SubAddr;\r
- WriteLength = 1;\r
- ReadLength = 1;\r
- Status = I2cReadMultipleByte (\r
- I2cDeviceAddr,\r
- I2cAddrMode,\r
- &WriteLength,\r
- &ReadLength,\r
- &Data[1]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Adjust output port bit given callers request.\r
- //\r
- if (LogicOne) {\r
- *RegValuePtr = *RegValuePtr | GpioNumMask;\r
- } else {\r
- *RegValuePtr = *RegValuePtr & ~(GpioNumMask);\r
- }\r
-\r
- //\r
- // Update register. Sub address at 1st byte, value at 2nd byte.\r
- //\r
- WriteLength = 2;\r
- Data[0] = SubAddr;\r
- Status = I2cWriteMultipleByte (\r
- I2cDeviceAddr,\r
- I2cAddrMode,\r
- &WriteLength,\r
- Data\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
-/**\r
-Set the direction of Pcal9555 IO Expander GPIO pin.\r
-\r
-@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
-@param GpioNum Gpio direction to configure - values 0-7 for Port0\r
-and 8-15 for Port1.\r
-@param CfgAsInput If TRUE set pin direction as input else set as output.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformPcal9555GpioSetDir (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum,\r
- IN CONST BOOLEAN CfgAsInput\r
- )\r
-{\r
- Pcal9555SetPortRegBit (\r
- Pcal9555SlaveAddr,\r
- GpioNum,\r
- PCAL9555_REG_CFG_PORT0,\r
- CfgAsInput\r
- );\r
-}\r
-\r
-/**\r
-Set the level of Pcal9555 IO Expander GPIO high or low.\r
-\r
-@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
-@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
-for Port1.\r
-@param HighLevel If TRUE set pin high else set pin low.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformPcal9555GpioSetLevel (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum,\r
- IN CONST BOOLEAN HighLevel\r
- )\r
-{\r
- Pcal9555SetPortRegBit (\r
- Pcal9555SlaveAddr,\r
- GpioNum,\r
- PCAL9555_REG_OUT_PORT0,\r
- HighLevel\r
- );\r
-}\r
-\r
-/**\r
-\r
-Enable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
-\r
-@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
-@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
-for Port1.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformPcal9555GpioEnablePull (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum\r
- )\r
-{\r
- Pcal9555SetPortRegBit (\r
- Pcal9555SlaveAddr,\r
- GpioNum,\r
- PCAL9555_REG_PULL_EN_PORT0,\r
- TRUE\r
- );\r
-}\r
-\r
-/**\r
-\r
-Disable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
-\r
-@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
-@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
-for Port1.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformPcal9555GpioDisablePull (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum\r
- )\r
-{\r
- Pcal9555SetPortRegBit (\r
- Pcal9555SlaveAddr,\r
- GpioNum,\r
- PCAL9555_REG_PULL_EN_PORT0,\r
- FALSE\r
- );\r
-}\r
-\r
-/**\r
-\r
-Get state of Pcal9555 GPIOs.\r
-\r
-@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
-@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
-for Port1.\r
-\r
-@retval TRUE GPIO pin is high\r
-@retval FALSE GPIO pin is low\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-PlatformPcal9555GpioGetState (\r
- IN CONST UINT32 Pcal9555SlaveAddr,\r
- IN CONST UINT32 GpioNum\r
- )\r
-{\r
- return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);\r
-}\r
-\r
-\r