blob: 55ef1d361f47d08026d756fcf9d817012e3068af [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Laurie4721f432018-05-07 15:24:10 -07002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi_device.h>
4#include <acpi/acpi_pld.h>
5#include <acpi/acpigen.h>
Duncan Laurie4721f432018-05-07 15:24:10 -07006#include <console/console.h>
7#include <device/device.h>
8#include <device/path.h>
Duncan Laurie4721f432018-05-07 15:24:10 -07009#include "chip.h"
10
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080011static bool usb_acpi_add_gpios_to_crs(struct drivers_usb_acpi_config *cfg)
12{
13 /*
14 * Return false if reset GPIO is not provided.
15 */
16 if (cfg->reset_gpio.pin_count == 0)
17 return false;
18
19 return true;
20}
21
Furquan Shaikh7536a392020-04-24 21:59:21 -070022static void usb_acpi_fill_ssdt_generator(const struct device *dev)
Duncan Laurie4721f432018-05-07 15:24:10 -070023{
24 struct drivers_usb_acpi_config *config = dev->chip_info;
25 const char *path = acpi_device_path(dev);
26
Karthikeyan Ramasubramaniand1c0f952020-11-02 16:26:52 -070027 if (!path || !config)
Duncan Laurie4721f432018-05-07 15:24:10 -070028 return;
29
30 /* Don't generate output for hubs, only ports */
31 if (config->type == UPC_TYPE_HUB)
32 return;
33
34 acpigen_write_scope(path);
35 if (config->desc)
36 acpigen_write_name_string("_DDN", config->desc);
37 acpigen_write_upc(config->type);
38
39 if (config->use_custom_pld) {
40 /* Use board defined PLD */
41 acpigen_write_pld(&config->custom_pld);
42 } else {
43 /* Fill PLD strucutre based on port type */
44 struct acpi_pld pld;
Duncan Lauriee1eca1d2018-12-01 17:14:35 -080045 acpi_pld_fill_usb(&pld, config->type, &config->group);
Duncan Laurie4721f432018-05-07 15:24:10 -070046 acpigen_write_pld(&pld);
47 }
48
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080049 /* Resources */
50 if (usb_acpi_add_gpios_to_crs(config) == true) {
51 struct acpi_dp *dsd;
52
53 acpigen_write_name("_CRS");
54 acpigen_write_resourcetemplate_header();
55 acpi_device_write_gpio(&config->reset_gpio);
56 acpigen_write_resourcetemplate_footer();
57
58 dsd = acpi_dp_new_table("_DSD");
59 acpi_dp_add_gpio(dsd, "reset-gpio", path, 0, 0,
Furquan Shaikhd2d5e442020-07-01 01:37:13 -070060 config->reset_gpio.active_low);
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080061 acpi_dp_write(dsd);
62 }
63
Duncan Laurie4721f432018-05-07 15:24:10 -070064 acpigen_pop_len();
65
66 printk(BIOS_INFO, "%s: %s at %s\n", path,
67 config->desc ? : dev->chip_ops->name, dev_path(dev));
68}
69
70static struct device_operations usb_acpi_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020071 .read_resources = noop_read_resources,
72 .set_resources = noop_set_resources,
Nico Huber68680dd2020-03-31 17:34:52 +020073 .scan_bus = scan_static_bus,
74 .acpi_fill_ssdt = usb_acpi_fill_ssdt_generator,
Duncan Laurie4721f432018-05-07 15:24:10 -070075};
76
77static void usb_acpi_enable(struct device *dev)
78{
79 dev->ops = &usb_acpi_ops;
80}
81
82struct chip_operations drivers_usb_acpi_ops = {
83 CHIP_NAME("USB ACPI Device")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010084 .enable_dev = usb_acpi_enable
Duncan Laurie4721f432018-05-07 15:24:10 -070085};