blob: 6c82f1a948c82717dad22bed57e3469997998436 [file] [log] [blame]
Felix Held8a3d4d52021-01-13 03:06:21 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
Felix Held2e4fa0c2021-01-13 03:16:03 +01003#include <amdblocks/aoac.h>
Felix Held8a3d4d52021-01-13 03:06:21 +01004#include <amdblocks/gpio_banks.h>
5#include <amdblocks/uart.h>
6#include <commonlib/helpers.h>
Felix Held2e4fa0c2021-01-13 03:16:03 +01007#include <console/console.h>
8#include <device/device.h>
Felix Held8a3d4d52021-01-13 03:06:21 +01009#include <device/mmio.h>
10#include <soc/gpio.h>
11#include <soc/southbridge.h>
12#include <soc/uart.h>
13#include <types.h>
14
Felix Heldf3777132021-01-14 00:58:53 +010015static const struct {
Felix Held8a3d4d52021-01-13 03:06:21 +010016 uintptr_t base;
17 struct soc_amd_gpio mux[2];
18} uart_info[] = {
19 [0] = { APU_UART0_BASE, {
20 PAD_NF(GPIO_143, UART0_TXD, PULL_NONE),
21 PAD_NF(GPIO_141, UART0_RXD, PULL_NONE),
22 } },
23 [1] = { APU_UART1_BASE, {
24 PAD_NF(GPIO_140, UART1_TXD, PULL_NONE),
25 PAD_NF(GPIO_142, UART1_RXD, PULL_NONE),
26 } },
27};
28
29uintptr_t get_uart_base(unsigned int idx)
30{
31 if (idx >= ARRAY_SIZE(uart_info))
32 return 0;
33
34 return uart_info[idx].base;
35}
36
37void clear_uart_legacy_config(void)
38{
39 write16((void *)FCH_LEGACY_UART_DECODE, 0);
40}
41
42void set_uart_config(unsigned int idx)
43{
44 if (idx >= ARRAY_SIZE(uart_info))
45 return;
46
47 program_gpios(uart_info[idx].mux, 2);
48}
Felix Held2e4fa0c2021-01-13 03:16:03 +010049
Felix Held63d20082021-02-16 01:35:27 +010050static const char *uart_acpi_name(const struct device *dev)
51{
52 switch (dev->path.mmio.addr) {
53 case APU_UART0_BASE:
54 return "FUR0";
55 case APU_UART1_BASE:
56 return "FUR1";
57 default:
58 return NULL;
59 }
60}
61
Felix Held2e4fa0c2021-01-13 03:16:03 +010062/* Even though this is called enable, it gets called for both enabled and disabled devices. */
63static void uart_enable(struct device *dev)
64{
65 unsigned int dev_id;
66
67 switch (dev->path.mmio.addr) {
68 case APU_UART0_BASE:
69 dev_id = FCH_AOAC_DEV_UART0;
70 break;
71 case APU_UART1_BASE:
72 dev_id = FCH_AOAC_DEV_UART1;
73 break;
74 default:
75 printk(BIOS_ERR, "%s: Unknown device: %s\n", __func__, dev_path(dev));
76 return;
77 }
78
79 if (dev->enabled) {
80 power_on_aoac_device(dev_id);
81 wait_for_aoac_enabled(dev_id);
82 } else {
83 power_off_aoac_device(dev_id);
84 }
85}
86
87struct device_operations cezanne_uart_mmio_ops = {
88 .read_resources = noop_read_resources,
89 .set_resources = noop_set_resources,
90 .scan_bus = scan_static_bus,
91 .enable = uart_enable,
Felix Held63d20082021-02-16 01:35:27 +010092 .acpi_name = uart_acpi_name,
93 .acpi_fill_ssdt = uart_inject_ssdt,
Felix Held2e4fa0c2021-01-13 03:16:03 +010094};