coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
usb_xhci.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cpu/x86/smm.h>
4 #include <delay.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
8 #include <device/mmio.h>
9 #include <device/pci_ops.h>
10 #include "chip.h"
11 #include "iobp.h"
12 #include "pch.h"
13 
14 #ifdef __SIMPLE_DEVICE__
15 static u8 *usb_xhci_mem_base(pci_devfn_t dev)
16 #else
17 static u8 *usb_xhci_mem_base(struct device *dev)
18 #endif
19 {
20  u32 mem_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
21 
22  /* Check if the controller is disabled or not present */
23  if (mem_base == 0 || mem_base == 0xffffffff)
24  return 0;
25 
26  return (u8 *)(mem_base & ~0xf);
27 }
28 
29 static int usb_xhci_port_count_usb3(u8 *mem_base)
30 {
31  if (!mem_base) {
32  /* Do not proceed if BAR is invalid */
33  return 0;
34  }
35 
36  if (pch_is_lp()) {
37  /* LynxPoint-LP has 4 SS ports */
38  return 4;
39  }
40 
41  /* LynxPoint-H can have 0, 2, 4, or 6 SS ports */
42  u32 fus = read32(mem_base + XHCI_USB3FUS);
43  fus >>= XHCI_USB3FUS_SS_SHIFT;
44  fus &= XHCI_USB3FUS_SS_MASK;
45  switch (fus) {
46  case 3: return 0;
47  case 2: return 2;
48  case 1: return 4;
49  case 0:
50  default: return 6;
51  }
52 }
53 
54 static void usb_xhci_reset_status_usb3(u8 *mem_base, int port)
55 {
56  u8 *portsc = mem_base + XHCI_USB3_PORTSC(port);
57  u32 status = read32(portsc);
58  /* Do not set Port Enabled/Disabled field */
59  status &= ~XHCI_USB3_PORTSC_PED;
60  /* Clear all change status bits */
61  status |= XHCI_USB3_PORTSC_CHST;
62  write32(portsc, status);
63 }
64 
65 static void usb_xhci_reset_port_usb3(u8 *mem_base, int port)
66 {
67  u8 *portsc = mem_base + XHCI_USB3_PORTSC(port);
68  write32(portsc, read32(portsc) | XHCI_USB3_PORTSC_WPR);
69 }
70 
71 #define XHCI_RESET_DELAY_US 1000 /* 1ms */
72 #define XHCI_RESET_TIMEOUT 100 /* 100ms */
73 
74 /*
75  * 1) Wait until port is done polling
76  * 2) If port is disconnected
77  * a) Issue warm port reset
78  * b) Poll for warm reset complete
79  * c) Write 1 to port change status bits
80  */
81 #ifdef __SIMPLE_DEVICE__
82 static void usb_xhci_reset_usb3(pci_devfn_t dev, int all)
83 #else
84 static void usb_xhci_reset_usb3(struct device *dev, int all)
85 #endif
86 {
87  u32 status, port_disabled;
88  int timeout, port;
89  u8 *mem_base = usb_xhci_mem_base(dev);
90  int port_count = usb_xhci_port_count_usb3(mem_base);
91 
92  if (!port_count)
93  return;
94 
95  /* Get mask of disabled ports */
96  port_disabled = pci_read_config32(dev, XHCI_USB3PDO);
97 
98  /* Wait until all enabled ports are done polling */
99  for (timeout = XHCI_RESET_TIMEOUT; timeout; timeout--) {
100  int complete = 1;
101  for (port = 0; port < port_count; port++) {
102  /* Skip disabled ports */
103  if (port_disabled & (1 << port))
104  continue;
105  /* Read port link status field */
106  status = read32(mem_base + XHCI_USB3_PORTSC(port));
107  status &= XHCI_USB3_PORTSC_PLS;
108  if (status == XHCI_PLSR_POLLING)
109  complete = 0;
110  }
111  /* Exit if all ports not polling */
112  if (complete)
113  break;
115  }
116 
117  /* Reset all requested ports */
118  for (port = 0; port < port_count; port++) {
119  u8 *portsc = mem_base + XHCI_USB3_PORTSC(port);
120  /* Skip disabled ports */
121  if (port_disabled & (1 << port))
122  continue;
123  status = read32(portsc) & XHCI_USB3_PORTSC_PLS;
124  /* Reset all or only disconnected ports */
125  if (all || (status == XHCI_PLSR_RXDETECT ||
126  status == XHCI_PLSR_POLLING))
127  usb_xhci_reset_port_usb3(mem_base, port);
128  else
129  port_disabled |= 1 << port;
130  }
131 
132  /* Wait for warm reset complete on all reset ports */
133  for (timeout = XHCI_RESET_TIMEOUT; timeout; timeout--) {
134  int complete = 1;
135  for (port = 0; port < port_count; port++) {
136  /* Only check ports that were reset */
137  if (port_disabled & (1 << port))
138  continue;
139  /* Check if warm reset is complete */
140  status = read32(mem_base + XHCI_USB3_PORTSC(port));
141  if (!(status & XHCI_USB3_PORTSC_WRC))
142  complete = 0;
143  }
144  /* Check for warm reset complete in any port */
145  if (complete)
146  break;
148  }
149 
150  /* Clear port change status bits */
151  for (port = 0; port < port_count; port++)
152  usb_xhci_reset_status_usb3(mem_base, port);
153 }
154 
155 #ifdef __SIMPLE_DEVICE__
156 
157 /* Handler for XHCI controller on entry to S3/S4/S5 */
158 void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
159 {
160  u32 reg32;
161  u8 *mem_base = usb_xhci_mem_base(dev);
162 
163  if (!mem_base || slp_typ < ACPI_S3)
164  return;
165 
166  if (pch_is_lp()) {
167  /* Set D0 state */
169 
170  /* Clear PCI 0xB0[14:13] */
171  pci_and_config32(dev, 0xb0, ~((1 << 14) | (1 << 13)));
172 
173  /* Clear MMIO 0x816c[14,2] */
174  reg32 = read32(mem_base + 0x816c);
175  reg32 &= ~((1 << 14) | (1 << 2));
176  write32(mem_base + 0x816c, reg32);
177 
178  /* Reset disconnected USB3 ports */
179  usb_xhci_reset_usb3(dev, 0);
180 
181  /* Set MMIO 0x80e0[15] */
182  reg32 = read32(mem_base + 0x80e0);
183  reg32 |= (1 << 15);
184  write32(mem_base + 0x80e0, reg32);
185  }
186 
187  /* Set D3Hot state and enable PME */
191 }
192 
193 /* Route all ports to XHCI controller */
194 void usb_xhci_route_all(void)
195 {
196  u32 port_mask, route;
197 
198  /* Skip if EHCI is already disabled */
199  if (RCBA32(FD) & PCH_DISABLE_EHCI1)
200  return;
201 
202  /* Set D0 state */
204 
205  /* Set USB3 superspeed enable */
208  route &= ~XHCI_USB3PR_SSEN;
209  route |= XHCI_USB3PR_SSEN & port_mask;
211 
212  /* Route USB2 ports to XHCI controller */
215  route &= ~XHCI_USB2PR_HCSEL;
216  route |= XHCI_USB2PR_HCSEL & port_mask;
218 
219  /* Disable EHCI controller */
221 
222  /* LynxPoint-H has a second EHCI controller */
223  if (!pch_is_lp())
225 
226  /* Reset and clear port change status */
228 }
229 
230 #else /* !__SIMPLE_DEVICE__ */
231 
232 static void usb_xhci_clock_gating(struct device *dev)
233 {
234  u32 reg32;
235 
236  /* IOBP 0xE5004001[7:6] = 11b */
237  pch_iobp_update(0xe5004001, ~0, (1 << 7) | (1 << 6));
238 
239  reg32 = pci_read_config32(dev, 0x40);
240  reg32 &= ~(1 << 23); /* unsupported request */
241 
242  if (pch_is_lp()) {
243  /* D20:F0:40h[18,17,8] = 111b */
244  reg32 |= (1 << 18) | (1 << 17) | (1 << 8);
245  /* D20:F0:40h[21,20,19] = 110b to enable XHCI Idle L1 */
246  reg32 &= ~(1 << 19);
247  reg32 |= (1 << 21) | (1 << 20);
248  } else {
249  /* D20:F0:40h[21,20,18,17,8] = 11111b */
250  reg32 |= (1 << 21) | (1 << 20) | (1 << 18) | (1 << 17) | (1 << 8);
251  }
252 
253  /* Avoid writing upper byte as it is write-once */
254  pci_write_config16(dev, 0x40, (u16)(reg32 & 0xffff));
255  pci_write_config8(dev, 0x40 + 2, (u8)((reg32 >> 16) & 0xff));
256 
257  /* D20:F0:44h[9,7,3] = 111b */
258  pci_or_config16(dev, 0x44, (1 << 9) | (1 << 7) | (1 << 3));
259 
260  reg32 = pci_read_config32(dev, 0xa0);
261  if (pch_is_lp()) {
262  /* D20:F0:A0h[18] = 1 */
263  reg32 |= (1 << 18);
264  } else {
265  /* D20:F0:A0h[6] = 1 */
266  reg32 |= (1 << 6);
267  }
268  pci_write_config32(dev, 0xa0, reg32);
269 
270  /* D20:F0:A4h[13] = 0 */
271  pci_and_config32(dev, 0xa4, ~(1 << 13));
272 }
273 
274 static void usb_xhci_init(struct device *dev)
275 {
276  u32 reg32;
277  u8 *mem_base = usb_xhci_mem_base(dev);
279 
280  /* D20:F0:74h[1:0] = 00b (set D0 state) */
282 
283  /* Enable clock gating first */
285 
286  reg32 = read32(mem_base + 0x8144);
287  if (pch_is_lp()) {
288  /* XHCIBAR + 8144h[8,7,6] = 111b */
289  reg32 |= (1 << 8) | (1 << 7) | (1 << 6);
290  } else {
291  /* XHCIBAR + 8144h[8,7,6] = 100b */
292  reg32 &= ~((1 << 7) | (1 << 6));
293  reg32 |= (1 << 8);
294  }
295  write32(mem_base + 0x8144, reg32);
296 
297  if (pch_is_lp()) {
298  /* XHCIBAR + 816Ch[19:0] = 000e0038h */
299  reg32 = read32(mem_base + 0x816c);
300  reg32 &= ~0x000fffff;
301  reg32 |= 0x000e0038;
302  write32(mem_base + 0x816c, reg32);
303 
304  /* D20:F0:B0h[17,14,13] = 100b */
305  pci_update_config32(dev, 0xb0, ~((1 << 14) | (1 << 13)), 1 << 17);
306  }
307 
308  reg32 = pci_read_config32(dev, 0x50);
309  if (pch_is_lp()) {
310  /* D20:F0:50h[28:0] = 0FCE2E5Fh */
311  reg32 &= ~0x1fffffff;
312  reg32 |= 0x0fce2e5f;
313  } else {
314  /* D20:F0:50h[26:0] = 07886E9Fh */
315  reg32 &= ~0x07ffffff;
316  reg32 |= 0x07886e9f;
317  }
318  pci_write_config32(dev, 0x50, reg32);
319 
320  /* D20:F0:44h[31] = 1 (Access Control Bit) */
321  pci_or_config32(dev, 0x44, 1 << 31);
322 
323  /* D20:F0:40h[31,23] = 10b (OC Configuration Done) */
324  pci_update_config32(dev, 0x40, ~(1 << 23), 1 << 31); /* unsupported request */
325 
326  if (acpi_is_wakeup_s3()) {
327  /* Reset ports that are disabled or
328  * polling before returning to the OS. */
329  usb_xhci_reset_usb3(dev, 0);
330  } else if (config && config->xhci_default) {
331  /* Route all ports to XHCI */
333  }
334 }
335 
336 static struct device_operations usb_xhci_ops = {
338  .set_resources = pci_dev_set_resources,
339  .enable_resources = pci_dev_enable_resources,
340  .init = usb_xhci_init,
341  .ops_pci = &pci_dev_ops_pci,
342 };
343 
344 static const unsigned short pci_device_ids[] = {
347  0
348 };
349 
350 static const struct pci_driver pch_usb_xhci __pci_driver = {
351  .ops = &usb_xhci_ops,
352  .vendor = PCI_VID_INTEL,
353  .devices = pci_device_ids,
354 };
355 #endif /* !__SIMPLE_DEVICE__ */
static int acpi_is_wakeup_s3(void)
Definition: acpi.h:9
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
port
Definition: i915.h:29
@ ACPI_S3
Definition: acpi.h:1383
#define APM_CNT_ROUTE_ALL_XHCI
Definition: smm.h:23
static __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Definition: pci_ops.h:120
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Definition: pci_ops.h:104
static __always_inline void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
Definition: pci_ops.h:158
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
enum board_config config
Definition: memory.c:448
#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_VID_INTEL
Definition: pci_ids.h:2157
#define PCI_DID_INTEL_LPT_H_XHCI
Definition: pci_ids.h:4112
#define PCI_DID_INTEL_LPT_LP_XHCI
Definition: pci_ids.h:4113
u32 pci_devfn_t
Definition: pci_type.h:8
int apm_control(u8 cmd)
Definition: smi_trigger.c:31
#define XHCI_PWR_CTL_STS
Definition: xhci.h:7
#define XHCI_USB3_PORTSC_PED
Definition: xhci.h:23
#define XHCI_USB3_PORTSC_WPR
Definition: xhci.h:24
#define XHCI_USB3PRM
Definition: xhci.h:11
#define XHCI_USB2PR
Definition: xhci.h:8
#define XHCI_USB3_PORTSC_CHST
Definition: xhci.h:17
#define XHCI_PLSR_POLLING
Definition: xhci.h:28
#define XHCI_USB3PDO
Definition: xhci.h:13
#define XHCI_USB3_PORTSC_WRC
Definition: xhci.h:21
#define XHCI_USB3PR
Definition: xhci.h:10
#define XHCI_USB2PRM
Definition: xhci.h:9
#define XHCI_USB3_PORTSC_PLS
Definition: xhci.h:25
#define XHCI_USB3_PORTSC(port)
Definition: xhci.h:16
#define XHCI_PLSR_RXDETECT
Definition: xhci.h:27
#define PCH_DISABLE_EHCI1
Definition: rcba.h:139
#define FD
Definition: rcba.h:125
void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
#define XHCI_USB3FUS_SS_MASK
Definition: xhci.h:20
#define XHCI_USB3FUS
Definition: xhci.h:19
#define XHCI_USB3PR_SSEN
Definition: xhci.h:17
#define XHCI_USB2PR_HCSEL
Definition: xhci.h:15
#define XHCI_USB3FUS_SS_SHIFT
Definition: xhci.h:21
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
Definition: pch.c:86
#define PCH_EHCI1_DEV
Definition: pch.h:77
#define PCH_XHCI_DEV
Definition: pch.h:88
#define PCH_EHCI2_DEV
Definition: pch.h:78
#define RCBA32(x)
Definition: rcba.h:14
static int pch_is_lp(void)
Definition: pch.h:104
#define PWR_CTL_STATUS_PME
Definition: pch.h:288
void usb_xhci_route_all(void)
#define PWR_CTL_SET_D3
Definition: pch.h:286
#define PWR_CTL_ENABLE_PME
Definition: pch.h:287
#define PWR_CTL_SET_D0
Definition: pch.h:285
void usb_ehci_disable(pci_devfn_t dev)
#define PWR_CTL_SET_MASK
Definition: pch.h:284
static void usb_xhci_reset_status_usb3(u8 *mem_base, int port)
Definition: usb_xhci.c:54
static void usb_xhci_clock_gating(struct device *dev)
Definition: usb_xhci.c:232
static int usb_xhci_port_count_usb3(u8 *mem_base)
Definition: usb_xhci.c:29
static struct device_operations usb_xhci_ops
Definition: usb_xhci.c:336
#define XHCI_RESET_DELAY_US
Definition: usb_xhci.c:71
static u8 * usb_xhci_mem_base(struct device *dev)
Definition: usb_xhci.c:17
static const struct pci_driver pch_usb_xhci __pci_driver
Definition: usb_xhci.c:350
static const unsigned short pci_device_ids[]
Definition: usb_xhci.c:344
static void usb_xhci_reset_port_usb3(u8 *mem_base, int port)
Definition: usb_xhci.c:65
#define XHCI_RESET_TIMEOUT
Definition: usb_xhci.c:72
static void usb_xhci_init(struct device *dev)
Definition: usb_xhci.c:274
static void usb_xhci_reset_usb3(struct device *dev, int all)
Definition: usb_xhci.c:84
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164
void udelay(uint32_t us)
Definition: udelay.c:15