blob: a6a004f76082c9c9141fde561fdf3cb53b9ad4b5 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Duncan Laurie4721f432018-05-07 15:24:10 -07003
4#include <arch/acpi_device.h>
5#include <arch/acpi_pld.h>
6#include <arch/acpigen.h>
7#include <console/console.h>
8#include <device/device.h>
9#include <device/path.h>
10#include <stdint.h>
Duncan Laurie4721f432018-05-07 15:24:10 -070011#include "chip.h"
12
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080013static bool usb_acpi_add_gpios_to_crs(struct drivers_usb_acpi_config *cfg)
14{
15 /*
16 * Return false if reset GPIO is not provided.
17 */
18 if (cfg->reset_gpio.pin_count == 0)
19 return false;
20
21 return true;
22}
23
Duncan Laurie4721f432018-05-07 15:24:10 -070024static void usb_acpi_fill_ssdt_generator(struct device *dev)
25{
26 struct drivers_usb_acpi_config *config = dev->chip_info;
27 const char *path = acpi_device_path(dev);
28
29 if (!dev->enabled || !path || !config)
30 return;
31
32 /* Don't generate output for hubs, only ports */
33 if (config->type == UPC_TYPE_HUB)
34 return;
35
36 acpigen_write_scope(path);
37 if (config->desc)
38 acpigen_write_name_string("_DDN", config->desc);
39 acpigen_write_upc(config->type);
40
41 if (config->use_custom_pld) {
42 /* Use board defined PLD */
43 acpigen_write_pld(&config->custom_pld);
44 } else {
45 /* Fill PLD strucutre based on port type */
46 struct acpi_pld pld;
Duncan Lauriee1eca1d2018-12-01 17:14:35 -080047 acpi_pld_fill_usb(&pld, config->type, &config->group);
Duncan Laurie4721f432018-05-07 15:24:10 -070048 acpigen_write_pld(&pld);
49 }
50
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080051 /* Resources */
52 if (usb_acpi_add_gpios_to_crs(config) == true) {
53 struct acpi_dp *dsd;
54
55 acpigen_write_name("_CRS");
56 acpigen_write_resourcetemplate_header();
57 acpi_device_write_gpio(&config->reset_gpio);
58 acpigen_write_resourcetemplate_footer();
59
60 dsd = acpi_dp_new_table("_DSD");
61 acpi_dp_add_gpio(dsd, "reset-gpio", path, 0, 0,
62 config->reset_gpio.polarity);
63 acpi_dp_write(dsd);
64 }
65
Duncan Laurie4721f432018-05-07 15:24:10 -070066 acpigen_pop_len();
67
68 printk(BIOS_INFO, "%s: %s at %s\n", path,
69 config->desc ? : dev->chip_ops->name, dev_path(dev));
70}
71
72static struct device_operations usb_acpi_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020073 .read_resources = noop_read_resources,
74 .set_resources = noop_set_resources,
Nico Huber68680dd2020-03-31 17:34:52 +020075 .scan_bus = scan_static_bus,
76 .acpi_fill_ssdt = usb_acpi_fill_ssdt_generator,
Duncan Laurie4721f432018-05-07 15:24:10 -070077};
78
79static void usb_acpi_enable(struct device *dev)
80{
81 dev->ops = &usb_acpi_ops;
82}
83
84struct chip_operations drivers_usb_acpi_ops = {
85 CHIP_NAME("USB ACPI Device")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010086 .enable_dev = usb_acpi_enable
Duncan Laurie4721f432018-05-07 15:24:10 -070087};