blob: c48c3da40f8c5df8606ce3b2ec1db1e3e3d706e9 [file] [log] [blame]
Felix Held3c44c622022-01-10 20:57:29 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3/* TODO: Check if this is still correct */
4
5#include <amdblocks/aoac.h>
6#include <amdblocks/gpio.h>
7#include <amdblocks/uart.h>
8#include <commonlib/helpers.h>
9#include <console/console.h>
10#include <device/device.h>
11#include <device/mmio.h>
12#include <soc/aoac_defs.h>
13#include <soc/gpio.h>
14#include <soc/southbridge.h>
15#include <soc/uart.h>
16#include <types.h>
17
18static const struct {
19 uintptr_t base;
20 struct soc_amd_gpio mux[2];
21} uart_info[] = {
22 [0] = { APU_UART0_BASE, {
23 PAD_NF(GPIO_143, UART0_TXD, PULL_NONE),
24 PAD_NF(GPIO_141, UART0_RXD, PULL_NONE),
25 } },
26 [1] = { APU_UART1_BASE, {
27 PAD_NF(GPIO_140, UART1_TXD, PULL_NONE),
28 PAD_NF(GPIO_142, UART1_RXD, PULL_NONE),
29 } },
30};
31
32uintptr_t get_uart_base(unsigned int idx)
33{
34 if (idx >= ARRAY_SIZE(uart_info))
35 return 0;
36
37 return uart_info[idx].base;
38}
39
40void clear_uart_legacy_config(void)
41{
42 write16((void *)FCH_LEGACY_UART_DECODE, 0);
43}
44
45void set_uart_config(unsigned int idx)
46{
47 if (idx >= ARRAY_SIZE(uart_info))
48 return;
49
50 gpio_configure_pads(uart_info[idx].mux, 2);
51}
52
53static const char *uart_acpi_name(const struct device *dev)
54{
55 switch (dev->path.mmio.addr) {
56 case APU_UART0_BASE:
57 return "FUR0";
58 case APU_UART1_BASE:
59 return "FUR1";
60 default:
61 return NULL;
62 }
63}
64
65/* Even though this is called enable, it gets called for both enabled and disabled devices. */
66static void uart_enable(struct device *dev)
67{
68 unsigned int dev_id;
69
70 switch (dev->path.mmio.addr) {
71 case APU_UART0_BASE:
72 dev_id = FCH_AOAC_DEV_UART0;
73 break;
74 case APU_UART1_BASE:
75 dev_id = FCH_AOAC_DEV_UART1;
76 break;
77 default:
78 printk(BIOS_ERR, "%s: Unknown device: %s\n", __func__, dev_path(dev));
79 return;
80 }
81
82 if (dev->enabled) {
83 power_on_aoac_device(dev_id);
84 wait_for_aoac_enabled(dev_id);
85 } else {
86 power_off_aoac_device(dev_id);
87 }
88}
89
90static void uart_read_resources(struct device *dev)
91{
92 mmio_resource(dev, 0, dev->path.mmio.addr / KiB, 4);
93}
94
95struct device_operations sabrina_uart_mmio_ops = {
96 .read_resources = uart_read_resources,
97 .set_resources = noop_set_resources,
98 .scan_bus = scan_static_bus,
99 .enable = uart_enable,
100 .acpi_name = uart_acpi_name,
101 .acpi_fill_ssdt = uart_inject_ssdt,
102};