1 /** @file
2 This file contains routines for GPIO native and chipset specific usage
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8 #include "GpioLibrary.h"
9
10 //
11 // Chipset specific data
12 //
13 //SerialIo
14 extern GPIO_PAD_NATIVE_FUNCTION mPchLpI2cGpio[PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER];
15 extern GPIO_PAD_NATIVE_FUNCTION mPchHI2cGpio[PCH_H_SERIALIO_MAX_I2C_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER];
16 extern GPIO_PAD_NATIVE_FUNCTION mPchLpUartGpio[PCH_SERIALIO_MAX_UART_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER];
17 extern GPIO_PAD_NATIVE_FUNCTION mPchHUartGpio[PCH_SERIALIO_MAX_UART_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER];
18 extern GPIO_PAD_NATIVE_FUNCTION mPchLpSpiGpio[PCH_SERIALIO_MAX_SPI_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER];
19 extern GPIO_PAD_NATIVE_FUNCTION mPchHSpiGpio[PCH_SERIALIO_MAX_SPI_CONTROLLERS][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER];
20
21 //SATA
22 extern GPIO_PAD_NATIVE_FUNCTION mPchLpSataPortResetToGpioMap[PCH_LP_AHCI_MAX_PORTS];
23 extern GPIO_PAD_NATIVE_FUNCTION mPchHSataPortResetToGpioMap[PCH_H_AHCI_MAX_PORTS];
24 extern GPIO_PAD_NATIVE_FUNCTION mPchLpSataDevSlpPinToGpioMap[PCH_LP_AHCI_MAX_PORTS];
25 extern GPIO_PAD_NATIVE_FUNCTION mPchHSataDevSlpPinToGpioMap[PCH_H_AHCI_MAX_PORTS];
26
27 //
28 // SKL specific
29 //
30 extern GPIO_GROUP_INFO mPchLpGpioGroupInfo[V_PCH_LP_GPIO_GROUP_MAX];
31 extern GPIO_GROUP_INFO mPchHGpioGroupInfo[V_PCH_H_GPIO_GROUP_MAX];
32
33 /**
34 This procedure will set GPIO mode
35
36 @param[in] GpioPad GPIO pad
37 @param[out] PadModeValue GPIO pad mode value
38
39 @retval EFI_SUCCESS The function completed successfully
40 @retval EFI_INVALID_PARAMETER Invalid group or pad number
41 **/
42 EFI_STATUS
SetGpioPadMode(IN GPIO_PAD GpioPad,IN GPIO_PAD_MODE PadModeValue)43 SetGpioPadMode (
44 IN GPIO_PAD GpioPad,
45 IN GPIO_PAD_MODE PadModeValue
46 )
47 {
48 UINT32 PadCfgOrMask;
49
50 if (!GpioIsPadValid (GpioPad)) {
51 ASSERT (FALSE);
52 return EFI_INVALID_PARAMETER;
53 }
54
55 if (!GpioIsPadHostOwned (GpioPad)) {
56 return EFI_UNSUPPORTED;
57 }
58
59 if (PadModeValue != (GPIO_PAD_MODE)GpioHardwareDefault) {
60
61 PadCfgOrMask = (((PadModeValue & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_PCH_GPIO_PAD_MODE);
62
63 GpioWritePadCfgReg (
64 GpioPad,
65 0,
66 (UINT32)~B_PCH_GPIO_PAD_MODE,
67 PadCfgOrMask
68 );
69 }
70
71 return EFI_SUCCESS;
72 }
73
74 /**
75 This procedure will get GPIO mode
76
77 @param[in] GpioPad GPIO pad
78 @param[out] PadModeValue GPIO pad mode value
79
80 @retval EFI_SUCCESS The function completed successfully
81 @retval EFI_INVALID_PARAMETER Invalid GpioPad
82 **/
83 EFI_STATUS
GetGpioPadMode(IN GPIO_PAD GpioPad,OUT GPIO_PAD_MODE * PadModeValue)84 GetGpioPadMode (
85 IN GPIO_PAD GpioPad,
86 OUT GPIO_PAD_MODE *PadModeValue
87 )
88 {
89 UINT32 PadCfgRegValue;
90
91 if (!GpioIsPadValid (GpioPad)) {
92 ASSERT (FALSE);
93 return EFI_INVALID_PARAMETER;
94 }
95
96 if (!GpioIsPadHostOwned (GpioPad)) {
97 return EFI_UNSUPPORTED;
98 }
99
100 GpioReadPadCfgReg (
101 GpioPad,
102 0,
103 &PadCfgRegValue
104 );
105
106 *PadModeValue = (GPIO_PAD_MODE)(((PadCfgRegValue & B_PCH_GPIO_PAD_MODE) >> (N_PCH_GPIO_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPIO_PAD_MODE_BIT_POS));
107
108 return EFI_SUCCESS;
109 }
110
111
112 /**
113 This procedure will retrieve address and length of GPIO info table
114
115 @param[out] GpioGroupInfoTableLength Length of GPIO group table
116
117 @retval Pointer to GPIO group table
118
119 **/
120 GPIO_GROUP_INFO*
GpioGetGroupInfoTable(OUT UINTN * GpioGroupInfoTableLength)121 GpioGetGroupInfoTable (
122 OUT UINTN *GpioGroupInfoTableLength
123 )
124 {
125 if (GetPchSeries () == PchLp) {
126 *GpioGroupInfoTableLength = sizeof (mPchLpGpioGroupInfo) / sizeof (GPIO_GROUP_INFO);
127 return mPchLpGpioGroupInfo;
128 } else {
129 *GpioGroupInfoTableLength = sizeof (mPchHGpioGroupInfo) / sizeof (GPIO_GROUP_INFO);
130 return mPchHGpioGroupInfo;
131 }
132 }
133
134
135 /**
136 This procedure is used to check if GpioPad is valid for certain chipset
137
138 @param[in] GpioPad GPIO pad
139
140 @retval TRUE This pin is valid on this chipset
141 FALSE Incorrect pin
142 **/
143 BOOLEAN
GpioIsCorrectPadForThisChipset(IN GPIO_PAD GpioPad)144 GpioIsCorrectPadForThisChipset (
145 IN GPIO_PAD GpioPad
146 )
147 {
148 PCH_SERIES PchSeries;
149
150 PchSeries = GetPchSeries ();
151
152 if ((PchSeries == PchH) && (GPIO_GET_CHIPSET_ID (GpioPad) == GPIO_SKL_H_CHIPSET_ID)) {
153 return TRUE;
154 } else if ((PchSeries == PchLp) && (GPIO_GET_CHIPSET_ID (GpioPad) == GPIO_SKL_LP_CHIPSET_ID)) {
155 return TRUE;
156 }
157
158 return FALSE;
159 }
160
161
162 /**
163 This procedure will get number of pads for certain GPIO group
164
165 @param[in] Group GPIO group number
166
167 @retval Value Pad number for group
168 If illegal group number then return 0
169 **/
170 UINT32
GpioGetPadPerGroup(IN GPIO_GROUP Group)171 GpioGetPadPerGroup (
172 IN GPIO_GROUP Group
173 )
174 {
175 GPIO_GROUP_INFO *GpioGroupInfo;
176 UINTN GpioGroupInfoLength;
177 UINT32 GroupIndex;
178 //
179 // Check if group argument exceeds GPIO GROUP INFO array
180 //
181 GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
182 GroupIndex = GpioGetGroupIndexFromGroup (Group);
183
184 if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
185 ASSERT (FALSE);
186 return 0;
187 } else {
188 return GpioGroupInfo[GroupIndex].PadPerGroup;
189 }
190 }
191
192 /**
193 This procedure will get number of groups
194
195 @param[in] none
196
197 @retval Value Group number
198 **/
199 UINT8
GpioGetNumberOfGroups(VOID)200 GpioGetNumberOfGroups (
201 VOID
202 )
203 {
204 if (GetPchSeries () == PchLp) {
205 return V_PCH_LP_GPIO_GROUP_MAX;
206 } else {
207 return V_PCH_H_GPIO_GROUP_MAX;
208 }
209 }
210 /**
211 This procedure will get lowest group
212
213 @param[in] none
214
215 @retval Value Lowest Group
216 **/
217 GPIO_GROUP
GpioGetLowestGroup(VOID)218 GpioGetLowestGroup (
219 VOID
220 )
221 {
222 if (GetPchSeries () == PchLp) {
223 return (UINT32) GPIO_SKL_LP_GROUP_GPP_A;
224 } else {
225 return (UINT32) GPIO_SKL_H_GROUP_GPP_A;
226 }
227 }
228 /**
229 This procedure will get highest group
230
231 @param[in] none
232
233 @retval Value Highest Group
234 **/
235 GPIO_GROUP
GpioGetHighestGroup(VOID)236 GpioGetHighestGroup (
237 VOID
238 )
239 {
240 if (GetPchSeries () == PchLp) {
241 return (UINT32) GPIO_SKL_LP_GROUP_GPD;
242 } else {
243 return (UINT32) GPIO_SKL_H_GROUP_GPD;
244 }
245 }
246
247 /**
248 This procedure will get group number
249
250 @param[in] GpioPad Gpio Pad
251
252 @retval Value Group number
253 **/
254 GPIO_GROUP
GpioGetGroupFromGpioPad(IN GPIO_PAD GpioPad)255 GpioGetGroupFromGpioPad (
256 IN GPIO_PAD GpioPad
257 )
258 {
259 return GPIO_GET_GROUP_FROM_PAD (GpioPad);
260 }
261
262 /**
263 This procedure will get group index (0 based)
264
265 @param[in] GpioPad Gpio Pad
266
267 @retval Value Group Index
268 **/
269 UINT32
GpioGetGroupIndexFromGpioPad(IN GPIO_PAD GpioPad)270 GpioGetGroupIndexFromGpioPad (
271 IN GPIO_PAD GpioPad
272 )
273 {
274 return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad);
275 }
276
277 /**
278 This procedure will get group index (0 based) from group
279
280 @param[in] GpioGroup Gpio Group
281
282 @retval Value Group Index
283 **/
284 UINT32
GpioGetGroupIndexFromGroup(IN GPIO_GROUP GpioGroup)285 GpioGetGroupIndexFromGroup (
286 IN GPIO_GROUP GpioGroup
287 )
288 {
289 return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup);
290 }
291
292 /**
293 This procedure will get pad number (0 based) from Gpio Pad
294
295 @param[in] GpioPad Gpio Pad
296
297 @retval Value Pad Number
298 **/
299 UINT32
GpioGetPadNumberFromGpioPad(IN GPIO_PAD GpioPad)300 GpioGetPadNumberFromGpioPad (
301 IN GPIO_PAD GpioPad
302 )
303 {
304 return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad);
305 }
306 /**
307 This procedure will return GpioPad from Group and PadNumber
308
309 @param[in] Group GPIO group
310 @param[in] PadNumber GPIO PadNumber
311
312 @retval GpioPad GpioPad
313 **/
314 GPIO_PAD
GpioGetGpioPadFromGroupAndPadNumber(IN GPIO_GROUP Group,IN UINT32 PadNumber)315 GpioGetGpioPadFromGroupAndPadNumber (
316 IN GPIO_GROUP Group,
317 IN UINT32 PadNumber
318 )
319 {
320 if (GetPchSeries () == PchLp) {
321 return GPIO_PAD_DEF (Group,PadNumber);
322 } else {
323 return GPIO_PAD_DEF (Group,PadNumber);
324 }
325 }
326
327 /**
328 This procedure will return GpioPad from GroupIndex and PadNumber
329
330 @param[in] GroupIndex GPIO GroupIndex
331 @param[in] PadNumber GPIO PadNumber
332
333 @retval GpioPad GpioPad
334 **/
335 GPIO_PAD
GpioGetGpioPadFromGroupIndexAndPadNumber(IN UINT32 GroupIndex,IN UINT32 PadNumber)336 GpioGetGpioPadFromGroupIndexAndPadNumber (
337 IN UINT32 GroupIndex,
338 IN UINT32 PadNumber
339 )
340 {
341 GPIO_GROUP Group;
342
343 if (GetPchSeries () == PchLp) {
344 Group = GPIO_GROUP_DEF (GroupIndex, GPIO_SKL_LP_CHIPSET_ID);
345 return GPIO_PAD_DEF (Group,PadNumber);
346 } else {
347 Group = GPIO_GROUP_DEF (GroupIndex, GPIO_SKL_H_CHIPSET_ID);
348 return GPIO_PAD_DEF (Group,PadNumber);
349 }
350 }
351
352
353 /**
354 This function sets SerialIo I2C controller pins into native mode
355
356 @param[in] SerialIoI2cControllerNumber I2C controller
357
358 @retval Status
359 **/
360 EFI_STATUS
GpioSetSerialIoI2cPinsIntoNativeMode(IN UINT32 SerialIoI2cControllerNumber)361 GpioSetSerialIoI2cPinsIntoNativeMode (
362 IN UINT32 SerialIoI2cControllerNumber
363 )
364 {
365 EFI_STATUS Status;
366 UINTN Index;
367 GPIO_PAD_NATIVE_FUNCTION (*I2cGpio) [PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER];
368
369 Status = EFI_SUCCESS;
370
371 if (GetPchSeries () == PchLp) {
372 ASSERT (SerialIoI2cControllerNumber < PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS);
373 I2cGpio = mPchLpI2cGpio;
374 } else {
375 ASSERT (SerialIoI2cControllerNumber < PCH_H_SERIALIO_MAX_I2C_CONTROLLERS);
376 I2cGpio = mPchHI2cGpio;
377 }
378
379 for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++) {
380 Status = SetGpioPadMode (I2cGpio[SerialIoI2cControllerNumber][Index].Pad, I2cGpio[SerialIoI2cControllerNumber][Index].Mode);
381 if (EFI_ERROR (Status)) {
382 return EFI_UNSUPPORTED;
383 }
384 GpioSetInputInversion (I2cGpio[SerialIoI2cControllerNumber][Index].Pad, 0);
385 }
386 return Status;
387 }
388
389 /**
390 This function sets SerialIo I2C controller pins tolerance
391
392 @param[in] SerialIoI2CControllerNumber I2C controller
393 @param[in] Pad1v8Tolerance TRUE: Enable 1v8 Pad tolerance
394 FALSE: Disable 1v8 Pad tolerance
395
396 @retval Status
397 **/
398 EFI_STATUS
GpioSetSerialIoI2CPinsTolerance(IN UINT32 SerialIoI2cControllerNumber,IN BOOLEAN Pad1v8Tolerance)399 GpioSetSerialIoI2CPinsTolerance (
400 IN UINT32 SerialIoI2cControllerNumber,
401 IN BOOLEAN Pad1v8Tolerance
402 )
403 {
404 EFI_STATUS Status;
405 UINTN Index;
406 GPIO_PAD_OWN PadOwnership;
407 GPIO_PAD_NATIVE_FUNCTION (*I2cGpio) [PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER];
408 GPIO_CONFIG GpioData;
409
410 Status = EFI_SUCCESS;
411
412 if (GetPchSeries () == PchLp) {
413 ASSERT (SerialIoI2cControllerNumber < PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS);
414 I2cGpio = mPchLpI2cGpio;
415 } else {
416 ASSERT (SerialIoI2cControllerNumber < PCH_H_SERIALIO_MAX_I2C_CONTROLLERS);
417 I2cGpio = mPchHI2cGpio;
418 }
419
420 ZeroMem (&GpioData, sizeof (GPIO_CONFIG));
421 if (Pad1v8Tolerance) {
422 GpioData.ElectricalConfig = GpioTolerance1v8;
423 } else {
424 GpioData.ElectricalConfig = GpioNoTolerance1v8;
425 }
426 for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++) {
427 GpioGetPadOwnership (I2cGpio[SerialIoI2cControllerNumber][Index].Pad , &PadOwnership);
428 if (PadOwnership == GpioPadOwnHost) {
429 Status = GpioSetPadConfig (I2cGpio[SerialIoI2cControllerNumber][Index].Pad, &GpioData);
430 } else {
431 return EFI_UNSUPPORTED;
432 }
433 }
434 return Status;
435 }
436
437
438 /**
439 This function sets SerialIo UART controller pins into native mode
440
441 @param[in] SerialIoI2CControllerNumber UART controller
442 @param[in] HardwareFlowControl Hardware Flow control
443
444 @retval Status
445 **/
446 EFI_STATUS
GpioSetSerialIoUartPinsIntoNativeMode(IN UINT32 SerialIoUartControllerNumber,IN BOOLEAN HardwareFlowControl)447 GpioSetSerialIoUartPinsIntoNativeMode (
448 IN UINT32 SerialIoUartControllerNumber,
449 IN BOOLEAN HardwareFlowControl
450 )
451 {
452 EFI_STATUS Status;
453 UINTN Index;
454 UINTN PinsUsed;
455 GPIO_PAD_NATIVE_FUNCTION (*UartGpio) [PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER];
456
457 Status = EFI_SUCCESS;
458
459 ASSERT (SerialIoUartControllerNumber < PCH_SERIALIO_MAX_UART_CONTROLLERS);
460
461 if (GetPchSeries () == PchLp) {
462 UartGpio = mPchLpUartGpio;
463 } else {
464 UartGpio = mPchHUartGpio;
465 }
466
467 if (HardwareFlowControl) {
468 PinsUsed = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER;
469 } else {
470 PinsUsed = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL;
471 }
472
473 for (Index = 0; Index < PinsUsed; Index++) {
474 Status = SetGpioPadMode (UartGpio[SerialIoUartControllerNumber][Index].Pad, UartGpio[SerialIoUartControllerNumber][Index].Mode);
475 if (EFI_ERROR (Status)) {
476 return EFI_UNSUPPORTED;
477 }
478 GpioSetInputInversion (UartGpio[SerialIoUartControllerNumber][Index].Pad, 0);
479 }
480 return Status;
481 }
482
483 /**
484 This function sets SerialIo SPI controller pins into native mode
485
486 @param[in] SerialIoI2CControllerNumber SPI controller
487
488 @retval Status
489 **/
490 EFI_STATUS
GpioSetSerialIoSpiPinsIntoNativeMode(IN UINT32 SerialIoSpiControllerNumber)491 GpioSetSerialIoSpiPinsIntoNativeMode (
492 IN UINT32 SerialIoSpiControllerNumber
493 )
494 {
495 EFI_STATUS Status;
496 UINTN Index;
497 GPIO_PAD_NATIVE_FUNCTION (*SpiGpio) [PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER];
498
499 Status = EFI_SUCCESS;
500
501 ASSERT (SerialIoSpiControllerNumber < PCH_SERIALIO_MAX_SPI_CONTROLLERS);
502
503 if (GetPchSeries () == PchLp) {
504 SpiGpio = mPchLpSpiGpio;
505 } else {
506 SpiGpio = mPchHSpiGpio;
507 }
508
509 for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER; Index++) {
510 Status = SetGpioPadMode (SpiGpio[SerialIoSpiControllerNumber][Index].Pad, SpiGpio[SerialIoSpiControllerNumber][Index].Mode);
511 if (EFI_ERROR (Status)) {
512 return EFI_UNSUPPORTED;
513 }
514 GpioSetInputInversion (SpiGpio[SerialIoSpiControllerNumber][Index].Pad, 0);
515 }
516 return Status;
517 }
518
519
520 /**
521 This function checks if GPIO pin is a GSPI chip select pin
522
523 @param[in] GpioPad GPIO pad
524 @param[in] PadMode GPIO pad mode
525
526 @retval TRUE Pin is in GPIO mode
527 FALSE Pin is in native mode
528 **/
529 BOOLEAN
GpioIsGpioPadAGSpiCsbPin(IN GPIO_PAD GpioPad,IN GPIO_PAD_MODE PadMode)530 GpioIsGpioPadAGSpiCsbPin (
531 IN GPIO_PAD GpioPad,
532 IN GPIO_PAD_MODE PadMode
533 )
534 {
535 UINT32 ControllerMax;
536 UINT32 ControllerIndex;
537 GPIO_PAD_OWN PadOwnership;
538 GPIO_PAD_NATIVE_FUNCTION (*SpiGpio) [PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER];
539
540 if (GetPchSeries () == PchLp) {
541 SpiGpio = mPchLpSpiGpio;
542 ControllerMax = sizeof (mPchLpSpiGpio) / sizeof (GPIO_PAD_NATIVE_FUNCTION) / PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER;
543 } else {
544 SpiGpio = mPchHSpiGpio;
545 ControllerMax = sizeof (mPchHSpiGpio) / sizeof (GPIO_PAD_NATIVE_FUNCTION) / PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER;
546 }
547
548 for (ControllerIndex = 0; ControllerIndex < ControllerMax; ControllerIndex++) {
549 if ((GpioPad == SpiGpio[ControllerIndex][0].Pad) &&
550 (PadMode == SpiGpio[ControllerIndex][0].Mode)) {
551 GpioGetPadOwnership (SpiGpio[ControllerIndex][0].Pad , &PadOwnership);
552 if (PadOwnership == GpioPadOwnHost) {
553 return TRUE;
554 } else {
555 return FALSE;
556 }
557 }
558 }
559 return FALSE;
560 }
561
562 /**
563 This function checks if GPIO pin for SATA reset port is in GPIO MODE
564
565 @param[in] SataPort SATA port number
566
567 @retval TRUE Pin is in GPIO mode
568 FALSE Pin is in native mode
569 **/
570 BOOLEAN
GpioIsSataResetPortInGpioMode(IN UINTN SataPort)571 GpioIsSataResetPortInGpioMode (
572 IN UINTN SataPort
573 )
574 {
575 EFI_STATUS Status;
576 UINT32 GpioPin;
577 GPIO_PAD_MODE GpioMode;
578
579
580 if (GetPchSeries () == PchLp) {
581 ASSERT (SataPort < PCH_LP_AHCI_MAX_PORTS);
582 GpioPin = mPchLpSataPortResetToGpioMap[SataPort].Pad;
583 } else {
584 ASSERT (SataPort < PCH_H_AHCI_MAX_PORTS);
585 GpioPin = mPchHSataPortResetToGpioMap[SataPort].Pad;
586 }
587
588 Status = GetGpioPadMode (GpioPin, &GpioMode);
589 if ((EFI_ERROR (Status)) || (GpioMode != GpioPadModeGpio)) {
590 return FALSE;
591 } else {
592 return TRUE;
593 }
594 }
595
596
597 /**
598 This function checks if GPIO pin is a SataDevSlp pin
599
600 @param[in] GpioPad GPIO pad
601 @param[in] PadMode GPIO pad mode
602
603 @retval TRUE Pin is in GPIO mode
604 FALSE Pin is in native mode
605 **/
606 BOOLEAN
GpioIsPadASataDevSlpPin(IN GPIO_PAD GpioPad,IN GPIO_PAD_MODE PadMode)607 GpioIsPadASataDevSlpPin (
608 IN GPIO_PAD GpioPad,
609 IN GPIO_PAD_MODE PadMode
610 )
611 {
612 UINT32 SataDevSlpPinMax;
613 UINT32 SataDevSlpPinIndex;
614 GPIO_PAD_OWN PadOwnership;
615 GPIO_PAD_NATIVE_FUNCTION *SataDevSlpPinToGpioMap;
616
617 if (GetPchSeries () == PchLp) {
618 SataDevSlpPinToGpioMap = mPchLpSataDevSlpPinToGpioMap;
619 SataDevSlpPinMax = sizeof (mPchLpSataDevSlpPinToGpioMap) /sizeof (GPIO_PAD_NATIVE_FUNCTION);
620 } else {
621 SataDevSlpPinToGpioMap = mPchHSataDevSlpPinToGpioMap;
622 SataDevSlpPinMax = sizeof (mPchHSataDevSlpPinToGpioMap) /sizeof (GPIO_PAD_NATIVE_FUNCTION);
623 }
624
625 for (SataDevSlpPinIndex = 0; SataDevSlpPinIndex < SataDevSlpPinMax; SataDevSlpPinIndex++) {
626 if ((GpioPad == SataDevSlpPinToGpioMap[SataDevSlpPinIndex].Pad) &&
627 (PadMode == SataDevSlpPinToGpioMap[SataDevSlpPinIndex].Mode)) {
628 GpioGetPadOwnership (SataDevSlpPinToGpioMap[SataDevSlpPinIndex].Pad , &PadOwnership);
629 if (PadOwnership == GpioPadOwnHost) {
630 return TRUE;
631 } else {
632 return FALSE;
633 }
634 }
635 }
636 return FALSE;
637 }
638
639 /**
640 This function checks if SataDevSlp pin is in native mode
641
642 @param[in] SataPort SATA port
643 @param[out] DevSlpPad DevSlpPad
644
645 @retval TRUE DevSlp is in native mode
646 FALSE DevSlp is not in native mode
647 **/
648 BOOLEAN
GpioIsSataDevSlpPinEnabled(IN UINTN SataPort,OUT GPIO_PAD * DevSlpPad)649 GpioIsSataDevSlpPinEnabled (
650 IN UINTN SataPort,
651 OUT GPIO_PAD *DevSlpPad
652 )
653 {
654 GPIO_PAD_MODE DevSlpPadMode;
655 GPIO_PAD DevSlpGpioPad;
656 GPIO_PAD_MODE GpioMode;
657 EFI_STATUS Status;
658
659 if (GetPchSeries () == PchLp) {
660 ASSERT (SataPort < PCH_LP_AHCI_MAX_PORTS);
661 DevSlpGpioPad = mPchLpSataDevSlpPinToGpioMap[SataPort].Pad;
662 DevSlpPadMode = mPchLpSataDevSlpPinToGpioMap[SataPort].Mode;
663 } else {
664 ASSERT (SataPort < PCH_H_AHCI_MAX_PORTS);
665 DevSlpGpioPad = mPchHSataDevSlpPinToGpioMap[SataPort].Pad;
666 DevSlpPadMode = mPchHSataDevSlpPinToGpioMap[SataPort].Mode;
667 }
668
669 Status = GetGpioPadMode (DevSlpGpioPad, &GpioMode);
670
671 if (EFI_ERROR (Status) || (GpioMode != DevSlpPadMode)) {
672 *DevSlpPad = 0x0;
673 return FALSE;
674 } else {
675 *DevSlpPad = DevSlpGpioPad;
676 return TRUE;
677 }
678 }
679
680