source: mainline/uspace/drv/bus/usb/xhci/hw_struct/regs.h@ 4db49344

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4db49344 was 8033f89, checked in by Ondřej Hlavatý <aearsis@…>, 8 years ago

xhci: cstyle

  • Property mode set to 100644
File size: 19.0 KB
Line 
1/*
2 * Copyright (c) 2017 Ondrej Hlavaty
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbxhci
30 * @{
31 */
32/** @file
33 * Memory-mapped register structures of the xHC.
34 *
35 * The main pr
36 */
37
38#ifndef XHCI_REGS_H
39#define XHCI_REGS_H
40
41#include <macros.h>
42#include <ddi.h>
43#include "common.h"
44
45#define XHCI_PIO_CHANGE_UDELAY 5
46
47/*
48 * These four are the main macros to be used.
49 * Semantics is usual - READ reads value, WRITE changes value, SET sets
50 * selected bits, CLEAR clears selected bits to 0.
51 *
52 * The key thing here is the order of macro expansion, expanding the reg_spec
53 * argument as more arguments (comma delimited) for the inner macro.
54 */
55#define XHCI_REG_RD(reg_set, reg_spec) XHCI_REG_RD_INNER(reg_set, reg_spec)
56#define XHCI_REG_WR(reg_set, reg_spec, value) XHCI_REG_WR_INNER(reg_set, value, reg_spec)
57#define XHCI_REG_SET(reg_set, reg_spec, value) XHCI_REG_SET_INNER(reg_set, value, reg_spec)
58#define XHCI_REG_CLR(reg_set, reg_spec, value) XHCI_REG_CLR_INNER(reg_set, value, reg_spec)
59#define XHCI_REG_MASK(reg_spec) XHCI_REG_MASK_INNER(reg_spec)
60#define XHCI_REG_SHIFT(reg_spec) XHCI_REG_SHIFT_INNER(reg_spec)
61
62/*
63 * These take a pointer to the field, and selects the type-specific macro.
64 */
65#define XHCI_REG_RD_INNER(reg_set, field, size, type, ...) \
66 XHCI_REG_RD_##type(&((reg_set)->field), size, ##__VA_ARGS__)
67
68#define XHCI_REG_WR_INNER(reg_set, value, field, size, type, ...) \
69 XHCI_REG_WR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
70
71#define XHCI_REG_SET_INNER(reg_set, value, field, size, type, ...) \
72 XHCI_REG_SET_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
73
74#define XHCI_REG_CLR_INNER(reg_set, value, field, size, type, ...) \
75 XHCI_REG_CLR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
76
77#define XHCI_REG_MASK_INNER(field, size, type, ...) \
78 XHCI_REG_MASK_##type(size, ##__VA_ARGS__)
79
80#define XHCI_REG_SHIFT_INNER(field, size, type, ...) \
81 XHCI_REG_SHIFT_##type(size, ##__VA_ARGS__)
82
83/*
84 * Field handling is the easiest. Just do it with whole field.
85 */
86#define XHCI_REG_RD_FIELD(ptr, size) \
87 xhci2host(size, pio_read_##size((ptr)))
88#define XHCI_REG_WR_FIELD(ptr, value, size) \
89 pio_write_##size((ptr), host2xhci(size, value))
90#define XHCI_REG_SET_FIELD(ptr, value, size) \
91 pio_set_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
92#define XHCI_REG_CLR_FIELD(ptr, value, size) \
93 pio_clear_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
94#define XHCI_REG_MASK_FIELD(size) (~((uint##size##_t) 0))
95#define XHCI_REG_SHIFT_FIELD(size) (0)
96
97/*
98 * Flags are just trivial case of ranges.
99 */
100#define XHCI_REG_RD_FLAG(ptr, size, offset) \
101 XHCI_REG_RD_RANGE((ptr), size, (offset), (offset))
102#define XHCI_REG_WR_FLAG(ptr, value, size, offset) \
103 XHCI_REG_WR_RANGE((ptr), (value), size, (offset), (offset))
104#define XHCI_REG_SET_FLAG(ptr, value, size, offset) \
105 XHCI_REG_SET_RANGE((ptr), (value), size, (offset), (offset))
106#define XHCI_REG_CLR_FLAG(ptr, value, size, offset) \
107 XHCI_REG_CLR_RANGE((ptr), (value), size, (offset), (offset))
108#define XHCI_REG_MASK_FLAG(size, offset) BIT_V(uint##size##_t, offset)
109#define XHCI_REG_SHIFT_FLAG(size, offset) (offset)
110
111/*
112 * Ranges are the most difficult. We need to play around with bitmasks.
113 */
114#define XHCI_REG_RD_RANGE(ptr, size, hi, lo) \
115 BIT_RANGE_EXTRACT(uint##size##_t, (hi), (lo), XHCI_REG_RD_FIELD((ptr), size))
116
117#define XHCI_REG_WR_RANGE(ptr, value, size, hi, lo) \
118 pio_change_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
119 (hi), (lo), (value))), \
120 host2xhci(size, BIT_RANGE(uint##size##_t, (hi), (lo))), \
121 XHCI_PIO_CHANGE_UDELAY);
122
123#define XHCI_REG_SET_RANGE(ptr, value, size, hi, lo) \
124 pio_set_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
125 (hi), (lo), (value))), \
126 XHCI_PIO_CHANGE_UDELAY);
127
128#define XHCI_REG_CLR_RANGE(ptr, value, size, hi, lo) \
129 pio_clear_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
130 (hi), (lo), (value))), \
131 XHCI_PIO_CHANGE_UDELAY);
132
133#define XHCI_REG_MASK_RANGE(size, hi, lo) BIT_RANGE(uint##size##_t, hi, lo)
134#define XHCI_REG_SHIFT_RANGE(size, hi, lo) (lo)
135
136/** HC capability registers: section 5.3 */
137typedef const struct xhci_cap_regs {
138
139 /* Size of this structure, offset for the operation registers */
140 const ioport8_t caplength;
141
142 const PADD8;
143
144 /* BCD of specification version */
145 const ioport16_t hciversion;
146
147 /*
148 * 7:0 - MaxSlots
149 * 18:8 - MaxIntrs
150 * 31:24 - MaxPorts
151 */
152 const ioport32_t hcsparams1;
153
154 /*
155 * 3:0 - IST
156 * 7:4 - ERST Max
157 * 25:21 - Max Scratchpad Bufs Hi
158 * 26 - SPR
159 * 31:27 - Max Scratchpad Bufs Lo
160 */
161 const ioport32_t hcsparams2;
162
163 /*
164 * 7:0 - U1 Device Exit Latency
165 * 31:16 - U2 Device Exit Latency
166 */
167 const ioport32_t hcsparams3;
168
169 /*
170 * 11 10 9 8 7 6 5 4 3 2 1 0
171 * 11:0 - CFC SEC SPC PAE NSS LTC C PIND PPC CSZ BNC AC64
172 * 15:12 - MaxPSASize
173 * 31:16 - xECP
174 */
175 const ioport32_t hccparams1;
176
177 /*
178 * 31:2 - Doorbell Array Offset
179 */
180 const ioport32_t dboff;
181
182 /*
183 * 31:5 - Runtime Register Space Offset
184 */
185 const ioport32_t rtsoff;
186
187 /*
188 * 5 4 3 2 1 0
189 * 5:0 - Flags: CIC LEC CTC FSC CMC U3C
190 */
191 const ioport32_t hccparams2;
192
193 // the rest to operational registers is reserved
194} xhci_cap_regs_t;
195
196/*
197 * The register specifiers are to be used as the reg_spec argument.
198 *
199 * The values are field, bitsize, type, (type specific args)
200 * When the type is RANGE: hi, lo
201 */
202#define XHCI_CAP_LENGTH caplength, 8, FIELD
203#define XHCI_CAP_VERSION hciversion, 16, FIELD
204#define XHCI_CAP_MAX_SLOTS hcsparams1, 32, RANGE, 7, 0
205#define XHCI_CAP_MAX_INTRS hcsparams1, 32, RANGE, 18, 8
206#define XHCI_CAP_MAX_PORTS hcsparams1, 32, RANGE, 31, 24
207#define XHCI_CAP_IST hcsparams2, 32, RANGE, 3, 0
208#define XHCI_CAP_ERST_MAX hcsparams2, 32, RANGE, 7, 4
209#define XHCI_CAP_MAX_SPBUF_HI hcsparams2, 32, RANGE, 25, 21
210#define XHCI_CAP_SPR hcsparams2, 32, FLAG, 26
211#define XHCI_CAP_MAX_SPBUF_LO hcsparams2, 32, RANGE, 31, 27
212#define XHCI_CAP_U1EL hcsparams3, 32, RANGE, 7, 0
213#define XHCI_CAP_U2EL hcsparams3, 32, RANGE, 31, 16
214#define XHCI_CAP_AC64 hccparams1, 32, FLAG, 0
215#define XHCI_CAP_BNC hccparams1, 32, FLAG, 1
216#define XHCI_CAP_CSZ hccparams1, 32, FLAG, 2
217#define XHCI_CAP_PPC hccparams1, 32, FLAG, 3
218#define XHCI_CAP_PIND hccparams1, 32, FLAG, 4
219#define XHCI_CAP_C hccparams1, 32, FLAG, 5
220#define XHCI_CAP_LTC hccparams1, 32, FLAG, 6
221#define XHCI_CAP_NSS hccparams1, 32, FLAG, 7
222#define XHCI_CAP_PAE hccparams1, 32, FLAG, 8
223#define XHCI_CAP_SPC hccparams1, 32, FLAG, 9
224#define XHCI_CAP_SEC hccparams1, 32, FLAG, 10
225#define XHCI_CAP_CFC hccparams1, 32, FLAG, 11
226#define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, RANGE, 15, 12
227#define XHCI_CAP_XECP hccparams1, 32, RANGE, 31, 16
228#define XHCI_CAP_DBOFF dboff, 32, FIELD
229#define XHCI_CAP_RTSOFF rtsoff, 32, FIELD
230#define XHCI_CAP_U3C hccparams2, 32, FLAG, 0
231#define XHCI_CAP_CMC hccparams2, 32, FLAG, 1
232#define XHCI_CAP_FSC hccparams2, 32, FLAG, 2
233#define XHCI_CAP_CTC hccparams2, 32, FLAG, 3
234#define XHCI_CAP_LEC hccparams2, 32, FLAG, 4
235#define XHCI_CAP_CIC hccparams2, 32, FLAG, 5
236
237static inline unsigned xhci_get_max_spbuf(xhci_cap_regs_t *cap_regs) {
238 return XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_HI) << 5
239 | XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_LO);
240}
241
242/**
243 * XHCI Port Register Set: section 5.4, table 32
244 */
245typedef struct xhci_port_regs {
246 /*
247 * 4 3 2 1 0
248 * 4:0 - PR OCA Z PED CCS
249 * 8:5 - PLS
250 * 9 - PP
251 * 13:10 - Port Speed
252 * 15:14 - PIC
253 * 27 26 25 24 23 22 21 20 19 18 17 16
254 * 27:16 - WOE WDE WCE CAS CEC PLC PRC OCC WRC PEC CSC LWS
255 * 30 - DR
256 * 31 - WPR
257 */
258 ioport32_t portsc;
259
260 /*
261 * Contents of this fields depends on the protocol supported by the port.
262 * USB3:
263 * 7:0 - U1 Timeout
264 * 15:8 - U2 Timeout
265 * 16 - Force Link PM Accept
266 * USB2:
267 * 2:0 - L1S
268 * 3 - RWE
269 * 7:4 - BESL
270 * 15:8 - L1 Device Slot
271 * 16 - HLE
272 * 31:28 - Test Mode
273 */
274 ioport32_t portpmsc;
275
276 /*
277 * This field is valid only for USB3 ports.
278 * 15:0 - Link Error Count
279 * 19:16 - RLC
280 * 23:20 - TLC
281 */
282 ioport32_t portli;
283
284 /*
285 * This field is valid only for USB2 ports.
286 * 1:0 - HIRDM
287 * 9:2 - L1 Timeout
288 * 13:10 - BESLD
289 */
290 ioport32_t porthlpmc;
291} xhci_port_regs_t;
292
293#define XHCI_PORT_CCS portsc, 32, FLAG, 0
294#define XHCI_PORT_PED portsc, 32, FLAG, 1
295#define XHCI_PORT_OCA portsc, 32, FLAG, 3
296#define XHCI_PORT_PR portsc, 32, FLAG, 4
297#define XHCI_PORT_PLS portsc, 32, RANGE, 8, 5
298#define XHCI_PORT_PP portsc, 32, FLAG, 9
299#define XHCI_PORT_PS portsc, 32, RANGE, 13, 10
300#define XHCI_PORT_PIC portsc, 32, RANGE, 15, 14
301#define XHCI_PORT_LWS portsc, 32, FLAG, 16
302#define XHCI_PORT_CSC portsc, 32, FLAG, 17
303#define XHCI_PORT_PEC portsc, 32, FLAG, 18
304#define XHCI_PORT_WRC portsc, 32, FLAG, 19
305#define XHCI_PORT_OCC portsc, 32, FLAG, 20
306#define XHCI_PORT_PRC portsc, 32, FLAG, 21
307#define XHCI_PORT_PLC portsc, 32, FLAG, 22
308#define XHCI_PORT_CEC portsc, 32, FLAG, 23
309#define XHCI_PORT_CAS portsc, 32, FLAG, 24
310#define XHCI_PORT_WCE portsc, 32, FLAG, 25
311#define XHCI_PORT_WDE portsc, 32, FLAG, 26
312#define XHCI_PORT_WOE portsc, 32, FLAG, 27
313#define XHCI_PORT_DR portsc, 32, FLAG, 30
314#define XHCI_PORT_WPR portsc, 32, FLAG, 31
315
316#define XHCI_PORT_USB3_U1TO portpmsc, 32, RANGE, 7, 0
317#define XHCI_PORT_USB3_U2TO portpmsc, 32, RANGE, 15, 8
318#define XHCI_PORT_USB3_FLPMA portpmsc, 32, FLAG, 16
319#define XHCI_PORT_USB3_LEC portli, 32, RANGE, 15, 0
320#define XHCI_PORT_USB3_RLC portli, 32, RANGE, 19, 16
321#define XHCI_PORT_USB3_TLC portli, 32, RANGE, 23, 20
322
323#define XHCI_PORT_USB2_L1S portpmsc, 32, RANGE, 2, 0
324#define XHCI_PORT_USB2_RWE portpmsc, 32, FLAG, 3
325#define XHCI_PORT_USB2_BESL portpmsc, 32, RANGE, 7, 4
326#define XHCI_PORT_USB2_L1DS portpmsc, 32, RANGE, 15, 8
327#define XHCI_PORT_USB2_HLE portpmsc, 32, FLAG, 16
328#define XHCI_PORT_USB2_TM portpmsc, 32, RANGE, 31, 28
329#define XHCI_PORT_USB2_HIRDM porthlpmc, 32, RANGE, 1, 0
330#define XHCI_PORT_USB2_L1TO porthlpmc, 32, RANGE, 9, 2
331#define XHCI_PORT_USB2_BESLD porthlpmc, 32, RANGE, 13, 10
332
333/**
334 * XHCI Operational Registers: section 5.4
335 */
336typedef struct xhci_op_regs {
337
338 /*
339 * 3 2 1 0
340 * 3:0 - HSEE INTE HCRST R/S
341 *
342 * 11 10 9 8 7
343 * 11:7 - EU3S EWE CRS CSS LHCRST
344 * 13 - CME
345 */
346 ioport32_t usbcmd;
347
348 /*
349 * 4 3 2 1 0
350 * 4:0 - PCD EINT HSE _ HCH
351 *
352 * 12 11 10 9 8
353 * 12:8 - HCE CNR SRE RSS SSS
354 */
355 ioport32_t usbsts;
356
357 /*
358 * Bitmask of page sizes supported: 128M .. 4K
359 */
360 ioport32_t pagesize;
361
362 PADD32[2];
363
364 /*
365 * 15:0 - Notification enable
366 */
367 ioport32_t dnctrl;
368
369 /* 3 2 1 0
370 * 3:0 - CRR CA CS RCS
371 * 64:6 - Command Ring Pointer
372 */
373 ioport32_t crcr_lo;
374 ioport32_t crcr_hi;
375
376 PADD32[4];
377
378 ioport32_t dcbaap_lo;
379 ioport32_t dcbaap_hi;
380
381 /*
382 * 7:0 - MaxSlotsEn
383 * 8 - U3E
384 * 9 - CIE
385 */
386 ioport32_t config;
387
388 /* Offset of portrs from op_regs addr is 0x400. */
389 PADD32[241];
390
391 /*
392 * Individual ports register sets
393 */
394 xhci_port_regs_t portrs[256];
395} xhci_op_regs_t;
396
397#define XHCI_OP_RS usbcmd, 32, FLAG, 0
398#define XHCI_OP_HCRST usbcmd, 32, FLAG, 1
399#define XHCI_OP_INTE usbcmd, 32, FLAG, 2
400#define XHCI_OP_HSEE usbcmd, 32, FLAG, 3
401#define XHCI_OP_LHCRST usbcmd, 32, FLAG, 7
402#define XHCI_OP_CSS usbcmd, 32, FLAG, 8
403#define XHCI_OP_CRS usbcmd, 32, FLAG, 9
404#define XHCI_OP_EWE usbcmd, 32, FLAG, 10
405#define XHCI_OP_EU3S usbcmd, 32, FLAG, 11
406#define XHCI_OP_CME usbcmd, 32, FLAG, 13
407#define XHCI_OP_HCH usbsts, 32, FLAG, 0
408#define XHCI_OP_HSE usbsts, 32, FLAG, 2
409#define XHCI_OP_EINT usbsts, 32, FLAG, 3
410#define XHCI_OP_PCD usbsts, 32, FLAG, 4
411#define XHCI_OP_SSS usbsts, 32, FLAG, 8
412#define XHCI_OP_RSS usbsts, 32, FLAG, 9
413#define XHCI_OP_SRE usbsts, 32, FLAG, 10
414#define XHCI_OP_CNR usbsts, 32, FLAG, 11
415#define XHCI_OP_HCE usbsts, 32, FLAG, 12
416#define XHCI_OP_PAGESIZE pagesize, 32, FIELD
417#define XHCI_OP_NOTIFICATION dnctrl, 32, RANGE, 15, 0
418#define XHCI_OP_RCS crcr_lo, 32, FLAG, 0
419#define XHCI_OP_CS crcr_lo, 32, FLAG, 1
420#define XHCI_OP_CA crcr_lo, 32, FLAG, 2
421#define XHCI_OP_CRR crcr_lo, 32, FLAG, 3
422/*
423 * This shall be RANGE, 6, 0, but the value containing CR pointer and RCS flag
424 * must be written at once.
425 */
426#define XHCI_OP_CRCR_LO crcr_lo, 32, FIELD
427#define XHCI_OP_CRCR_HI crcr_hi, 32, FIELD
428#define XHCI_OP_DCBAAP_LO dcbaap_lo, 32, FIELD
429#define XHCI_OP_DCBAAP_HI dcbaap_hi, 32, FIELD
430#define XHCI_OP_MAX_SLOTS_EN config, 32, RANGE, 7, 0
431#define XHCI_OP_U3E config, 32, FLAG, 8
432#define XHCI_OP_CIE config, 32, FLAG, 9
433
434/* Aggregating field to read & write whole status at once */
435#define XHCI_OP_STATUS usbsts, 32, RANGE, 12, 0
436
437/* RW1C fields in usbsts */
438#define XHCI_STATUS_ACK_MASK 0x41C
439
440/**
441 * Interrupter Register Set: section 5.5.2
442 */
443typedef struct xhci_interrupter_regs {
444 /*
445 * 0 - Interrupt Pending
446 * 1 - Interrupt Enable
447 */
448 ioport32_t iman;
449
450 /*
451 * 15:0 - Interrupt Moderation Interval
452 * 31:16 - Interrupt Moderation Counter
453 */
454 ioport32_t imod;
455
456 ioport32_t erstsz;
457
458 PADD32;
459
460 ioport32_t erstba_lo;
461 ioport32_t erstba_hi;
462
463 /*
464 * 2:0 - Dequeue ERST Segment Index
465 * 3 - Event Handler Busy
466 * 63:4 - Event Ring Dequeue Pointer
467 */
468 ioport32_t erdp_lo;
469 ioport32_t erdp_hi;
470} xhci_interrupter_regs_t;
471
472#define XHCI_INTR_IP iman, 32, FLAG, 0
473#define XHCI_INTR_IE iman, 32, FLAG, 1
474#define XHCI_INTR_IMI imod, 32, RANGE, 15, 0
475#define XHCI_INTR_IMC imod, 32, RANGE, 31, 16
476#define XHCI_INTR_ERSTSZ erstsz, 32, FIELD
477#define XHCI_INTR_ERSTBA_LO erstba_lo, 32, FIELD
478#define XHCI_INTR_ERSTBA_HI erstba_hi, 32, FIELD
479#define XHCI_INTR_ERDP_ESI erdp_lo, 32, RANGE, 2, 0
480#define XHCI_INTR_ERDP_EHB erdp_lo, 32, FLAG, 3
481#define XHCI_INTR_ERDP_LO erdp_lo, 32, FIELD
482#define XHCI_INTR_ERDP_HI erdp_hi, 32, FIELD
483
484/**
485 * XHCI Runtime registers: section 5.5
486 */
487typedef struct xhci_rt_regs {
488 ioport32_t mfindex;
489
490 PADD32 [7];
491
492 xhci_interrupter_regs_t ir [];
493} xhci_rt_regs_t;
494
495#define XHCI_RT_MFINDEX mfindex, 32, RANGE, 13, 0
496#define XHCI_MFINDEX_MAX (1 << 14)
497
498/**
499 * XHCI Doorbell Registers: section 5.6
500 *
501 * These registers are to be written as a whole field.
502 */
503typedef ioport32_t xhci_doorbell_t;
504
505enum xhci_plt {
506 XHCI_PSI_PLT_SYMM,
507 XHCI_PSI_PLT_RSVD,
508 XHCI_PSI_PLT_RX,
509 XHCI_PSI_PLT_TX
510};
511
512/**
513 * Protocol speed ID: section 7.2.1
514 */
515typedef struct xhci_psi {
516 xhci_dword_t psi;
517} xhci_psi_t;
518
519#define XHCI_PSI_PSIV psi, 32, RANGE, 3, 0
520#define XHCI_PSI_PSIE psi, 32, RANGE, 5, 4
521#define XHCI_PSI_PLT psi, 32, RANGE, 7, 6
522#define XHCI_PSI_PFD psi, 32, FLAG, 8
523#define XHCI_PSI_PSIM psi, 32, RANGE, 31, 16
524
525enum xhci_extcap_type {
526 XHCI_EC_RESERVED = 0,
527 XHCI_EC_USB_LEGACY,
528 XHCI_EC_SUPPORTED_PROTOCOL,
529 XHCI_EC_EXTENDED_POWER_MANAGEMENT,
530 XHCI_EC_IOV,
531 XHCI_EC_MSI,
532 XHCI_EC_LOCALMEM,
533 XHCI_EC_DEBUG = 10,
534 XHCI_EC_MSIX = 17,
535 XHCI_EC_MAX = 255
536};
537
538/**
539 * xHCI Extended Capability: section 7
540 */
541typedef struct xhci_extcap {
542 xhci_dword_t header;
543 xhci_dword_t cap_specific[];
544} xhci_extcap_t;
545
546#define XHCI_EC_CAP_ID header, 32, RANGE, 7, 0
547#define XHCI_EC_SIZE header, 32, RANGE, 15, 8
548
549/* Supported protocol */
550#define XHCI_EC_SP_MINOR header, 32, RANGE, 23, 16
551#define XHCI_EC_SP_MAJOR header, 32, RANGE, 31, 24
552#define XHCI_EC_SP_NAME cap_specific[0], 32, FIELD
553#define XHCI_EC_SP_CP_OFF cap_specific[1], 32, RANGE, 7, 0
554#define XHCI_EC_SP_CP_COUNT cap_specific[1], 32, RANGE, 15, 8
555#define XHCI_EC_SP_PSIC cap_specific[1], 32, RANGE, 31, 28
556#define XHCI_EC_SP_SLOT_TYPE cap_specific[2], 32, RANGE, 4, 0
557
558typedef union {
559 char str [4];
560 uint32_t packed;
561} xhci_sp_name_t;
562
563static const xhci_sp_name_t xhci_name_usb = {
564 .str = "USB "
565};
566
567static inline xhci_extcap_t *xhci_extcap_next(const xhci_extcap_t *cur)
568{
569 unsigned dword_offset = XHCI_REG_RD(cur, XHCI_EC_SIZE);
570 if (!dword_offset)
571 return NULL;
572 return (xhci_extcap_t *) (((xhci_dword_t *) cur) + dword_offset);
573}
574
575static inline xhci_psi_t *xhci_extcap_psi(const xhci_extcap_t *ec, unsigned psid)
576{
577 assert(XHCI_REG_RD(ec, XHCI_EC_CAP_ID) == XHCI_EC_SUPPORTED_PROTOCOL);
578 assert(XHCI_REG_RD(ec, XHCI_EC_SP_PSIC) > psid);
579
580 unsigned dword_offset = 4 + psid;
581 return (xhci_psi_t *) (((xhci_dword_t *) ec) + dword_offset);
582}
583
584/**
585 * USB Legacy Support: section 7.1
586 *
587 * Legacy support have an exception from dword-access, because it needs to be
588 * byte-accessed.
589 */
590typedef struct xhci_extcap_legsup {
591 ioport8_t cap_id;
592 ioport8_t size; /**< Next Capability Pointer */
593 ioport8_t sem_bios;
594 ioport8_t sem_os;
595
596 /** USB Legacy Support Control/Status - RW for BIOS, RO for OS */
597 xhci_dword_t usblegctlsts;
598} xhci_legsup_t;
599
600#define XHCI_LEGSUP_SEM_BIOS sem_bios, 8, FLAG, 0
601#define XHCI_LEGSUP_SEM_OS sem_os, 8, FLAG, 0
602
603/* 4.22.1 BIOS may take up to 1 second to release the device */
604#define XHCI_LEGSUP_BIOS_TIMEOUT_US 1000000
605#define XHCI_LEGSUP_POLLING_DELAY_1MS 1000
606
607#endif
608/**
609 * @}
610 */
Note: See TracBrowser for help on using the repository browser.