2 Helper routines with common PEI / DXE implementation.
4 Copyright (c) 2013-2016 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "CommonHeader.h"
11 #include <Library/I2cLib.h>
13 CHAR16
*mPlatTypeNameTable
[] = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION
};
14 UINTN mPlatTypeNameTableLen
= ((sizeof(mPlatTypeNameTable
)) / sizeof (CHAR16
*));
17 // Routines defined in other source modules of this component.
21 // Routines local to this source module.
25 // Routines shared with other souce modules in this component.
29 WriteFirstFreeSpiProtect (
30 IN CONST UINT32 PchRootComplexBar
,
31 IN CONST UINT32 DirectValue
,
32 IN CONST UINT32 BaseAddress
,
33 IN CONST UINT32 Length
,
41 ASSERT (PchRootComplexBar
> 0);
44 if (OffsetPtr
!= NULL
) {
47 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) == 0) {
48 Offset
= R_QNC_RCRB_SPIPBR0
;
50 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR1
) == 0) {
51 Offset
= R_QNC_RCRB_SPIPBR1
;
53 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR2
) == 0) {
54 Offset
= R_QNC_RCRB_SPIPBR2
;
59 if (DirectValue
== 0) {
60 StepLen
= ALIGN_VALUE (Length
,SIZE_4KB
); // Bring up to 4K boundary.
61 RegVal
= BaseAddress
+ StepLen
- 1;
62 RegVal
&= 0x00FFF000; // Set EDS Protected Range Limit (PRL).
63 RegVal
|= ((BaseAddress
>> 12) & 0xfff); // or in EDS Protected Range Base (PRB).
70 RegVal
|= B_QNC_RCRB_SPIPBRn_WPE
;
71 MmioWrite32 (PchRootComplexBar
+ Offset
, RegVal
);
72 if (RegVal
== MmioRead32 (PchRootComplexBar
+ Offset
)) {
73 if (OffsetPtr
!= NULL
) {
78 return EFI_DEVICE_ERROR
;
84 // Routines exported by this component.
88 Clear SPI Protect registers.
90 @retval EFI_SUCCESS SPI protect registers cleared.
91 @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.
96 PlatformClearSpiProtect (
100 UINT32 PchRootComplexBar
;
102 PchRootComplexBar
= QNC_RCRB_BASE
;
104 // Check if the SPI interface has been locked-down.
106 if ((MmioRead16 (PchRootComplexBar
+ R_QNC_RCRB_SPIS
) & B_QNC_RCRB_SPIS_SCL
) != 0) {
107 return EFI_ACCESS_DENIED
;
109 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
, 0);
110 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
111 return EFI_ACCESS_DENIED
;
113 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR1
, 0);
114 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
115 return EFI_ACCESS_DENIED
;
117 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR2
, 0);
118 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
119 return EFI_ACCESS_DENIED
;
125 Determine if an SPI address range is protected.
127 @param SpiBaseAddress Base of SPI range.
128 @param Length Length of SPI range.
130 @retval TRUE Range is protected.
131 @retval FALSE Range is not protected.
135 PlatformIsSpiRangeProtected (
136 IN CONST UINT32 SpiBaseAddress
,
137 IN CONST UINT32 Length
143 UINT32 ProtectedBase
;
144 UINT32 ProtectedLimit
;
145 UINT32 PchRootComplexBar
;
147 PchRootComplexBar
= QNC_RCRB_BASE
;
150 Offset
= R_QNC_RCRB_SPIPBR0
;
151 Limit
= SpiBaseAddress
+ (Length
- 1);
153 RegVal
= MmioRead32 (PchRootComplexBar
+ Offset
);
154 if ((RegVal
& B_QNC_RCRB_SPIPBRn_WPE
) != 0) {
155 ProtectedBase
= (RegVal
& 0xfff) << 12;
156 ProtectedLimit
= (RegVal
& 0x00fff000) + 0xfff;
157 if (SpiBaseAddress
>= ProtectedBase
&& Limit
<= ProtectedLimit
) {
161 if (Offset
== R_QNC_RCRB_SPIPBR0
) {
162 Offset
= R_QNC_RCRB_SPIPBR1
;
163 } else if (Offset
== R_QNC_RCRB_SPIPBR1
) {
164 Offset
= R_QNC_RCRB_SPIPBR2
;
174 Set Legacy GPIO Level
176 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
177 @param GpioNum GPIO bit to change.
178 @param HighLevel If TRUE set GPIO High else Set GPIO low.
183 PlatformLegacyGpioSetLevel (
184 IN CONST UINT32 LevelRegOffset
,
185 IN CONST UINT32 GpioNum
,
186 IN CONST BOOLEAN HighLevel
190 UINT32 GpioBaseAddress
;
193 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
194 ASSERT (GpioBaseAddress
> 0);
196 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
197 GpioNumMask
= (1 << GpioNum
);
199 RegValue
|= (GpioNumMask
);
201 RegValue
&= ~(GpioNumMask
);
203 IoWrite32 (GpioBaseAddress
+ LevelRegOffset
, RegValue
);
207 Get Legacy GPIO Level
209 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
210 @param GpioNum GPIO bit to check.
212 @retval TRUE If bit is SET.
213 @retval FALSE If bit is CLEAR.
218 PlatformLegacyGpioGetLevel (
219 IN CONST UINT32 LevelRegOffset
,
220 IN CONST UINT32 GpioNum
224 UINT32 GpioBaseAddress
;
227 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
228 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
229 GpioNumMask
= (1 << GpioNum
);
230 return ((RegValue
& GpioNumMask
) != 0);
235 Pcal9555GetPortRegBit (
236 IN CONST UINT32 Pcal9555SlaveAddr
,
237 IN CONST UINT32 GpioNum
,
238 IN CONST UINT8 RegBase
245 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
246 EFI_I2C_ADDR_MODE I2cAddrMode
;
251 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
252 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
256 GpioNumMask
= (UINT8
)(1 << GpioNum
);
258 SubAddr
= RegBase
+ 1;
259 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
263 // Output port value always at 2nd byte in Data variable.
265 RegValuePtr
= &Data
[1];
268 // On read entry sub address at 2nd byte, on read exit output
269 // port value in 2nd byte.
274 Status
= I2cReadMultipleByte (
281 ASSERT_EFI_ERROR (Status
);
284 // Adjust output port bit given callers request.
286 return ((*RegValuePtr
& GpioNumMask
) != 0);
290 Pcal9555SetPortRegBit (
291 IN CONST UINT32 Pcal9555SlaveAddr
,
292 IN CONST UINT32 GpioNum
,
293 IN CONST UINT8 RegBase
,
294 IN CONST BOOLEAN LogicOne
301 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
302 EFI_I2C_ADDR_MODE I2cAddrMode
;
307 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
308 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
312 GpioNumMask
= (UINT8
)(1 << GpioNum
);
314 SubAddr
= RegBase
+ 1;
315 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
319 // Output port value always at 2nd byte in Data variable.
321 RegValuePtr
= &Data
[1];
324 // On read entry sub address at 2nd byte, on read exit output
325 // port value in 2nd byte.
330 Status
= I2cReadMultipleByte (
337 ASSERT_EFI_ERROR (Status
);
340 // Adjust output port bit given callers request.
343 *RegValuePtr
= *RegValuePtr
| GpioNumMask
;
345 *RegValuePtr
= *RegValuePtr
& ~(GpioNumMask
);
349 // Update register. Sub address at 1st byte, value at 2nd byte.
353 Status
= I2cWriteMultipleByte (
359 ASSERT_EFI_ERROR (Status
);
363 Set the direction of Pcal9555 IO Expander GPIO pin.
365 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
366 @param GpioNum Gpio direction to configure - values 0-7 for Port0
368 @param CfgAsInput If TRUE set pin direction as input else set as output.
373 PlatformPcal9555GpioSetDir (
374 IN CONST UINT32 Pcal9555SlaveAddr
,
375 IN CONST UINT32 GpioNum
,
376 IN CONST BOOLEAN CfgAsInput
379 Pcal9555SetPortRegBit (
382 PCAL9555_REG_CFG_PORT0
,
388 Set the level of Pcal9555 IO Expander GPIO high or low.
390 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
391 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
393 @param HighLevel If TRUE set pin high else set pin low.
398 PlatformPcal9555GpioSetLevel (
399 IN CONST UINT32 Pcal9555SlaveAddr
,
400 IN CONST UINT32 GpioNum
,
401 IN CONST BOOLEAN HighLevel
404 Pcal9555SetPortRegBit (
407 PCAL9555_REG_OUT_PORT0
,
414 Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
416 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
417 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
423 PlatformPcal9555GpioEnablePull (
424 IN CONST UINT32 Pcal9555SlaveAddr
,
425 IN CONST UINT32 GpioNum
428 Pcal9555SetPortRegBit (
431 PCAL9555_REG_PULL_EN_PORT0
,
438 Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
440 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
441 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
447 PlatformPcal9555GpioDisablePull (
448 IN CONST UINT32 Pcal9555SlaveAddr
,
449 IN CONST UINT32 GpioNum
452 Pcal9555SetPortRegBit (
455 PCAL9555_REG_PULL_EN_PORT0
,
462 Get state of Pcal9555 GPIOs.
464 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
465 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
468 @retval TRUE GPIO pin is high
469 @retval FALSE GPIO pin is low
473 PlatformPcal9555GpioGetState (
474 IN CONST UINT32 Pcal9555SlaveAddr
,
475 IN CONST UINT32 GpioNum
478 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr
, GpioNum
, PCAL9555_REG_IN_PORT0
);