xref: /openbmc/linux/drivers/usb/dwc3/gadget.h (revision 9d778f0c)
1b33f69f5SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */
2bfad65eeSFelipe Balbi /*
372246da4SFelipe Balbi  * gadget.h - DesignWare USB3 DRD Gadget Header
472246da4SFelipe Balbi  *
510623b87SAlexander A. Klimov  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
672246da4SFelipe Balbi  *
772246da4SFelipe Balbi  * Authors: Felipe Balbi <balbi@ti.com>,
872246da4SFelipe Balbi  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
972246da4SFelipe Balbi  */
1072246da4SFelipe Balbi 
1172246da4SFelipe Balbi #ifndef __DRIVERS_USB_DWC3_GADGET_H
1272246da4SFelipe Balbi #define __DRIVERS_USB_DWC3_GADGET_H
1372246da4SFelipe Balbi 
1472246da4SFelipe Balbi #include <linux/list.h>
1572246da4SFelipe Balbi #include <linux/usb/gadget.h>
1672246da4SFelipe Balbi #include "io.h"
1772246da4SFelipe Balbi 
1872246da4SFelipe Balbi struct dwc3;
1972246da4SFelipe Balbi #define to_dwc3_ep(ep)		(container_of(ep, struct dwc3_ep, endpoint))
20e81a7018SPeter Chen #define gadget_to_dwc(g)	(dev_get_platdata(&g->dev))
2172246da4SFelipe Balbi 
22dc1c70a7SFelipe Balbi /* DEPCFG parameter 1 */
237369090aSFelipe Balbi #define DWC3_DEPCFG_INT_NUM(n)		(((n) & 0x1f) << 0)
24ff3f0789SRoger Quadros #define DWC3_DEPCFG_XFER_COMPLETE_EN	BIT(8)
25ff3f0789SRoger Quadros #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	BIT(9)
26ff3f0789SRoger Quadros #define DWC3_DEPCFG_XFER_NOT_READY_EN	BIT(10)
27ff3f0789SRoger Quadros #define DWC3_DEPCFG_FIFO_ERROR_EN	BIT(11)
289a7faac3SErich E. Hoover #define DWC3_DEPCFG_STREAM_EVENT_EN	BIT(13)
297369090aSFelipe Balbi #define DWC3_DEPCFG_BINTERVAL_M1(n)	(((n) & 0xff) << 16)
30ff3f0789SRoger Quadros #define DWC3_DEPCFG_STREAM_CAPABLE	BIT(24)
317369090aSFelipe Balbi #define DWC3_DEPCFG_EP_NUMBER(n)	(((n) & 0x1f) << 25)
32ff3f0789SRoger Quadros #define DWC3_DEPCFG_BULK_BASED		BIT(30)
33ff3f0789SRoger Quadros #define DWC3_DEPCFG_FIFO_BASED		BIT(31)
3472246da4SFelipe Balbi 
35dc1c70a7SFelipe Balbi /* DEPCFG parameter 0 */
367369090aSFelipe Balbi #define DWC3_DEPCFG_EP_TYPE(n)		(((n) & 0x3) << 1)
377369090aSFelipe Balbi #define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	(((n) & 0x7ff) << 3)
387369090aSFelipe Balbi #define DWC3_DEPCFG_FIFO_NUMBER(n)	(((n) & 0x1f) << 17)
397369090aSFelipe Balbi #define DWC3_DEPCFG_BURST_SIZE(n)	(((n) & 0xf) << 22)
40dc1c70a7SFelipe Balbi #define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
412c61a8efSPaul Zimmerman /* This applies for core versions earlier than 1.94a */
42ff3f0789SRoger Quadros #define DWC3_DEPCFG_IGN_SEQ_NUM		BIT(31)
432c61a8efSPaul Zimmerman /* These apply for core versions 1.94a and later */
442c61a8efSPaul Zimmerman #define DWC3_DEPCFG_ACTION_INIT		(0 << 30)
45ff3f0789SRoger Quadros #define DWC3_DEPCFG_ACTION_RESTORE	BIT(30)
462c61a8efSPaul Zimmerman #define DWC3_DEPCFG_ACTION_MODIFY	(2 << 30)
4772246da4SFelipe Balbi 
48dc1c70a7SFelipe Balbi /* DEPXFERCFG parameter 0 */
49dc1c70a7SFelipe Balbi #define DWC3_DEPXFERCFG_NUM_XFER_RES(n)	((n) & 0xffff)
5072246da4SFelipe Balbi 
51729dcffdSAnurag Kumar Vulisha /* U1 Device exit Latency */
52729dcffdSAnurag Kumar Vulisha #define DWC3_DEFAULT_U1_DEV_EXIT_LAT	0x0A	/* Less then 10 microsec */
53729dcffdSAnurag Kumar Vulisha 
54729dcffdSAnurag Kumar Vulisha /* U2 Device exit Latency */
55729dcffdSAnurag Kumar Vulisha #define DWC3_DEFAULT_U2_DEV_EXIT_LAT	0x1FF	/* Less then 511 microsec */
56729dcffdSAnurag Kumar Vulisha 
57ca143785SMichael Grzeschik /* Frame/Microframe Number Mask */
58ca143785SMichael Grzeschik #define DWC3_FRNUMBER_MASK		0x3fff
5972246da4SFelipe Balbi /* -------------------------------------------------------------------------- */
6072246da4SFelipe Balbi 
6172246da4SFelipe Balbi #define to_dwc3_request(r)	(container_of(r, struct dwc3_request, request))
6272246da4SFelipe Balbi 
63bfad65eeSFelipe Balbi /**
64bfad65eeSFelipe Balbi  * next_request - gets the next request on the given list
65bfad65eeSFelipe Balbi  * @list: the request list to operate on
66bfad65eeSFelipe Balbi  *
67bfad65eeSFelipe Balbi  * Caller should take care of locking. This function return %NULL or the first
68bfad65eeSFelipe Balbi  * request available on @list.
69bfad65eeSFelipe Balbi  */
next_request(struct list_head * list)7072246da4SFelipe Balbi static inline struct dwc3_request *next_request(struct list_head *list)
7172246da4SFelipe Balbi {
72785c91f8SMasahiro Yamada 	return list_first_entry_or_null(list, struct dwc3_request, list);
7372246da4SFelipe Balbi }
7472246da4SFelipe Balbi 
75bfad65eeSFelipe Balbi /**
76bfad65eeSFelipe Balbi  * dwc3_gadget_move_started_request - move @req to the started_list
77bfad65eeSFelipe Balbi  * @req: the request to be moved
78bfad65eeSFelipe Balbi  *
79bfad65eeSFelipe Balbi  * Caller should take care of locking. This function will move @req from its
80bfad65eeSFelipe Balbi  * current list to the endpoint's started_list.
81bfad65eeSFelipe Balbi  */
dwc3_gadget_move_started_request(struct dwc3_request * req)82aa3342c8SFelipe Balbi static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
8372246da4SFelipe Balbi {
8472246da4SFelipe Balbi 	struct dwc3_ep		*dep = req->dep;
8572246da4SFelipe Balbi 
86a3af5e3aSFelipe Balbi 	req->status = DWC3_REQUEST_STATUS_STARTED;
87aa3342c8SFelipe Balbi 	list_move_tail(&req->list, &dep->started_list);
8872246da4SFelipe Balbi }
8972246da4SFelipe Balbi 
90d5443bbfSFelipe Balbi /**
91d5443bbfSFelipe Balbi  * dwc3_gadget_move_cancelled_request - move @req to the cancelled_list
92d5443bbfSFelipe Balbi  * @req: the request to be moved
9304dd6e76SRay Chi  * @reason: cancelled reason for the dwc3 request
94d5443bbfSFelipe Balbi  *
95d5443bbfSFelipe Balbi  * Caller should take care of locking. This function will move @req from its
96d5443bbfSFelipe Balbi  * current list to the endpoint's cancelled_list.
97d5443bbfSFelipe Balbi  */
dwc3_gadget_move_cancelled_request(struct dwc3_request * req,unsigned int reason)9804dd6e76SRay Chi static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req,
9904dd6e76SRay Chi 		unsigned int reason)
100d5443bbfSFelipe Balbi {
101d5443bbfSFelipe Balbi 	struct dwc3_ep		*dep = req->dep;
102d5443bbfSFelipe Balbi 
10304dd6e76SRay Chi 	req->status = reason;
104d5443bbfSFelipe Balbi 	list_move_tail(&req->list, &dep->cancelled_list);
105d5443bbfSFelipe Balbi }
106d5443bbfSFelipe Balbi 
10772246da4SFelipe Balbi void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
10872246da4SFelipe Balbi 		int status);
10972246da4SFelipe Balbi 
11025b8ff68SFelipe Balbi void dwc3_ep0_interrupt(struct dwc3 *dwc,
11125b8ff68SFelipe Balbi 		const struct dwc3_event_depevt *event);
11272246da4SFelipe Balbi void dwc3_ep0_out_start(struct dwc3 *dwc);
113*9d778f0cSMayank Rana void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep);
114*9d778f0cSMayank Rana void dwc3_ep0_stall_and_restart(struct dwc3 *dwc);
11533fb691bSFelipe Balbi int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
11608f0d966SPratyush Anand int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
11772246da4SFelipe Balbi int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
11872246da4SFelipe Balbi 		gfp_t gfp_flags);
1197a608559SFelipe Balbi int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol);
120d97c78a1SThinh Nguyen void dwc3_ep0_send_delayed_status(struct dwc3 *dwc);
121e4cf6580SThinh Nguyen void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt);
12272246da4SFelipe Balbi 
12372246da4SFelipe Balbi /**
12472246da4SFelipe Balbi  * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
125bfad65eeSFelipe Balbi  * @dep: dwc3 endpoint
12672246da4SFelipe Balbi  *
127bfad65eeSFelipe Balbi  * Caller should take care of locking. Returns the transfer resource
128bfad65eeSFelipe Balbi  * index for a given endpoint.
12972246da4SFelipe Balbi  */
dwc3_gadget_ep_get_transfer_index(struct dwc3_ep * dep)1304439661dSFelipe Balbi static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
13172246da4SFelipe Balbi {
13272246da4SFelipe Balbi 	u32			res_id;
13372246da4SFelipe Balbi 
1342eb88016SFelipe Balbi 	res_id = dwc3_readl(dep->regs, DWC3_DEPCMD);
1354439661dSFelipe Balbi 	dep->resource_index = DWC3_DEPCMD_GET_RSC_IDX(res_id);
13672246da4SFelipe Balbi }
13772246da4SFelipe Balbi 
1385b738211SThinh Nguyen /**
1395b738211SThinh Nguyen  * dwc3_gadget_dctl_write_safe - write to DCTL safe from link state change
1405b738211SThinh Nguyen  * @dwc: pointer to our context structure
1415b738211SThinh Nguyen  * @value: value to write to DCTL
1425b738211SThinh Nguyen  *
1435b738211SThinh Nguyen  * Use this function when doing read-modify-write to DCTL. It will not
1445b738211SThinh Nguyen  * send link state change request.
1455b738211SThinh Nguyen  */
dwc3_gadget_dctl_write_safe(struct dwc3 * dwc,u32 value)1465b738211SThinh Nguyen static inline void dwc3_gadget_dctl_write_safe(struct dwc3 *dwc, u32 value)
1475b738211SThinh Nguyen {
1485b738211SThinh Nguyen 	value &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
1495b738211SThinh Nguyen 	dwc3_writel(dwc->regs, DWC3_DCTL, value);
1505b738211SThinh Nguyen }
1515b738211SThinh Nguyen 
15272246da4SFelipe Balbi #endif /* __DRIVERS_USB_DWC3_GADGET_H */
153