xref: /openbsd/sys/dev/usb/xhcivar.h (revision 581cc054)
1 /* $OpenBSD: xhcivar.h,v 1.16 2024/08/17 01:55:03 jsg Exp $ */
2 
3 /*
4  * Copyright (c) 2014 Martin Pieuchot
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef	_XHCIVAR_H_
20 #define	_XHCIVAR_H_
21 
22 /* Default command execution time (implementation defined). */
23 #define	XHCI_CMD_TIMEOUT	MSEC_TO_NSEC(500)
24 
25 #define	XHCI_MAX_CMDS		(16 * 1)
26 #define	XHCI_MAX_EVTS		(16 * 13)
27 #define	XHCI_MAX_XFER		(16 * 16)
28 
29 struct usbd_dma_info {
30 	bus_dma_tag_t		 tag;
31 	bus_dmamap_t		 map;
32 	bus_dma_segment_t	 seg;
33 	int			 nsegs;
34 	bus_addr_t		 paddr;
35 	caddr_t			 vaddr;
36 	bus_size_t		 size;
37 };
38 
39 struct xhci_xfer {
40 	struct usbd_xfer	 xfer;
41 	int			 index;		/* Index of the last TRB */
42 	size_t			 ntrb;		/* Number of associated TRBs */
43 	size_t			 zerotd;	/* Is zero len TD required? */
44 };
45 
46 struct xhci_ring {
47 	struct xhci_trb		*trbs;
48 	size_t			 ntrb;
49 	struct usbd_dma_info	 dma;
50 
51 	uint32_t		 index;
52 	uint32_t		 toggle;	/* Producer/Consumer bit */
53 };
54 
55 struct xhci_soft_dev {
56 	struct xhci_inctx	*input_ctx;	/* Input context */
57 	struct xhci_sctx	*slot_ctx;
58 	struct xhci_epctx	*ep_ctx[31];
59 	struct usbd_dma_info	 ictx_dma;
60 
61 	struct usbd_dma_info	 octx_dma;	/* Output context */
62 
63 	struct xhci_pipe	*pipes[31];
64 };
65 
66 /* Device context segment table. */
67 struct xhci_devctx {
68 	uint64_t		*segs;		/* at most USB_MAX_DEVICES+1 */
69 	struct usbd_dma_info	 dma;
70 };
71 
72 /* Event ring segment table. */
73 struct xhci_erst {
74 	struct xhci_erseg	*segs;		/* One segment per event ring */
75 	struct usbd_dma_info	 dma;
76 };
77 
78 struct xhci_scratchpad {
79 	struct usbd_dma_info	 table_dma;
80 	struct usbd_dma_info	 pages_dma;
81 	int			 npage;
82 };
83 
84 struct xhci_softc {
85 	struct usbd_bus		 sc_bus;
86 
87 	bus_space_tag_t		 iot;
88 	bus_space_handle_t	 ioh;
89 	bus_size_t		 sc_size;
90 
91 	int			 sc_dead;
92 	int			 sc_saved_state;
93 
94 	bus_size_t		 sc_oper_off;	/* Operational Register space */
95 	bus_size_t		 sc_runt_off;	/* Runtime */
96 	bus_size_t		 sc_door_off;	/* Doorbell  */
97 
98 	uint16_t		 sc_version;	/* xHCI version */
99 	uint32_t		 sc_pagesize;	/* xHCI page size, minimum 4k */
100 	uint32_t		 sc_ctxsize;	/* 32/64 byte context structs */
101 
102 	int			 sc_noport;	/* Maximum number of ports */
103 
104 	u_int8_t		 sc_conf;	/* Device configuration */
105 	struct usbd_xfer	*sc_intrxfer;	/* Root HUB interrupt xfer */
106 
107 	struct xhci_devctx	 sc_dcbaa;	/* Device context base addr. */
108 	struct xhci_ring	 sc_cmd_ring;	/* Command ring */
109 	struct rwlock		 sc_cmd_lock;	/* Serialize commands */
110 
111 	struct xhci_erst	 sc_erst;	/* Event ring segment table */
112 	struct xhci_ring	 sc_evt_ring;	/* Event ring */
113 
114 	struct xhci_scratchpad	 sc_spad;	/* Optional scratchpad */
115 
116 	int 			 sc_noslot;	/* Maximum number of slots */
117 	struct xhci_soft_dev	 sc_sdevs[USB_MAX_DEVICES];
118 
119 	struct xhci_trb		*sc_cmd_trb;
120 	struct xhci_trb		 sc_result_trb;
121 
122 	char			 sc_vendor[16];	/* Vendor string for root hub */
123 	int			 sc_id_vendor;	/* Vendor ID for root hub */
124 
125 	int			 sc_flags;
126 #define XHCI_NOCSS		 0x01
127 };
128 
129 int	xhci_init(struct xhci_softc *);
130 void	xhci_config(struct xhci_softc *);
131 void	xhci_reinit(struct xhci_softc *);
132 int	xhci_intr(void *);
133 int	xhci_detach(struct device *, int);
134 int	xhci_activate(struct device *, int);
135 
136 #define	XREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
137 #define	XREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
138 #define	XREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
139 #define	XWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
140 #define	XWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
141 #define	XWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
142 
143 #define	XOREAD4(sc, a)							\
144 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a))
145 #define	XOWRITE4(sc, a, x)						\
146 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a), (x))
147 
148 #define	XRREAD4(sc, a) \
149 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a))
150 #define	XRWRITE4(sc, a, x) \
151 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a), (x))
152 
153 #define	XDREAD4(sc, a) \
154 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a))
155 #define	XDWRITE4(sc, a, x) \
156 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a), (x))
157 
158 #endif /* _XHCIVAR_H_ */
159