blob: da1ba0bb74e0980a0b8863f857c0277b3614e292 [file] [log] [blame]
Marc Jones24484842017-05-04 21:17:45 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Google Inc.
5 * Copyright (C) 2015 Intel Corporation
6 * Copyright (C) 2017 Advanced Micro Devices, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Kyösti Mälkki13f66502019-03-03 08:01:05 +020018#include <device/mmio.h>
Marc Jones469c01e2017-09-24 21:04:03 -060019#include <console/console.h>
Richard Spiegel5401aa22018-09-11 11:36:38 -070020#include <delay.h>
Marc Jones9156cac2017-07-12 11:05:38 -060021#include <gpio.h>
Marc Jones24484842017-05-04 21:17:45 -060022#include <soc/gpio.h>
Richard Spiegel5401aa22018-09-11 11:36:38 -070023#include <soc/pci_devs.h>
Daniel Kurtz95cb1e72018-06-06 15:55:16 -060024#include <soc/southbridge.h>
Richard Spiegel2db06bb2018-04-20 16:50:12 -070025#include <assert.h>
Richard Spiegel2db06bb2018-04-20 16:50:12 -070026
27static const struct soc_amd_event gpio_event_table[] = {
28 { GPIO_1, GEVENT_19 },
29 { GPIO_2, GEVENT_8 },
30 { GPIO_3, GEVENT_2 },
31 { GPIO_4, GEVENT_4 },
32 { GPIO_5, GEVENT_7 },
33 { GPIO_6, GEVENT_10 },
34 { GPIO_7, GEVENT_11 },
35 { GPIO_8, GEVENT_23 },
36 { GPIO_9, GEVENT_22 },
37 { GPIO_11, GEVENT_18 },
38 { GPIO_13, GEVENT_21 },
39 { GPIO_14, GEVENT_6 },
40 { GPIO_15, GEVENT_20 },
41 { GPIO_16, GEVENT_12 },
42 { GPIO_17, GEVENT_13 },
43 { GPIO_18, GEVENT_14 },
44 { GPIO_21, GEVENT_5 },
45 { GPIO_22, GEVENT_3 },
46 { GPIO_23, GEVENT_16 },
47 { GPIO_24, GEVENT_15 },
48 { GPIO_65, GEVENT_0 },
49 { GPIO_66, GEVENT_1 },
50 { GPIO_68, GEVENT_9 },
51 { GPIO_69, GEVENT_17 },
52};
53
54static int get_gpio_gevent(uint8_t gpio)
55{
56 int i;
57
58 for (i = 0; i < ARRAY_SIZE(gpio_event_table); i++) {
59 if (gpio_event_table[i].gpio == gpio)
60 return (int)gpio_event_table[i].event;
61 }
62 return -1;
63}
64
65static void mem_read_write32(uint32_t *address, uint32_t value, uint32_t mask)
66{
67 uint32_t reg32;
68
69 value &= mask;
70 reg32 = read32(address);
71 reg32 &= ~mask;
72 reg32 |= value;
73 write32(address, reg32);
74}
75
76__weak void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
77{
78 printk(BIOS_WARNING, "Warning: SMI disabled!\n");
79}
80
81static void program_smi(uint32_t flag, int gevent_num)
82{
83 uint32_t trigger;
84
85 trigger = flag & FLAGS_TRIGGER_MASK;
86 /*
87 * Only level trigger is allowed for SMI. Trigger values are 0
88 * through 3, with 0-1 being level trigger and 2-3 being edge
89 * trigger. GPIO_TRIGGER_EDGE_LOW is 2, so trigger has to be
90 * less than GPIO_TRIGGER_EDGE_LOW.
91 */
92 assert(trigger < GPIO_TRIGGER_EDGE_LOW);
93
94 if (trigger == GPIO_TRIGGER_LEVEL_HIGH)
95 configure_gevent_smi(gevent_num, SMI_MODE_SMI,
96 SMI_SCI_LVL_HIGH);
97 if (trigger == GPIO_TRIGGER_LEVEL_LOW)
98 configure_gevent_smi(gevent_num, SMI_MODE_SMI,
99 SMI_SCI_LVL_LOW);
100}
101
Daniel Kurtz95cb1e72018-06-06 15:55:16 -0600102static void route_sci(uint8_t event)
103{
104 smi_write8(SMI_SCI_MAP(event), event);
105}
106
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700107static void get_sci_config_bits(uint32_t flag, uint32_t *edge, uint32_t *level)
108{
109 uint32_t trigger;
110
111 trigger = flag & FLAGS_TRIGGER_MASK;
112 switch (trigger) {
113 case GPIO_TRIGGER_LEVEL_LOW:
114 *edge = SCI_TRIGGER_LEVEL;
115 *level = 0;
116 break;
117 case GPIO_TRIGGER_LEVEL_HIGH:
118 *edge = SCI_TRIGGER_LEVEL;
119 *level = 1;
120 break;
121 case GPIO_TRIGGER_EDGE_LOW:
122 *edge = SCI_TRIGGER_EDGE;
123 *level = 0;
124 break;
125 case GPIO_TRIGGER_EDGE_HIGH:
126 *edge = SCI_TRIGGER_EDGE;
127 *level = 1;
128 break;
129 default:
130 break;
131 }
132}
Marc Jones24484842017-05-04 21:17:45 -0600133
Richard Spiegel93459d62018-05-16 14:08:33 -0700134uintptr_t gpio_get_address(gpio_t gpio_num)
Marc Jones469c01e2017-09-24 21:04:03 -0600135{
136 uintptr_t gpio_address;
137
138 if (gpio_num < 64)
139 gpio_address = GPIO_BANK0_CONTROL(gpio_num);
140 else if (gpio_num < 128)
141 gpio_address = GPIO_BANK1_CONTROL(gpio_num);
142 else
143 gpio_address = GPIO_BANK2_CONTROL(gpio_num);
144
145 return gpio_address;
146}
Marc Jones9156cac2017-07-12 11:05:38 -0600147
Marc Jones24484842017-05-04 21:17:45 -0600148int gpio_get(gpio_t gpio_num)
149{
150 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600151 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones24484842017-05-04 21:17:45 -0600152
Marc Jones469c01e2017-09-24 21:04:03 -0600153 reg = read32((void *)gpio_address);
Marc Jones24484842017-05-04 21:17:45 -0600154
155 return !!(reg & GPIO_PIN_STS);
156}
Marc Jones9156cac2017-07-12 11:05:38 -0600157
Marc Jones9156cac2017-07-12 11:05:38 -0600158void gpio_set(gpio_t gpio_num, int value)
159{
160 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600161 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones9156cac2017-07-12 11:05:38 -0600162
Marc Jones469c01e2017-09-24 21:04:03 -0600163 reg = read32((void *)gpio_address);
Marc Jones9156cac2017-07-12 11:05:38 -0600164 reg &= ~GPIO_OUTPUT_MASK;
165 reg |= !!value << GPIO_OUTPUT_SHIFT;
Jonathan Neuschäfer15192da2018-09-11 20:13:41 +0200166 write32((void *)gpio_address, reg);
Marc Jones9156cac2017-07-12 11:05:38 -0600167}
168
169void gpio_input_pulldown(gpio_t gpio_num)
170{
171 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600172 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones9156cac2017-07-12 11:05:38 -0600173
Marc Jones469c01e2017-09-24 21:04:03 -0600174 reg = read32((void *)gpio_address);
Marc Jones9156cac2017-07-12 11:05:38 -0600175 reg &= ~GPIO_PULLUP_ENABLE;
176 reg |= GPIO_PULLDOWN_ENABLE;
Jonathan Neuschäfer15192da2018-09-11 20:13:41 +0200177 write32((void *)gpio_address, reg);
Marc Jones9156cac2017-07-12 11:05:38 -0600178}
179
180void gpio_input_pullup(gpio_t gpio_num)
181{
182 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600183 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones9156cac2017-07-12 11:05:38 -0600184
Marc Jones469c01e2017-09-24 21:04:03 -0600185 reg = read32((void *)gpio_address);
Marc Jones9156cac2017-07-12 11:05:38 -0600186 reg &= ~GPIO_PULLDOWN_ENABLE;
187 reg |= GPIO_PULLUP_ENABLE;
Jonathan Neuschäfer15192da2018-09-11 20:13:41 +0200188 write32((void *)gpio_address, reg);
Marc Jones9156cac2017-07-12 11:05:38 -0600189}
190
191void gpio_input(gpio_t gpio_num)
192{
193 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600194 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones9156cac2017-07-12 11:05:38 -0600195
Marc Jones469c01e2017-09-24 21:04:03 -0600196 reg = read32((void *)gpio_address);
Marc Jones9156cac2017-07-12 11:05:38 -0600197 reg &= ~GPIO_OUTPUT_ENABLE;
Jonathan Neuschäfer15192da2018-09-11 20:13:41 +0200198 write32((void *)gpio_address, reg);
Marc Jones9156cac2017-07-12 11:05:38 -0600199}
200
201void gpio_output(gpio_t gpio_num, int value)
202{
203 uint32_t reg;
Marc Jones469c01e2017-09-24 21:04:03 -0600204 uintptr_t gpio_address = gpio_get_address(gpio_num);
Marc Jones9156cac2017-07-12 11:05:38 -0600205
Marc Jones469c01e2017-09-24 21:04:03 -0600206 reg = read32((void *)gpio_address);
Marc Jones9156cac2017-07-12 11:05:38 -0600207 reg |= GPIO_OUTPUT_ENABLE;
Jonathan Neuschäfer15192da2018-09-11 20:13:41 +0200208 write32((void *)gpio_address, reg);
Richard Spiegel7a52c172018-04-26 08:19:12 -0700209 gpio_set(gpio_num, value);
Marc Jones9156cac2017-07-12 11:05:38 -0600210}
Justin TerAvest949d6662018-01-24 14:20:03 -0700211
212const char *gpio_acpi_path(gpio_t gpio)
213{
Aaron Durbin7ad0ce72018-01-29 21:52:38 -0700214 return "\\_SB.GPIO";
Justin TerAvest949d6662018-01-24 14:20:03 -0700215}
216
217uint16_t gpio_acpi_pin(gpio_t gpio)
218{
219 return gpio;
220}
Chris Ching2269a3c2018-02-05 16:46:41 -0700221
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700222void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
Chris Ching2269a3c2018-02-05 16:46:41 -0700223{
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700224 uint8_t *mux_ptr;
Raul E Rangeldf306422019-01-24 11:52:20 -0700225 uint32_t *gpio_ptr, *inter_master;
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700226 uint32_t control, control_flags, edge_level, direction;
Raul Rangel034e5e62019-01-17 21:39:19 +0000227 uint32_t mask, bit_edge, bit_level;
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700228 uint8_t mux, index, gpio;
229 int gevent_num;
Chris Ching2269a3c2018-02-05 16:46:41 -0700230
Raul E Rangeldf306422019-01-24 11:52:20 -0700231 inter_master = (uint32_t *)(uintptr_t)(GPIO_CONTROL_MMIO_BASE
232 + GPIO_MASTER_SWITCH);
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700233 direction = 0;
234 edge_level = 0;
235 mask = 0;
Raul E Rangeldf306422019-01-24 11:52:20 -0700236
237 /*
238 * Disable blocking wake/interrupt status generation while updating
239 * debounce registers. Otherwise when a debounce register is updated
240 * the whole GPIO controller will zero out all interrupt enable status
241 * bits while the delay happens. This could cause us to drop the bits
242 * due to the read-modify-write that happens on each register.
243 *
244 * Additionally disable interrupt generation so we don't get any
245 * spurious interrupts while updating the registers.
246 */
247 mem_read_write32(inter_master, 0, GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);
248
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700249 for (index = 0; index < size; index++) {
250 gpio = gpio_list_ptr[index].gpio;
251 mux = gpio_list_ptr[index].function;
252 control = gpio_list_ptr[index].control;
253 control_flags = gpio_list_ptr[index].flags;
Chris Ching2269a3c2018-02-05 16:46:41 -0700254
Richard Spiegel63405da2018-10-16 15:04:14 -0700255 mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE);
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700256 write8(mux_ptr, mux & AMD_GPIO_MUX_MASK);
Richard Spiegel5401aa22018-09-11 11:36:38 -0700257 read8(mux_ptr); /* Flush posted write */
Daniel Kurtz95cb1e72018-06-06 15:55:16 -0600258 /* special case if pin 2 is assigned to wake */
259 if ((gpio == 2) && !(mux & AMD_GPIO_MUX_MASK))
260 route_sci(GPIO_2_EVENT);
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700261 gpio_ptr = (uint32_t *)gpio_get_address(gpio);
Chris Ching2269a3c2018-02-05 16:46:41 -0700262
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700263 if (control_flags & GPIO_SPECIAL_FLAG) {
264 gevent_num = get_gpio_gevent(gpio);
265 if (gevent_num < 0) {
266 printk(BIOS_WARNING, "Warning: GPIO pin %d has"
267 " no associated gevent!\n", gpio);
268 continue;
269 }
270 switch (control_flags & GPIO_SPECIAL_MASK) {
271 case GPIO_DEBOUNCE_FLAG:
272 mem_read_write32(gpio_ptr, control,
273 GPIO_DEBOUNCE_MASK);
274 break;
275 case GPIO_WAKE_FLAG:
276 mem_read_write32(gpio_ptr, control,
277 INT_WAKE_MASK);
278 break;
279 case GPIO_INT_FLAG:
280 mem_read_write32(gpio_ptr, control,
281 AMD_GPIO_CONTROL_MASK);
282 break;
283 case GPIO_SMI_FLAG:
284 mem_read_write32(gpio_ptr, control,
285 INT_SCI_SMI_MASK);
286 program_smi(control_flags, gevent_num);
287 break;
288 case GPIO_SCI_FLAG:
289 mem_read_write32(gpio_ptr, control,
290 INT_SCI_SMI_MASK);
291 get_sci_config_bits(control_flags, &bit_edge,
292 &bit_level);
293 edge_level |= bit_edge << gevent_num;
294 direction |= bit_level << gevent_num;
295 mask |= (1 << gevent_num);
Daniel Kurtz95cb1e72018-06-06 15:55:16 -0600296 route_sci(gevent_num);
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700297 break;
298 default:
299 printk(BIOS_WARNING, "Error, flags 0x%08x\n",
300 control_flags);
301 break;
302 }
303 } else {
304 mem_read_write32(gpio_ptr, control,
305 AMD_GPIO_CONTROL_MASK);
306 }
307 }
Raul E Rangeldf306422019-01-24 11:52:20 -0700308
309 /*
310 * Re-enable interrupt status generation.
311 *
312 * We leave MASK_STATUS disabled because the kernel may reconfigure the
313 * debounce registers while the drivers load. This will cause interrupts
314 * to be missed during boot.
315 */
316 mem_read_write32(inter_master, GPIO_INTERRUPT_EN, GPIO_INTERRUPT_EN);
317
Richard Spiegel2db06bb2018-04-20 16:50:12 -0700318 /* Set all SCI trigger direction (high/low) */
319 mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_TRIG),
320 direction, mask);
321
322 /* Set all SCI trigger level (edge/level) */
323 mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_LEVEL),
324 edge_level, mask);
Chris Ching2269a3c2018-02-05 16:46:41 -0700325}
326
Richard Spiegel5401aa22018-09-11 11:36:38 -0700327/*
328 * I2C pins are open drain with external pull up, so in order to bit bang them
329 * all, SCL pins must become GPIO inputs with no pull, then they need to be
330 * toggled between input-no-pull and output-low. This table is for the initial
331 * conversion of all SCL pins to input with no pull.
332 */
333static const struct soc_amd_gpio i2c_2_gpi[] = {
334 PAD_GPI(I2C0_SCL_PIN, PULL_NONE),
335 PAD_GPI(I2C1_SCL_PIN, PULL_NONE),
336 PAD_GPI(I2C2_SCL_PIN, PULL_NONE),
337 PAD_GPI(I2C3_SCL_PIN, PULL_NONE),
338};
339#define saved_pins_count ARRAY_SIZE(i2c_2_gpi)
340
341/*
342 * To program I2C pins without destroying their programming, the registers
343 * that will be changed need to be saved first.
344 */
345static void save_i2c_pin_registers(uint8_t gpio,
346 struct soc_amd_i2c_save *save_table)
347{
348 uint32_t *gpio_ptr;
349 uint8_t *mux_ptr;
350
Richard Spiegel63405da2018-10-16 15:04:14 -0700351 mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE);
Richard Spiegel5401aa22018-09-11 11:36:38 -0700352 gpio_ptr = (uint32_t *)gpio_get_address(gpio);
353 save_table->mux_value = read8(mux_ptr);
354 save_table->control_value = read32(gpio_ptr);
355}
356
357static void restore_i2c_pin_registers(uint8_t gpio,
358 struct soc_amd_i2c_save *save_table)
359{
360 uint32_t *gpio_ptr;
361 uint8_t *mux_ptr;
362
Richard Spiegel63405da2018-10-16 15:04:14 -0700363 mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE);
Richard Spiegel5401aa22018-09-11 11:36:38 -0700364 gpio_ptr = (uint32_t *)gpio_get_address(gpio);
365 write8(mux_ptr, save_table->mux_value);
366 read8(mux_ptr);
367 write32(gpio_ptr, save_table->control_value);
368 read32(gpio_ptr);
369}
370
371/* Slaves to be reset are controlled by devicetree register i2c_scl_reset */
372void sb_reset_i2c_slaves(void)
373{
374 const struct soc_amd_stoneyridge_config *cfg;
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300375 const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
Richard Spiegel5401aa22018-09-11 11:36:38 -0700376 struct soc_amd_i2c_save save_table[saved_pins_count];
377 uint8_t i, j, control;
378
379 if (!dev || !dev->chip_info)
380 return;
381 cfg = dev->chip_info;
382 control = cfg->i2c_scl_reset & GPIO_I2C_MASK;
383 if (control == 0)
384 return;
385
386 /* Save and reprogram I2C SCL pins */
387 for (i = 0; i < saved_pins_count; i++)
388 save_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]);
389 sb_program_gpios(i2c_2_gpi, saved_pins_count);
390
391 /*
392 * Toggle SCL back and forth 9 times under 100KHz. A single read is
393 * needed after the writes to force the posted write to complete.
394 */
395 for (j = 0; j < 9; j++) {
396 if (control & GPIO_I2C0_SCL)
397 write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_LOW);
398 if (control & GPIO_I2C1_SCL)
399 write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_LOW);
400 if (control & GPIO_I2C2_SCL)
401 write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_LOW);
402 if (control & GPIO_I2C3_SCL)
403 write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_LOW);
404
405 read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */
406 udelay(4); /* 4usec gets 85KHz for 1 pin, 70KHz for 4 pins */
407
408 if (control & GPIO_I2C0_SCL)
409 write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_HIGH);
410 if (control & GPIO_I2C1_SCL)
411 write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_HIGH);
412 if (control & GPIO_I2C2_SCL)
413 write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_HIGH);
414 if (control & GPIO_I2C3_SCL)
415 write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_HIGH);
416
417 read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */
418 udelay(4);
419 }
420
421 /* Restore I2C pins. */
422 for (i = 0; i < saved_pins_count; i++)
423 restore_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]);
424}
425
Chris Ching2269a3c2018-02-05 16:46:41 -0700426int gpio_interrupt_status(gpio_t gpio)
427{
428 uintptr_t gpio_address = gpio_get_address(gpio);
429 uint32_t reg = read32((void *)gpio_address);
430
431 if (reg & GPIO_INT_STATUS) {
432 /* Clear interrupt status, preserve wake status */
433 reg &= ~GPIO_WAKE_STATUS;
434 write32((void *)gpio_address, reg);
435 return 1;
436 }
437
438 return 0;
439}