2 Helper routines with common PEI / DXE implementation.
4 Copyright (c) 2013-2016 Intel Corporation.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "CommonHeader.h"
17 #include <Library/I2cLib.h>
19 CHAR16
*mPlatTypeNameTable
[] = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION
};
20 UINTN mPlatTypeNameTableLen
= ((sizeof(mPlatTypeNameTable
)) / sizeof (CHAR16
*));
23 // Routines defined in other source modules of this component.
27 // Routines local to this source module.
31 // Routines shared with other souce modules in this component.
35 WriteFirstFreeSpiProtect (
36 IN CONST UINT32 PchRootComplexBar
,
37 IN CONST UINT32 DirectValue
,
38 IN CONST UINT32 BaseAddress
,
39 IN CONST UINT32 Length
,
47 ASSERT (PchRootComplexBar
> 0);
50 if (OffsetPtr
!= NULL
) {
53 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) == 0) {
54 Offset
= R_QNC_RCRB_SPIPBR0
;
56 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR1
) == 0) {
57 Offset
= R_QNC_RCRB_SPIPBR1
;
59 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR2
) == 0) {
60 Offset
= R_QNC_RCRB_SPIPBR2
;
65 if (DirectValue
== 0) {
66 StepLen
= ALIGN_VALUE (Length
,SIZE_4KB
); // Bring up to 4K boundary.
67 RegVal
= BaseAddress
+ StepLen
- 1;
68 RegVal
&= 0x00FFF000; // Set EDS Protected Range Limit (PRL).
69 RegVal
|= ((BaseAddress
>> 12) & 0xfff); // or in EDS Protected Range Base (PRB).
76 RegVal
|= B_QNC_RCRB_SPIPBRn_WPE
;
77 MmioWrite32 (PchRootComplexBar
+ Offset
, RegVal
);
78 if (RegVal
== MmioRead32 (PchRootComplexBar
+ Offset
)) {
79 if (OffsetPtr
!= NULL
) {
84 return EFI_DEVICE_ERROR
;
90 // Routines exported by this component.
94 Clear SPI Protect registers.
96 @retval EFI_SUCCESS SPI protect registers cleared.
97 @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.
102 PlatformClearSpiProtect (
106 UINT32 PchRootComplexBar
;
108 PchRootComplexBar
= QNC_RCRB_BASE
;
110 // Check if the SPI interface has been locked-down.
112 if ((MmioRead16 (PchRootComplexBar
+ R_QNC_RCRB_SPIS
) & B_QNC_RCRB_SPIS_SCL
) != 0) {
113 return EFI_ACCESS_DENIED
;
115 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
, 0);
116 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
117 return EFI_ACCESS_DENIED
;
119 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR1
, 0);
120 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
121 return EFI_ACCESS_DENIED
;
123 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR2
, 0);
124 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
125 return EFI_ACCESS_DENIED
;
131 Determine if an SPI address range is protected.
133 @param SpiBaseAddress Base of SPI range.
134 @param Length Length of SPI range.
136 @retval TRUE Range is protected.
137 @retval FALSE Range is not protected.
141 PlatformIsSpiRangeProtected (
142 IN CONST UINT32 SpiBaseAddress
,
143 IN CONST UINT32 Length
149 UINT32 ProtectedBase
;
150 UINT32 ProtectedLimit
;
151 UINT32 PchRootComplexBar
;
153 PchRootComplexBar
= QNC_RCRB_BASE
;
156 Offset
= R_QNC_RCRB_SPIPBR0
;
157 Limit
= SpiBaseAddress
+ (Length
- 1);
159 RegVal
= MmioRead32 (PchRootComplexBar
+ Offset
);
160 if ((RegVal
& B_QNC_RCRB_SPIPBRn_WPE
) != 0) {
161 ProtectedBase
= (RegVal
& 0xfff) << 12;
162 ProtectedLimit
= (RegVal
& 0x00fff000) + 0xfff;
163 if (SpiBaseAddress
>= ProtectedBase
&& Limit
<= ProtectedLimit
) {
167 if (Offset
== R_QNC_RCRB_SPIPBR0
) {
168 Offset
= R_QNC_RCRB_SPIPBR1
;
169 } else if (Offset
== R_QNC_RCRB_SPIPBR1
) {
170 Offset
= R_QNC_RCRB_SPIPBR2
;
180 Set Legacy GPIO Level
182 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
183 @param GpioNum GPIO bit to change.
184 @param HighLevel If TRUE set GPIO High else Set GPIO low.
189 PlatformLegacyGpioSetLevel (
190 IN CONST UINT32 LevelRegOffset
,
191 IN CONST UINT32 GpioNum
,
192 IN CONST BOOLEAN HighLevel
196 UINT32 GpioBaseAddress
;
199 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
200 ASSERT (GpioBaseAddress
> 0);
202 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
203 GpioNumMask
= (1 << GpioNum
);
205 RegValue
|= (GpioNumMask
);
207 RegValue
&= ~(GpioNumMask
);
209 IoWrite32 (GpioBaseAddress
+ LevelRegOffset
, RegValue
);
213 Get Legacy GPIO Level
215 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
216 @param GpioNum GPIO bit to check.
218 @retval TRUE If bit is SET.
219 @retval FALSE If bit is CLEAR.
224 PlatformLegacyGpioGetLevel (
225 IN CONST UINT32 LevelRegOffset
,
226 IN CONST UINT32 GpioNum
230 UINT32 GpioBaseAddress
;
233 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
234 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
235 GpioNumMask
= (1 << GpioNum
);
236 return ((RegValue
& GpioNumMask
) != 0);
241 Pcal9555GetPortRegBit (
242 IN CONST UINT32 Pcal9555SlaveAddr
,
243 IN CONST UINT32 GpioNum
,
244 IN CONST UINT8 RegBase
251 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
252 EFI_I2C_ADDR_MODE I2cAddrMode
;
257 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
258 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
262 GpioNumMask
= (UINT8
)(1 << GpioNum
);
264 SubAddr
= RegBase
+ 1;
265 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
269 // Output port value always at 2nd byte in Data variable.
271 RegValuePtr
= &Data
[1];
274 // On read entry sub address at 2nd byte, on read exit output
275 // port value in 2nd byte.
280 Status
= I2cReadMultipleByte (
287 ASSERT_EFI_ERROR (Status
);
290 // Adjust output port bit given callers request.
292 return ((*RegValuePtr
& GpioNumMask
) != 0);
296 Pcal9555SetPortRegBit (
297 IN CONST UINT32 Pcal9555SlaveAddr
,
298 IN CONST UINT32 GpioNum
,
299 IN CONST UINT8 RegBase
,
300 IN CONST BOOLEAN LogicOne
307 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
308 EFI_I2C_ADDR_MODE I2cAddrMode
;
313 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
314 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
318 GpioNumMask
= (UINT8
)(1 << GpioNum
);
320 SubAddr
= RegBase
+ 1;
321 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
325 // Output port value always at 2nd byte in Data variable.
327 RegValuePtr
= &Data
[1];
330 // On read entry sub address at 2nd byte, on read exit output
331 // port value in 2nd byte.
336 Status
= I2cReadMultipleByte (
343 ASSERT_EFI_ERROR (Status
);
346 // Adjust output port bit given callers request.
349 *RegValuePtr
= *RegValuePtr
| GpioNumMask
;
351 *RegValuePtr
= *RegValuePtr
& ~(GpioNumMask
);
355 // Update register. Sub address at 1st byte, value at 2nd byte.
359 Status
= I2cWriteMultipleByte (
365 ASSERT_EFI_ERROR (Status
);
369 Set the direction of Pcal9555 IO Expander GPIO pin.
371 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
372 @param GpioNum Gpio direction to configure - values 0-7 for Port0
374 @param CfgAsInput If TRUE set pin direction as input else set as output.
379 PlatformPcal9555GpioSetDir (
380 IN CONST UINT32 Pcal9555SlaveAddr
,
381 IN CONST UINT32 GpioNum
,
382 IN CONST BOOLEAN CfgAsInput
385 Pcal9555SetPortRegBit (
388 PCAL9555_REG_CFG_PORT0
,
394 Set the level of Pcal9555 IO Expander GPIO high or low.
396 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
397 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
399 @param HighLevel If TRUE set pin high else set pin low.
404 PlatformPcal9555GpioSetLevel (
405 IN CONST UINT32 Pcal9555SlaveAddr
,
406 IN CONST UINT32 GpioNum
,
407 IN CONST BOOLEAN HighLevel
410 Pcal9555SetPortRegBit (
413 PCAL9555_REG_OUT_PORT0
,
420 Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
422 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
423 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
429 PlatformPcal9555GpioEnablePull (
430 IN CONST UINT32 Pcal9555SlaveAddr
,
431 IN CONST UINT32 GpioNum
434 Pcal9555SetPortRegBit (
437 PCAL9555_REG_PULL_EN_PORT0
,
444 Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
446 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
447 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
453 PlatformPcal9555GpioDisablePull (
454 IN CONST UINT32 Pcal9555SlaveAddr
,
455 IN CONST UINT32 GpioNum
458 Pcal9555SetPortRegBit (
461 PCAL9555_REG_PULL_EN_PORT0
,
468 Get state of Pcal9555 GPIOs.
470 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
471 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
474 @retval TRUE GPIO pin is high
475 @retval FALSE GPIO pin is low
479 PlatformPcal9555GpioGetState (
480 IN CONST UINT32 Pcal9555SlaveAddr
,
481 IN CONST UINT32 GpioNum
484 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr
, GpioNum
, PCAL9555_REG_IN_PORT0
);