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);
1139d778f0cSMayank Rana void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep);
1149d778f0cSMayank 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);
122*65b1f311SThinh Nguyen int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index);
12372246da4SFelipe Balbi
12472246da4SFelipe Balbi /**
12572246da4SFelipe Balbi * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
126bfad65eeSFelipe Balbi * @dep: dwc3 endpoint
12772246da4SFelipe Balbi *
128bfad65eeSFelipe Balbi * Caller should take care of locking. Returns the transfer resource
129bfad65eeSFelipe Balbi * index for a given endpoint.
13072246da4SFelipe Balbi */
dwc3_gadget_ep_get_transfer_index(struct dwc3_ep * dep)1314439661dSFelipe Balbi static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
13272246da4SFelipe Balbi {
13372246da4SFelipe Balbi u32 res_id;
13472246da4SFelipe Balbi
1352eb88016SFelipe Balbi res_id = dwc3_readl(dep->regs, DWC3_DEPCMD);
1364439661dSFelipe Balbi dep->resource_index = DWC3_DEPCMD_GET_RSC_IDX(res_id);
13772246da4SFelipe Balbi }
13872246da4SFelipe Balbi
1395b738211SThinh Nguyen /**
1405b738211SThinh Nguyen * dwc3_gadget_dctl_write_safe - write to DCTL safe from link state change
1415b738211SThinh Nguyen * @dwc: pointer to our context structure
1425b738211SThinh Nguyen * @value: value to write to DCTL
1435b738211SThinh Nguyen *
1445b738211SThinh Nguyen * Use this function when doing read-modify-write to DCTL. It will not
1455b738211SThinh Nguyen * send link state change request.
1465b738211SThinh Nguyen */
dwc3_gadget_dctl_write_safe(struct dwc3 * dwc,u32 value)1475b738211SThinh Nguyen static inline void dwc3_gadget_dctl_write_safe(struct dwc3 *dwc, u32 value)
1485b738211SThinh Nguyen {
1495b738211SThinh Nguyen value &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
1505b738211SThinh Nguyen dwc3_writel(dwc->regs, DWC3_DCTL, value);
1515b738211SThinh Nguyen }
1525b738211SThinh Nguyen
15372246da4SFelipe Balbi #endif /* __DRIVERS_USB_DWC3_GADGET_H */
154