xref: /openbsd-src/sys/dev/usb/dwc2/dwc2.h (revision a9beb1ed4245313a4b68e10ec33a67c806523ec4)
1*a9beb1edSmglocker /*	$OpenBSD: dwc2.h,v 1.16 2022/09/04 08:42:39 mglocker Exp $	*/
225e434cbSuebayasi /*	$NetBSD: dwc2.h,v 1.4 2014/12/23 16:20:06 macallan Exp $	*/
3578f812dSuebayasi 
4578f812dSuebayasi /*-
5578f812dSuebayasi  * Copyright (c) 2013 The NetBSD Foundation, Inc.
6578f812dSuebayasi  * All rights reserved.
7578f812dSuebayasi  *
8578f812dSuebayasi  * This code is derived from software contributed to The NetBSD Foundation
9578f812dSuebayasi  * by Nick Hudson
10578f812dSuebayasi  *
11578f812dSuebayasi  * Redistribution and use in source and binary forms, with or without
12578f812dSuebayasi  * modification, are permitted provided that the following conditions
13578f812dSuebayasi  * are met:
14578f812dSuebayasi  * 1. Redistributions of source code must retain the above copyright
15578f812dSuebayasi  *    notice, this list of conditions and the following disclaimer.
16578f812dSuebayasi  * 2. Redistributions in binary form must reproduce the above copyright
17578f812dSuebayasi  *    notice, this list of conditions and the following disclaimer in the
18578f812dSuebayasi  *    documentation and/or other materials provided with the distribution.
19578f812dSuebayasi  *
20578f812dSuebayasi  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21578f812dSuebayasi  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22578f812dSuebayasi  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23578f812dSuebayasi  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24578f812dSuebayasi  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25578f812dSuebayasi  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26578f812dSuebayasi  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27578f812dSuebayasi  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28578f812dSuebayasi  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29578f812dSuebayasi  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30578f812dSuebayasi  * POSSIBILITY OF SUCH DAMAGE.
31578f812dSuebayasi  */
32578f812dSuebayasi 
33578f812dSuebayasi #ifndef _EXTERNAL_BSD_DWC2_DWC2_H_
34578f812dSuebayasi #define _EXTERNAL_BSD_DWC2_DWC2_H_
35578f812dSuebayasi 
36578f812dSuebayasi #include <sys/param.h>
37578f812dSuebayasi #include <sys/kernel.h>
38578f812dSuebayasi 
39309465dbSuebayasi #include <sys/task.h>
40578f812dSuebayasi 
41c95c98b7Sjmatthew #include <lib/libkern/libkern.h>
42578f812dSuebayasi 
4305c50565Suebayasi #define STATIC
4405c50565Suebayasi 
45*a9beb1edSmglocker // #define DWC2_DEBUG
46578f812dSuebayasi // #define VERBOSE_DEBUG
47578f812dSuebayasi // #define CONFIG_USB_DWC2_TRACK_MISSED_SOFS
48578f812dSuebayasi 
49d05ae140Smglocker #define CONFIG_USB_DWC2_HOST		1
50d05ae140Smglocker #define CONFIG_USB_DWC2_DUAL_ROLE	0
51d05ae140Smglocker #define CONFIG_USB_DWC2_PERIPHERAL	0
52d05ae140Smglocker 
53578f812dSuebayasi typedef int irqreturn_t;
54578f812dSuebayasi #define	IRQ_NONE 0
55578f812dSuebayasi #define IRQ_HANDLED 1
56578f812dSuebayasi 
57578f812dSuebayasi #define	u8	uint8_t
58578f812dSuebayasi #define	u16	uint16_t
59578f812dSuebayasi #define	s16	int16_t
60578f812dSuebayasi #define	u32	uint32_t
61578f812dSuebayasi #define	u64	uint64_t
62578f812dSuebayasi 
63578f812dSuebayasi #define	dma_addr_t	bus_addr_t
64578f812dSuebayasi 
65578f812dSuebayasi #ifdef DWC2_DEBUG
66578f812dSuebayasi extern int dwc2debug;
67578f812dSuebayasi #define	dev_info(d,fmt,...) do {			\
68578f812dSuebayasi 	printf("%s: " fmt, device_xname(d), 		\
69578f812dSuebayasi 	    ## __VA_ARGS__);				\
70578f812dSuebayasi } while (0)
71578f812dSuebayasi #define	dev_warn(d,fmt,...) do {			\
72578f812dSuebayasi 	printf("%s: " fmt, device_xname(d), 		\
73578f812dSuebayasi 	    ## __VA_ARGS__);				\
74578f812dSuebayasi } while (0)
75578f812dSuebayasi #define	dev_err(d,fmt,...) do {				\
76578f812dSuebayasi 	printf("%s: " fmt, device_xname(d), 		\
77578f812dSuebayasi 	    ## __VA_ARGS__);				\
78578f812dSuebayasi } while (0)
79578f812dSuebayasi #define	dev_dbg(d,fmt,...) do {				\
80578f812dSuebayasi 	if (dwc2debug >= 1) {				\
81578f812dSuebayasi 	    printf("%s: " fmt, device_xname(d), 	\
82578f812dSuebayasi 		    ## __VA_ARGS__);			\
83578f812dSuebayasi 	}						\
84578f812dSuebayasi } while (0)
85578f812dSuebayasi #define	dev_vdbg(d,fmt,...) do {			\
86578f812dSuebayasi 	if (dwc2debug >= 2) {				\
87578f812dSuebayasi 	    printf("%s: " fmt, device_xname(d), 	\
88578f812dSuebayasi 		    ## __VA_ARGS__);			\
89578f812dSuebayasi 	}						\
90578f812dSuebayasi } while (0)
91578f812dSuebayasi #else
92578f812dSuebayasi #define	dev_info(...) do { } while (0)
93578f812dSuebayasi #define	dev_warn(...) do { } while (0)
94578f812dSuebayasi #define	dev_err(...) do { } while (0)
95578f812dSuebayasi #define	dev_dbg(...) do { } while (0)
96578f812dSuebayasi #define	dev_vdbg(...) do { } while (0)
97578f812dSuebayasi #endif
98578f812dSuebayasi 
99578f812dSuebayasi enum usb_otg_state {
100578f812dSuebayasi 	OTG_STATE_RESERVED = 0,
101578f812dSuebayasi 
102578f812dSuebayasi 	OTG_STATE_A_HOST,
103578f812dSuebayasi 	OTG_STATE_A_PERIPHERAL,
104578f812dSuebayasi 	OTG_STATE_A_SUSPEND,
105578f812dSuebayasi 	OTG_STATE_B_HOST,
106578f812dSuebayasi 	OTG_STATE_B_PERIPHERAL,
107578f812dSuebayasi };
108578f812dSuebayasi 
109b6c5b329Suebayasi #define spinlock_t		struct mutex
110*a9beb1edSmglocker #define spin_lock_init(lock)	mtx_init(lock, IPL_VM)
111b6c5b329Suebayasi #define spin_lock(l)		do { mtx_enter(l); } while (0)
112b6c5b329Suebayasi #define spin_unlock(l)		do { mtx_leave(l); } while (0)
113578f812dSuebayasi 
114578f812dSuebayasi #define	spin_lock_irqsave(l, f)		\
115b6c5b329Suebayasi 	do { mtx_enter(l); (void)(f); } while (0)
116578f812dSuebayasi 
117*a9beb1edSmglocker #define	spin_trylock_irqsave(l, f)	mtx_enter_try(l)
118*a9beb1edSmglocker 
119578f812dSuebayasi #define	spin_unlock_irqrestore(l, f)	\
120b6c5b329Suebayasi 	do { mtx_leave(l); (void)(f); } while (0)
121578f812dSuebayasi 
122578f812dSuebayasi #define	IRQ_RETVAL(r)	(r)
123578f812dSuebayasi 
124578f812dSuebayasi #define	USB_ENDPOINT_XFER_CONTROL	UE_CONTROL		/* 0 */
125578f812dSuebayasi #define	USB_ENDPOINT_XFER_ISOC		UE_ISOCHRONOUS		/* 1 */
126578f812dSuebayasi #define	USB_ENDPOINT_XFER_BULK		UE_BULK			/* 2 */
127578f812dSuebayasi #define	USB_ENDPOINT_XFER_INT		UE_INTERRUPT		/* 3 */
128578f812dSuebayasi 
129578f812dSuebayasi #define USB_DIR_IN			UE_DIR_IN
130578f812dSuebayasi #define USB_DIR_OUT			UE_DIR_OUT
131578f812dSuebayasi 
132578f812dSuebayasi #define	USB_PORT_FEAT_CONNECTION	UHF_PORT_CONNECTION
133578f812dSuebayasi #define	USB_PORT_FEAT_ENABLE		UHF_PORT_ENABLE
134578f812dSuebayasi #define	USB_PORT_FEAT_SUSPEND		UHF_PORT_SUSPEND
135578f812dSuebayasi #define	USB_PORT_FEAT_OVER_CURRENT	UHF_PORT_OVER_CURRENT
136578f812dSuebayasi #define	USB_PORT_FEAT_RESET		UHF_PORT_RESET
137578f812dSuebayasi // #define	USB_PORT_FEAT_L1		5	/* L1 suspend */
138578f812dSuebayasi #define	USB_PORT_FEAT_POWER		UHF_PORT_POWER
139578f812dSuebayasi #define	USB_PORT_FEAT_LOWSPEED		UHF_PORT_LOW_SPEED
140578f812dSuebayasi #define	USB_PORT_FEAT_C_CONNECTION	UHF_C_PORT_CONNECTION
141578f812dSuebayasi #define	USB_PORT_FEAT_C_ENABLE		UHF_C_PORT_ENABLE
142578f812dSuebayasi #define	USB_PORT_FEAT_C_SUSPEND		UHF_C_PORT_SUSPEND
143578f812dSuebayasi #define	USB_PORT_FEAT_C_OVER_CURRENT	UHF_C_PORT_OVER_CURRENT
144578f812dSuebayasi #define	USB_PORT_FEAT_C_RESET		UHF_C_PORT_RESET
145578f812dSuebayasi #define	USB_PORT_FEAT_TEST              UHF_PORT_TEST
146578f812dSuebayasi #define	USB_PORT_FEAT_INDICATOR         UHF_PORT_INDICATOR
147578f812dSuebayasi #define	USB_PORT_FEAT_C_PORT_L1         UHF_C_PORT_L1
148578f812dSuebayasi 
149578f812dSuebayasi #define	C_HUB_LOCAL_POWER		UHF_C_HUB_LOCAL_POWER
150578f812dSuebayasi #define	C_HUB_OVER_CURRENT		UHF_C_HUB_OVER_CURRENT
151578f812dSuebayasi 
152578f812dSuebayasi #define USB_REQ_GET_STATUS		UR_GET_STATUS
153578f812dSuebayasi #define USB_REQ_CLEAR_FEATURE		UR_CLEAR_FEATURE
154578f812dSuebayasi #define USB_REQ_SET_FEATURE		UR_SET_FEATURE
155578f812dSuebayasi #define USB_REQ_GET_DESCRIPTOR		UR_GET_DESCRIPTOR
156578f812dSuebayasi 
157578f812dSuebayasi #define	ClearHubFeature		((UT_WRITE_CLASS_DEVICE << 8) | USB_REQ_CLEAR_FEATURE)
158578f812dSuebayasi #define	ClearPortFeature	((UT_WRITE_CLASS_OTHER << 8) | USB_REQ_CLEAR_FEATURE)
159578f812dSuebayasi #define	GetHubDescriptor	((UT_READ_CLASS_DEVICE << 8) | USB_REQ_GET_DESCRIPTOR)
160578f812dSuebayasi #define	GetHubStatus		((UT_READ_CLASS_DEVICE << 8) | USB_REQ_GET_STATUS)
161578f812dSuebayasi #define	GetPortStatus		((UT_READ_CLASS_OTHER << 8) | USB_REQ_GET_STATUS)
162578f812dSuebayasi #define	SetHubFeature		((UT_WRITE_CLASS_DEVICE << 8) | USB_REQ_SET_FEATURE)
163578f812dSuebayasi #define	SetPortFeature		((UT_WRITE_CLASS_OTHER << 8) | USB_REQ_SET_FEATURE)
164578f812dSuebayasi 
165578f812dSuebayasi #define	USB_PORT_STAT_CONNECTION	UPS_CURRENT_CONNECT_STATUS
166578f812dSuebayasi #define	USB_PORT_STAT_ENABLE		UPS_PORT_ENABLED
167578f812dSuebayasi #define	USB_PORT_STAT_SUSPEND		UPS_SUSPEND
168578f812dSuebayasi #define	USB_PORT_STAT_OVERCURRENT	UPS_OVERCURRENT_INDICATOR
169578f812dSuebayasi #define	USB_PORT_STAT_RESET		UPS_RESET
170578f812dSuebayasi #define	USB_PORT_STAT_L1		UPS_PORT_L1
171578f812dSuebayasi #define	USB_PORT_STAT_POWER		UPS_PORT_POWER
172578f812dSuebayasi #define	USB_PORT_STAT_LOW_SPEED		UPS_LOW_SPEED
173578f812dSuebayasi #define	USB_PORT_STAT_HIGH_SPEED        UPS_HIGH_SPEED
174578f812dSuebayasi #define	USB_PORT_STAT_TEST              UPS_PORT_TEST
175578f812dSuebayasi #define	USB_PORT_STAT_INDICATOR         UPS_PORT_INDICATOR
176578f812dSuebayasi 
177578f812dSuebayasi #define	USB_PORT_STAT_C_CONNECTION	UPS_C_CONNECT_STATUS
178578f812dSuebayasi #define	USB_PORT_STAT_C_ENABLE		UPS_C_PORT_ENABLED
179578f812dSuebayasi #define	USB_PORT_STAT_C_SUSPEND		UPS_C_SUSPEND
180578f812dSuebayasi #define	USB_PORT_STAT_C_OVERCURRENT	UPS_C_OVERCURRENT_INDICATOR
181578f812dSuebayasi #define	USB_PORT_STAT_C_RESET		UPS_C_PORT_RESET
182578f812dSuebayasi #define	USB_PORT_STAT_C_L1		UPS_C_PORT_L1
183578f812dSuebayasi 
184d05ae140Smglocker #define	USB_DT_HUB			UDESC_HUB
185d05ae140Smglocker 
186d05ae140Smglocker /* See USB 2.0 spec Table 11-13, offset 3 */
187d05ae140Smglocker #define HUB_CHAR_LPSM		UHD_PWR
188d05ae140Smglocker #define HUB_CHAR_COMMON_LPSM	UHD_PWR_GANGED
189d05ae140Smglocker #define HUB_CHAR_INDV_PORT_LPSM	UHD_PWR_INDIVIDUAL
190d05ae140Smglocker #define HUB_CHAR_NO_LPSM	UHD_PWR_NO_SWITCH
191d05ae140Smglocker 
192d05ae140Smglocker #define HUB_CHAR_COMPOUND	UHD_COMPOUND
193d05ae140Smglocker 
194d05ae140Smglocker #define HUB_CHAR_OCPM		UHD_OC
195d05ae140Smglocker #define HUB_CHAR_COMMON_OCPM	UHD_OC_GLOBAL
196d05ae140Smglocker #define HUB_CHAR_INDV_PORT_OCPM	UHD_OC_INDIVIDUAL
197d05ae140Smglocker #define HUB_CHAR_NO_OCPM	UHD_OC_NONE
198d05ae140Smglocker 
199d05ae140Smglocker #define HUB_CHAR_TTTT		UHD_TT_THINK
200d05ae140Smglocker #define HUB_CHAR_PORTIND	UHD_PORT_IND
201d05ae140Smglocker 
202d05ae140Smglocker enum usb_dr_mode {
203d05ae140Smglocker 	USB_DR_MODE_UNKNOWN,
204d05ae140Smglocker 	USB_DR_MODE_HOST,
205d05ae140Smglocker 	USB_DR_MODE_PERIPHERAL,
206d05ae140Smglocker 	USB_DR_MODE_OTG,
207d05ae140Smglocker };
208d05ae140Smglocker 
209d05ae140Smglocker struct usb_phy;
210d05ae140Smglocker struct usb_hcd;
211d05ae140Smglocker 
212d05ae140Smglocker static inline int
usb_phy_set_suspend(struct usb_phy * x,int suspend)213d05ae140Smglocker usb_phy_set_suspend(struct usb_phy *x, int suspend)
214d05ae140Smglocker {
215d05ae140Smglocker 
216d05ae140Smglocker 	return 0;
217d05ae140Smglocker }
218d05ae140Smglocker 
219d05ae140Smglocker static inline void
usb_hcd_resume_root_hub(struct usb_hcd * hcd)220d05ae140Smglocker usb_hcd_resume_root_hub(struct usb_hcd *hcd)
221d05ae140Smglocker {
222d05ae140Smglocker 
223d05ae140Smglocker 	return;
224d05ae140Smglocker }
225d05ae140Smglocker 
226d05ae140Smglocker static inline int
usb_disabled(void)227d05ae140Smglocker usb_disabled(void)
228d05ae140Smglocker {
229d05ae140Smglocker 
230d05ae140Smglocker 	return 0;
231d05ae140Smglocker }
232d05ae140Smglocker 
233d05ae140Smglocker static inline void
udelay(unsigned long usecs)234578f812dSuebayasi udelay(unsigned long usecs)
235578f812dSuebayasi {
236578f812dSuebayasi 	DELAY(usecs);
237578f812dSuebayasi }
238578f812dSuebayasi 
239d05ae140Smglocker static inline void
mdelay(unsigned long msecs)240*a9beb1edSmglocker mdelay(unsigned long msecs)
241d05ae140Smglocker {
242*a9beb1edSmglocker 	int loops = msecs;
243*a9beb1edSmglocker 	while (loops--)
244*a9beb1edSmglocker 		DELAY(1000);
245d05ae140Smglocker }
246d05ae140Smglocker 
247*a9beb1edSmglocker static inline void
usleep_range(unsigned long min,unsigned long max)248*a9beb1edSmglocker usleep_range(unsigned long min, unsigned long max)
249*a9beb1edSmglocker {
250*a9beb1edSmglocker 	DELAY((min + max) / 2);
251*a9beb1edSmglocker }
252*a9beb1edSmglocker 
253*a9beb1edSmglocker #define dwc2_msleep(x)	mdelay(x)
254*a9beb1edSmglocker 
255578f812dSuebayasi #define	EREMOTEIO	EIO
256578f812dSuebayasi #define	ECOMM		EIO
257d05ae140Smglocker #define	ENOTSUPP	ENOTSUP
258578f812dSuebayasi 
2590395aa1eSuebayasi void dw_timeout(void *);
260578f812dSuebayasi 
261578f812dSuebayasi struct delayed_work {
262b6c5b329Suebayasi 	struct task work;
2630395aa1eSuebayasi 	struct timeout dw_timer;
264578f812dSuebayasi 
265b6c5b329Suebayasi 	struct taskq *dw_wq;
2669eb3c3f2Suebayasi 	void (*dw_fn)(void *);
267ea6872ecSjmatthew 	void *dw_arg;
268578f812dSuebayasi };
269578f812dSuebayasi 
270d05ae140Smglocker static inline void
INIT_DELAYED_WORK(struct delayed_work * dw,void (* fn)(void *),void * arg)271ea6872ecSjmatthew INIT_DELAYED_WORK(struct delayed_work *dw, void (*fn)(void *), void *arg)
272578f812dSuebayasi {
273ea6872ecSjmatthew 	dw->dw_fn = fn;
274ea6872ecSjmatthew 	dw->dw_arg = arg;
275016aa740Suebayasi 	timeout_set(&dw->dw_timer, dw_timeout, dw);
276578f812dSuebayasi }
277578f812dSuebayasi 
278d05ae140Smglocker static inline void
queue_delayed_work(struct taskq * wq,struct delayed_work * dw,int j)279b6c5b329Suebayasi queue_delayed_work(struct taskq *wq, struct delayed_work *dw, int j)
280578f812dSuebayasi {
281ea6872ecSjmatthew 	dw->dw_wq = wq;
282016aa740Suebayasi 	timeout_add(&dw->dw_timer, j);
283578f812dSuebayasi }
284578f812dSuebayasi 
285d05ae140Smglocker #define USB_RESUME_TIMEOUT	40 /* ms */
286d05ae140Smglocker 
287578f812dSuebayasi #endif
288