xref: /openbsd/sys/dev/usb/xhcivar.h (revision 09467b48)
1 /* $OpenBSD: xhcivar.h,v 1.11 2019/10/06 17:30:00 mpi 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 };
44 
45 struct xhci_ring {
46 	struct xhci_trb		*trbs;
47 	size_t			 ntrb;
48 	struct usbd_dma_info	 dma;
49 
50 	uint32_t		 index;
51 	uint32_t		 toggle;	/* Producer/Consumer bit */
52 };
53 
54 struct xhci_soft_dev {
55 	struct xhci_inctx	*input_ctx;	/* Input context */
56 	struct xhci_sctx	*slot_ctx;
57 	struct xhci_epctx	*ep_ctx[31];
58 	struct usbd_dma_info	 ictx_dma;
59 
60 	struct usbd_dma_info	 octx_dma;	/* Output context */
61 
62 	struct xhci_pipe	*pipes[31];
63 };
64 
65 /* Device context segment table. */
66 struct xhci_devctx {
67 	uint64_t		*segs;		/* at most USB_MAX_DEVICES+1 */
68 	struct usbd_dma_info	 dma;
69 };
70 
71 /* Event ring segment table. */
72 struct xhci_erst {
73 	struct xhci_erseg	*segs;		/* One segment per event ring */
74 	struct usbd_dma_info	 dma;
75 };
76 
77 struct xhci_scratchpad {
78 	struct usbd_dma_info	 table_dma;
79 	struct usbd_dma_info	 pages_dma;
80 	int			 npage;
81 };
82 
83 struct xhci_softc {
84 	struct usbd_bus		 sc_bus;
85 
86 	bus_space_tag_t		 iot;
87 	bus_space_handle_t	 ioh;
88 	bus_size_t		 sc_size;
89 
90 	bus_size_t		 sc_oper_off;	/* Operational Register space */
91 	bus_size_t		 sc_runt_off;	/* Runtime */
92 	bus_size_t		 sc_door_off;	/* Doorbell  */
93 
94 	uint16_t		 sc_version;	/* xHCI version */
95 	uint32_t		 sc_pagesize;	/* xHCI page size, minimum 4k */
96 	uint32_t		 sc_ctxsize;	/* 32/64 byte context structs */
97 
98 	int			 sc_noport;	/* Maximum number of ports */
99 
100 	u_int8_t		 sc_conf;	/* Device configuration */
101 	struct usbd_xfer	*sc_intrxfer;	/* Root HUB interrupt xfer */
102 
103 	struct xhci_devctx	 sc_dcbaa;	/* Device context base addr. */
104 	struct xhci_ring	 sc_cmd_ring;	/* Command ring */
105 	struct rwlock		 sc_cmd_lock;	/* Serialize commands */
106 
107 	struct xhci_erst	 sc_erst;	/* Event ring segment table */
108 	struct xhci_ring	 sc_evt_ring;	/* Event ring */
109 
110 	struct xhci_scratchpad	 sc_spad;	/* Optional scratchpad */
111 
112 	int 			 sc_noslot;	/* Maximum number of slots */
113 	struct xhci_soft_dev	 sc_sdevs[USB_MAX_DEVICES];
114 
115 	struct xhci_trb		*sc_cmd_trb;
116 	struct xhci_trb		 sc_result_trb;
117 
118 	char			 sc_vendor[16];	/* Vendor string for root hub */
119 	int			 sc_id_vendor;	/* Vendor ID for root hub */
120 };
121 
122 int	xhci_init(struct xhci_softc *);
123 void	xhci_config(struct xhci_softc *);
124 int	xhci_intr(void *);
125 int	xhci_detach(struct device *, int);
126 int	xhci_activate(struct device *, int);
127 
128 #define	XREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
129 #define	XREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
130 #define	XREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
131 #define	XWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
132 #define	XWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
133 #define	XWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
134 
135 #define	XOREAD4(sc, a)							\
136 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a))
137 #define	XOWRITE4(sc, a, x)						\
138 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a), (x))
139 
140 #define	XRREAD4(sc, a) \
141 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a))
142 #define	XRWRITE4(sc, a, x) \
143 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a), (x))
144 
145 #define	XDREAD4(sc, a) \
146 	bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a))
147 #define	XDWRITE4(sc, a, x) \
148 	bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a), (x))
149 
150 #endif /* _XHCIVAR_H_ */
151