coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
xhci.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi_device.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
9 #include <intelblocks/acpi.h>
10 #include <intelblocks/xhci.h>
11 #include <soc/pci_devs.h>
12 
13 #define XHCI_USB2 2
14 #define XHCI_USB3 3
15 
16 #define XHCI_USBCMD 0x80
17 #define USBCMD_HCRST (1 << 1)
18 
19 /* Current Connect Status */
20 #define XHCI_STATUS_CCS (1 << 0)
21 
22 static uint8_t *xhci_mem_base(void)
23 {
25 
26  /* Check if the controller is disabled or not present */
27  if (mem_base == 0 || mem_base == 0xffffffff)
28  return 0;
29 
30  return (uint8_t *)(mem_base & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
31 }
32 
33 void xhci_host_reset(void)
34 {
35  uint8_t *xhci_base = xhci_mem_base();
36  if (!xhci_base)
37  return;
38 
39  setbits8(xhci_base + XHCI_USBCMD, USBCMD_HCRST);
40 }
41 
42 #if ENV_RAMSTAGE
43 static bool is_usb_port_connected(const struct xhci_usb_info *info,
44  unsigned int port_type, unsigned int port_id)
45 {
46  uintptr_t port_sts_reg;
47  uint32_t port_status;
48  const struct resource *res;
49 
50  /* Support only USB2 or USB3 ports */
51  if (!(port_type == XHCI_USB2 || port_type == XHCI_USB3))
52  return false;
53 
54  /* Mark out of bound port id as not connected */
55  if ((port_type == XHCI_USB2 && port_id >= info->num_usb2_ports) ||
56  (port_type == XHCI_USB3 && port_id >= info->num_usb3_ports))
57  return false;
58 
59  /* Calculate port status register address and read the status */
61  /* If the memory BAR is not allocated for XHCI, leave the devices enabled */
62  if (!res)
63  return true;
64 
65  if (port_type == XHCI_USB2)
66  port_sts_reg = (uintptr_t)res->base +
67  info->usb2_port_status_reg + port_id * 0x10;
68  else
69  port_sts_reg = (uintptr_t)res->base +
70  info->usb3_port_status_reg + port_id * 0x10;
71  port_status = read32((void *)port_sts_reg);
72 
73  /* Ensure that the status is not all 1s */
74  if (port_status == 0xffffffff)
75  return false;
76 
77  return !!(port_status & XHCI_STATUS_CCS);
78 }
79 
80 void usb_xhci_disable_unused(bool (*ext_usb_xhci_en_cb)(unsigned int port_type,
81  unsigned int port_id))
82 {
83  struct device *xhci, *hub = NULL, *port = NULL;
86  bool enable;
87 
89  if (!xhci) {
90  printk(BIOS_ERR, "%s: Could not locate XHCI device in DT\n", __func__);
91  return;
92  }
93 
94  while ((hub = dev_bus_each_child(xhci->link_list, hub)) != NULL) {
95  while ((port = dev_bus_each_child(hub->link_list, port)) != NULL) {
96  enable = true;
98  if (config->type == UPC_TYPE_INTERNAL) {
99  /* Probe the connect status of internal ports */
100  enable = is_usb_port_connected(info, port->path.usb.port_type,
101  port->path.usb.port_id);
102  } else if (ext_usb_xhci_en_cb) {
103  /* Check the mainboard for the status of external ports */
104  enable = ext_usb_xhci_en_cb(port->path.usb.port_type,
105  port->path.usb.port_id);
106  }
107 
108  if (!enable) {
109  printk(BIOS_INFO, "%s: Disabling USB Type%d Id%d\n",
110  __func__, port->path.usb.port_type,
111  port->path.usb.port_id);
112  port->enabled = 0;
113  }
114  }
115  }
116 }
117 
118 __weak void soc_xhci_init(struct device *dev) { /* no-op */ }
119 
120 static struct device_operations usb_xhci_ops = {
122  .set_resources = pci_dev_set_resources,
123  .enable_resources = pci_dev_enable_resources,
124  .init = soc_xhci_init,
125  .ops_pci = &pci_dev_ops_pci,
126  .scan_bus = scan_static_bus,
127 #if CONFIG(HAVE_ACPI_TABLES)
128  .acpi_name = soc_acpi_name,
129 #endif
130 };
131 
132 static const unsigned short pci_device_ids[] = {
153  0
154 };
155 
156 static const struct pci_driver pch_usb_xhci __pci_driver = {
157  .ops = &usb_xhci_ops,
158  .vendor = PCI_VID_INTEL,
159  .devices = pci_device_ids,
160 };
161 #endif
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
DEVTREE_CONST struct device * dev_bus_each_child(const struct bus *parent, DEVTREE_CONST struct device *prev_child)
Given a device and previous match iterate through all the children.
Definition: device_const.c:353
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
static struct smmstore_params_info info
Definition: ramstage.c:12
port
Definition: i915.h:29
@ UPC_TYPE_INTERNAL
Definition: acpi.h:1055
static DEVTREE_CONST void * config_of(const struct device *dev)
Definition: device.h:382
#define setbits8(addr, set)
Definition: mmio.h:19
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
#define PCI_BASE_ADDRESS_MEM_ATTR_MASK
Definition: pci_def.h:77
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
struct pci_operations pci_dev_ops_pci
Default device operation for PCI devices.
Definition: pci_device.c:911
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_DID_INTEL_CNP_H_XHCI
Definition: pci_ids.h:4122
#define PCI_DID_INTEL_JSP_XHCI
Definition: pci_ids.h:4131
#define PCI_DID_INTEL_UPT_H_XHCI
Definition: pci_ids.h:4120
#define PCI_DID_INTEL_MCC_XHCI
Definition: pci_ids.h:4130
#define PCI_DID_INTEL_GLK_XHCI
Definition: pci_ids.h:4115
#define PCI_DID_INTEL_LWB_XHCI_SUPER
Definition: pci_ids.h:4119
#define PCI_DID_INTEL_APL_XHCI
Definition: pci_ids.h:4114
#define PCI_DID_INTEL_TGP_LP_XHCI
Definition: pci_ids.h:4126
#define PCI_DID_INTEL_SPT_H_XHCI
Definition: pci_ids.h:4117
#define PCI_DID_INTEL_SPT_LP_XHCI
Definition: pci_ids.h:4116
#define PCI_DID_INTEL_MTL_XHCI
Definition: pci_ids.h:4137
#define PCI_DID_INTEL_LWB_XHCI
Definition: pci_ids.h:4118
#define PCI_DID_INTEL_CMP_LP_XHCI
Definition: pci_ids.h:4124
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
#define PCI_DID_INTEL_ADP_P_XHCI
Definition: pci_ids.h:4132
#define PCI_DID_INTEL_TGP_H_XHCI
Definition: pci_ids.h:4128
#define PCI_DID_INTEL_CMP_H_XHCI
Definition: pci_ids.h:4125
#define PCI_DID_INTEL_ADP_M_XHCI
Definition: pci_ids.h:4136
#define PCI_DID_INTEL_CNL_LP_XHCI
Definition: pci_ids.h:4121
#define PCI_DID_INTEL_ICP_LP_XHCI
Definition: pci_ids.h:4123
#define PCI_DID_INTEL_ADP_S_XHCI
Definition: pci_ids.h:4133
void scan_static_bus(struct device *bus)
Definition: root_device.c:89
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
static const char * soc_acpi_name(const struct device *dev)
Definition: chip.c:29
#define PCH_DEV_XHCI
Definition: pci_devs.h:128
#define PCH_DEVFN_XHCI
Definition: pci_devs.h:124
const struct xhci_usb_info * soc_get_xhci_usb_info(pci_devfn_t xhci_dev)
Definition: xhci.c:36
static const struct pci_driver baytrail_xhci __pci_driver
Definition: xhci.c:239
void usb_xhci_disable_unused(bool(*ext_usb_xhci_en_cb)(unsigned int port_type, unsigned int port_id))
static const unsigned short pci_device_ids[]
Definition: xhci.c:28
#define XHCI_USBCMD
Definition: xhci.c:16
#define XHCI_USB2
Definition: xhci.c:13
#define USBCMD_HCRST
Definition: xhci.c:17
static uint8_t * xhci_mem_base(void)
Definition: xhci.c:22
#define XHCI_STATUS_CCS
Definition: xhci.c:20
void xhci_host_reset(void)
Definition: xhci.c:33
#define XHCI_USB3
Definition: xhci.c:14
static struct device_operations usb_xhci_ops
Definition: xhci.c:23
void soc_xhci_init(struct device *dev)
Definition: xhci.c:56
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
resource_t base
Definition: resource.h:45