soc/amd/common: Don't init SMIs or SCIs in psp_verstage
[coreboot.git] / src / soc / amd / common / block / gpio_banks / gpio.c
blobb9646b9412e60807f32b877bbcc0b1b0fb01cb2e
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <device/device.h>
5 #include <console/console.h>
6 #include <gpio.h>
7 #include <amdblocks/acpimmio.h>
8 #include <amdblocks/gpio_banks.h>
9 #include <soc/gpio.h>
10 #include <soc/smi.h>
11 #include <assert.h>
13 static int get_gpio_gevent(uint8_t gpio, const struct soc_amd_event *table,
14 size_t items)
16 int i;
18 for (i = 0; i < items; i++) {
19 if ((table + i)->gpio == gpio)
20 return (int)(table + i)->event;
22 return -1;
25 static void program_smi(uint32_t flags, int gevent_num)
27 uint8_t level;
29 if (!is_gpio_event_level_triggered(flags)) {
30 printk(BIOS_ERR, "ERROR: %s - Only level trigger allowed for SMI!\n", __func__);
31 assert(0);
32 return;
35 if (is_gpio_event_active_high(flags))
36 level = SMI_SCI_LVL_HIGH;
37 else
38 level = SMI_SCI_LVL_LOW;
40 configure_gevent_smi(gevent_num, SMI_MODE_SMI, level);
43 struct sci_trigger_regs {
44 uint32_t mask;
45 uint32_t polarity;
46 uint32_t level;
50 * For each general purpose event, GPE, the choice of edge/level triggered
51 * event is represented as a single bit in SMI_SCI_LEVEL register.
53 * In a similar fashion, polarity (rising/falling, hi/lo) of each GPE is
54 * represented as a single bit in SMI_SCI_TRIG register.
56 static void fill_sci_trigger(uint32_t flags, int gpe, struct sci_trigger_regs *regs)
58 uint32_t mask = 1 << gpe;
60 regs->mask |= mask;
62 if (is_gpio_event_level_triggered(flags))
63 regs->level |= mask;
64 else
65 regs->level &= ~mask;
67 if (is_gpio_event_active_high(flags))
68 regs->polarity |= mask;
69 else
70 regs->polarity &= ~mask;
73 /* TODO: See configure_scimap() implementations. */
74 static void set_sci_trigger(const struct sci_trigger_regs *regs)
76 uint32_t value;
78 value = smi_read32(SMI_SCI_TRIG);
79 value &= ~regs->mask;
80 value |= regs->polarity;
81 smi_write32(SMI_SCI_TRIG, value);
83 value = smi_read32(SMI_SCI_LEVEL);
84 value &= ~regs->mask;
85 value |= regs->level;
86 smi_write32(SMI_SCI_LEVEL, value);
89 uintptr_t gpio_get_address(gpio_t gpio_num)
91 return (uintptr_t)gpio_ctrl_ptr(gpio_num);
94 static void __gpio_update32(gpio_t gpio_num, uint32_t mask, uint32_t or)
96 uint32_t reg;
98 reg = gpio_read32(gpio_num);
99 reg &= mask;
100 reg |= or;
101 gpio_write32(gpio_num, reg);
104 /* Set specified bits of a register to match those of ctrl. */
105 static void __gpio_setbits32(gpio_t gpio_num, uint32_t mask, uint32_t ctrl)
107 __gpio_update32(gpio_num, ~mask, ctrl & mask);
110 static void __gpio_and32(gpio_t gpio_num, uint32_t mask)
112 __gpio_update32(gpio_num, mask, 0);
115 static void __gpio_or32(gpio_t gpio_num, uint32_t or)
117 __gpio_update32(gpio_num, -1UL, or);
120 static void master_switch_clr(uint32_t mask)
122 const uint8_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
123 __gpio_and32(master_reg, ~mask);
126 static void master_switch_set(uint32_t or)
128 const uint8_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
129 __gpio_or32(master_reg, or);
132 int gpio_get(gpio_t gpio_num)
134 uint32_t reg;
136 reg = gpio_read32(gpio_num);
137 return !!(reg & GPIO_PIN_STS);
140 void gpio_set(gpio_t gpio_num, int value)
142 __gpio_setbits32(gpio_num, GPIO_OUTPUT_VALUE, value ? GPIO_OUTPUT_VALUE : 0);
145 void gpio_input_pulldown(gpio_t gpio_num)
147 __gpio_setbits32(gpio_num, GPIO_PULL_MASK, GPIO_PULLDOWN_ENABLE);
150 void gpio_input_pullup(gpio_t gpio_num)
152 __gpio_setbits32(gpio_num, GPIO_PULL_MASK, GPIO_PULLUP_ENABLE);
155 void gpio_input(gpio_t gpio_num)
157 __gpio_and32(gpio_num, ~GPIO_OUTPUT_ENABLE);
160 void gpio_output(gpio_t gpio_num, int value)
162 __gpio_or32(gpio_num, GPIO_OUTPUT_ENABLE);
163 gpio_set(gpio_num, value);
166 const char *gpio_acpi_path(gpio_t gpio)
168 return "\\_SB.GPIO";
171 uint16_t gpio_acpi_pin(gpio_t gpio)
173 return gpio;
176 __weak void soc_gpio_hook(uint8_t gpio, uint8_t mux) {}
178 void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
180 uint32_t control, control_flags;
181 uint8_t mux, index, gpio;
182 int gevent_num;
183 const struct soc_amd_event *gev_tbl;
184 struct sci_trigger_regs sci_trigger_cfg = { 0 };
185 size_t gev_items;
186 const bool can_set_smi_flags = !(CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) &&
187 ENV_SEPARATE_VERSTAGE);
190 * Disable blocking wake/interrupt status generation while updating
191 * debounce registers. Otherwise when a debounce register is updated
192 * the whole GPIO controller will zero out all interrupt enable status
193 * bits while the delay happens. This could cause us to drop the bits
194 * due to the read-modify-write that happens on each register.
196 * Additionally disable interrupt generation so we don't get any
197 * spurious interrupts while updating the registers.
199 master_switch_clr(GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);
201 if (can_set_smi_flags)
202 soc_get_gpio_event_table(&gev_tbl, &gev_items);
204 for (index = 0; index < size; index++) {
205 gpio = gpio_list_ptr[index].gpio;
206 mux = gpio_list_ptr[index].function;
207 control = gpio_list_ptr[index].control;
208 control_flags = gpio_list_ptr[index].flags;
210 iomux_write8(gpio, mux & AMD_GPIO_MUX_MASK);
211 iomux_read8(gpio); /* Flush posted write */
213 soc_gpio_hook(gpio, mux);
215 /* Clear interrupt and wake status (write 1-to-clear bits) */
216 control |= GPIO_INT_STATUS | GPIO_WAKE_STATUS;
217 __gpio_setbits32(gpio, PAD_CFG_MASK, control);
219 if (control_flags == 0)
220 continue;
222 /* Can't set SMI flags from PSP */
223 if (!can_set_smi_flags)
224 continue;
226 gevent_num = get_gpio_gevent(gpio, gev_tbl, gev_items);
227 if (gevent_num < 0) {
228 printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n",
229 gpio);
230 continue;
233 if (control_flags & GPIO_FLAG_SMI) {
234 program_smi(control_flags, gevent_num);
235 } else if (control_flags & GPIO_FLAG_SCI) {
236 fill_sci_trigger(control_flags, gevent_num, &sci_trigger_cfg);
237 soc_route_sci(gevent_num);
242 * Re-enable interrupt status generation.
244 * We leave MASK_STATUS disabled because the kernel may reconfigure the
245 * debounce registers while the drivers load. This will cause interrupts
246 * to be missed during boot.
248 master_switch_set(GPIO_INTERRUPT_EN);
250 /* Set all SCI trigger polarity (high/low) and level (edge/level). */
251 if (can_set_smi_flags)
252 set_sci_trigger(&sci_trigger_cfg);
255 int gpio_interrupt_status(gpio_t gpio)
257 uint32_t reg = gpio_read32(gpio);
259 if (reg & GPIO_INT_STATUS) {
260 /* Clear interrupt status, preserve wake status */
261 reg &= ~GPIO_WAKE_STATUS;
262 gpio_write32(gpio, reg);
263 return 1;
266 return 0;
270 * This function checks to see if there is an override config present for the
271 * provided pad_config. If no override config is present, then the input config
272 * is returned. Else, it returns the override config.
274 static const struct soc_amd_gpio *gpio_get_config(const struct soc_amd_gpio *c,
275 const struct soc_amd_gpio *override_cfg_table,
276 size_t num)
278 size_t i;
279 if (override_cfg_table == NULL)
280 return c;
281 for (i = 0; i < num; i++) {
282 if (c->gpio == override_cfg_table[i].gpio)
283 return override_cfg_table + i;
285 return c;
287 void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg,
288 size_t base_num_pads,
289 const struct soc_amd_gpio *override_cfg,
290 size_t override_num_pads)
292 size_t i;
293 const struct soc_amd_gpio *c;
295 for (i = 0; i < base_num_pads; i++) {
296 c = gpio_get_config(base_cfg + i, override_cfg,
297 override_num_pads);
298 program_gpios(c, 1);