]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
QuarkPlatformPkg/PlatformHelperLib: Remove PlatformDebugPortGetChar8()
[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
b303605e
MK
93/**\r
94 Clear SPI Protect registers.\r
95\r
96 @retval EFI_SUCCESS SPI protect registers cleared.\r
97 @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.\r
98**/\r
99\r
100EFI_STATUS\r
101EFIAPI\r
102PlatformClearSpiProtect (\r
103 VOID\r
104 )\r
105{\r
106 UINT32 PchRootComplexBar;\r
107\r
108 PchRootComplexBar = QNC_RCRB_BASE;\r
109 //\r
110 // Check if the SPI interface has been locked-down.\r
111 //\r
112 if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {\r
113 return EFI_ACCESS_DENIED;\r
114 }\r
115 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0, 0);\r
116 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
117 return EFI_ACCESS_DENIED;\r
118 }\r
119 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1, 0);\r
120 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
121 return EFI_ACCESS_DENIED;\r
122 }\r
123 MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2, 0);\r
124 if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {\r
125 return EFI_ACCESS_DENIED;\r
126 }\r
127 return EFI_SUCCESS;\r
128}\r
129\r
130/**\r
131 Determine if an SPI address range is protected.\r
132\r
133 @param SpiBaseAddress Base of SPI range.\r
134 @param Length Length of SPI range.\r
135\r
136 @retval TRUE Range is protected.\r
137 @retval FALSE Range is not protected.\r
138**/\r
139BOOLEAN\r
140EFIAPI\r
141PlatformIsSpiRangeProtected (\r
142 IN CONST UINT32 SpiBaseAddress,\r
143 IN CONST UINT32 Length\r
144 )\r
145{\r
146 UINT32 RegVal;\r
147 UINT32 Offset;\r
148 UINT32 Limit;\r
149 UINT32 ProtectedBase;\r
150 UINT32 ProtectedLimit;\r
151 UINT32 PchRootComplexBar;\r
152\r
153 PchRootComplexBar = QNC_RCRB_BASE;\r
154\r
155 if (Length > 0) {\r
156 Offset = R_QNC_RCRB_SPIPBR0;\r
157 Limit = SpiBaseAddress + (Length - 1);\r
158 do {\r
159 RegVal = MmioRead32 (PchRootComplexBar + Offset);\r
160 if ((RegVal & B_QNC_RCRB_SPIPBRn_WPE) != 0) {\r
161 ProtectedBase = (RegVal & 0xfff) << 12;\r
162 ProtectedLimit = (RegVal & 0x00fff000) + 0xfff;\r
163 if (SpiBaseAddress >= ProtectedBase && Limit <= ProtectedLimit) {\r
164 return TRUE;\r
165 }\r
166 }\r
167 if (Offset == R_QNC_RCRB_SPIPBR0) {\r
168 Offset = R_QNC_RCRB_SPIPBR1;\r
169 } else if (Offset == R_QNC_RCRB_SPIPBR1) {\r
170 Offset = R_QNC_RCRB_SPIPBR2;\r
171 } else {\r
172 break;\r
173 }\r
174 } while (TRUE);\r
175 }\r
176 return FALSE;\r
177}\r
178\r
179/**\r
180 Set Legacy GPIO Level\r
181\r
182 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
183 @param GpioNum GPIO bit to change.\r
184 @param HighLevel If TRUE set GPIO High else Set GPIO low.\r
185\r
186**/\r
187VOID\r
188EFIAPI\r
189PlatformLegacyGpioSetLevel (\r
190 IN CONST UINT32 LevelRegOffset,\r
191 IN CONST UINT32 GpioNum,\r
192 IN CONST BOOLEAN HighLevel\r
193 )\r
194{\r
195 UINT32 RegValue;\r
196 UINT32 GpioBaseAddress;\r
197 UINT32 GpioNumMask;\r
198\r
199 GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
200 ASSERT (GpioBaseAddress > 0);\r
201\r
202 RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
203 GpioNumMask = (1 << GpioNum);\r
204 if (HighLevel) {\r
205 RegValue |= (GpioNumMask);\r
206 } else {\r
207 RegValue &= ~(GpioNumMask);\r
208 }\r
209 IoWrite32 (GpioBaseAddress + LevelRegOffset, RegValue);\r
210}\r
211\r
212/**\r
213 Get Legacy GPIO Level\r
214\r
215 @param LevelRegOffset GPIO level register Offset from GPIO Base Address.\r
216 @param GpioNum GPIO bit to check.\r
217\r
218 @retval TRUE If bit is SET.\r
219 @retval FALSE If bit is CLEAR.\r
220\r
221**/\r
222BOOLEAN\r
223EFIAPI\r
224PlatformLegacyGpioGetLevel (\r
225 IN CONST UINT32 LevelRegOffset,\r
226 IN CONST UINT32 GpioNum\r
227 )\r
228{\r
229 UINT32 RegValue;\r
230 UINT32 GpioBaseAddress;\r
231 UINT32 GpioNumMask;\r
232\r
233 GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
234 RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);\r
235 GpioNumMask = (1 << GpioNum);\r
236 return ((RegValue & GpioNumMask) != 0);\r
237}\r
b1169100
MK
238\r
239\r
240BOOLEAN\r
241Pcal9555GetPortRegBit (\r
242 IN CONST UINT32 Pcal9555SlaveAddr,\r
243 IN CONST UINT32 GpioNum,\r
244 IN CONST UINT8 RegBase\r
245 )\r
246{\r
247 EFI_STATUS Status;\r
248 UINTN ReadLength;\r
249 UINTN WriteLength;\r
250 UINT8 Data[2];\r
251 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
252 EFI_I2C_ADDR_MODE I2cAddrMode;\r
253 UINT8 *RegValuePtr;\r
254 UINT8 GpioNumMask;\r
255 UINT8 SubAddr;\r
256\r
257 I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
258 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
259\r
260 if (GpioNum < 8) {\r
261 SubAddr = RegBase;\r
262 GpioNumMask = (UINT8)(1 << GpioNum);\r
263 } else {\r
264 SubAddr = RegBase + 1;\r
265 GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
266 }\r
267\r
268 //\r
269 // Output port value always at 2nd byte in Data variable.\r
270 //\r
271 RegValuePtr = &Data[1];\r
272\r
273 //\r
274 // On read entry sub address at 2nd byte, on read exit output\r
275 // port value in 2nd byte.\r
276 //\r
277 Data[1] = SubAddr;\r
278 WriteLength = 1;\r
279 ReadLength = 1;\r
280 Status = I2cReadMultipleByte (\r
281 I2cDeviceAddr,\r
282 I2cAddrMode,\r
283 &WriteLength,\r
284 &ReadLength,\r
285 &Data[1]\r
286 );\r
287 ASSERT_EFI_ERROR (Status);\r
288\r
289 //\r
290 // Adjust output port bit given callers request.\r
291 //\r
292 return ((*RegValuePtr & GpioNumMask) != 0);\r
293}\r
294\r
295VOID\r
296Pcal9555SetPortRegBit (\r
297 IN CONST UINT32 Pcal9555SlaveAddr,\r
298 IN CONST UINT32 GpioNum,\r
299 IN CONST UINT8 RegBase,\r
300 IN CONST BOOLEAN LogicOne\r
301 )\r
302{\r
303 EFI_STATUS Status;\r
304 UINTN ReadLength;\r
305 UINTN WriteLength;\r
306 UINT8 Data[2];\r
307 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
308 EFI_I2C_ADDR_MODE I2cAddrMode;\r
309 UINT8 *RegValuePtr;\r
310 UINT8 GpioNumMask;\r
311 UINT8 SubAddr;\r
312\r
313 I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;\r
314 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
315\r
316 if (GpioNum < 8) {\r
317 SubAddr = RegBase;\r
318 GpioNumMask = (UINT8)(1 << GpioNum);\r
319 } else {\r
320 SubAddr = RegBase + 1;\r
321 GpioNumMask = (UINT8)(1 << (GpioNum - 8));\r
322 }\r
323\r
324 //\r
325 // Output port value always at 2nd byte in Data variable.\r
326 //\r
327 RegValuePtr = &Data[1];\r
328\r
329 //\r
330 // On read entry sub address at 2nd byte, on read exit output\r
331 // port value in 2nd byte.\r
332 //\r
333 Data[1] = SubAddr;\r
334 WriteLength = 1;\r
335 ReadLength = 1;\r
336 Status = I2cReadMultipleByte (\r
337 I2cDeviceAddr,\r
338 I2cAddrMode,\r
339 &WriteLength,\r
340 &ReadLength,\r
341 &Data[1]\r
342 );\r
343 ASSERT_EFI_ERROR (Status);\r
344\r
345 //\r
346 // Adjust output port bit given callers request.\r
347 //\r
348 if (LogicOne) {\r
349 *RegValuePtr = *RegValuePtr | GpioNumMask;\r
350 } else {\r
351 *RegValuePtr = *RegValuePtr & ~(GpioNumMask);\r
352 }\r
353\r
354 //\r
355 // Update register. Sub address at 1st byte, value at 2nd byte.\r
356 //\r
357 WriteLength = 2;\r
358 Data[0] = SubAddr;\r
359 Status = I2cWriteMultipleByte (\r
360 I2cDeviceAddr,\r
361 I2cAddrMode,\r
362 &WriteLength,\r
363 Data\r
364 );\r
365 ASSERT_EFI_ERROR (Status);\r
366}\r
367\r
368/**\r
369Set the direction of Pcal9555 IO Expander GPIO pin.\r
370\r
371@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
372@param GpioNum Gpio direction to configure - values 0-7 for Port0\r
373and 8-15 for Port1.\r
374@param CfgAsInput If TRUE set pin direction as input else set as output.\r
375\r
376**/\r
377VOID\r
378EFIAPI\r
379PlatformPcal9555GpioSetDir (\r
380 IN CONST UINT32 Pcal9555SlaveAddr,\r
381 IN CONST UINT32 GpioNum,\r
382 IN CONST BOOLEAN CfgAsInput\r
383 )\r
384{\r
385 Pcal9555SetPortRegBit (\r
386 Pcal9555SlaveAddr,\r
387 GpioNum,\r
388 PCAL9555_REG_CFG_PORT0,\r
389 CfgAsInput\r
390 );\r
391}\r
392\r
393/**\r
394Set the level of Pcal9555 IO Expander GPIO high or low.\r
395\r
396@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
397@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
398for Port1.\r
399@param HighLevel If TRUE set pin high else set pin low.\r
400\r
401**/\r
402VOID\r
403EFIAPI\r
404PlatformPcal9555GpioSetLevel (\r
405 IN CONST UINT32 Pcal9555SlaveAddr,\r
406 IN CONST UINT32 GpioNum,\r
407 IN CONST BOOLEAN HighLevel\r
408 )\r
409{\r
410 Pcal9555SetPortRegBit (\r
411 Pcal9555SlaveAddr,\r
412 GpioNum,\r
413 PCAL9555_REG_OUT_PORT0,\r
414 HighLevel\r
415 );\r
416}\r
417\r
418/**\r
419\r
420Enable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
421\r
422@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
423@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
424for Port1.\r
425\r
426**/\r
427VOID\r
428EFIAPI\r
429PlatformPcal9555GpioEnablePull (\r
430 IN CONST UINT32 Pcal9555SlaveAddr,\r
431 IN CONST UINT32 GpioNum\r
432 )\r
433{\r
434 Pcal9555SetPortRegBit (\r
435 Pcal9555SlaveAddr,\r
436 GpioNum,\r
437 PCAL9555_REG_PULL_EN_PORT0,\r
438 TRUE\r
439 );\r
440}\r
441\r
442/**\r
443\r
444Disable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
445\r
446@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
447@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
448for Port1.\r
449\r
450**/\r
451VOID\r
452EFIAPI\r
453PlatformPcal9555GpioDisablePull (\r
454 IN CONST UINT32 Pcal9555SlaveAddr,\r
455 IN CONST UINT32 GpioNum\r
456 )\r
457{\r
458 Pcal9555SetPortRegBit (\r
459 Pcal9555SlaveAddr,\r
460 GpioNum,\r
461 PCAL9555_REG_PULL_EN_PORT0,\r
462 FALSE\r
463 );\r
464}\r
465\r
466/**\r
467\r
468Get state of Pcal9555 GPIOs.\r
469\r
470@param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
471@param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
472for Port1.\r
473\r
474@retval TRUE GPIO pin is high\r
475@retval FALSE GPIO pin is low\r
476**/\r
477BOOLEAN\r
478EFIAPI\r
479PlatformPcal9555GpioGetState (\r
480 IN CONST UINT32 Pcal9555SlaveAddr,\r
481 IN CONST UINT32 GpioNum\r
482 )\r
483{\r
484 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);\r
485}\r
486\r
487\r