]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
FatPkg: INF/DEC file updates to EDK II packages
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformHelperLib / PlatformHelperLib.c
CommitLineData
b303605e
MK
1/** @file\r
2Helper routines with common PEI / DXE implementation.\r
3\r
b1169100 4Copyright (c) 2013-2016 Intel Corporation.\r
b303605e
MK
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "CommonHeader.h"\r
b1169100 17#include <Library/I2cLib.h>\r
b303605e
MK
18\r
19CHAR16 *mPlatTypeNameTable[] = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION };\r
20UINTN mPlatTypeNameTableLen = ((sizeof(mPlatTypeNameTable)) / sizeof (CHAR16 *));\r
21\r
22//\r
23// Routines defined in other source modules of this component.\r
24//\r
25\r
26//\r
27// Routines local to this source module.\r
28//\r
29\r
30//\r
31// Routines shared with other souce modules in this component.\r
32//\r
33\r
34EFI_STATUS\r
35WriteFirstFreeSpiProtect (\r
36 IN CONST UINT32 PchRootComplexBar,\r
37 IN CONST UINT32 DirectValue,\r
38 IN CONST UINT32 BaseAddress,\r
39 IN CONST UINT32 Length,\r
40 OUT UINT32 *OffsetPtr\r
41 )\r
42{\r
43 UINT32 RegVal;\r
44 UINT32 Offset;\r
45 UINT32 StepLen;\r
46\r
47 ASSERT (PchRootComplexBar > 0);\r
48\r
49 Offset = 0;\r
50 if (OffsetPtr != NULL) {\r
51 *OffsetPtr = Offset;\r
52 }\r
53 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) == 0) {\r
54 Offset = R_QNC_RCRB_SPIPBR0;\r
55 } else {\r
56 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1) == 0) {\r
57 Offset = R_QNC_RCRB_SPIPBR1;\r
58 } else {\r
59 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2) == 0) {\r
60 Offset = R_QNC_RCRB_SPIPBR2;\r
61 }\r
62 }\r
63 }\r
64 if (Offset != 0) {\r
65 if (DirectValue == 0) {\r
66 StepLen = ALIGN_VALUE (Length,SIZE_4KB); // Bring up to 4K boundary.\r
67 RegVal = BaseAddress + StepLen - 1;\r
68 RegVal &= 0x00FFF000; // Set EDS Protected Range Limit (PRL).\r
69 RegVal |= ((BaseAddress >> 12) & 0xfff); // or in EDS Protected Range Base (PRB).\r
70 } else {\r
71 RegVal = DirectValue;\r
72 }\r
73 //\r
74 // Enable protection.\r
75 //\r
76 RegVal |= B_QNC_RCRB_SPIPBRn_WPE;\r
77 MmioWrite32 (PchRootComplexBar + Offset, RegVal);\r
78 if (RegVal == MmioRead32 (PchRootComplexBar + Offset)) {\r
79 if (OffsetPtr != NULL) {\r
80 *OffsetPtr = Offset;\r
81 }\r
82 return EFI_SUCCESS;\r
83 }\r
84 return EFI_DEVICE_ERROR;\r
85 }\r
86 return EFI_NOT_FOUND;\r
87}\r
88\r
89//\r
90// Routines exported by this component.\r
91//\r
92\r
93/**\r
94 Read 8bit character from debug stream.\r
95\r
96 Block until character is read.\r
97\r
98 @return 8bit character read from debug stream.\r
99\r
100**/\r
101CHAR8\r
102EFIAPI\r
103PlatformDebugPortGetChar8 (\r
104 VOID\r
105 )\r
106{\r
107 CHAR8 Got;\r
108\r
109 do {\r
110 if (SerialPortPoll ()) {\r
111 if (SerialPortRead ((UINT8 *) &Got, 1) == 1) {\r
112 break;\r
113 }\r
114 }\r
115 } while (TRUE);\r
116\r
117 return Got;\r
118}\r
119\r
120/**\r
121 Clear SPI Protect registers.\r
122\r
123 @retval EFI_SUCCESS SPI protect registers cleared.\r
124 @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.\r
125**/\r
126\r
127EFI_STATUS\r
128EFIAPI\r
129PlatformClearSpiProtect (\r
130 VOID\r
131 )\r
132{\r
133 UINT32 PchRootComplexBar;\r
134\r
135 PchRootComplexBar = QNC_RCRB_BASE;\r
136 //\r
137 // Check if the SPI interface has been locked-down.\r
138 //\r
139 if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {\r
140 return EFI_ACCESS_DENIED;\r
141 }\r
142 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0, 0);\r
143 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
144 return EFI_ACCESS_DENIED;\r
145 }\r
146 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1, 0);\r
147 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
148 return EFI_ACCESS_DENIED;\r
149 }\r
150 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2, 0);\r
151 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
152 return EFI_ACCESS_DENIED;\r
153 }\r
154 return EFI_SUCCESS;\r
155}\r
156\r
157/**\r
158 Determine if an SPI address range is protected.\r
159\r
160 @param SpiBaseAddress Base of SPI range.\r
161 @param Length Length of SPI range.\r
162\r
163 @retval TRUE Range is protected.\r
164 @retval FALSE Range is not protected.\r
165**/\r
166BOOLEAN\r
167EFIAPI\r
168PlatformIsSpiRangeProtected (\r
169 IN CONST UINT32 SpiBaseAddress,\r
170 IN CONST UINT32 Length\r
171 )\r
172{\r
173 UINT32 RegVal;\r
174 UINT32 Offset;\r
175 UINT32 Limit;\r
176 UINT32 ProtectedBase;\r
177 UINT32 ProtectedLimit;\r
178 UINT32 PchRootComplexBar;\r
179\r
180 PchRootComplexBar = QNC_RCRB_BASE;\r
181\r
182 if (Length > 0) {\r
183 Offset = R_QNC_RCRB_SPIPBR0;\r
184 Limit = SpiBaseAddress + (Length - 1);\r
185 do {\r
186 RegVal = MmioRead32 (PchRootComplexBar + Offset);\r
187 if ((RegVal & B_QNC_RCRB_SPIPBRn_WPE) != 0) {\r
188 ProtectedBase = (RegVal & 0xfff) << 12;\r
189 ProtectedLimit = (RegVal & 0x00fff000) + 0xfff;\r
190 if (SpiBaseAddress >= ProtectedBase && Limit <= ProtectedLimit) {\r
191 return TRUE;\r
192 }\r
193 }\r
194 if (Offset == R_QNC_RCRB_SPIPBR0) {\r
195 Offset = R_QNC_RCRB_SPIPBR1;\r
196 } else if (Offset == R_QNC_RCRB_SPIPBR1) {\r
197 Offset = R_QNC_RCRB_SPIPBR2;\r
198 } else {\r
199 break;\r
200 }\r
201 } while (TRUE);\r
202 }\r
203 return FALSE;\r
204}\r
205\r
206/**\r
207 Set Legacy GPIO Level\r
208\r
209 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
210 @param GpioNum GPIO bit to change.\r
211 @param HighLevel If TRUE set GPIO High else Set GPIO low.\r
212\r
213**/\r
214VOID\r
215EFIAPI\r
216PlatformLegacyGpioSetLevel (\r
217 IN CONST UINT32 LevelRegOffset,\r
218 IN CONST UINT32 GpioNum,\r
219 IN CONST BOOLEAN HighLevel\r
220 )\r
221{\r
222 UINT32 RegValue;\r
223 UINT32 GpioBaseAddress;\r
224 UINT32 GpioNumMask;\r
225\r
226 GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
227 ASSERT (GpioBaseAddress > 0);\r
228\r
229 RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
230 GpioNumMask = (1 << GpioNum);\r
231 if (HighLevel) {\r
232 RegValue |= (GpioNumMask);\r
233 } else {\r
234 RegValue &= ~(GpioNumMask);\r
235 }\r
236 IoWrite32 (GpioBaseAddress + LevelRegOffset, RegValue);\r
237}\r
238\r
239/**\r
240 Get Legacy GPIO Level\r
241\r
242 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
243 @param GpioNum GPIO bit to check.\r
244\r
245 @retval TRUE If bit is SET.\r
246 @retval FALSE If bit is CLEAR.\r
247\r
248**/\r
249BOOLEAN\r
250EFIAPI\r
251PlatformLegacyGpioGetLevel (\r
252 IN CONST UINT32 LevelRegOffset,\r
253 IN CONST UINT32 GpioNum\r
254 )\r
255{\r
256 UINT32 RegValue;\r
257 UINT32 GpioBaseAddress;\r
258 UINT32 GpioNumMask;\r
259\r
260 GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
261 RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
262 GpioNumMask = (1 << GpioNum);\r
263 return ((RegValue & GpioNumMask) != 0);\r
264}\r
b1169100
MK
265\r
266\r
267BOOLEAN\r
268Pcal9555GetPortRegBit (\r
269 IN CONST UINT32 Pcal9555SlaveAddr,\r
270 IN CONST UINT32 GpioNum,\r
271 IN CONST UINT8 RegBase\r
272 )\r
273{\r
274 EFI_STATUS Status;\r
275 UINTN ReadLength;\r
276 UINTN WriteLength;\r
277 UINT8 Data[2];\r
278 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
279 EFI_I2C_ADDR_MODE I2cAddrMode;\r
280 UINT8 *RegValuePtr;\r
281 UINT8 GpioNumMask;\r
282 UINT8 SubAddr;\r
283\r
284 I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
285 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
286\r
287 if (GpioNum < 8) {\r
288 SubAddr = RegBase;\r
289 GpioNumMask = (UINT8)(1 << GpioNum);\r
290 } else {\r
291 SubAddr = RegBase + 1;\r
292 GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
293 }\r
294\r
295 //\r
296 // Output port value always at 2nd byte in Data variable.\r
297 //\r
298 RegValuePtr = &Data[1];\r
299\r
300 //\r
301 // On read entry sub address at 2nd byte, on read exit output\r
302 // port value in 2nd byte.\r
303 //\r
304 Data[1] = SubAddr;\r
305 WriteLength = 1;\r
306 ReadLength = 1;\r
307 Status = I2cReadMultipleByte (\r
308 I2cDeviceAddr,\r
309 I2cAddrMode,\r
310 &WriteLength,\r
311 &ReadLength,\r
312 &Data[1]\r
313 );\r
314 ASSERT_EFI_ERROR (Status);\r
315\r
316 //\r
317 // Adjust output port bit given callers request.\r
318 //\r
319 return ((*RegValuePtr & GpioNumMask) != 0);\r
320}\r
321\r
322VOID\r
323Pcal9555SetPortRegBit (\r
324 IN CONST UINT32 Pcal9555SlaveAddr,\r
325 IN CONST UINT32 GpioNum,\r
326 IN CONST UINT8 RegBase,\r
327 IN CONST BOOLEAN LogicOne\r
328 )\r
329{\r
330 EFI_STATUS Status;\r
331 UINTN ReadLength;\r
332 UINTN WriteLength;\r
333 UINT8 Data[2];\r
334 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
335 EFI_I2C_ADDR_MODE I2cAddrMode;\r
336 UINT8 *RegValuePtr;\r
337 UINT8 GpioNumMask;\r
338 UINT8 SubAddr;\r
339\r
340 I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
341 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
342\r
343 if (GpioNum < 8) {\r
344 SubAddr = RegBase;\r
345 GpioNumMask = (UINT8)(1 << GpioNum);\r
346 } else {\r
347 SubAddr = RegBase + 1;\r
348 GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
349 }\r
350\r
351 //\r
352 // Output port value always at 2nd byte in Data variable.\r
353 //\r
354 RegValuePtr = &Data[1];\r
355\r
356 //\r
357 // On read entry sub address at 2nd byte, on read exit output\r
358 // port value in 2nd byte.\r
359 //\r
360 Data[1] = SubAddr;\r
361 WriteLength = 1;\r
362 ReadLength = 1;\r
363 Status = I2cReadMultipleByte (\r
364 I2cDeviceAddr,\r
365 I2cAddrMode,\r
366 &WriteLength,\r
367 &ReadLength,\r
368 &Data[1]\r
369 );\r
370 ASSERT_EFI_ERROR (Status);\r
371\r
372 //\r
373 // Adjust output port bit given callers request.\r
374 //\r
375 if (LogicOne) {\r
376 *RegValuePtr = *RegValuePtr | GpioNumMask;\r
377 } else {\r
378 *RegValuePtr = *RegValuePtr & ~(GpioNumMask);\r
379 }\r
380\r
381 //\r
382 // Update register. Sub address at 1st byte, value at 2nd byte.\r
383 //\r
384 WriteLength = 2;\r
385 Data[0] = SubAddr;\r
386 Status = I2cWriteMultipleByte (\r
387 I2cDeviceAddr,\r
388 I2cAddrMode,\r
389 &WriteLength,\r
390 Data\r
391 );\r
392 ASSERT_EFI_ERROR (Status);\r
393}\r
394\r
395/**\r
396Set the direction of Pcal9555 IO Expander GPIO pin.\r
397\r
398@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
399@param GpioNum Gpio direction to configure - values 0-7 for Port0\r
400and 8-15 for Port1.\r
401@param CfgAsInput If TRUE set pin direction as input else set as output.\r
402\r
403**/\r
404VOID\r
405EFIAPI\r
406PlatformPcal9555GpioSetDir (\r
407 IN CONST UINT32 Pcal9555SlaveAddr,\r
408 IN CONST UINT32 GpioNum,\r
409 IN CONST BOOLEAN CfgAsInput\r
410 )\r
411{\r
412 Pcal9555SetPortRegBit (\r
413 Pcal9555SlaveAddr,\r
414 GpioNum,\r
415 PCAL9555_REG_CFG_PORT0,\r
416 CfgAsInput\r
417 );\r
418}\r
419\r
420/**\r
421Set the level of Pcal9555 IO Expander GPIO high or low.\r
422\r
423@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
424@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
425for Port1.\r
426@param HighLevel If TRUE set pin high else set pin low.\r
427\r
428**/\r
429VOID\r
430EFIAPI\r
431PlatformPcal9555GpioSetLevel (\r
432 IN CONST UINT32 Pcal9555SlaveAddr,\r
433 IN CONST UINT32 GpioNum,\r
434 IN CONST BOOLEAN HighLevel\r
435 )\r
436{\r
437 Pcal9555SetPortRegBit (\r
438 Pcal9555SlaveAddr,\r
439 GpioNum,\r
440 PCAL9555_REG_OUT_PORT0,\r
441 HighLevel\r
442 );\r
443}\r
444\r
445/**\r
446\r
447Enable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
448\r
449@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
450@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
451for Port1.\r
452\r
453**/\r
454VOID\r
455EFIAPI\r
456PlatformPcal9555GpioEnablePull (\r
457 IN CONST UINT32 Pcal9555SlaveAddr,\r
458 IN CONST UINT32 GpioNum\r
459 )\r
460{\r
461 Pcal9555SetPortRegBit (\r
462 Pcal9555SlaveAddr,\r
463 GpioNum,\r
464 PCAL9555_REG_PULL_EN_PORT0,\r
465 TRUE\r
466 );\r
467}\r
468\r
469/**\r
470\r
471Disable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
472\r
473@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
474@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
475for Port1.\r
476\r
477**/\r
478VOID\r
479EFIAPI\r
480PlatformPcal9555GpioDisablePull (\r
481 IN CONST UINT32 Pcal9555SlaveAddr,\r
482 IN CONST UINT32 GpioNum\r
483 )\r
484{\r
485 Pcal9555SetPortRegBit (\r
486 Pcal9555SlaveAddr,\r
487 GpioNum,\r
488 PCAL9555_REG_PULL_EN_PORT0,\r
489 FALSE\r
490 );\r
491}\r
492\r
493/**\r
494\r
495Get state of Pcal9555 GPIOs.\r
496\r
497@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
498@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
499for Port1.\r
500\r
501@retval TRUE GPIO pin is high\r
502@retval FALSE GPIO pin is low\r
503**/\r
504BOOLEAN\r
505EFIAPI\r
506PlatformPcal9555GpioGetState (\r
507 IN CONST UINT32 Pcal9555SlaveAddr,\r
508 IN CONST UINT32 GpioNum\r
509 )\r
510{\r
511 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);\r
512}\r
513\r
514\r