1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_device.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/mmio.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <drivers/usb/acpi/chip.h>
10 #include <intelblocks/acpi.h>
11 #include <intelblocks/xhci.h>
12 #include <soc/pci_devs.h>
17 #define XHCI_USBCMD 0x80
18 #define USBCMD_HCRST (1 << 1)
20 /* Current Connect Status */
21 #define XHCI_STATUS_CCS (1 << 0)
23 static uint8_t *xhci_mem_base(void)
25 uint32_t mem_base
= pci_read_config32(PCH_DEV_XHCI
, PCI_BASE_ADDRESS_0
);
27 /* Check if the controller is disabled or not present */
28 if (mem_base
== 0 || mem_base
== 0xffffffff)
31 return (uint8_t *)(uintptr_t)(mem_base
& ~PCI_BASE_ADDRESS_MEM_ATTR_MASK
);
34 void xhci_host_reset(void)
36 uint8_t *xhci_base
= xhci_mem_base();
40 setbits8(xhci_base
+ XHCI_USBCMD
, USBCMD_HCRST
);
44 static bool is_usb_port_connected(const struct xhci_usb_info
*info
,
45 unsigned int port_type
, unsigned int port_id
)
47 uintptr_t port_sts_reg
;
49 const struct resource
*res
;
51 /* Support only USB2 or USB3 ports */
52 if (!(port_type
== XHCI_USB2
|| port_type
== XHCI_USB3
))
55 /* Mark out of bound port id as not connected */
56 if ((port_type
== XHCI_USB2
&& port_id
>= info
->num_usb2_ports
) ||
57 (port_type
== XHCI_USB3
&& port_id
>= info
->num_usb3_ports
))
60 /* Calculate port status register address and read the status */
61 res
= probe_resource(PCH_DEV_XHCI
, PCI_BASE_ADDRESS_0
);
62 /* If the memory BAR is not allocated for XHCI, leave the devices enabled */
66 if (port_type
== XHCI_USB2
)
67 port_sts_reg
= (uintptr_t)res
->base
+
68 info
->usb2_port_status_reg
+ port_id
* 0x10;
70 port_sts_reg
= (uintptr_t)res
->base
+
71 info
->usb3_port_status_reg
+ port_id
* 0x10;
72 port_status
= read32p(port_sts_reg
);
74 /* Ensure that the status is not all 1s */
75 if (port_status
== 0xffffffff)
78 return !!(port_status
& XHCI_STATUS_CCS
);
81 void usb_xhci_disable_unused(bool (*ext_usb_xhci_en_cb
)(unsigned int port_type
,
82 unsigned int port_id
))
84 struct device
*xhci
, *hub
= NULL
, *port
= NULL
;
85 const struct xhci_usb_info
*info
= soc_get_xhci_usb_info(PCH_DEVFN_XHCI
);
86 struct drivers_usb_acpi_config
*config
;
89 xhci
= pcidev_path_on_root(PCH_DEVFN_XHCI
);
91 printk(BIOS_ERR
, "%s: Could not locate XHCI device in DT\n", __func__
);
95 while ((hub
= dev_bus_each_child(xhci
->downstream
, hub
)) != NULL
) {
96 while ((port
= dev_bus_each_child(hub
->downstream
, port
)) != NULL
) {
98 config
= config_of(port
);
99 if (config
->type
== UPC_TYPE_INTERNAL
) {
100 /* Probe the connect status of internal ports */
101 enable
= is_usb_port_connected(info
, port
->path
.usb
.port_type
,
102 port
->path
.usb
.port_id
);
103 } else if (ext_usb_xhci_en_cb
) {
104 /* Check the mainboard for the status of external ports */
105 enable
= ext_usb_xhci_en_cb(port
->path
.usb
.port_type
,
106 port
->path
.usb
.port_id
);
110 printk(BIOS_INFO
, "%s: Disabling USB Type%d Id%d\n",
111 __func__
, port
->path
.usb
.port_type
,
112 port
->path
.usb
.port_id
);
119 __weak
void soc_xhci_init(struct device
*dev
) { /* no-op */ }
121 struct device_operations usb_xhci_ops
= {
122 .read_resources
= pci_dev_read_resources
,
123 .set_resources
= pci_dev_set_resources
,
124 .enable_resources
= pci_dev_enable_resources
,
125 .init
= soc_xhci_init
,
126 .ops_pci
= &pci_dev_ops_pci
,
127 .scan_bus
= scan_static_bus
,
128 #if CONFIG(HAVE_ACPI_TABLES)
129 .acpi_name
= soc_acpi_name
,
133 static const unsigned short pci_device_ids
[] = {
134 PCI_DID_INTEL_PTL_H_XHCI
,
135 PCI_DID_INTEL_PTL_U_H_XHCI
,
136 PCI_DID_INTEL_LNL_XHCI
,
137 PCI_DID_INTEL_MTL_XHCI
,
138 PCI_DID_INTEL_APL_XHCI
,
139 PCI_DID_INTEL_CNL_LP_XHCI
,
140 PCI_DID_INTEL_GLK_XHCI
,
141 PCI_DID_INTEL_LWB_XHCI
,
142 PCI_DID_INTEL_LWB_XHCI_SUPER
,
143 PCI_DID_INTEL_CNP_H_XHCI
,
144 PCI_DID_INTEL_ICP_LP_XHCI
,
145 PCI_DID_INTEL_CMP_LP_XHCI
,
146 PCI_DID_INTEL_CMP_H_XHCI
,
147 PCI_DID_INTEL_TGP_LP_XHCI
,
148 PCI_DID_INTEL_TGP_H_XHCI
,
149 PCI_DID_INTEL_MCC_XHCI
,
150 PCI_DID_INTEL_JSP_XHCI
,
151 PCI_DID_INTEL_ADP_P_XHCI
,
152 PCI_DID_INTEL_ADP_S_XHCI
,
153 PCI_DID_INTEL_ADP_M_XHCI
,
154 PCI_DID_INTEL_RPP_S_XHCI
,
155 PCI_DID_INTEL_SNR_XHCI
,
159 static const struct pci_driver pch_usb_xhci __pci_driver
= {
160 .ops
= &usb_xhci_ops
,
161 .vendor
= PCI_VID_INTEL
,
162 .devices
= pci_device_ids
,