1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <device/device.h>
5 #include <console/console.h>
7 #include <amdblocks/acpimmio.h>
8 #include <amdblocks/gpio_banks.h>
13 static int get_gpio_gevent(uint8_t gpio
, const struct soc_amd_event
*table
,
18 for (i
= 0; i
< items
; i
++) {
19 if ((table
+ i
)->gpio
== gpio
)
20 return (int)(table
+ i
)->event
;
25 static void program_smi(uint32_t flags
, int gevent_num
)
29 if (!is_gpio_event_level_triggered(flags
)) {
30 printk(BIOS_ERR
, "ERROR: %s - Only level trigger allowed for SMI!\n", __func__
);
35 if (is_gpio_event_active_high(flags
))
36 level
= SMI_SCI_LVL_HIGH
;
38 level
= SMI_SCI_LVL_LOW
;
40 configure_gevent_smi(gevent_num
, SMI_MODE_SMI
, level
);
43 struct sci_trigger_regs
{
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
;
62 if (is_gpio_event_level_triggered(flags
))
67 if (is_gpio_event_active_high(flags
))
68 regs
->polarity
|= mask
;
70 regs
->polarity
&= ~mask
;
73 /* TODO: See configure_scimap() implementations. */
74 static void set_sci_trigger(const struct sci_trigger_regs
*regs
)
78 value
= smi_read32(SMI_SCI_TRIG
);
80 value
|= regs
->polarity
;
81 smi_write32(SMI_SCI_TRIG
, value
);
83 value
= smi_read32(SMI_SCI_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)
98 reg
= gpio_read32(gpio_num
);
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
)
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
)
171 uint16_t gpio_acpi_pin(gpio_t 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
;
183 const struct soc_amd_event
*gev_tbl
;
184 struct sci_trigger_regs sci_trigger_cfg
= { 0 };
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)
222 /* Can't set SMI flags from PSP */
223 if (!can_set_smi_flags
)
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",
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
);
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
,
279 if (override_cfg_table
== NULL
)
281 for (i
= 0; i
< num
; i
++) {
282 if (c
->gpio
== override_cfg_table
[i
].gpio
)
283 return override_cfg_table
+ i
;
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
)
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
,