1/*
2 * Copyright 2006, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Michael Lotz <mmlr@mlotz.ch>
7 */
8
9#ifndef EHCI_HARDWARE_H
10#define EHCI_HARDWARE_H
11
12// Host Controller Capability Registers (EHCI Spec 2.2)
13#define EHCI_CAPLENGTH			0x00		// Capability Register Length
14#define EHCI_HCIVERSION			0x02		// Interface Version Number
15#define EHCI_HCSPARAMS			0x04		// Structural Parameters
16#define EHCI_HCCPARAMS			0x08		// Capability Parameters
17#define EHCI_HCSP_PORTROUTE		0x0c		// Companion Port Route Description
18
19// Host Controller Operational Registers (EHCI Spec 2.3)
20#define EHCI_USBCMD				0x00		// USB Command
21#define EHCI_USBSTS				0x04		// USB Status
22#define EHCI_USBINTR			0x08		// USB Interrupt Enable
23#define EHCI_FRINDEX			0x0c		// USB Frame Index
24#define EHCI_CTRDSSEGMENT		0x10		// 4GB Segment Selector
25#define EHCI_PERIODICLISTBASE	0x14		// Frame List Base Address
26#define EHCI_ASYNCLISTADDR		0x18		// Next Asynchronous List Address
27#define EHCI_CONFIGFLAG			0x40		// Configured Flag Register
28#define EHCI_PORTSC				0x44		// Port Status/Control
29
30
31// USB Command Register (EHCI Spec 2.3.1)
32#define EHCI_USBCMD_ITC_SHIFT	16			// Interrupt Threshold Control
33#define EHCI_USBCMD_ITC_MASK	0xff
34#define EHCI_USBCMD_PPCEE		(1 << 15)	// Per-Port Change Events Enable
35#define EHCI_USBCMD_FSP			(1 << 14)	// Fully Synchronized Prefetch
36#define EHCI_USBCMD_ASPE		(1 << 13)	// Async Schedule Prefetch Enable
37#define EHCI_USBCMD_PSPE		(1 << 12)	// Periodic Schedule Prefetch Enable
38#define EHCI_USBCMD_ASPME		(1 << 11)	// Async Schedule Park Mode Enable
39#define EHCI_USBCMD_ASPMC_SHIFT	8			// Async Schedule Park Mode Count
40#define EHCI_USBCMD_ASPMC_MASK	0x03
41#define EHCI_USBCMD_LHCRESET	(1 << 7)	// Light Host Controller Reset
42#define EHCI_USBCMD_INTONAAD	(1 << 6)	// Interrupt on Async Advance Doorbell
43#define EHCI_USBCMD_ASENABLE	(1 << 5)	// Asynchronous Schedule Enable
44#define EHCI_USBCMD_PSENABLE	(1 << 4)	// Periodic Schedule Enable
45#define EHCI_USBCMD_FLS_SHIFT	2			// Frame List Size
46#define EHCI_USBCMD_FLS_MASK	0x03
47#define EHCI_USBCMD_HCRESET		(1 << 1)	// Host Controller Reset
48#define EHCI_USBCMD_RUNSTOP		(1 << 0)	// Run/Stop
49
50
51// USB Status Register (EHCI Spec 2.3.2)
52#define EHCI_USBSTS_ASSTATUS	(1 << 15)	// Asynchronous Schedule Status
53#define EHCI_USBSTS_PSSTATUS	(1 << 14)	// Periodic Schedule Status
54#define EHCI_USBSTS_RECLAMATION	(1 << 13)	// Reclamation
55#define EHCI_USBSTS_HCHALTED	(1 << 12)	// Host Controller Halted
56#define EHCI_USBSTS_INTONAA		(1 << 5)	// Interrupt on Async Advance
57#define EHCI_USBSTS_HOSTSYSERR	(1 << 4)	// Host System Error
58#define EHCI_USBSTS_FLROLLOVER	(1 << 3)	// Frame List Rollover
59#define EHCI_USBSTS_PORTCHANGE	(1 << 2)	// Port Change Detected
60#define EHCI_USBSTS_USBERRINT	(1 << 1)	// USB Error Interrupt
61#define EHCI_USBSTS_USBINT		(1 << 0)	// USB Interrupt
62#define EHCI_USBSTS_INTMASK		0x3f
63
64
65// USB Interrupt Enable Register (EHCI Spec 2.3.3)
66#define EHCI_USBINTR_INTONAA	(1 << 5)	// Interrupt on Async Advance Enable
67#define EHCI_USBINTR_HOSTSYSERR	(1 << 4)	// Host System Error Enable
68#define EHCI_USBINTR_FLROLLOVER	(1 << 3)	// Frame List Rollover Enable
69#define EHCI_USBINTR_PORTCHANGE	(1 << 2)	// Port Change Interrupt Enable
70#define EHCI_USBINTR_USBERRINT	(1 << 1)	// USB Error Interrupt Enable
71#define EHCI_USBINTR_USBINT		(1 << 0)	// USB Interrupt Enable
72
73
74// Configure Flag Register (EHCI Spec 2.3.8)
75#define EHCI_CONFIGFLAG_FLAG	(1 << 0)	// Configure Flag
76
77
78// Port Status and Control (EHCI Spec 2.3.9)
79#define EHCI_PORTSC_WAKEOVERCUR	(1 << 22)	// Wake on Over-Current Enable
80#define EHCI_PORTSC_WAKEDISCON	(1 << 21)	// Wake on Disconnect Enable
81#define EHCI_PORTSC_WAKECONNECT	(1 << 20)	// Wake on Connect Enable
82#define EHCI_PORTSC_PTC_SHIFT	16			// Port Test Control
83#define EHCI_PORTSC_PTC_MASK	0x07
84#define EHCI_PORTSC_PIC_SHIFT	14			// Port Indicator Control
85#define EHCI_PORTSC_PIC_MASK	0x03
86#define EHCI_PORTSC_PORTOWNER	(1 << 13)	// Port Owner
87#define EHCI_PORTSC_PORTPOWER	(1 << 12)	// Port Power
88#define EHCI_PORTSC_DPLUS		(1 << 11)	// Logical Level of D+
89#define EHCI_PORTSC_DMINUS		(1 << 10)	// Logical Level of D-
90#define EHCI_PORTSC_PORTRESET	(1 << 8)	// Port Reset
91#define EHCI_PORTSC_SUSPEND		(1 << 7)	// Suspend
92#define EHCI_PORTSC_FORCERESUME	(1 << 6)	// Force Port Resume
93#define EHCI_PORTSC_OCCHANGE	(1 << 5)	// Over-Current Change
94#define EHCI_PORTSC_OCACTIVE	(1 << 4)	// Over-Current Active
95#define EHCI_PORTSC_ENABLECHANGE (1 << 3)	// Port Enable/Disable Change
96#define EHCI_PORTSC_ENABLE		(1 << 2)	// Port Enabled/Disabled
97#define EHCI_PORTSC_CONNCHANGE	(1 << 1)	// Connect Status Change
98#define EHCI_PORTSC_CONNSTATUS	(1 << 0)	// Current Connect Status
99
100#define EHCI_PORTSC_DATAMASK	0xffffffd5
101
102
103// Extended Capabilities
104#define EHCI_ECP_SHIFT			8			// Extended Capability Pointer
105#define EHCI_ECP_MASK			0xff
106#define EHCI_LEGSUP_CAPID_MASK	0xff
107#define EHCI_LEGSUP_CAPID		0x01
108#define EHCI_LEGSUP_OSOWNED		(1 << 24)	// OS Owned Semaphore
109#define EHCI_LEGSUP_BIOSOWNED	(1 << 16)	// BIOS Owned Semaphore
110
111#define EHCI_HCCPARAMS_FPLC		(1 << 19)	// 32 Frames Period List
112#define EHCI_HCCPARAMS_PPCEC	(1 << 18)	// Per-Port Change Event
113#define EHCI_HCCPARAMS_LPM		(1 << 17)	// Link Power Management
114#define EHCI_HCCPARAMS_HP		(1 << 16)	// Hardware Prefetch
115#define EHCI_HCCPARAMS_FRAME_CACHE(x)	((x >> 7) & 0x1)	// Isochronous Periodic Threshold
116#define EHCI_HCCPARAMS_IPT(x)	((x >> 4) & 0x7)	// Isochronous Periodic Threshold
117
118
119// Data Structures (EHCI Spec 3)
120
121
122// Applies to ehci_qh.next_phy, ehci_sitd.next_phy, ehci_itd.next_phy
123#define EHCI_ITEM_TYPE_ITD		(0 << 1)	// Isochronous Transfer Descriptor
124#define EHCI_ITEM_TYPE_QH		(1 << 1)	// Queue Head
125#define EHCI_ITEM_TYPE_SITD		(2 << 1)	// Split Transaction Isochronous TD
126#define EHCI_ITEM_TYPE_FSTN		(3 << 1)	// Frame Span Traversal Node
127#define EHCI_ITEM_TERMINATE		(1 << 0)	// Terminate
128
129
130// Isochronous (High-Speed) Transfer Descriptors (iTD, EHCI Spec 3.2)
131typedef struct ehci_itd {
132	// Hardware Part
133	uint32		next_phy;
134	uint32		token[8];
135	uint32		buffer_phy[7];
136	uint32		ext_buffer_phy[7];
137
138	// Software Part
139	uint32		this_phy;
140	struct ehci_itd	*next;
141	struct ehci_itd	*prev;
142	uint32		last_token;
143} ehci_itd;
144
145#define EHCI_ITD_TOFFSET_SHIFT	0
146#define EHCI_ITD_TOFFSET_MASK	0x0fff
147#define EHCI_ITD_IOC			(1 << 15)
148#define EHCI_ITD_PG_SHIFT		12
149#define EHCI_ITD_PG_MASK		0x07
150#define EHCI_ITD_TLENGTH_SHIFT	16
151#define EHCI_ITD_TLENGTH_MASK	0x0fff
152#define EHCI_ITD_STATUS_SHIFT	28
153#define EHCI_ITD_STATUS_MASK	0xf
154#define EHCI_ITD_STATUS_ACTIVE	(1 << 3)	// Active
155#define EHCI_ITD_STATUS_BUFFER	(1 << 2)	// Data Buffer Error
156#define EHCI_ITD_STATUS_BABBLE	(1 << 1)	// Babble Detected
157#define EHCI_ITD_STATUS_TERROR	(1 << 0)	// Transaction Error
158#define EHCI_ITD_ADDRESS_SHIFT	0
159#define EHCI_ITD_ADDRESS_MASK	0x7f
160#define EHCI_ITD_ENDPOINT_SHIFT	8
161#define EHCI_ITD_ENDPOINT_MASK	0xf
162#define EHCI_ITD_DIR_SHIFT	11
163#define EHCI_ITD_MUL_SHIFT	0
164#define EHCI_ITD_MUL_MASK	0x3
165#define EHCI_ITD_BUFFERPOINTER_SHIFT	12
166#define EHCI_ITD_BUFFERPOINTER_MASK	0xfffff
167#define EHCI_ITD_MAXPACKETSIZE_SHIFT	0
168#define EHCI_ITD_MAXPACKETSIZE_MASK	0x7ff
169#define EHCI_ITD_MAXPACKETSIZE_LENGTH	11
170
171
172// Split Transaction Isochronous Transfer Descriptors (siTD, EHCI Spec 3.3)
173typedef struct ehci_sitd {
174	// Hardware Part
175	uint32		next_phy;
176	uint8		port_number;
177	uint8		hub_address;
178	uint8		endpoint;
179	uint8		device_address;
180	uint16		reserved1;
181	uint8		cmask;
182	uint8		smask;
183	uint16		transfer_length;
184	uint8		cprogmask;
185	uint8		status;
186	uint32		buffer_phy[2];
187	uint32		back_phy;
188	uint32		ext_buffer_phy[2];
189
190	// Software Part
191	uint32		this_phy;
192	struct ehci_sitd *next;
193	struct ehci_sitd *prev;
194	size_t		buffer_size;
195	void		*buffer_log;
196} _PACKED ehci_sitd;
197
198// Queue Element Transfer Descriptors (qTD, EHCI Spec 3.5)
199typedef struct ehci_qtd {
200	// Hardware Part
201	uint32		next_phy;
202	uint32		alt_next_phy;
203	uint32		token;
204	uint32		buffer_phy[5];
205	uint32		ext_buffer_phy[5];
206
207	// Software Part
208	uint32		this_phy;
209	struct ehci_qtd	*next_log;
210	struct ehci_qtd	*alt_next_log;
211	size_t		buffer_size;
212	void		*buffer_log;
213} _PACKED ehci_qtd;
214
215
216#define EHCI_QTD_DATA_TOGGLE	(1U << 31)
217#define EHCI_QTD_BYTES_SHIFT	16
218#define EHCI_QTD_BYTES_MASK		0x7fff
219#define EHCI_QTD_IOC			(1 << 15)
220#define EHCI_QTD_CPAGE_SHIFT	12
221#define EHCI_QTD_CPAGE_MASK		0x07
222#define EHCI_QTD_ERRCOUNT_SHIFT	10
223#define EHCI_QTD_ERRCOUNT_MASK	0x03
224#define EHCI_QTD_PID_SHIFT		8
225#define EHCI_QTD_PID_MASK		0x03
226#define EHCI_QTD_PID_OUT		0x00
227#define EHCI_QTD_PID_IN			0x01
228#define EHCI_QTD_PID_SETUP		0x02
229#define EHCI_QTD_STATUS_SHIFT	0
230#define EHCI_QTD_STATUS_MASK	0x7f
231#define EHCI_QTD_STATUS_ERRMASK	0x50
232#define EHCI_QTD_STATUS_ACTIVE	(1 << 7)	// Active
233#define EHCI_QTD_STATUS_HALTED	(1 << 6)	// Halted
234#define EHCI_QTD_STATUS_BUFFER	(1 << 5)	// Data Buffer Error
235#define EHCI_QTD_STATUS_BABBLE	(1 << 4)	// Babble Detected
236#define EHCI_QTD_STATUS_TERROR	(1 << 3)	// Transaction Error
237#define EHCI_QTD_STATUS_MISSED	(1 << 2)	// Missed Micro-Frame
238#define EHCI_QTD_STATUS_SPLIT	(1 << 1)	// Split Transaction State
239#define EHCI_QTD_STATUS_PING	(1 << 0)	// Ping State
240#define EHCI_QTD_STATUS_LS_ERR	(1 << 0)	// Full-/Lowspeed Error
241#define EHCI_QTD_PAGE_MASK		0xfffff000
242
243
244// Queue Head (QH, EHCI Spec 3.6)
245typedef struct ehci_qh {
246	// Hardware Part
247	uint32		next_phy;
248	uint32		endpoint_chars;
249	uint32		endpoint_caps;
250	uint32		current_qtd_phy;
251
252	struct {
253		uint32		next_phy;
254		uint32		alt_next_phy;
255		uint32		token;
256		uint32		buffer_phy[5];
257		uint32		ext_buffer_phy[5];
258	} overlay;
259
260	// Software Part
261	uint32		this_phy;
262	struct ehci_qh *next_log;
263	struct ehci_qh *prev_log;
264	ehci_qtd	*stray_log;
265	ehci_qtd	*element_log;
266} ehci_qh;
267
268
269typedef struct {
270	ehci_qh		queue_head;
271#ifdef B_HAIKU_64_BIT
272	uint32		padding[6];
273#else
274	uint32		padding[2];
275#endif
276} interrupt_entry;
277
278typedef struct {
279	ehci_itd	itd;
280#ifdef B_HAIKU_64_BIT
281	uint32		padding[1]; // align on 128
282#else
283	uint32		padding[5]; // align on 128
284#endif
285} itd_entry;
286
287typedef struct {
288	ehci_sitd	sitd;
289
290#ifdef B_HAIKU_64_BIT
291	uint32		padding[14]; // align on 64
292#else
293	uint32 		padding[2]; // align on 64
294#endif
295} sitd_entry;
296
297#define EHCI_INTERRUPT_ENTRIES_COUNT	(7 + 1)		// (log 128 / log 2) + 1
298#define EHCI_VFRAMELIST_ENTRIES_COUNT	128
299#define EHCI_FRAMELIST_ENTRIES_COUNT	1024
300
301#define MAX_AVAILABLE_BANDWIDTH	125	// Microseconds
302
303
304// Applies to ehci_qh.endpoint_chars
305#define EHCI_QH_CHARS_RL_SHIFT	28			// NAK Count Reload
306#define EHCI_QH_CHARS_RL_MASK	0x07
307#define EHCI_QH_CHARS_CONTROL	(1 << 27)	// Control Endpoint Flag
308#define EHCI_QH_CHARS_MPL_SHIFT	16			// Max Packet Length
309#define EHCI_QH_CHARS_MPL_MASK	0x03ff
310#define EHCI_QH_CHARS_RECHEAD	(1 << 15)	// Head of Reclamation List Flag
311#define EHCI_QH_CHARS_TOGGLE	(1 << 14)	// Data Toggle Control
312#define EHCI_QH_CHARS_EPS_FULL	(0 << 12)	// Endpoint is Full-Speed
313#define EHCI_QH_CHARS_EPS_LOW	(1 << 12)	// Endpoint is Low-Speed
314#define EHCI_QH_CHARS_EPS_HIGH	(2 << 12)	// Endpoint is High-Speed
315#define EHCI_QH_CHARS_EPT_SHIFT	8			// Endpoint Number
316#define EHCI_QH_CHARS_EPT_MASK	0x0f
317#define EHCI_QH_CHARS_INACTIVE	(1 << 7)	// Inactive on Next Transaction
318#define EHCI_QH_CHARS_DEV_SHIFT	0			// Device Address
319#define EHCI_QH_CHARS_DEV_MASK	0x7f
320
321
322// Applies to ehci_qh.endpoint_caps
323#define EHCI_QH_CAPS_MULT_SHIFT	30			// Transactions per Micro-Frame
324#define EHCI_QH_CAPS_MULT_MASK	0x03
325#define EHCI_QH_CAPS_PORT_SHIFT	23			// Hub Port (Split-Transaction)
326#define EHCI_QH_CAPS_PORT_MASK	0x7f
327#define EHCI_QH_CAPS_HUB_SHIFT	16			// Hub Address (Split-Transaction)
328#define EHCI_QH_CAPS_HUB_MASK	0x7f
329#define EHCI_QH_CAPS_SCM_SHIFT	8			// Split Completion Mask
330#define EHCI_QH_CAPS_SCM_MASK	0xff
331#define EHCI_QH_CAPS_ISM_SHIFT	0			// Interrupt Schedule Mask
332#define EHCI_QH_CAPS_ISM_MASK	0xff
333
334
335// Applies to ehci_qh.overlay[EHCI_QH_OL_*_INDEX]
336#define EHCI_QH_OL_NAK_INDEX	1			// NAK Counter
337#define EHCI_QH_OL_NAK_SHIFT	1
338#define EHCI_QH_OL_NAK_MASK		0x0f
339#define EHCI_QH_OL_TOGGLE_INDEX	2			// Data Toggle
340#define EHCI_QH_OL_TOGGLE		(1U << 31)
341#define EHCI_QH_OL_IOC_INDEX	2			// Interrupt on Complete
342#define EHCI_QH_OL_IOC			(1 << 15)
343#define EHCI_QH_OL_ERRC_INDEX	2			// Error Counter
344#define EHCI_QH_OL_ERRC_SHIFT	10
345#define EHCI_QH_OL_ERRC_MASK	0x03
346#define EHCI_QH_OL_PING_INDEX	2			// Ping State
347#define EHCI_QH_OL_PING			(1 << 0)
348#define EHCI_QH_OL_CPROG_INDEX	4			// Split-Transaction Complete-Split Progress
349#define EHCI_QH_OL_CPROG_SHIFT	0
350#define EHCI_QH_OL_CPROG_MASK	0xff
351#define EHCI_QH_OL_FTAG_INDEX	5			// Split-Transaction Frame Tag
352#define EHCI_QH_OL_FTAG_SHIFT	0
353#define EHCI_QH_OL_FTAG_MASK	0x0f
354#define EHCI_QH_OL_BYTES_INDEX	5			// Transfered Bytes
355#define EHCI_QH_OL_BYTES_SHIFT	5
356#define EHCI_QH_OL_BYTES_MASK	0x7f
357
358
359// ToDo: Periodic Frame Span Traversal Node (FSTN, EHCI Spec 3.7)
360
361
362// Quirk registers and values
363#define	AMD_SBX00_VENDOR				0x1002
364#define	AMD_SBX00_SMBUS_CONTROLLER		0x4385
365#define	AMD_SB600_EHCI_CONTROLLER		0x4386
366#define	AMD_SB700_SB800_EHCI_CONTROLLER	0x4396
367
368#define	AMD_SBX00_EHCI_MISC_REGISTER	0x50	// Advanced config register
369#define	AMD_SBX00_EHCI_MISC_DISABLE_PERIODIC_LIST_CACHE		(1 << 27)
370
371#endif // !EHCI_HARDWARE_H
372