soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / drivers / uart / acpi / acpi.c
blobc43dc52f2db7fdba07d3b46cb7b30e52056e069c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <acpi/acpi_device.h>
4 #include <acpi/acpigen.h>
5 #include <console/console.h>
6 #include <device/path.h>
7 #include <string.h>
8 #include "chip.h"
10 static bool uart_acpi_add_gpios_to_crs(struct drivers_uart_acpi_config *config)
13 * Return false if:
14 * 1. GPIOs are exported via a power resource, or
15 * 2. Both reset and enable GPIOs are not provided.
17 if (config->has_power_resource ||
18 ((config->reset_gpio.pin_count == 0) &&
19 (config->enable_gpio.pin_count == 0)))
20 return false;
22 return true;
25 static int uart_acpi_write_gpio(struct acpi_gpio *gpio, int *curr_index)
27 int ret = -1;
29 if (gpio->pin_count == 0)
30 return ret;
32 acpi_device_write_gpio(gpio);
33 ret = *curr_index;
34 (*curr_index)++;
36 return ret;
39 static void uart_acpi_fill_ssdt(const struct device *dev)
41 const char *scope = acpi_device_scope(dev);
42 const char *path = acpi_device_path(dev);
43 struct drivers_uart_acpi_config *config = dev->chip_info;
44 int curr_index = 0;
45 int irq_gpio_index = -1;
46 int reset_gpio_index = -1;
47 int enable_gpio_index = -1;
49 if (!scope)
50 return;
52 if (!config->hid) {
53 printk(BIOS_ERR, "%s: ERROR: HID required\n", dev_path(dev));
54 return;
57 acpigen_write_scope(scope);
58 acpigen_write_device(acpi_device_name(dev));
60 acpigen_write_name_string("_HID", config->hid);
61 if (config->cid)
62 acpigen_write_name_string("_CID", config->cid);
63 acpigen_write_name_integer("_UID", config->uid);
64 acpigen_write_name_string("_DDN", config->desc);
65 acpigen_write_STA(acpi_device_status(dev));
67 /* Resources */
68 acpigen_write_name("_CRS");
69 acpigen_write_resourcetemplate_header();
71 /* Fix up resource pointer to this scope */
72 config->uart.resource = scope;
73 acpi_device_write_uart(&config->uart);
75 /* Use either Interrupt() or GpioInt() */
76 if (config->irq_gpio.pin_count)
77 acpi_device_write_gpio(&config->irq_gpio);
78 else
79 acpi_device_write_interrupt(&config->irq);
81 /* Add enable/reset GPIOs if needed */
82 if (uart_acpi_add_gpios_to_crs(config)) {
83 reset_gpio_index = uart_acpi_write_gpio(&config->reset_gpio,
84 &curr_index);
85 enable_gpio_index = uart_acpi_write_gpio(&config->enable_gpio,
86 &curr_index);
88 acpigen_write_resourcetemplate_footer();
90 /* Wake capabilities */
91 if (config->wake) {
92 acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D3_HOT);
93 acpigen_write_PRW(config->wake, SLP_TYP_S3);
96 /* Write device properties if needed */
97 if (config->compat_string || irq_gpio_index >= 0 ||
98 reset_gpio_index >= 0 || enable_gpio_index >= 0) {
99 struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
100 if (config->compat_string)
101 acpi_dp_add_string(dsd, "compatible",
102 config->compat_string);
103 if (irq_gpio_index >= 0)
104 acpi_dp_add_gpio(dsd, "irq-gpios", path,
105 irq_gpio_index, 0,
106 config->irq_gpio.active_low);
107 if (reset_gpio_index >= 0)
108 acpi_dp_add_gpio(dsd, "reset-gpios", path,
109 reset_gpio_index, 0,
110 config->reset_gpio.active_low);
111 if (enable_gpio_index >= 0)
112 acpi_dp_add_gpio(dsd, "enable-gpios", path,
113 enable_gpio_index, 0,
114 config->enable_gpio.active_low);
115 acpi_dp_write(dsd);
118 /* Power Resource */
119 if (config->has_power_resource) {
120 const struct acpi_power_res_params power_res_params = {
121 &config->reset_gpio,
122 config->reset_delay_ms,
123 config->reset_off_delay_ms,
124 &config->enable_gpio,
125 config->enable_delay_ms,
126 config->enable_off_delay_ms,
127 &config->stop_gpio,
128 config->stop_delay_ms,
129 config->stop_off_delay_ms
131 acpi_device_add_power_res(&power_res_params);
134 acpigen_pop_len(); /* Device */
135 acpigen_pop_len(); /* Scope */
137 printk(BIOS_INFO, "%s: %s at %s\n", path, config->desc, dev_path(dev));
140 static const char *uart_acpi_name(const struct device *dev)
142 struct drivers_uart_acpi_config *config = dev->chip_info;
143 static char name[5];
145 if (config->name)
146 return config->name;
148 snprintf(name, sizeof(name), "D%03.3X", dev->path.generic.id);
149 return name;
152 static struct device_operations uart_acpi_dev_ops = {
153 .read_resources = noop_read_resources,
154 .set_resources = noop_set_resources,
155 .acpi_fill_ssdt = uart_acpi_fill_ssdt,
156 .acpi_name = uart_acpi_name,
159 static void uart_acpi_enable(struct device *dev)
161 struct drivers_uart_acpi_config *config = dev->chip_info;
163 if (config->desc)
164 dev->name = config->desc;
165 else
166 config->desc = dev->chip_ops->name;
168 dev->ops = &uart_acpi_dev_ops;
171 struct chip_operations drivers_uart_acpi_ops = {
172 CHIP_NAME("ACPI UART Device")
173 .enable_dev = uart_acpi_enable