blob: 163de2de5882c903c63608a6dc02d6f14d79c927 [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Marshall Dawson251d3052019-05-02 17:27:57 -06002
Kyösti Mälkkib0db8132021-01-21 16:34:43 +02003#include <acpi/acpi_pm.h>
Marshall Dawson251d3052019-05-02 17:27:57 -06004#include <device/mmio.h>
5#include <device/device.h>
6#include <console/console.h>
Aaron Durbine05f4dc2020-08-17 16:22:09 -06007#include <elog.h>
Marshall Dawson251d3052019-05-02 17:27:57 -06008#include <gpio.h>
Kyösti Mälkkib0db8132021-01-21 16:34:43 +02009#include <amdblocks/acpi.h>
Marshall Dawson251d3052019-05-02 17:27:57 -060010#include <amdblocks/acpimmio.h>
Felix Helddea4e0f2021-09-22 20:05:53 +020011#include <amdblocks/gpio.h>
Felix Helda5a52952020-12-01 18:14:01 +010012#include <amdblocks/smi.h>
Marshall Dawson251d3052019-05-02 17:27:57 -060013#include <soc/gpio.h>
14#include <soc/smi.h>
15#include <assert.h>
Aaron Durbine05f4dc2020-08-17 16:22:09 -060016#include <string.h>
Felix Held16ae6822021-09-20 21:15:13 +020017#include <types.h>
Marshall Dawson251d3052019-05-02 17:27:57 -060018
Felix Held8b760002021-08-05 16:12:01 +020019/*
20 * acpimmio_gpio0, acpimmio_remote_gpio and acpimmio_iomux are defined in
21 * soc/amd/common/block/acpimmio/mmio_util.c and declared as extern variables/constants in
22 * amdblocks/acpimmio.h which is included in this file.
23 */
24
Felix Heldf5658cf2021-08-03 03:15:27 +020025/* MMIO access of new-style GPIO bank configuration registers */
Felix Heldd0911e92021-07-30 03:04:54 +020026static inline void *gpio_ctrl_ptr(gpio_t gpio_num)
Felix Heldf5658cf2021-08-03 03:15:27 +020027{
Felix Heldb4fe8c52021-07-28 21:24:40 +020028 if (SOC_GPIO_TOTAL_PINS < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER ||
29 /* Verstage on PSP would need to map acpimmio_remote_gpio */
30 (CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && ENV_SEPARATE_VERSTAGE) ||
31 gpio_num < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER)
32 return acpimmio_gpio0 + gpio_num * sizeof(uint32_t);
33 else
34 return acpimmio_remote_gpio +
35 (gpio_num - AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER) * sizeof(uint32_t);
Felix Heldf5658cf2021-08-03 03:15:27 +020036}
37
Felix Heldd0911e92021-07-30 03:04:54 +020038static inline uint32_t gpio_read32(gpio_t gpio_num)
Felix Heldf5658cf2021-08-03 03:15:27 +020039{
40 return read32(gpio_ctrl_ptr(gpio_num));
41}
42
Felix Heldd0911e92021-07-30 03:04:54 +020043static inline void gpio_write32(gpio_t gpio_num, uint32_t value)
Felix Heldf5658cf2021-08-03 03:15:27 +020044{
45 write32(gpio_ctrl_ptr(gpio_num), value);
46}
47
Felix Heldaa9ad052021-08-04 01:57:38 +020048static inline void *gpio_mux_ptr(gpio_t gpio_num)
Felix Held85e733f2021-08-03 18:42:04 +020049{
Felix Heldb4fe8c52021-07-28 21:24:40 +020050 if (SOC_GPIO_TOTAL_PINS < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER ||
51 /* Verstage on PSP would need to map acpimmio_remote_gpio */
52 (CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && ENV_SEPARATE_VERSTAGE) ||
53 gpio_num < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER)
54 return acpimmio_iomux + gpio_num;
55 else
56 return acpimmio_remote_gpio + AMD_GPIO_REMOTE_GPIO_MUX_OFFSET +
57 (gpio_num - AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER);
Felix Held85e733f2021-08-03 18:42:04 +020058}
59
Felix Heldb7f05632021-08-05 15:52:46 +020060static uint8_t get_gpio_mux(gpio_t gpio_num)
Felix Held85e733f2021-08-03 18:42:04 +020061{
Felix Heldaa9ad052021-08-04 01:57:38 +020062 return read8(gpio_mux_ptr(gpio_num));
63}
64
Felix Heldb7f05632021-08-05 15:52:46 +020065static void set_gpio_mux(gpio_t gpio_num, uint8_t function)
Felix Heldaa9ad052021-08-04 01:57:38 +020066{
Felix Heldb7f05632021-08-05 15:52:46 +020067 write8(gpio_mux_ptr(gpio_num), function & AMD_GPIO_MUX_MASK);
68 get_gpio_mux(gpio_num); /* Flush posted write */
Felix Heldad38ac012021-08-03 15:53:36 +020069}
70
Felix Held298150d2021-07-28 17:36:46 +020071static int get_gpio_gevent(gpio_t gpio, const struct soc_amd_event *table,
Marshall Dawson251d3052019-05-02 17:27:57 -060072 size_t items)
73{
Felix Held75196bf2021-07-30 03:09:25 +020074 size_t i;
Marshall Dawson251d3052019-05-02 17:27:57 -060075
76 for (i = 0; i < items; i++) {
77 if ((table + i)->gpio == gpio)
78 return (int)(table + i)->event;
79 }
80 return -1;
81}
82
Felix Heldf80e6d62021-07-30 03:26:15 +020083static void program_smi(uint32_t flags, unsigned int gevent_num)
Marshall Dawson251d3052019-05-02 17:27:57 -060084{
Furquan Shaikhaf8123c2020-06-26 18:55:17 -070085 uint8_t level;
Marshall Dawson251d3052019-05-02 17:27:57 -060086
Furquan Shaikhaf8123c2020-06-26 18:55:17 -070087 if (!is_gpio_event_level_triggered(flags)) {
88 printk(BIOS_ERR, "ERROR: %s - Only level trigger allowed for SMI!\n", __func__);
Julius Werner3e034b62020-07-29 17:39:21 -070089 BUG();
Furquan Shaikhaf8123c2020-06-26 18:55:17 -070090 return;
91 }
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +030092
Furquan Shaikhaf8123c2020-06-26 18:55:17 -070093 if (is_gpio_event_active_high(flags))
94 level = SMI_SCI_LVL_HIGH;
95 else
96 level = SMI_SCI_LVL_LOW;
97
98 configure_gevent_smi(gevent_num, SMI_MODE_SMI, level);
Marshall Dawson251d3052019-05-02 17:27:57 -060099}
100
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300101/*
102 * For each general purpose event, GPE, the choice of edge/level triggered
103 * event is represented as a single bit in SMI_SCI_LEVEL register.
104 *
105 * In a similar fashion, polarity (rising/falling, hi/lo) of each GPE is
106 * represented as a single bit in SMI_SCI_TRIG register.
107 */
Felix Heldf80e6d62021-07-30 03:26:15 +0200108static void program_sci(uint32_t flags, unsigned int gevent_num)
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300109{
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300110 struct sci_source sci;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300111
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300112 sci.scimap = gevent_num;
113 sci.gpe = gevent_num;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300114
Furquan Shaikhaf8123c2020-06-26 18:55:17 -0700115 if (is_gpio_event_level_triggered(flags))
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300116 sci.level = SMI_SCI_LVL;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300117 else
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300118 sci.level = SMI_SCI_EDG;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300119
Furquan Shaikhaf8123c2020-06-26 18:55:17 -0700120 if (is_gpio_event_active_high(flags))
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300121 sci.direction = SMI_SCI_LVL_HIGH;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300122 else
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300123 sci.direction = SMI_SCI_LVL_LOW;
Kyösti Mälkkic4f5e4e2020-06-22 12:03:51 +0300124
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300125 configure_scimap(&sci);
Marshall Dawson251d3052019-05-02 17:27:57 -0600126}
127
Kyösti Mälkki41353952020-06-22 18:50:55 +0300128static void gpio_update32(gpio_t gpio_num, uint32_t mask, uint32_t or)
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300129{
130 uint32_t reg;
Marshall Dawson251d3052019-05-02 17:27:57 -0600131
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300132 reg = gpio_read32(gpio_num);
133 reg &= mask;
134 reg |= or;
135 gpio_write32(gpio_num, reg);
136}
137
Furquan Shaikh05726e82020-06-30 10:35:27 -0700138/* Set specified bits of a register to match those of ctrl. */
Kyösti Mälkki41353952020-06-22 18:50:55 +0300139static void gpio_setbits32(gpio_t gpio_num, uint32_t mask, uint32_t ctrl)
Furquan Shaikh05726e82020-06-30 10:35:27 -0700140{
Kyösti Mälkki41353952020-06-22 18:50:55 +0300141 gpio_update32(gpio_num, ~mask, ctrl & mask);
Furquan Shaikh05726e82020-06-30 10:35:27 -0700142}
143
Kyösti Mälkki41353952020-06-22 18:50:55 +0300144static void gpio_and32(gpio_t gpio_num, uint32_t mask)
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300145{
Kyösti Mälkki41353952020-06-22 18:50:55 +0300146 gpio_update32(gpio_num, mask, 0);
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300147}
148
Kyösti Mälkki41353952020-06-22 18:50:55 +0300149static void gpio_or32(gpio_t gpio_num, uint32_t or)
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300150{
Kyösti Mälkki41353952020-06-22 18:50:55 +0300151 gpio_update32(gpio_num, -1UL, or);
Marshall Dawson251d3052019-05-02 17:27:57 -0600152}
153
Kyösti Mälkki419c6902020-06-22 08:06:52 +0300154static void master_switch_clr(uint32_t mask)
155{
Felix Heldd0911e92021-07-30 03:04:54 +0200156 const gpio_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
Kyösti Mälkki41353952020-06-22 18:50:55 +0300157 gpio_and32(master_reg, ~mask);
Kyösti Mälkki419c6902020-06-22 08:06:52 +0300158}
159
160static void master_switch_set(uint32_t or)
161{
Felix Heldd0911e92021-07-30 03:04:54 +0200162 const gpio_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
Kyösti Mälkki41353952020-06-22 18:50:55 +0300163 gpio_or32(master_reg, or);
Kyösti Mälkki419c6902020-06-22 08:06:52 +0300164}
165
Marshall Dawson251d3052019-05-02 17:27:57 -0600166int gpio_get(gpio_t gpio_num)
167{
168 uint32_t reg;
Marshall Dawson251d3052019-05-02 17:27:57 -0600169
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300170 reg = gpio_read32(gpio_num);
Marshall Dawson251d3052019-05-02 17:27:57 -0600171 return !!(reg & GPIO_PIN_STS);
172}
173
174void gpio_set(gpio_t gpio_num, int value)
175{
Kyösti Mälkki41353952020-06-22 18:50:55 +0300176 gpio_setbits32(gpio_num, GPIO_OUTPUT_VALUE, value ? GPIO_OUTPUT_VALUE : 0);
Marshall Dawson251d3052019-05-02 17:27:57 -0600177}
178
179void gpio_input_pulldown(gpio_t gpio_num)
180{
Felix Helda1f254b2021-01-05 00:36:51 +0100181 gpio_setbits32(gpio_num, GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE, GPIO_PULLDOWN_ENABLE);
Marshall Dawson251d3052019-05-02 17:27:57 -0600182}
183
184void gpio_input_pullup(gpio_t gpio_num)
185{
Felix Helda1f254b2021-01-05 00:36:51 +0100186 gpio_setbits32(gpio_num, GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE, GPIO_PULLUP_ENABLE);
Marshall Dawson251d3052019-05-02 17:27:57 -0600187}
188
189void gpio_input(gpio_t gpio_num)
190{
Felix Helddec00dd2021-01-05 00:32:25 +0100191 gpio_and32(gpio_num, ~(GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE));
Marshall Dawson251d3052019-05-02 17:27:57 -0600192}
193
194void gpio_output(gpio_t gpio_num, int value)
195{
Felix Held15dd9b82021-01-05 00:17:56 +0100196 /* set GPIO output value before setting the direction to output to avoid glitches */
Marshall Dawson251d3052019-05-02 17:27:57 -0600197 gpio_set(gpio_num, value);
Felix Held15dd9b82021-01-05 00:17:56 +0100198 gpio_or32(gpio_num, GPIO_OUTPUT_ENABLE);
Marshall Dawson251d3052019-05-02 17:27:57 -0600199}
200
201const char *gpio_acpi_path(gpio_t gpio)
202{
203 return "\\_SB.GPIO";
204}
205
206uint16_t gpio_acpi_pin(gpio_t gpio)
207{
208 return gpio;
209}
210
Felix Held35cee382021-08-03 02:55:34 +0200211void gpio_save_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
212{
Felix Held029a4a02021-08-03 03:36:53 +0200213 save->mux_value = get_gpio_mux(gpio);
Felix Held35cee382021-08-03 02:55:34 +0200214 save->control_value = gpio_read32(gpio);
215}
216
217void gpio_restore_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
218{
219 set_gpio_mux(gpio, save->mux_value);
220 gpio_write32(gpio, save->control_value);
221 gpio_read32(gpio); /* Flush posted write */
222}
223
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300224static void set_single_gpio(const struct soc_amd_gpio *g)
Marshall Dawson251d3052019-05-02 17:27:57 -0600225{
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300226 static const struct soc_amd_event *gev_tbl;
227 static size_t gev_items;
Marshall Dawson251d3052019-05-02 17:27:57 -0600228 int gevent_num;
Felix Held4b027692021-08-03 20:09:54 +0200229 const bool can_set_smi_flags = !((CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) &&
230 ENV_SEPARATE_VERSTAGE) ||
231 CONFIG(SOC_AMD_COMMON_BLOCK_BANKED_GPIOS_NON_SOC_CODEBASE));
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300232
Felix Held21813c32021-07-28 20:30:17 +0200233 set_gpio_mux(g->gpio, g->function);
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300234
Kyösti Mälkki0589e3c2020-06-22 13:35:35 +0300235 gpio_setbits32(g->gpio, PAD_CFG_MASK, g->control);
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300236 /* Clear interrupt and wake status (write 1-to-clear bits) */
Kyösti Mälkki0589e3c2020-06-22 13:35:35 +0300237 gpio_or32(g->gpio, GPIO_INT_STATUS | GPIO_WAKE_STATUS);
238 if (g->flags == 0)
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300239 return;
240
241 /* Can't set SMI flags from PSP */
242 if (!can_set_smi_flags)
243 return;
244
245 if (gev_tbl == NULL)
246 soc_get_gpio_event_table(&gev_tbl, &gev_items);
247
Kyösti Mälkki0589e3c2020-06-22 13:35:35 +0300248 gevent_num = get_gpio_gevent(g->gpio, gev_tbl, gev_items);
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300249 if (gevent_num < 0) {
250 printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n",
Kyösti Mälkki0589e3c2020-06-22 13:35:35 +0300251 g->gpio);
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300252 return;
253 }
254
Kyösti Mälkki0589e3c2020-06-22 13:35:35 +0300255 if (g->flags & GPIO_FLAG_SMI) {
256 program_smi(g->flags, gevent_num);
257 } else if (g->flags & GPIO_FLAG_SCI) {
Kyösti Mälkki31d49ec2020-07-02 20:46:25 +0300258 program_sci(g->flags, gevent_num);
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300259 }
260}
261
Felix Heldf7f1f162021-09-20 21:12:22 +0200262void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg,
263 size_t base_num_pads,
264 const struct soc_amd_gpio *override_cfg,
265 size_t override_num_pads)
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300266{
Felix Heldf7f1f162021-09-20 21:12:22 +0200267 const struct soc_amd_gpio *c;
268 size_t i, j;
Kyösti Mälkkiff730fe2020-07-01 01:43:55 +0300269
Felix Heldf7f1f162021-09-20 21:12:22 +0200270 if (!base_cfg || !base_num_pads)
Martin Roth3190ba82020-11-05 11:20:19 -0700271 return;
Marshall Dawson251d3052019-05-02 17:27:57 -0600272
Marshall Dawson251d3052019-05-02 17:27:57 -0600273 /*
274 * Disable blocking wake/interrupt status generation while updating
275 * debounce registers. Otherwise when a debounce register is updated
276 * the whole GPIO controller will zero out all interrupt enable status
277 * bits while the delay happens. This could cause us to drop the bits
278 * due to the read-modify-write that happens on each register.
279 *
280 * Additionally disable interrupt generation so we don't get any
281 * spurious interrupts while updating the registers.
282 */
Kyösti Mälkki419c6902020-06-22 08:06:52 +0300283 master_switch_clr(GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);
Marshall Dawson251d3052019-05-02 17:27:57 -0600284
Felix Heldf7f1f162021-09-20 21:12:22 +0200285 for (i = 0; i < base_num_pads; i++) {
286 c = &base_cfg[i];
287 /* Check if override exist for GPIO from the base configuration */
288 for (j = 0; override_cfg && j < override_num_pads; j++) {
289 if (c->gpio == override_cfg[j].gpio) {
290 c = &override_cfg[j];
291 break;
292 }
293 }
294 set_single_gpio(c);
295 }
Marshall Dawson251d3052019-05-02 17:27:57 -0600296
297 /*
298 * Re-enable interrupt status generation.
299 *
300 * We leave MASK_STATUS disabled because the kernel may reconfigure the
301 * debounce registers while the drivers load. This will cause interrupts
302 * to be missed during boot.
303 */
Kyösti Mälkki419c6902020-06-22 08:06:52 +0300304 master_switch_set(GPIO_INTERRUPT_EN);
Marshall Dawson251d3052019-05-02 17:27:57 -0600305}
306
Felix Held7011fa12021-09-22 16:36:12 +0200307void gpio_configure_pads(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
Felix Heldf7f1f162021-09-20 21:12:22 +0200308{
309 gpio_configure_pads_with_override(gpio_list_ptr, size, NULL, 0);
310}
311
Marshall Dawson251d3052019-05-02 17:27:57 -0600312int gpio_interrupt_status(gpio_t gpio)
313{
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300314 uint32_t reg = gpio_read32(gpio);
Marshall Dawson251d3052019-05-02 17:27:57 -0600315
316 if (reg & GPIO_INT_STATUS) {
317 /* Clear interrupt status, preserve wake status */
318 reg &= ~GPIO_WAKE_STATUS;
Kyösti Mälkki39bd46f2020-06-18 19:18:21 +0300319 gpio_write32(gpio, reg);
Marshall Dawson251d3052019-05-02 17:27:57 -0600320 return 1;
321 }
322
323 return 0;
324}
Peichao Wang712311f2020-04-18 08:25:53 +0800325
Felix Heldd0911e92021-07-30 03:04:54 +0200326static void check_and_add_wake_gpio(gpio_t begin, gpio_t end, struct gpio_wake_state *state)
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600327{
Felix Heldd0911e92021-07-30 03:04:54 +0200328 gpio_t i;
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600329 uint32_t reg;
330
331 for (i = begin; i < end; i++) {
332 reg = gpio_read32(i);
333 if (!(reg & GPIO_WAKE_STATUS))
334 continue;
335 printk(BIOS_INFO, "GPIO %d woke system.\n", i);
336 if (state->num_valid_wake_gpios >= ARRAY_SIZE(state->wake_gpios))
337 continue;
338 state->wake_gpios[state->num_valid_wake_gpios++] = i;
339 }
340}
341
Felix Heldafa750b2021-07-30 03:07:42 +0200342static void check_gpios(uint32_t wake_stat, unsigned int bit_limit, gpio_t gpio_base,
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600343 struct gpio_wake_state *state)
344{
Felix Heldafa750b2021-07-30 03:07:42 +0200345 unsigned int i;
Felix Heldd0911e92021-07-30 03:04:54 +0200346 gpio_t begin;
347 gpio_t end;
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600348
349 for (i = 0; i < bit_limit; i++) {
350 if (!(wake_stat & BIT(i)))
351 continue;
Felix Heldb93a9a22021-07-30 02:58:19 +0200352 /* Each wake status register bit is for 4 GPIOs that then will be checked */
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600353 begin = gpio_base + i * 4;
354 end = begin + 4;
355 /* There is no gpio 63. */
356 if (begin == 60)
357 end = 63;
358 check_and_add_wake_gpio(begin, end, state);
359 }
360}
361
362void gpio_fill_wake_state(struct gpio_wake_state *state)
363{
364 /* Turn the wake registers into "gpio" index to conform to existing API. */
Felix Heldd0911e92021-07-30 03:04:54 +0200365 const gpio_t stat0 = GPIO_WAKE_STAT_0 / sizeof(uint32_t);
366 const gpio_t stat1 = GPIO_WAKE_STAT_1 / sizeof(uint32_t);
367 const gpio_t control_switch = GPIO_MASTER_SWITCH / sizeof(uint32_t);
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600368
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600369 memset(state, 0, sizeof(*state));
370
371 state->control_switch = gpio_read32(control_switch);
372 state->wake_stat[0] = gpio_read32(stat0);
373 state->wake_stat[1] = gpio_read32(stat1);
374
375 printk(BIOS_INFO, "GPIO Control Switch: 0x%08x, Wake Stat 0: 0x%08x, Wake Stat 1: 0x%08x\n",
376 state->control_switch, state->wake_stat[0], state->wake_stat[1]);
377
378 check_gpios(state->wake_stat[0], 32, 0, state);
379 check_gpios(state->wake_stat[1], 14, 128, state);
380}
381
Kyösti Mälkkib0db8132021-01-21 16:34:43 +0200382void gpio_add_events(void)
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600383{
Kyösti Mälkkib0db8132021-01-21 16:34:43 +0200384 const struct chipset_power_state *ps;
385 const struct gpio_wake_state *state;
Felix Heldafa750b2021-07-30 03:07:42 +0200386 unsigned int i;
387 unsigned int end;
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600388
Kyösti Mälkkib0db8132021-01-21 16:34:43 +0200389 if (acpi_pm_state_for_elog(&ps) < 0)
390 return;
391 state = &ps->gpio_state;
392
Aaron Durbine05f4dc2020-08-17 16:22:09 -0600393 end = MIN(state->num_valid_wake_gpios, ARRAY_SIZE(state->wake_gpios));
394 for (i = 0; i < end; i++)
395 elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, state->wake_gpios[i]);
396}