1 /** @file
2   Header file for GPIO Lib implementation.
3 
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 #ifndef _GPIO_LIBRARY_H_
9 #define _GPIO_LIBRARY_H_
10 
11 #include <Base.h>
12 #include <Uefi/UefiBaseType.h>
13 #include <Library/IoLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <PchAccess.h>
17 #include <GpioPinsSklLp.h>
18 #include <GpioPinsSklH.h>
19 #include <Library/GpioLib.h>
20 #include <Library/GpioNativeLib.h>
21 #include <Library/MmPciLib.h>
22 #include <Library/PchInfoLib.h>
23 #include <Library/PchCycleDecodingLib.h>
24 #include <Library/PchSbiAccessLib.h>
25 
26 typedef struct {
27   GPIO_PAD       Pad;
28   GPIO_PAD_MODE  Mode;
29 } GPIO_PAD_NATIVE_FUNCTION;
30 
31 
32 // BIT15-0  - pad number
33 // BIT31-16 - group info
34 //   BIT23- 16 - group index
35 //   BIT31- 24 - chipset ID
36 #define PAD_INFO_MASK          0x0000FFFF
37 #define GROUP_INFO_POSITION    16
38 #define GROUP_INFO_MASK        0xFFFF0000
39 #define GROUP_INDEX_MASK       0x00FF0000
40 #define UNIQUE_ID_MASK         0xFF000000
41 #define UNIQUE_ID_POSITION     24
42 
43 #define GPIO_PAD_DEF(Group,Pad)               (UINT32)(((Group) << 16) + (Pad))
44 #define GPIO_GROUP_DEF(Index,ChipsetId)       ((Index) | ((ChipsetId) << 8))
45 #define GPIO_GET_GROUP_INDEX(Group)           ((Group) & 0xFF)
46 #define GPIO_GET_GROUP_FROM_PAD(Pad)          ((Pad) >> 16)
47 #define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad)    GPIO_GET_GROUP_INDEX (((Pad) >> 16))
48 #define GPIO_GET_PAD_NUMBER(Pad)              ((Pad) & 0xFFFF)
49 #define GPIO_GET_CHIPSET_ID(Pad)              ((Pad) >> 24)
50 
51 #define GPIO_GET_PAD_POSITION(PadNumber)      ((PadNumber) % 32)
52 #define GPIO_GET_DW_NUM(PadNumber)            ((PadNumber) / 32)
53 
54 //
55 // Unique ID used in GpioPad defines
56 //
57 #define GPIO_SKL_H_CHIPSET_ID       0x1
58 #define GPIO_SKL_LP_CHIPSET_ID      0x2
59 
60 //
61 // Below defines are based on GPIO_CONFIG structure fields
62 //
63 #define B_GPIO_PAD_MODE_MASK                            0xF
64 #define N_GPIO_PAD_MODE_BIT_POS                         0
65 #define B_GPIO_HOSTSW_OWN_MASK                          0x3
66 #define N_GPIO_HOSTSW_OWN_BIT_POS                       0
67 #define B_GPIO_DIRECTION_MASK                           0x1F
68 #define B_GPIO_DIRECTION_DIR_MASK                       0x7
69 #define N_GPIO_DIRECTION_DIR_BIT_POS                    0
70 #define B_GPIO_DIRECTION_INV_MASK                       0x18
71 #define N_GPIO_DIRECTION_INV_BIT_POS                    3
72 #define B_GPIO_OUTPUT_MASK                              0x3
73 #define N_GPIO_OUTPUT_BIT_POS                           0
74 #define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS            0
75 #define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS              5
76 #define B_GPIO_RESET_CONFIG_RESET_MASK                  0x3F
77 #define N_GPIO_RESET_CONFIG_OLD_RESET_TYPE              BIT1
78 #define B_GPIO_RESET_CONFIG_OLD_RESET_MASK              0xF
79 #define N_GPIO_RESET_CONFIG_RESET_BIT_POS               0
80 #define B_GPIO_RESET_CONFIG_GPD_RESET_MASK              (BIT5 | BIT4)
81 #define B_GPIO_RESET_CONFIG_GPP_RESET_MASK              (BIT3 | BIT2)
82 #define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS    0
83 #define N_GPIO_ELECTRICAL_CONFIG_1V8_TOLERANCE_BIT_POS  5
84 #define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS               0
85 
86 //
87 // Structure for storing information about registers offset, community,
88 // maximal pad number for available groups
89 //
90 typedef struct {
91   PCH_SBI_PID  Community;
92   UINT32       PadOwnOffset;
93   UINT32       HostOwnOffset;
94   UINT32       GpiIsOffset;
95   UINT32       GpiIeOffset;
96   UINT32       GpiGpeStsOffset;
97   UINT32       GpiGpeEnOffset;
98   UINT32       SmiStsOffset;
99   UINT32       SmiEnOffset;
100   UINT32       NmiStsOffset;
101   UINT32       NmiEnOffset;
102   UINT32       PadCfgLockOffset;
103   UINT32       PadCfgLockTxOffset;
104   UINT32       PadCfgOffset;
105   UINT32       PadPerGroup;
106 } GPIO_GROUP_INFO;
107 
108 //
109 // If in GPIO_GROUP_INFO structure certain register doesn't exist
110 // it will have value equal to NO_REGISTER_FOR_PROPERTY
111 //
112 #define NO_REGISTER_FOR_PROPERTY (~0u)
113 
114 //
115 // PADCFG register is split into multiple DW registers
116 // PAD_CFG_SIZE holds number of bytes used by all those registers for one pad
117 //
118 #define PAD_CFG_SIZE 0x08
119 
120 /**
121   This procedure is used to check if GpioPad is valid for certain chipset
122 
123   @param[in]  GpioPad             GPIO pad
124 
125   @retval TRUE                    This pin is valid on this chipset
126           FALSE                   Incorrect pin
127 **/
128 BOOLEAN
129 GpioIsCorrectPadForThisChipset (
130   IN  GPIO_PAD        GpioPad
131   );
132 
133 
134 /**
135   This procedure will retrieve address and length of GPIO info table
136 
137   @param[out]  GpioGroupInfoTableLength   Length of GPIO group table
138 
139   @retval Pointer to GPIO group table
140 
141 **/
142 GPIO_GROUP_INFO*
143 GpioGetGroupInfoTable (
144   OUT UINTN               *GpioGroupInfoTableLength
145   );
146 
147 /**
148   This procedure will check if GpioPad is owned by host.
149 
150   @param[in] GpioPad       GPIO pad
151 
152   @retval TRUE             GPIO pad is owned by host
153   @retval FALSE            GPIO pad is not owned by host and should not be used with GPIO lib API
154 **/
155 BOOLEAN
156 GpioIsPadHostOwned (
157   IN GPIO_PAD             GpioPad
158   );
159 
160 /**
161   This procedure will check if GpioPad argument is valid.
162   Function will check below conditions:
163    - GpioPad represents a pad for current PCH
164    - GpioPad belongs to valid GpioGroup
165    - GPIO PadNumber is not greater than number of pads for this group
166 
167   @param[in] GpioPad       GPIO pad
168 
169   @retval TRUE             GPIO pad is valid and can be used with GPIO lib API
170   @retval FALSE            GPIO pad is invalid and cannot be used with GPIO lib API
171 **/
172 BOOLEAN
173 GpioIsPadValid (
174   IN GPIO_PAD             GpioPad
175   );
176 
177 /**
178   This procedure will write or read GPIO Pad Configuration register
179 
180   @param[in] GpioPad              GPIO pad
181   @param[in] DwReg                Choose PADCFG register: 0:DW0, 1:DW1
182   @param[out] PadCfgRegValue      Read data
183 
184   @retval none
185 **/
186 VOID
187 GpioReadPadCfgReg (
188   IN GPIO_PAD             GpioPad,
189   IN UINT8                DwReg,
190   OUT UINT32              *PadCfgRegValue
191   );
192 
193 /**
194   This procedure will write or read GPIO Pad Configuration register
195 
196   @param[in] GpioPad              GPIO pad
197   @param[in] DwReg                Choose PADCFG register: 0:DW0, 1:DW1
198   @param[in] PadCfgAndMask        Mask to be AND'ed with PADCFG reg value
199   @param[in] PadCfgOrMask         Mask to be OR'ed with PADCFG reg value
200 
201   @retval none
202 **/
203 VOID
204 GpioWritePadCfgReg (
205   IN GPIO_PAD             GpioPad,
206   IN UINT8                DwReg,
207   IN UINT32               PadCfgAndMask,
208   IN UINT32               PadCfgOrMask
209   );
210 
211 /**
212   This procedure will set GPIO mode
213 
214   @param[in]  GpioPad             GPIO pad
215   @param[out] PadModeValue        GPIO pad mode value
216 
217   @retval EFI_SUCCESS             The function completed successfully
218   @retval EFI_INVALID_PARAMETER   Invalid group or pad number
219 **/
220 EFI_STATUS
221 SetGpioPadMode (
222   IN GPIO_PAD                GpioPad,
223   IN GPIO_PAD_MODE           PadModeValue
224   );
225 
226 /**
227   This procedure will get GPIO mode
228 
229   @param[in]  GpioPad             GPIO pad
230   @param[out] PadModeValue        GPIO pad mode value
231 
232   @retval EFI_SUCCESS             The function completed successfully
233   @retval EFI_INVALID_PARAMETER   Invalid group or pad number
234 **/
235 EFI_STATUS
236 GetGpioPadMode (
237   IN  GPIO_PAD                 GpioPad,
238   OUT GPIO_PAD_MODE            *PadModeValue
239   );
240 
241 /**
242   This function checks if GPIO pin is a GSPI chip select pin
243 
244   @param[in]  GpioPad             GPIO pad
245   @param[in]  PadMode             GPIO pad mode
246 
247   @retval TRUE                    Pin is in GPIO mode
248           FALSE                   Pin is in native mode
249 **/
250 BOOLEAN
251 GpioIsGpioPadAGSpiCsbPin (
252   IN  GPIO_PAD        GpioPad,
253   IN  GPIO_PAD_MODE   PadMode
254   );
255 
256 /**
257   This function checks if GPIO pin is a SataDevSlp pin
258 
259   @param[in]  GpioPad             GPIO pad
260   @param[in]  PadMode             GPIO pad mode
261 
262   @retval TRUE                    Pin is in GPIO mode
263           FALSE                   Pin is in native mode
264 **/
265 BOOLEAN
266 GpioIsPadASataDevSlpPin (
267   IN  GPIO_PAD        GpioPad,
268   IN  GPIO_PAD_MODE   PadMode
269   );
270 
271 /**
272   This internal procedure will calculate GPIO_RESET_CONFIG value  (new type)
273   based on provided PadRstCfg for a specific GPIO Pad.
274 
275   @param[in]  GpioPad               GPIO Pad
276   @param[in]  PadRstCfg             GPIO PadRstCfg value
277 
278   @retval GpioResetConfig           GPIO Reset configuration (new type)
279 **/
280 GPIO_RESET_CONFIG
281 GpioResetConfigFromPadRstCfg (
282   IN  GPIO_PAD           GpioPad,
283   IN  UINT32             PadRstCfg
284   );
285 
286 /**
287   This internal procedure will calculate PadRstCfg register value based
288   on provided GPIO Reset configuration for a certain pad.
289 
290   @param[in]  GpioPad                   GPIO Pad
291   @param[in]  GpioResetConfig           GPIO Reset configuration
292   @param[out] PadRstCfg                 GPIO PadRstCfg value
293 
294   @retval EFI_SUCCESS                   The function completed successfully
295   @retval EFI_INVALID_PARAMETER         Invalid configuration
296 **/
297 EFI_STATUS
298 GpioPadRstCfgFromResetConfig (
299   IN  GPIO_PAD           GpioPad,
300   IN  GPIO_RESET_CONFIG  GpioResetConfig,
301   OUT UINT32             *PadRstCfg
302   );
303 
304 /**
305   This procedure will calculate PADCFG register value based on GpioConfig data
306 
307   @param[in]  GpioPad                   GPIO Pad
308   @param[in]  GpioConfig                GPIO Configuration data
309   @param[out] PadCfgDwReg               PADCFG DWx register value
310   @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
311 
312   @retval Status
313 **/
314 EFI_STATUS
315 GpioPadCfgRegValueFromGpioConfig (
316   IN  GPIO_PAD           GpioPad,
317   IN  CONST GPIO_CONFIG  *GpioConfig,
318   OUT UINT32             *PadCfgDwReg,
319   OUT UINT32             *PadCfgDwRegMask
320   );
321 #endif // _GPIO_LIBRARY_H_
322