ehci.h revision 190749
1/* $FreeBSD: head/sys/dev/usb/controller/ehci.h 190749 2009-04-05 21:24:15Z piso $ */
2/*-
3 * Copyright (c) 2001 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Lennart Augustsson (lennart@augustsson.net).
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *        This product includes software developed by the NetBSD
20 *        Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 *    contributors may be used to endorse or promote products derived
23 *    from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _EHCI_H_
39#define	_EHCI_H_
40
41#define	EHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128)
42
43/* PCI config registers */
44#define	PCI_CBMEM		0x10	/* configuration base MEM */
45#define	PCI_INTERFACE_EHCI	0x20
46#define	PCI_USBREV		0x60	/* RO USB protocol revision */
47#define	PCI_USB_REV_MASK	0xff
48#define	PCI_USB_REV_PRE_1_0	0x00
49#define	PCI_USB_REV_1_0		0x10
50#define	PCI_USB_REV_1_1		0x11
51#define	PCI_USB_REV_2_0		0x20
52#define	PCI_EHCI_FLADJ		0x61	/* RW Frame len adj, SOF=59488+6*fladj */
53#define	PCI_EHCI_PORTWAKECAP	0x62	/* RW Port wake caps (opt)  */
54
55/* EHCI Extended Capabilities */
56#define	EHCI_EC_LEGSUP		0x01
57#define	EHCI_EECP_NEXT(x)	(((x) >> 8) & 0xff)
58#define	EHCI_EECP_ID(x)		((x) & 0xff)
59
60/* Legacy support extended capability */
61#define	EHCI_LEGSUP_BIOS_SEM		0x02
62#define	EHCI_LEGSUP_OS_SEM		0x03
63#define	EHCI_LEGSUP_USBLEGCTLSTS	0x04
64
65/* EHCI capability registers */
66#define	EHCI_CAPLENGTH		0x00	/* RO Capability register length field */
67/* reserved			0x01 */
68#define	EHCI_HCIVERSION		0x02	/* RO Interface version number */
69#define	EHCI_HCSPARAMS		0x04	/* RO Structural parameters */
70#define	EHCI_HCS_DEBUGPORT(x)	(((x) >> 20) & 0xf)
71#define	EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
72#define	EHCI_HCS_N_CC(x)	(((x) >> 12) & 0xf)	/* # of companion ctlrs */
73#define	EHCI_HCS_N_PCC(x)	(((x) >> 8) & 0xf)	/* # of ports per comp. */
74#define	EHCI_HCS_PPC(x)		((x) & 0x10)	/* port power control */
75#define	EHCI_HCS_N_PORTS(x)	((x) & 0xf)	/* # of ports */
76#define	EHCI_HCCPARAMS		0x08	/* RO Capability parameters */
77#define	EHCI_HCC_EECP(x)	(((x) >> 8) & 0xff)	/* extended ports caps */
78#define	EHCI_HCC_IST(x)		(((x) >> 4) & 0xf)	/* isoc sched threshold */
79#define	EHCI_HCC_ASPC(x)	((x) & 0x4)	/* async sched park cap */
80#define	EHCI_HCC_PFLF(x)	((x) & 0x2)	/* prog frame list flag */
81#define	EHCI_HCC_64BIT(x)	((x) & 0x1)	/* 64 bit address cap */
82#define	EHCI_HCSP_PORTROUTE	0x0c	/* RO Companion port route description */
83
84/* EHCI operational registers.  Offset given by EHCI_CAPLENGTH register */
85#define	EHCI_USBCMD		0x00	/* RO, RW, WO Command register */
86#define	EHCI_CMD_ITC_M		0x00ff0000	/* RW interrupt threshold ctrl */
87#define	EHCI_CMD_ITC_1		0x00010000
88#define	EHCI_CMD_ITC_2		0x00020000
89#define	EHCI_CMD_ITC_4		0x00040000
90#define	EHCI_CMD_ITC_8		0x00080000
91#define	EHCI_CMD_ITC_16		0x00100000
92#define	EHCI_CMD_ITC_32		0x00200000
93#define	EHCI_CMD_ITC_64		0x00400000
94#define	EHCI_CMD_ASPME		0x00000800	/* RW/RO async park enable */
95#define	EHCI_CMD_ASPMC		0x00000300	/* RW/RO async park count */
96#define	EHCI_CMD_LHCR		0x00000080	/* RW light host ctrl reset */
97#define	EHCI_CMD_IAAD		0x00000040	/* RW intr on async adv door
98						 * bell */
99#define	EHCI_CMD_ASE		0x00000020	/* RW async sched enable */
100#define	EHCI_CMD_PSE		0x00000010	/* RW periodic sched enable */
101#define	EHCI_CMD_FLS_M		0x0000000c	/* RW/RO frame list size */
102#define	EHCI_CMD_FLS(x)		(((x) >> 2) & 3)	/* RW/RO frame list size */
103#define	EHCI_CMD_HCRESET	0x00000002	/* RW reset */
104#define	EHCI_CMD_RS		0x00000001	/* RW run/stop */
105#define	EHCI_USBSTS		0x04	/* RO, RW, RWC Status register */
106#define	EHCI_STS_ASS		0x00008000	/* RO async sched status */
107#define	EHCI_STS_PSS		0x00004000	/* RO periodic sched status */
108#define	EHCI_STS_REC		0x00002000	/* RO reclamation */
109#define	EHCI_STS_HCH		0x00001000	/* RO host controller halted */
110#define	EHCI_STS_IAA		0x00000020	/* RWC interrupt on async adv */
111#define	EHCI_STS_HSE		0x00000010	/* RWC host system error */
112#define	EHCI_STS_FLR		0x00000008	/* RWC frame list rollover */
113#define	EHCI_STS_PCD		0x00000004	/* RWC port change detect */
114#define	EHCI_STS_ERRINT		0x00000002	/* RWC error interrupt */
115#define	EHCI_STS_INT		0x00000001	/* RWC interrupt */
116#define	EHCI_STS_INTRS(x)	((x) & 0x3f)
117
118/*
119 * NOTE: the doorbell interrupt is enabled, but the doorbell is never
120 * used! SiS chipsets require this.
121 */
122#define	EHCI_NORMAL_INTRS	(EHCI_STS_IAA | EHCI_STS_HSE |	\
123				EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT)
124
125#define	EHCI_USBINTR		0x08	/* RW Interrupt register */
126#define	EHCI_INTR_IAAE		0x00000020	/* interrupt on async advance
127						 * ena */
128#define	EHCI_INTR_HSEE		0x00000010	/* host system error ena */
129#define	EHCI_INTR_FLRE		0x00000008	/* frame list rollover ena */
130#define	EHCI_INTR_PCIE		0x00000004	/* port change ena */
131#define	EHCI_INTR_UEIE		0x00000002	/* USB error intr ena */
132#define	EHCI_INTR_UIE		0x00000001	/* USB intr ena */
133
134#define	EHCI_FRINDEX		0x0c	/* RW Frame Index register */
135
136#define	EHCI_CTRLDSSEGMENT	0x10	/* RW Control Data Structure Segment */
137
138#define	EHCI_PERIODICLISTBASE	0x14	/* RW Periodic List Base */
139#define	EHCI_ASYNCLISTADDR	0x18	/* RW Async List Base */
140
141#define	EHCI_CONFIGFLAG		0x40	/* RW Configure Flag register */
142#define	EHCI_CONF_CF		0x00000001	/* RW configure flag */
143
144#define	EHCI_PORTSC(n)		(0x40+(4*(n)))	/* RO, RW, RWC Port Status reg */
145#define	EHCI_PS_WKOC_E		0x00400000	/* RW wake on over current ena */
146#define	EHCI_PS_WKDSCNNT_E	0x00200000	/* RW wake on disconnect ena */
147#define	EHCI_PS_WKCNNT_E	0x00100000	/* RW wake on connect ena */
148#define	EHCI_PS_PTC		0x000f0000	/* RW port test control */
149#define	EHCI_PS_PIC		0x0000c000	/* RW port indicator control */
150#define	EHCI_PS_PO		0x00002000	/* RW port owner */
151#define	EHCI_PS_PP		0x00001000	/* RW,RO port power */
152#define	EHCI_PS_LS		0x00000c00	/* RO line status */
153#define	EHCI_PS_IS_LOWSPEED(x)	(((x) & EHCI_PS_LS) == 0x00000400)
154#define	EHCI_PS_PR		0x00000100	/* RW port reset */
155#define	EHCI_PS_SUSP		0x00000080	/* RW suspend */
156#define	EHCI_PS_FPR		0x00000040	/* RW force port resume */
157#define	EHCI_PS_OCC		0x00000020	/* RWC over current change */
158#define	EHCI_PS_OCA		0x00000010	/* RO over current active */
159#define	EHCI_PS_PEC		0x00000008	/* RWC port enable change */
160#define	EHCI_PS_PE		0x00000004	/* RW port enable */
161#define	EHCI_PS_CSC		0x00000002	/* RWC connect status change */
162#define	EHCI_PS_CS		0x00000001	/* RO connect status */
163#define	EHCI_PS_CLEAR		(EHCI_PS_OCC | EHCI_PS_PEC | EHCI_PS_CSC)
164
165#define	EHCI_USBMODE		0x68	/* RW USB Device mode register */
166#define	EHCI_UM_CM		0x00000003	/* R/WO Controller Mode */
167#define	EHCI_UM_CM_IDLE		0x0	/* Idle */
168#define	EHCI_UM_CM_HOST		0x3	/* Host Controller */
169#define	EHCI_UM_ES		0x00000004	/* R/WO Endian Select */
170#define	EHCI_UM_ES_LE		0x0	/* Little-endian byte alignment */
171#define	EHCI_UM_ES_BE		0x4	/* Big-endian byte alignment */
172#define	EHCI_UM_SDIS		0x00000010	/* R/WO Stream Disable Mode */
173
174#define	EHCI_PORT_RESET_COMPLETE	2	/* ms */
175
176/*
177 * Alignment NOTE: structures must be aligned so that the hardware can index
178 * without performing addition.
179 */
180#define	EHCI_FRAMELIST_ALIGN          0x1000	/* bytes */
181#define	EHCI_FRAMELIST_COUNT            1024	/* units */
182#define	EHCI_VIRTUAL_FRAMELIST_COUNT     128	/* units */
183
184#if ((8*EHCI_VIRTUAL_FRAMELIST_COUNT) < USB_MAX_HS_ISOC_FRAMES_PER_XFER)
185#error "maximum number of high-speed isochronous frames is higher than supported!"
186#endif
187
188#if (EHCI_VIRTUAL_FRAMELIST_COUNT < USB_MAX_FS_ISOC_FRAMES_PER_XFER)
189#error "maximum number of full-speed isochronous frames is higher than supported!"
190#endif
191
192/* Link types */
193#define	EHCI_LINK_TERMINATE	0x00000001
194#define	EHCI_LINK_TYPE(x)	((x) & 0x00000006)
195#define	EHCI_LINK_ITD		0x0
196#define	EHCI_LINK_QH		0x2
197#define	EHCI_LINK_SITD		0x4
198#define	EHCI_LINK_FSTN		0x6
199#define	EHCI_LINK_ADDR(x)	((x) &~ 0x1f)
200
201/* Structures alignment (bytes) */
202#define	EHCI_ITD_ALIGN	128
203#define	EHCI_SITD_ALIGN	64
204#define	EHCI_QTD_ALIGN	64
205#define	EHCI_QH_ALIGN	128
206#define	EHCI_FSTN_ALIGN	32
207/* Data buffers are divided into one or more pages */
208#define	EHCI_PAGE_SIZE	0x1000
209#if	((USB_PAGE_SIZE < EHCI_PAGE_SIZE) || (EHCI_PAGE_SIZE == 0) ||	\
210	(USB_PAGE_SIZE < EHCI_ITD_ALIGN) || (EHCI_ITD_ALIGN == 0) ||	\
211	(USB_PAGE_SIZE < EHCI_SITD_ALIGN) || (EHCI_SITD_ALIGN == 0) ||	\
212	(USB_PAGE_SIZE < EHCI_QTD_ALIGN) || (EHCI_QTD_ALIGN == 0) ||	\
213	(USB_PAGE_SIZE < EHCI_QH_ALIGN) || (EHCI_QH_ALIGN == 0) ||	\
214	(USB_PAGE_SIZE < EHCI_FSTN_ALIGN) || (EHCI_FSTN_ALIGN == 0))
215#error	"Invalid USB page size!"
216#endif
217
218
219/*
220 * Isochronous Transfer Descriptor.  This descriptor is used for high speed
221 * transfers only.
222 */
223struct ehci_itd {
224	volatile uint32_t itd_next;
225	volatile uint32_t itd_status[8];
226#define	EHCI_ITD_SET_LEN(x)	((x) << 16)
227#define	EHCI_ITD_GET_LEN(x)	(((x) >> 16) & 0xFFF)
228#define	EHCI_ITD_IOC		(1 << 15)
229#define	EHCI_ITD_SET_PG(x)	((x) << 12)
230#define	EHCI_ITD_GET_PG(x)	(((x) >> 12) & 0x7)
231#define	EHCI_ITD_SET_OFFS(x)	(x)
232#define	EHCI_ITD_GET_OFFS(x)	(((x) >> 0) & 0xFFF)
233#define	EHCI_ITD_ACTIVE		(1 << 31)
234#define	EHCI_ITD_DATABUFERR	(1 << 30)
235#define	EHCI_ITD_BABBLE		(1 << 29)
236#define	EHCI_ITD_XACTERR	(1 << 28)
237	volatile uint32_t itd_bp[7];
238	/* itd_bp[0] */
239#define	EHCI_ITD_SET_ADDR(x)	(x)
240#define	EHCI_ITD_GET_ADDR(x)	(((x) >> 0) & 0x7F)
241#define	EHCI_ITD_SET_ENDPT(x)	((x) << 8)
242#define	EHCI_ITD_GET_ENDPT(x)	(((x) >> 8) & 0xF)
243	/* itd_bp[1] */
244#define	EHCI_ITD_SET_DIR_IN	(1 << 11)
245#define	EHCI_ITD_SET_DIR_OUT	(0 << 11)
246#define	EHCI_ITD_SET_MPL(x)	(x)
247#define	EHCI_ITD_GET_MPL(x)	(((x) >> 0) & 0x7FF)
248	volatile uint32_t itd_bp_hi[7];
249/*
250 * Extra information needed:
251 */
252	uint32_t itd_self;
253	struct ehci_itd *next;
254	struct ehci_itd *prev;
255	struct ehci_itd *obj_next;
256	struct usb2_page_cache *page_cache;
257} __aligned(EHCI_ITD_ALIGN);
258
259typedef struct ehci_itd ehci_itd_t;
260
261/*
262 * Split Transaction Isochronous Transfer Descriptor.  This descriptor is used
263 * for full speed transfers only.
264 */
265struct ehci_sitd {
266	volatile uint32_t sitd_next;
267	volatile uint32_t sitd_portaddr;
268#define	EHCI_SITD_SET_DIR_OUT	(0 << 31)
269#define	EHCI_SITD_SET_DIR_IN	(1 << 31)
270#define	EHCI_SITD_SET_ADDR(x)	(x)
271#define	EHCI_SITD_GET_ADDR(x)	((x) & 0x7F)
272#define	EHCI_SITD_SET_ENDPT(x)	((x) << 8)
273#define	EHCI_SITD_GET_ENDPT(x)	(((x) >> 8) & 0xF)
274#define	EHCI_SITD_GET_DIR(x)	((x) >> 31)
275#define	EHCI_SITD_SET_PORT(x)	((x) << 24)
276#define	EHCI_SITD_GET_PORT(x)	(((x) >> 24) & 0x7F)
277#define	EHCI_SITD_SET_HUBA(x)	((x) << 16)
278#define	EHCI_SITD_GET_HUBA(x)	(((x) >> 16) & 0x7F)
279	volatile uint32_t sitd_mask;
280#define	EHCI_SITD_SET_SMASK(x)	(x)
281#define	EHCI_SITD_SET_CMASK(x)	((x) << 8)
282	volatile uint32_t sitd_status;
283#define	EHCI_SITD_COMPLETE_SPLIT	(1<<1)
284#define	EHCI_SITD_START_SPLIT		(0<<1)
285#define	EHCI_SITD_MISSED_MICRO_FRAME	(1<<2)
286#define	EHCI_SITD_XACTERR		(1<<3)
287#define	EHCI_SITD_BABBLE		(1<<4)
288#define	EHCI_SITD_DATABUFERR		(1<<5)
289#define	EHCI_SITD_ERROR			(1<<6)
290#define	EHCI_SITD_ACTIVE		(1<<7)
291#define	EHCI_SITD_IOC			(1<<31)
292#define	EHCI_SITD_SET_LEN(len)		((len)<<16)
293#define	EHCI_SITD_GET_LEN(x)		(((x)>>16) & 0x3FF)
294	volatile uint32_t sitd_bp[2];
295	volatile uint32_t sitd_back;
296	volatile uint32_t sitd_bp_hi[2];
297/*
298 * Extra information needed:
299 */
300	uint32_t sitd_self;
301	struct ehci_sitd *next;
302	struct ehci_sitd *prev;
303	struct ehci_sitd *obj_next;
304	struct usb2_page_cache *page_cache;
305} __aligned(EHCI_SITD_ALIGN);
306
307typedef struct ehci_sitd ehci_sitd_t;
308
309/* Queue Element Transfer Descriptor */
310struct ehci_qtd {
311	volatile uint32_t qtd_next;
312	volatile uint32_t qtd_altnext;
313	volatile uint32_t qtd_status;
314#define	EHCI_QTD_GET_STATUS(x)	(((x) >>  0) & 0xff)
315#define	EHCI_QTD_SET_STATUS(x)  ((x) << 0)
316#define	EHCI_QTD_ACTIVE		0x80
317#define	EHCI_QTD_HALTED		0x40
318#define	EHCI_QTD_BUFERR		0x20
319#define	EHCI_QTD_BABBLE		0x10
320#define	EHCI_QTD_XACTERR	0x08
321#define	EHCI_QTD_MISSEDMICRO	0x04
322#define	EHCI_QTD_SPLITXSTATE	0x02
323#define	EHCI_QTD_PINGSTATE	0x01
324#define	EHCI_QTD_STATERRS	0x74
325#define	EHCI_QTD_GET_PID(x)	(((x) >>  8) & 0x3)
326#define	EHCI_QTD_SET_PID(x)	((x) <<  8)
327#define	EHCI_QTD_PID_OUT	0x0
328#define	EHCI_QTD_PID_IN		0x1
329#define	EHCI_QTD_PID_SETUP	0x2
330#define	EHCI_QTD_GET_CERR(x)	(((x) >> 10) &  0x3)
331#define	EHCI_QTD_SET_CERR(x)	((x) << 10)
332#define	EHCI_QTD_GET_C_PAGE(x)	(((x) >> 12) &  0x7)
333#define	EHCI_QTD_SET_C_PAGE(x)	((x) << 12)
334#define	EHCI_QTD_GET_IOC(x)	(((x) >> 15) &  0x1)
335#define	EHCI_QTD_IOC		0x00008000
336#define	EHCI_QTD_GET_BYTES(x)	(((x) >> 16) &  0x7fff)
337#define	EHCI_QTD_SET_BYTES(x)	((x) << 16)
338#define	EHCI_QTD_GET_TOGGLE(x)	(((x) >> 31) &  0x1)
339#define	EHCI_QTD_SET_TOGGLE(x)	((x) << 31)
340#define	EHCI_QTD_TOGGLE_MASK	0x80000000
341#define	EHCI_QTD_NBUFFERS	5
342#define	EHCI_QTD_PAYLOAD_MAX ((EHCI_QTD_NBUFFERS-1)*EHCI_PAGE_SIZE)
343	volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS];
344	volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
345/*
346 * Extra information needed:
347 */
348	struct ehci_qtd *alt_next;
349	struct ehci_qtd *obj_next;
350	struct usb2_page_cache *page_cache;
351	uint32_t qtd_self;
352	uint16_t len;
353} __aligned(EHCI_QTD_ALIGN);
354
355typedef struct ehci_qtd ehci_qtd_t;
356
357/* Queue Head Sub Structure */
358struct ehci_qh_sub {
359	volatile uint32_t qtd_next;
360	volatile uint32_t qtd_altnext;
361	volatile uint32_t qtd_status;
362	volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS];
363	volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
364} __aligned(4);
365
366/* Queue Head */
367struct ehci_qh {
368	volatile uint32_t qh_link;
369	volatile uint32_t qh_endp;
370#define	EHCI_QH_GET_ADDR(x)	(((x) >>  0) & 0x7f)	/* endpoint addr */
371#define	EHCI_QH_SET_ADDR(x)	(x)
372#define	EHCI_QH_ADDRMASK	0x0000007f
373#define	EHCI_QH_GET_INACT(x)	(((x) >>  7) & 0x01)	/* inactivate on next */
374#define	EHCI_QH_INACT		0x00000080
375#define	EHCI_QH_GET_ENDPT(x)	(((x) >>  8) & 0x0f)	/* endpoint no */
376#define	EHCI_QH_SET_ENDPT(x)	((x) <<  8)
377#define	EHCI_QH_GET_EPS(x)	(((x) >> 12) & 0x03)	/* endpoint speed */
378#define	EHCI_QH_SET_EPS(x)	((x) << 12)
379#define	EHCI_QH_SPEED_FULL	0x0
380#define	EHCI_QH_SPEED_LOW	0x1
381#define	EHCI_QH_SPEED_HIGH	0x2
382#define	EHCI_QH_GET_DTC(x)	(((x) >> 14) & 0x01)	/* data toggle control */
383#define	EHCI_QH_DTC		0x00004000
384#define	EHCI_QH_GET_HRECL(x)	(((x) >> 15) & 0x01)	/* head of reclamation */
385#define	EHCI_QH_HRECL		0x00008000
386#define	EHCI_QH_GET_MPL(x)	(((x) >> 16) & 0x7ff)	/* max packet len */
387#define	EHCI_QH_SET_MPL(x)	((x) << 16)
388#define	EHCI_QH_MPLMASK		0x07ff0000
389#define	EHCI_QH_GET_CTL(x)	(((x) >> 27) & 0x01)	/* control endpoint */
390#define	EHCI_QH_CTL		0x08000000
391#define	EHCI_QH_GET_NRL(x)	(((x) >> 28) & 0x0f)	/* NAK reload */
392#define	EHCI_QH_SET_NRL(x)	((x) << 28)
393	volatile uint32_t qh_endphub;
394#define	EHCI_QH_GET_SMASK(x)	(((x) >>  0) & 0xff)	/* intr sched mask */
395#define	EHCI_QH_SET_SMASK(x)	((x) <<  0)
396#define	EHCI_QH_GET_CMASK(x)	(((x) >>  8) & 0xff)	/* split completion mask */
397#define	EHCI_QH_SET_CMASK(x)	((x) <<  8)
398#define	EHCI_QH_GET_HUBA(x)	(((x) >> 16) & 0x7f)	/* hub address */
399#define	EHCI_QH_SET_HUBA(x)	((x) << 16)
400#define	EHCI_QH_GET_PORT(x)	(((x) >> 23) & 0x7f)	/* hub port */
401#define	EHCI_QH_SET_PORT(x)	((x) << 23)
402#define	EHCI_QH_GET_MULT(x)	(((x) >> 30) & 0x03)	/* pipe multiplier */
403#define	EHCI_QH_SET_MULT(x)	((x) << 30)
404	volatile uint32_t qh_curqtd;
405	struct ehci_qh_sub qh_qtd;
406/*
407 * Extra information needed:
408 */
409	struct ehci_qh *next;
410	struct ehci_qh *prev;
411	struct ehci_qh *obj_next;
412	struct usb2_page_cache *page_cache;
413	uint32_t qh_self;
414} __aligned(EHCI_QH_ALIGN);
415
416typedef struct ehci_qh ehci_qh_t;
417
418/* Periodic Frame Span Traversal Node */
419struct ehci_fstn {
420	volatile uint32_t fstn_link;
421	volatile uint32_t fstn_back;
422} __aligned(EHCI_FSTN_ALIGN);
423
424typedef struct ehci_fstn ehci_fstn_t;
425
426struct ehci_hw_softc {
427	struct usb2_page_cache pframes_pc;
428	struct usb2_page_cache async_start_pc;
429	struct usb2_page_cache intr_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
430	struct usb2_page_cache isoc_hs_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
431	struct usb2_page_cache isoc_fs_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
432
433	struct usb2_page pframes_pg;
434	struct usb2_page async_start_pg;
435	struct usb2_page intr_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
436	struct usb2_page isoc_hs_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
437	struct usb2_page isoc_fs_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
438};
439
440struct ehci_config_desc {
441	struct usb2_config_descriptor confd;
442	struct usb2_interface_descriptor ifcd;
443	struct usb2_endpoint_descriptor endpd;
444} __packed;
445
446union ehci_hub_desc {
447	struct usb2_status stat;
448	struct usb2_port_status ps;
449	struct usb2_device_descriptor devd;
450	struct usb2_device_qualifier odevd;
451	struct usb2_hub_descriptor hubd;
452	uint8_t	temp[128];
453};
454
455typedef struct ehci_softc {
456	struct ehci_hw_softc sc_hw;
457	struct usb2_bus sc_bus;		/* base device */
458	struct usb2_callout sc_tmo_pcd;
459	union ehci_hub_desc sc_hub_desc;
460
461	struct usb2_device *sc_devices[EHCI_MAX_DEVICES];
462	struct resource *sc_io_res;
463	struct resource *sc_irq_res;
464	struct ehci_qh *sc_async_p_last;
465	struct ehci_qh *sc_intr_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
466	struct ehci_sitd *sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
467	struct ehci_itd *sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
468	void   *sc_intr_hdl;
469	bus_size_t sc_io_size;
470	bus_space_tag_t sc_io_tag;
471	bus_space_handle_t sc_io_hdl;
472
473	uint32_t sc_eintrs;
474	uint32_t sc_cmd;		/* shadow of cmd register during
475					 * suspend */
476
477	uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT];
478	uint16_t sc_id_vendor;		/* vendor ID for root hub */
479	uint16_t sc_flags;		/* chip specific flags */
480#define	EHCI_SCFLG_SETMODE	0x0001	/* set bridge mode again after init */
481#define	EHCI_SCFLG_FORCESPEED	0x0002	/* force speed */
482#define	EHCI_SCFLG_NORESTERM	0x0004	/* don't terminate reset sequence */
483#define	EHCI_SCFLG_BIGEDESC	0x0008	/* big-endian byte order descriptors */
484#define	EHCI_SCFLG_BIGEMMIO	0x0010	/* big-endian byte order MMIO */
485#define	EHCI_SCFLG_TT		0x0020	/* transaction translator present */
486
487	uint8_t	sc_offs;		/* offset to operational registers */
488	uint8_t	sc_doorbell_disable;	/* set on doorbell failure */
489	uint8_t	sc_noport;
490	uint8_t	sc_addr;		/* device address */
491	uint8_t	sc_conf;		/* device configuration */
492	uint8_t	sc_isreset;
493	uint8_t	sc_hub_idata[8];
494
495	char	sc_vendor[16];		/* vendor string for root hub */
496
497} ehci_softc_t;
498
499#define	EREAD1(sc, a)	bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
500#define	EREAD2(sc, a)	bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
501#define	EREAD4(sc, a)	bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
502#define	EWRITE1(sc, a, x)						\
503	    bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
504#define	EWRITE2(sc, a, x)						\
505	    bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
506#define	EWRITE4(sc, a, x)						\
507	    bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
508#define	EOREAD1(sc, a)							\
509	    bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
510#define	EOREAD2(sc, a)							\
511	    bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
512#define	EOREAD4(sc, a)							\
513	    bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
514#define	EOWRITE1(sc, a, x)						\
515	    bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
516#define	EOWRITE2(sc, a, x)						\
517	    bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
518#define	EOWRITE4(sc, a, x)						\
519	    bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
520
521#ifdef USB_EHCI_BIG_ENDIAN_DESC
522/*
523 * Handle byte order conversion between host and ``host controller''.
524 * Typically the latter is little-endian but some controllers require
525 * big-endian in which case we may need to manually swap.
526 */
527static __inline uint32_t
528htohc32(const struct ehci_softc *sc, const uint32_t v)
529{
530	return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe32(v) : htole32(v);
531}
532
533static __inline uint16_t
534htohc16(const struct ehci_softc *sc, const uint16_t v)
535{
536	return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe16(v) : htole16(v);
537}
538
539static __inline uint32_t
540hc32toh(const struct ehci_softc *sc, const uint32_t v)
541{
542	return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be32toh(v) : le32toh(v);
543}
544
545static __inline uint16_t
546hc16toh(const struct ehci_softc *sc, const uint16_t v)
547{
548	return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be16toh(v) : le16toh(v);
549}
550#else
551/*
552 * Normal little-endian only conversion routines.
553 */
554static __inline uint32_t
555htohc32(const struct ehci_softc *sc, const uint32_t v)
556{
557	return htole32(v);
558}
559
560static __inline uint16_t
561htohc16(const struct ehci_softc *sc, const uint16_t v)
562{
563	return htole16(v);
564}
565
566static __inline uint32_t
567hc32toh(const struct ehci_softc *sc, const uint32_t v)
568{
569	return le32toh(v);
570}
571
572static __inline uint16_t
573hc16toh(const struct ehci_softc *sc, const uint16_t v)
574{
575	return le16toh(v);
576}
577#endif
578
579usb2_bus_mem_cb_t ehci_iterate_hw_softc;
580
581usb2_error_t ehci_reset(ehci_softc_t *sc);
582usb2_error_t ehci_init(ehci_softc_t *sc);
583void	ehci_detach(struct ehci_softc *sc);
584void	ehci_suspend(struct ehci_softc *sc);
585void	ehci_resume(struct ehci_softc *sc);
586void	ehci_shutdown(ehci_softc_t *sc);
587void	ehci_interrupt(ehci_softc_t *sc);
588
589#endif					/* _EHCI_H_ */
590