blob: cf535d7aece49270c18bc1a5c09f505b1fe77bd5 [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 Helddea4e0f2021-09-22 20:05:53 +02004#include <amdblocks/gpio.h>
Felix Held8a3d4d52021-01-13 03:06:21 +01005#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>
Felix Held117823e2021-06-15 16:33:29 +020010#include <soc/aoac_defs.h>
Felix Held8a3d4d52021-01-13 03:06:21 +010011#include <soc/gpio.h>
12#include <soc/southbridge.h>
13#include <soc/uart.h>
14#include <types.h>
15
Felix Heldf3777132021-01-14 00:58:53 +010016static const struct {
Felix Held8a3d4d52021-01-13 03:06:21 +010017 uintptr_t base;
18 struct soc_amd_gpio mux[2];
19} uart_info[] = {
20 [0] = { APU_UART0_BASE, {
21 PAD_NF(GPIO_143, UART0_TXD, PULL_NONE),
22 PAD_NF(GPIO_141, UART0_RXD, PULL_NONE),
23 } },
24 [1] = { APU_UART1_BASE, {
25 PAD_NF(GPIO_140, UART1_TXD, PULL_NONE),
26 PAD_NF(GPIO_142, UART1_RXD, PULL_NONE),
27 } },
28};
29
30uintptr_t get_uart_base(unsigned int idx)
31{
32 if (idx >= ARRAY_SIZE(uart_info))
33 return 0;
34
35 return uart_info[idx].base;
36}
37
38void clear_uart_legacy_config(void)
39{
40 write16((void *)FCH_LEGACY_UART_DECODE, 0);
41}
42
43void set_uart_config(unsigned int idx)
44{
45 if (idx >= ARRAY_SIZE(uart_info))
46 return;
47
Felix Held7011fa12021-09-22 16:36:12 +020048 gpio_configure_pads(uart_info[idx].mux, 2);
Felix Held8a3d4d52021-01-13 03:06:21 +010049}
Felix Held2e4fa0c2021-01-13 03:16:03 +010050
Felix Held63d20082021-02-16 01:35:27 +010051static const char *uart_acpi_name(const struct device *dev)
52{
53 switch (dev->path.mmio.addr) {
54 case APU_UART0_BASE:
55 return "FUR0";
56 case APU_UART1_BASE:
57 return "FUR1";
58 default:
59 return NULL;
60 }
61}
62
Felix Held2e4fa0c2021-01-13 03:16:03 +010063/* Even though this is called enable, it gets called for both enabled and disabled devices. */
64static void uart_enable(struct device *dev)
65{
66 unsigned int dev_id;
67
68 switch (dev->path.mmio.addr) {
69 case APU_UART0_BASE:
70 dev_id = FCH_AOAC_DEV_UART0;
71 break;
72 case APU_UART1_BASE:
73 dev_id = FCH_AOAC_DEV_UART1;
74 break;
75 default:
76 printk(BIOS_ERR, "%s: Unknown device: %s\n", __func__, dev_path(dev));
77 return;
78 }
79
80 if (dev->enabled) {
81 power_on_aoac_device(dev_id);
82 wait_for_aoac_enabled(dev_id);
83 } else {
84 power_off_aoac_device(dev_id);
85 }
86}
87
Felix Heldad6f87d2021-10-12 23:35:48 +020088static void uart_read_resources(struct device *dev)
89{
90 mmio_resource(dev, 0, dev->path.mmio.addr / KiB, 4);
91}
92
Felix Held2e4fa0c2021-01-13 03:16:03 +010093struct device_operations cezanne_uart_mmio_ops = {
Felix Heldad6f87d2021-10-12 23:35:48 +020094 .read_resources = uart_read_resources,
Felix Held2e4fa0c2021-01-13 03:16:03 +010095 .set_resources = noop_set_resources,
96 .scan_bus = scan_static_bus,
97 .enable = uart_enable,
Felix Held63d20082021-02-16 01:35:27 +010098 .acpi_name = uart_acpi_name,
99 .acpi_fill_ssdt = uart_inject_ssdt,
Felix Held2e4fa0c2021-01-13 03:16:03 +0100100};