blob: 2402e8bd12259c500932db03f16ffa57dc50a686 [file] [log] [blame]
Duncan Laurie4721f432018-05-07 15:24:10 -07001/*
2 * This file is part of the coreboot project.
3 *
Duncan Laurie4721f432018-05-07 15:24:10 -07004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <arch/acpi_device.h>
15#include <arch/acpi_pld.h>
16#include <arch/acpigen.h>
17#include <console/console.h>
18#include <device/device.h>
19#include <device/path.h>
20#include <stdint.h>
Duncan Laurie4721f432018-05-07 15:24:10 -070021#include "chip.h"
22
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080023static bool usb_acpi_add_gpios_to_crs(struct drivers_usb_acpi_config *cfg)
24{
25 /*
26 * Return false if reset GPIO is not provided.
27 */
28 if (cfg->reset_gpio.pin_count == 0)
29 return false;
30
31 return true;
32}
33
Duncan Laurie4721f432018-05-07 15:24:10 -070034static void usb_acpi_fill_ssdt_generator(struct device *dev)
35{
36 struct drivers_usb_acpi_config *config = dev->chip_info;
37 const char *path = acpi_device_path(dev);
38
39 if (!dev->enabled || !path || !config)
40 return;
41
42 /* Don't generate output for hubs, only ports */
43 if (config->type == UPC_TYPE_HUB)
44 return;
45
46 acpigen_write_scope(path);
47 if (config->desc)
48 acpigen_write_name_string("_DDN", config->desc);
49 acpigen_write_upc(config->type);
50
51 if (config->use_custom_pld) {
52 /* Use board defined PLD */
53 acpigen_write_pld(&config->custom_pld);
54 } else {
55 /* Fill PLD strucutre based on port type */
56 struct acpi_pld pld;
Duncan Lauriee1eca1d2018-12-01 17:14:35 -080057 acpi_pld_fill_usb(&pld, config->type, &config->group);
Duncan Laurie4721f432018-05-07 15:24:10 -070058 acpigen_write_pld(&pld);
59 }
60
Nick Vaccaro0a495eb2018-11-12 19:43:35 -080061 /* Resources */
62 if (usb_acpi_add_gpios_to_crs(config) == true) {
63 struct acpi_dp *dsd;
64
65 acpigen_write_name("_CRS");
66 acpigen_write_resourcetemplate_header();
67 acpi_device_write_gpio(&config->reset_gpio);
68 acpigen_write_resourcetemplate_footer();
69
70 dsd = acpi_dp_new_table("_DSD");
71 acpi_dp_add_gpio(dsd, "reset-gpio", path, 0, 0,
72 config->reset_gpio.polarity);
73 acpi_dp_write(dsd);
74 }
75
Duncan Laurie4721f432018-05-07 15:24:10 -070076 acpigen_pop_len();
77
78 printk(BIOS_INFO, "%s: %s at %s\n", path,
79 config->desc ? : dev->chip_ops->name, dev_path(dev));
80}
81
82static struct device_operations usb_acpi_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +020083 .read_resources = DEVICE_NOOP,
84 .set_resources = DEVICE_NOOP,
85 .enable_resources = DEVICE_NOOP,
86 .scan_bus = scan_static_bus,
87 .acpi_fill_ssdt = usb_acpi_fill_ssdt_generator,
Duncan Laurie4721f432018-05-07 15:24:10 -070088};
89
90static void usb_acpi_enable(struct device *dev)
91{
92 dev->ops = &usb_acpi_ops;
93}
94
95struct chip_operations drivers_usb_acpi_ops = {
96 CHIP_NAME("USB ACPI Device")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010097 .enable_dev = usb_acpi_enable
Duncan Laurie4721f432018-05-07 15:24:10 -070098};