blob: 05260bfe16ed9a884aa4395c027d86af6726c93f [file] [log] [blame]
Angel Pons80d92382020-04-05 15:47:00 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Mariusz Szafranskia4041332017-08-02 17:28:17 +02002
3#include <stdint.h>
4#include <string.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +02006#include <console/console.h>
7#include <device/device.h>
8#include <device/pci.h>
9
10#include <soc/iomap.h>
11#include <soc/pcr.h>
12#include <soc/soc_util.h>
Julien Viard de Galbert7ebb6b02018-03-01 16:03:31 +010013#include <soc/gpio_dnv.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020014
15// Community PadOwnOffset HostOwnOffset
16// GpiIsOffset
17// GpiIeOffset GpiGpeStsOffset GpiGpeEnOffset
18// SmiStsOffset
19// SmiEnOffset NmiStsOffset NmiEnOffset
20// PadCfgLockOffset
21// PadCfgLockTxOffset PadCfgOffset PadPerGroup
22static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = {
23 {PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN,
24 R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE,
25 R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN,
26 R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN,
27 R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN,
28 R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX,
29 R_PCH_PCR_GPIO_NC_PADCFG_OFFSET,
30 V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL
31 {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN,
32 R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS,
33 R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS,
34 R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,
35 NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY,
36 NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK,
37 R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX,
38 R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET,
39 V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX
40 {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN,
41 R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS,
42 R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS,
43 R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS,
44 R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS,
45 R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK,
46 R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET,
47 V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0
48 {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN,
49 R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS,
50 R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS,
51 R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS,
52 R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS,
53 R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK,
54 R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET,
55 V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1
56};
57
58/* Retrieve address and length of GPIO info table */
59static struct GPIO_GROUP_INFO *
60GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength)
61{
Patrick Georgi6b688f52021-02-12 13:49:11 +010062 *GpioGroupInfoTableLength = ARRAY_SIZE(mGpioGroupInfo);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020063 return (struct GPIO_GROUP_INFO *)mGpioGroupInfo;
64}
65
66/* Get Gpio Pad Ownership */
67static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal)
68{
69 uint32_t Mask;
70 uint32_t RegOffset;
71 uint32_t GroupIndex;
72 uint32_t PadNumber;
73 struct GPIO_GROUP_INFO *GpioGroupInfo;
74 uint32_t GpioGroupInfoLength;
75 uint32_t PadOwnRegValue;
76
77 GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad);
78 PadNumber = GPIO_GET_PAD_NUMBER(GpioPad);
79
80 GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);
81
82 //
83 // Check if group argument exceeds GPIO GROUP INFO array
84 //
85 if ((uint32_t)GroupIndex >= GpioGroupInfoLength) {
86 printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO "
87 "group range\n",
88 GroupIndex);
89 return;
90 }
91
92 //
93 // Check if legal pin number
94 //
95 if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
96 printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible "
97 "range for this group\n",
98 PadNumber);
99 return;
100 }
101 //
102 // Calculate RegOffset using Pad Ownership offset and GPIO Pad number.
103 // One DWord register contains information for 8 pads.
104 //
105 RegOffset =
106 GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4;
107
108 //
109 // Calculate pad bit position within DWord register
110 //
111 PadNumber %= 8;
112 Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4);
113
114 PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS(
115 GpioGroupInfo[GroupIndex].Community, RegOffset));
116
117 *PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4));
118}
119
Julien Viard de Galbert7ebb6b02018-03-01 16:03:31 +0100120void gpio_configure_dnv_pads(const struct dnv_pad_config *gpio, size_t num)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200121{
122 /* Return if gpio not valid */
123 if ((gpio == NULL) || (num == 0))
124 return;
125
126 uint32_t Index;
127 uint32_t Dw0Reg;
128 uint32_t Dw0RegMask;
129 uint32_t Dw1Reg;
130 uint32_t Dw1RegMask;
131 uint32_t PadCfgReg;
132 uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX];
133 uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX];
134 uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX];
135 uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX];
136 struct GPIO_GROUP_INFO *GpioGroupInfo;
137 uint32_t GpioGroupInfoLength;
138 GPIO_PAD GpioGroupOffset;
139 uint32_t NumberOfGroups;
140 GPIO_PAD_OWN PadOwnVal;
Julien Viard de Galbert7ebb6b02018-03-01 16:03:31 +0100141 struct dnv_pad_config *GpioData;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200142 GPIO_PAD Group;
143 uint32_t GroupIndex;
144 uint32_t PadNumber;
145 uint32_t FinalValue;
146 uint32_t Data32;
147 uint32_t PadMode1, PadMode2;
148
149 PadOwnVal = GpioPadOwnHost;
150
151 memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg));
152 memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask));
153 memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg));
154 memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask));
155
156 GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);
157
158 GpioGroupOffset = GPIO_DNV_GROUP_MIN;
159 NumberOfGroups = V_PCH_GPIO_GROUP_MAX;
160
161 for (Index = 0; Index < (uint32_t)num; Index++) {
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200162 Dw0RegMask = 0;
163 Dw0Reg = 0;
164 Dw1RegMask = 0;
165 Dw1Reg = 0;
166
Julien Viard de Galbert7ebb6b02018-03-01 16:03:31 +0100167 GpioData = (struct dnv_pad_config *)&(gpio[Index]);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200168
169 Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad);
170 GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad);
171 PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad);
172
173 //
174 // Check if group index argument exceeds GPIO group index range
175 //
176 if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) {
177 printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index "
178 "(GroupIndex=%d, Pad=%d)!\n",
179 GroupIndex, PadNumber);
180 continue;
181 }
182
183 //
184 // Check if group argument exceeds GPIO group range
185 //
186 if ((Group < GpioGroupOffset) ||
187 (Group >= NumberOfGroups + GpioGroupOffset)) {
188 printk(BIOS_ERR,
189 "GPIO ERROR: Invalid Group (Group=%d)!\n",
190 Group);
191 return;
192 }
193
194 //
195 // Check if legal pin number
196 //
197 if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
198 printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber "
199 "(PadNumber=%d)!\n",
200 PadNumber);
201 return;
202 }
203
204 //
205 // Check if selected GPIO Pad is not owned by CSME/ISH
206 //
207 GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal);
208
209 if (PadOwnVal != GpioPadOwnHost) {
210 printk(BIOS_ERR, "GPIO WARNING: Accessing pad not "
211 "owned by host (Group=%d, Pad=%d)!",
212 GroupIndex, PadNumber);
213 if (PadOwnVal == GpioPadOwnCsme)
214 printk(BIOS_ERR, "The owner is CSME\n");
215 else if (PadOwnVal == GpioPadOwnIsh)
216 printk(BIOS_ERR, "The owner is ISH\n");
217 printk(BIOS_ERR, "** Please make sure the GPIO usage "
218 "in sync between CSME/ISH and Host IA "
219 "FW configuration.\n");
220 printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH "
221 "should not do any configuration by "
222 "Host IA FW.\n");
223 continue;
224 }
225
226 //
227 // Configure Reset Type (PadRstCfg)
228 //
229 Dw0RegMask |=
230 ((((GpioData->GpioConfig.PowerConfig &
231 GPIO_CONF_RESET_MASK) >>
232 GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault)
233 ? 0x0
234 : B_PCH_GPIO_RST_CONF);
235 Dw0Reg |= (((GpioData->GpioConfig.PowerConfig &
236 GPIO_CONF_RESET_MASK) >>
237 (GPIO_CONF_RESET_BIT_POS + 1))
238 << N_PCH_GPIO_RST_CONF);
239
240 //
241 // Configure how interrupt is triggered (RxEvCfg)
242 //
243 Dw0RegMask |=
244 ((((GpioData->GpioConfig.InterruptConfig &
245 GPIO_CONF_INT_TRIG_MASK) >>
246 GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault)
247 ? 0x0
248 : B_PCH_GPIO_RX_LVL_EDG);
249 Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
250 GPIO_CONF_INT_TRIG_MASK) >>
251 (GPIO_CONF_INT_TRIG_BIT_POS + 1))
252 << N_PCH_GPIO_RX_LVL_EDG);
253
254 //
255 // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
256 //
257 Dw0RegMask |=
258 ((((GpioData->GpioConfig.InterruptConfig &
259 GPIO_CONF_INT_ROUTE_MASK) >>
260 GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault)
261 ? 0x0
262 : (B_PCH_GPIO_RX_NMI_ROUTE |
263 B_PCH_GPIO_RX_SCI_ROUTE |
264 B_PCH_GPIO_RX_SMI_ROUTE |
265 B_PCH_GPIO_RX_APIC_ROUTE));
266 Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
267 GPIO_CONF_INT_ROUTE_MASK) >>
268 (GPIO_CONF_INT_ROUTE_BIT_POS + 1))
269 << N_PCH_GPIO_RX_NMI_ROUTE);
270
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100271 // If CFIO is not Working as GPIO mode, Don't move TxDisable and
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200272 // RxDisable
273 if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) {
274 //
275 // Configure GPIO direction (GPIORxDis and GPIOTxDis)
276 //
277 Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
278 GPIO_CONF_DIR_MASK) >>
279 GPIO_CONF_DIR_BIT_POS) ==
280 GpioHardwareDefault)
281 ? 0x0
282 : (B_PCH_GPIO_RXDIS |
283 B_PCH_GPIO_TXDIS));
284 Dw0Reg |= (((GpioData->GpioConfig.Direction &
285 GPIO_CONF_DIR_MASK) >>
286 (GPIO_CONF_DIR_BIT_POS + 1))
287 << N_PCH_GPIO_TXDIS);
288 }
289
290 //
291 // Configure GPIO input inversion (RXINV)
292 //
293 Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
294 GPIO_CONF_INV_MASK) >>
295 GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault)
296 ? 0x0
297 : B_PCH_GPIO_RXINV);
298 Dw0Reg |= (((GpioData->GpioConfig.Direction &
299 GPIO_CONF_INV_MASK) >>
300 (GPIO_CONF_INV_BIT_POS + 1))
301 << N_PCH_GPIO_RXINV);
302
303 //
304 // Configure GPIO output state (GPIOTxState)
305 //
306 Dw0RegMask |=
307 ((((GpioData->GpioConfig.OutputState &
308 GPIO_CONF_OUTPUT_MASK) >>
309 GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault)
310 ? 0x0
311 : B_PCH_GPIO_TX_STATE);
312 Dw0Reg |= (((GpioData->GpioConfig.OutputState &
313 GPIO_CONF_OUTPUT_MASK) >>
314 (GPIO_CONF_OUTPUT_BIT_POS + 1))
315 << N_PCH_GPIO_TX_STATE);
316
317 //
318 // Configure GPIO RX raw override to '1' (RXRAW1)
319 //
320 Dw0RegMask |=
321 ((((GpioData->GpioConfig.OtherSettings &
322 GPIO_CONF_RXRAW_MASK) >>
323 GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault)
324 ? 0x0
325 : B_PCH_GPIO_RX_RAW1);
326 Dw0Reg |= (((GpioData->GpioConfig.OtherSettings &
327 GPIO_CONF_RXRAW_MASK) >>
328 (GPIO_CONF_RXRAW_BIT_POS + 1))
329 << N_PCH_GPIO_RX_RAW1);
330
331 //
332 // Configure GPIO Pad Mode (PMode)
333 //
334 Dw0RegMask |=
335 ((((GpioData->GpioConfig.PadMode &
336 GPIO_CONF_PAD_MODE_MASK) >>
337 GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault)
338 ? 0x0
339 : B_PCH_GPIO_PAD_MODE);
340 Dw0Reg |= (((GpioData->GpioConfig.PadMode &
341 GPIO_CONF_PAD_MODE_MASK) >>
342 (GPIO_CONF_PAD_MODE_BIT_POS + 1))
343 << N_PCH_GPIO_PAD_MODE);
344
345 //
346 // Configure GPIO termination (Term)
347 //
348 Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig &
349 GPIO_CONF_TERM_MASK) >>
350 GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault)
351 ? 0x0
352 : B_PCH_GPIO_TERM);
353 Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
354 GPIO_CONF_TERM_MASK) >>
355 (GPIO_CONF_TERM_BIT_POS + 1))
356 << N_PCH_GPIO_TERM);
357
358 //
359 // Configure GPIO pad tolerance (padtol)
360 //
361 Dw1RegMask |=
362 ((((GpioData->GpioConfig.ElectricalConfig &
363 GPIO_CONF_PADTOL_MASK) >>
364 GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault)
365 ? 0x0
366 : B_PCH_GPIO_PADTOL);
367 Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
368 GPIO_CONF_PADTOL_MASK) >>
369 (GPIO_CONF_PADTOL_BIT_POS + 1))
370 << N_PCH_GPIO_PADTOL);
371
372 //
373 // Check for additional requirements on setting PADCFG register
374 //
375
376 //
377 // Create PADCFG register offset using group and pad number
378 //
379 PadCfgReg = 0x8 * PadNumber +
380 GpioGroupInfo[GroupIndex].PadCfgOffset;
381 Data32 = read32((void *)PCH_PCR_ADDRESS(
382 GpioGroupInfo[GroupIndex].Community, PadCfgReg));
383
384 FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg);
385
386 PadMode1 =
387 (Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;
388 PadMode2 =
389 (Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;
390
391 if (((Data32 & B_PCH_GPIO_PAD_MODE) !=
392 (FinalValue & B_PCH_GPIO_PAD_MODE)) ||
393 (PadMode2 == 0)) {
394 printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: "
395 "0x%x PadModeP1: %d P2: %d ",
396 GpioGroupInfo[GroupIndex].Community, PadCfgReg,
397 PadMode1, PadMode2);
398 printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32,
399 FinalValue);
400 //
401 // Write PADCFG DW0 register``
402 //
403 mmio_andthenor32(
404 (void *)(uint32_t)PCH_PCR_ADDRESS(
405 GpioGroupInfo[GroupIndex].Community,
406 PadCfgReg),
407 ~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg);
408 }
409
410 Data32 = read32((void *)PCH_PCR_ADDRESS(
411 GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4));
412 FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg);
413 if (Data32 != FinalValue) {
414 //
415 // Write PADCFG DW1 register
416 //
417 mmio_andthenor32(
418 (void *)(uint32_t)PCH_PCR_ADDRESS(
419 GpioGroupInfo[GroupIndex].Community,
420 PadCfgReg + 0x4),
421 ~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg);
422 }
423
424 //
425 // Update value to be programmed in HOSTSW_OWN register
426 //
Patrick Rudolphdcf30e82022-03-22 09:02:16 +0100427 HostSoftOwnRegMask[GroupIndex] |=
428 ((uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1) << PadNumber;
429 HostSoftOwnReg[GroupIndex] |=
430 ((uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1) << PadNumber;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200431
432 //
433 // Update value to be programmed in GPI_GPE_EN register
434 //
Patrick Rudolphdcf30e82022-03-22 09:02:16 +0100435 GpiGpeEnRegMask[GroupIndex] |=
436 ((uint64_t)GpioData->GpioConfig.InterruptConfig & 0x1) << PadNumber;
437 GpiGpeEnReg[GroupIndex] |=
438 (((uint64_t)GpioData->GpioConfig.InterruptConfig & GpioIntSci) >> 3)
439 << PadNumber;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200440 }
441
442 for (Index = 0; Index < NumberOfGroups; Index++) {
443 //
444 // Write HOSTSW_OWN registers
445 //
446 if (GpioGroupInfo[Index].HostOwnOffset !=
447 NO_REGISTER_FOR_PROPERTY) {
448 mmio_andthenor32(
449 (void *)PCH_PCR_ADDRESS(
450 GpioGroupInfo[Index].Community,
451 GpioGroupInfo[Index].HostOwnOffset),
452 ~(uint32_t)(HostSoftOwnRegMask[Index] &
453 0xFFFFFFFF),
454 (uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF));
455 mmio_andthenor32(
456 (void *)PCH_PCR_ADDRESS(
457 GpioGroupInfo[Index].Community,
458 GpioGroupInfo[Index].HostOwnOffset +
459 0x4),
Patrick Rudolphdcf30e82022-03-22 09:02:16 +0100460 ~(uint32_t)(HostSoftOwnRegMask[Index] >> 32),
461 (uint32_t)(HostSoftOwnReg[Index] >> 32));
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200462 }
463
464 //
465 // Write GPI_GPE_EN registers
466 //
467 if (GpioGroupInfo[Index].GpiGpeEnOffset !=
468 NO_REGISTER_FOR_PROPERTY) {
469 mmio_andthenor32(
470 (void *)PCH_PCR_ADDRESS(
471 GpioGroupInfo[Index].Community,
472 GpioGroupInfo[Index].GpiGpeEnOffset),
473 ~(uint32_t)(GpiGpeEnRegMask[Index] &
474 0xFFFFFFFF),
475 (uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF));
476 mmio_andthenor32(
477 (void *)PCH_PCR_ADDRESS(
478 GpioGroupInfo[Index].Community,
479 GpioGroupInfo[Index].GpiGpeEnOffset +
480 0x4),
Patrick Rudolphdcf30e82022-03-22 09:02:16 +0100481 ~(uint32_t)(GpiGpeEnRegMask[Index] >> 32),
482 (uint32_t)(GpiGpeEnReg[Index] >> 32));
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200483 }
484 }
485}