blob: bab2c0f436d950302e6e43ed314e9e2e48f34bf9 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Subrata Banika554b0c2017-02-16 16:08:49 +05303
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpi_device.h>
Karthikeyan Ramasubramanianef0c2262019-06-06 15:35:11 -06005#include <console/console.h>
Subrata Banika554b0c2017-02-16 16:08:49 +05306#include <device/device.h>
7#include <device/pci.h>
8#include <device/pci_ids.h>
Karthikeyan Ramasubramanianef0c2262019-06-06 15:35:11 -06009#include <drivers/usb/acpi/chip.h>
Duncan Lauriebf713b02018-05-07 15:33:18 -070010#include <intelblocks/acpi.h>
Subrata Banika554b0c2017-02-16 16:08:49 +053011#include <intelblocks/xhci.h>
Karthikeyan Ramasubramanianef0c2262019-06-06 15:35:11 -060012#include <soc/pci_devs.h>
13
14#define XHCI_USB2 2
15#define XHCI_USB3 3
16
17/* Current Connect Status */
18#define XHCI_STATUS_CCS (1 << 0)
19
20static bool is_usb_port_connected(const struct xhci_usb_info *info,
21 unsigned int port_type, unsigned int port_id)
22{
23 uintptr_t port_sts_reg;
24 uint32_t port_status;
25 const struct resource *res;
26
27 /* Support only USB2 or USB3 ports */
28 if (!(port_type == XHCI_USB2 || port_type == XHCI_USB3))
29 return false;
30
31 /* Mark out of bound port id as not connected */
32 if ((port_type == XHCI_USB2 && port_id >= info->num_usb2_ports) ||
33 (port_type == XHCI_USB3 && port_id >= info->num_usb3_ports))
34 return false;
35
36 /* Calculate port status register address and read the status */
37 res = find_resource(PCH_DEV_XHCI, PCI_BASE_ADDRESS_0);
38 /* If the memory BAR is not allocated for XHCI, leave the devices enabled */
39 if (!res)
40 return true;
41
42 if (port_type == XHCI_USB2)
43 port_sts_reg = (uintptr_t)res->base +
44 info->usb2_port_status_reg + port_id * 0x10;
45 else
46 port_sts_reg = (uintptr_t)res->base +
47 info->usb3_port_status_reg + port_id * 0x10;
48 port_status = read32((void *)port_sts_reg);
49
50 /* Ensure that the status is not all 1s */
51 if (port_status == 0xffffffff)
52 return false;
53
54 return !!(port_status & XHCI_STATUS_CCS);
55}
56
57void usb_xhci_disable_unused(bool (*ext_usb_xhci_en_cb)(unsigned int port_type,
58 unsigned int port_id))
59{
60 struct device *xhci, *hub = NULL, *port = NULL;
61 const struct xhci_usb_info *info = soc_get_xhci_usb_info();
62 struct drivers_usb_acpi_config *config;
63 bool enable;
64
65 xhci = pcidev_path_on_root(PCH_DEVFN_XHCI);
66 if (!xhci) {
67 printk(BIOS_ERR, "%s: Could not locate XHCI device in DT\n", __func__);
68 return;
69 }
70
71 while ((hub = dev_bus_each_child(xhci->link_list, hub)) != NULL) {
72 while ((port = dev_bus_each_child(hub->link_list, port)) != NULL) {
73 enable = true;
74 config = config_of(port);
75 if (config->type == UPC_TYPE_INTERNAL) {
76 /* Probe the connect status of internal ports */
77 enable = is_usb_port_connected(info, port->path.usb.port_type,
78 port->path.usb.port_id);
79 } else if (ext_usb_xhci_en_cb) {
80 /* Check the mainboard for the status of external ports */
81 enable = ext_usb_xhci_en_cb(port->path.usb.port_type,
82 port->path.usb.port_id);
83 }
84
85 if (!enable) {
86 printk(BIOS_INFO, "%s: Disabling USB Type%d Id%d\n",
87 __func__, port->path.usb.port_type,
88 port->path.usb.port_id);
89 port->enabled = 0;
90 }
91 }
92 }
93}
Subrata Banika554b0c2017-02-16 16:08:49 +053094
Aaron Durbin64031672018-04-21 14:45:32 -060095__weak void soc_xhci_init(struct device *dev) { /* no-op */ }
Subrata Banika554b0c2017-02-16 16:08:49 +053096
97static struct device_operations usb_xhci_ops = {
Elyes HAOUAS1d191272018-11-27 12:23:48 +010098 .read_resources = pci_dev_read_resources,
99 .set_resources = pci_dev_set_resources,
100 .enable_resources = pci_dev_enable_resources,
Subrata Banika554b0c2017-02-16 16:08:49 +0530101 .init = soc_xhci_init,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530102 .ops_pci = &pci_dev_ops_pci,
Nico Hubera89c82e2017-09-14 15:40:28 +0200103 .scan_bus = scan_static_bus,
Julius Wernercd49cce2019-03-05 16:53:33 -0800104#if CONFIG(HAVE_ACPI_TABLES)
Elyes HAOUAS1d191272018-11-27 12:23:48 +0100105 .acpi_name = soc_acpi_name,
Subrata Banik98376b82018-05-22 16:18:16 +0530106#endif
Subrata Banika554b0c2017-02-16 16:08:49 +0530107};
108
109static const unsigned short pci_device_ids[] = {
Aaron Durbinf27d98f2017-05-05 16:52:52 -0500110 PCI_DEVICE_ID_INTEL_APL_XHCI,
Lijian Zhaobbedef92017-07-29 16:38:38 -0700111 PCI_DEVICE_ID_INTEL_CNL_LP_XHCI,
Subrata Banikfc98c012017-05-03 13:29:19 +0530112 PCI_DEVICE_ID_INTEL_GLK_XHCI,
113 PCI_DEVICE_ID_INTEL_SPT_LP_XHCI,
V Sowmya7c150472018-01-23 14:44:45 +0530114 PCI_DEVICE_ID_INTEL_SPT_H_XHCI,
Maxim Polyakov571d07d2019-08-22 13:11:32 +0300115 PCI_DEVICE_ID_INTEL_LWB_XHCI,
116 PCI_DEVICE_ID_INTEL_LWB_XHCI_SUPER,
V Sowmyaacc2a482018-01-23 15:27:23 +0530117 PCI_DEVICE_ID_INTEL_KBP_H_XHCI,
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +0800118 PCI_DEVICE_ID_INTEL_CNP_H_XHCI,
Aamir Bohra9eac0392018-06-30 12:07:04 +0530119 PCI_DEVICE_ID_INTEL_ICP_LP_XHCI,
Ronak Kanabarda7ffb482019-02-05 01:51:13 +0530120 PCI_DEVICE_ID_INTEL_CMP_LP_XHCI,
Gaggery Tsai12a651c2019-12-05 11:23:20 -0800121 PCI_DEVICE_ID_INTEL_CMP_H_XHCI,
Ravi Sarawadi6b5bf402019-10-21 22:25:04 -0700122 PCI_DEVICE_ID_INTEL_TGP_LP_XHCI,
Tan, Lean Sheng26136092020-01-20 19:13:56 -0800123 PCI_DEVICE_ID_INTEL_MCC_XHCI,
Meera Ravindranath3f4af0d2020-02-12 16:01:22 +0530124 PCI_DEVICE_ID_INTEL_JSP_XHCI,
Subrata Banika554b0c2017-02-16 16:08:49 +0530125 0
126};
127
128static const struct pci_driver pch_usb_xhci __pci_driver = {
129 .ops = &usb_xhci_ops,
130 .vendor = PCI_VENDOR_ID_INTEL,
131 .devices = pci_device_ids,
132};