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 Read 8bit character from debug stream.
96 Block until character is read.
98 @return 8bit character read from debug stream.
103 PlatformDebugPortGetChar8 (
110 if (SerialPortPoll ()) {
111 if (SerialPortRead ((UINT8
*) &Got
, 1) == 1) {
121 Clear SPI Protect registers.
123 @retval EFI_SUCCESS SPI protect registers cleared.
124 @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.
129 PlatformClearSpiProtect (
133 UINT32 PchRootComplexBar
;
135 PchRootComplexBar
= QNC_RCRB_BASE
;
137 // Check if the SPI interface has been locked-down.
139 if ((MmioRead16 (PchRootComplexBar
+ R_QNC_RCRB_SPIS
) & B_QNC_RCRB_SPIS_SCL
) != 0) {
140 return EFI_ACCESS_DENIED
;
142 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
, 0);
143 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
144 return EFI_ACCESS_DENIED
;
146 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR1
, 0);
147 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
148 return EFI_ACCESS_DENIED
;
150 MmioWrite32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR2
, 0);
151 if (MmioRead32 (PchRootComplexBar
+ R_QNC_RCRB_SPIPBR0
) != 0) {
152 return EFI_ACCESS_DENIED
;
158 Determine if an SPI address range is protected.
160 @param SpiBaseAddress Base of SPI range.
161 @param Length Length of SPI range.
163 @retval TRUE Range is protected.
164 @retval FALSE Range is not protected.
168 PlatformIsSpiRangeProtected (
169 IN CONST UINT32 SpiBaseAddress
,
170 IN CONST UINT32 Length
176 UINT32 ProtectedBase
;
177 UINT32 ProtectedLimit
;
178 UINT32 PchRootComplexBar
;
180 PchRootComplexBar
= QNC_RCRB_BASE
;
183 Offset
= R_QNC_RCRB_SPIPBR0
;
184 Limit
= SpiBaseAddress
+ (Length
- 1);
186 RegVal
= MmioRead32 (PchRootComplexBar
+ Offset
);
187 if ((RegVal
& B_QNC_RCRB_SPIPBRn_WPE
) != 0) {
188 ProtectedBase
= (RegVal
& 0xfff) << 12;
189 ProtectedLimit
= (RegVal
& 0x00fff000) + 0xfff;
190 if (SpiBaseAddress
>= ProtectedBase
&& Limit
<= ProtectedLimit
) {
194 if (Offset
== R_QNC_RCRB_SPIPBR0
) {
195 Offset
= R_QNC_RCRB_SPIPBR1
;
196 } else if (Offset
== R_QNC_RCRB_SPIPBR1
) {
197 Offset
= R_QNC_RCRB_SPIPBR2
;
207 Set Legacy GPIO Level
209 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
210 @param GpioNum GPIO bit to change.
211 @param HighLevel If TRUE set GPIO High else Set GPIO low.
216 PlatformLegacyGpioSetLevel (
217 IN CONST UINT32 LevelRegOffset
,
218 IN CONST UINT32 GpioNum
,
219 IN CONST BOOLEAN HighLevel
223 UINT32 GpioBaseAddress
;
226 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
227 ASSERT (GpioBaseAddress
> 0);
229 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
230 GpioNumMask
= (1 << GpioNum
);
232 RegValue
|= (GpioNumMask
);
234 RegValue
&= ~(GpioNumMask
);
236 IoWrite32 (GpioBaseAddress
+ LevelRegOffset
, RegValue
);
240 Get Legacy GPIO Level
242 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
243 @param GpioNum GPIO bit to check.
245 @retval TRUE If bit is SET.
246 @retval FALSE If bit is CLEAR.
251 PlatformLegacyGpioGetLevel (
252 IN CONST UINT32 LevelRegOffset
,
253 IN CONST UINT32 GpioNum
257 UINT32 GpioBaseAddress
;
260 GpioBaseAddress
= LpcPciCfg32 (R_QNC_LPC_GBA_BASE
) & B_QNC_LPC_GPA_BASE_MASK
;
261 RegValue
= IoRead32 (GpioBaseAddress
+ LevelRegOffset
);
262 GpioNumMask
= (1 << GpioNum
);
263 return ((RegValue
& GpioNumMask
) != 0);
268 Pcal9555GetPortRegBit (
269 IN CONST UINT32 Pcal9555SlaveAddr
,
270 IN CONST UINT32 GpioNum
,
271 IN CONST UINT8 RegBase
278 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
279 EFI_I2C_ADDR_MODE I2cAddrMode
;
284 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
285 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
289 GpioNumMask
= (UINT8
)(1 << GpioNum
);
291 SubAddr
= RegBase
+ 1;
292 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
296 // Output port value always at 2nd byte in Data variable.
298 RegValuePtr
= &Data
[1];
301 // On read entry sub address at 2nd byte, on read exit output
302 // port value in 2nd byte.
307 Status
= I2cReadMultipleByte (
314 ASSERT_EFI_ERROR (Status
);
317 // Adjust output port bit given callers request.
319 return ((*RegValuePtr
& GpioNumMask
) != 0);
323 Pcal9555SetPortRegBit (
324 IN CONST UINT32 Pcal9555SlaveAddr
,
325 IN CONST UINT32 GpioNum
,
326 IN CONST UINT8 RegBase
,
327 IN CONST BOOLEAN LogicOne
334 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr
;
335 EFI_I2C_ADDR_MODE I2cAddrMode
;
340 I2cDeviceAddr
.I2CDeviceAddress
= (UINTN
)Pcal9555SlaveAddr
;
341 I2cAddrMode
= EfiI2CSevenBitAddrMode
;
345 GpioNumMask
= (UINT8
)(1 << GpioNum
);
347 SubAddr
= RegBase
+ 1;
348 GpioNumMask
= (UINT8
)(1 << (GpioNum
- 8));
352 // Output port value always at 2nd byte in Data variable.
354 RegValuePtr
= &Data
[1];
357 // On read entry sub address at 2nd byte, on read exit output
358 // port value in 2nd byte.
363 Status
= I2cReadMultipleByte (
370 ASSERT_EFI_ERROR (Status
);
373 // Adjust output port bit given callers request.
376 *RegValuePtr
= *RegValuePtr
| GpioNumMask
;
378 *RegValuePtr
= *RegValuePtr
& ~(GpioNumMask
);
382 // Update register. Sub address at 1st byte, value at 2nd byte.
386 Status
= I2cWriteMultipleByte (
392 ASSERT_EFI_ERROR (Status
);
396 Set the direction of Pcal9555 IO Expander GPIO pin.
398 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
399 @param GpioNum Gpio direction to configure - values 0-7 for Port0
401 @param CfgAsInput If TRUE set pin direction as input else set as output.
406 PlatformPcal9555GpioSetDir (
407 IN CONST UINT32 Pcal9555SlaveAddr
,
408 IN CONST UINT32 GpioNum
,
409 IN CONST BOOLEAN CfgAsInput
412 Pcal9555SetPortRegBit (
415 PCAL9555_REG_CFG_PORT0
,
421 Set the level of Pcal9555 IO Expander GPIO high or low.
423 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
424 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
426 @param HighLevel If TRUE set pin high else set pin low.
431 PlatformPcal9555GpioSetLevel (
432 IN CONST UINT32 Pcal9555SlaveAddr
,
433 IN CONST UINT32 GpioNum
,
434 IN CONST BOOLEAN HighLevel
437 Pcal9555SetPortRegBit (
440 PCAL9555_REG_OUT_PORT0
,
447 Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
449 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
450 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
456 PlatformPcal9555GpioEnablePull (
457 IN CONST UINT32 Pcal9555SlaveAddr
,
458 IN CONST UINT32 GpioNum
461 Pcal9555SetPortRegBit (
464 PCAL9555_REG_PULL_EN_PORT0
,
471 Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
473 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
474 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
480 PlatformPcal9555GpioDisablePull (
481 IN CONST UINT32 Pcal9555SlaveAddr
,
482 IN CONST UINT32 GpioNum
485 Pcal9555SetPortRegBit (
488 PCAL9555_REG_PULL_EN_PORT0
,
495 Get state of Pcal9555 GPIOs.
497 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
498 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
501 @retval TRUE GPIO pin is high
502 @retval FALSE GPIO pin is low
506 PlatformPcal9555GpioGetState (
507 IN CONST UINT32 Pcal9555SlaveAddr
,
508 IN CONST UINT32 GpioNum
511 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr
, GpioNum
, PCAL9555_REG_IN_PORT0
);