// SPDX-License-Identifier: GPL-2.0 /* * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link * * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi <[email protected]>, * Sebastian Andrzej Siewior <[email protected]> */ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/list.h> #include <linux/dma-mapping.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include "debug.h" #include "core.h" #include "gadget.h" #include "io.h" #define DWC3_ALIGN_FRAME(d, n) … /** * dwc3_gadget_set_test_mode - enables usb2 test modes * @dwc: pointer to our context structure * @mode: the mode to set (J, K SE0 NAK, Force Enable) * * Caller should take care of locking. This function will return 0 on * success or -EINVAL if wrong Test Selector is passed. */ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) { … } /** * dwc3_gadget_get_link_state - gets current state of usb link * @dwc: pointer to our context structure * * Caller should take care of locking. This function will * return the link state on success (>= 0) or -ETIMEDOUT. */ int dwc3_gadget_get_link_state(struct dwc3 *dwc) { … } /** * dwc3_gadget_set_link_state - sets usb link to a particular state * @dwc: pointer to our context structure * @state: the state to put link into * * Caller should take care of locking. This function will * return 0 on success or -ETIMEDOUT. */ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) { … } static void dwc3_ep0_reset_state(struct dwc3 *dwc) { … } /** * dwc3_ep_inc_trb - increment a trb index. * @index: Pointer to the TRB index to increment. * * The index should never point to the link TRB. After incrementing, * if it is point to the link TRB, wrap around to the beginning. The * link TRB is always at the last TRB entry. */ static void dwc3_ep_inc_trb(u8 *index) { … } /** * dwc3_ep_inc_enq - increment endpoint's enqueue pointer * @dep: The endpoint whose enqueue pointer we're incrementing */ static void dwc3_ep_inc_enq(struct dwc3_ep *dep) { … } /** * dwc3_ep_inc_deq - increment endpoint's dequeue pointer * @dep: The endpoint whose enqueue pointer we're incrementing */ static void dwc3_ep_inc_deq(struct dwc3_ep *dep) { … } static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, struct dwc3_request *req, int status) { … } /** * dwc3_gadget_giveback - call struct usb_request's ->complete callback * @dep: The endpoint to whom the request belongs to * @req: The request we're giving back * @status: completion code for the request * * Must be called with controller's lock held and interrupts disabled. This * function will unmap @req and call its ->complete() callback to notify upper * layers that it has completed. */ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status) { … } /** * dwc3_send_gadget_generic_command - issue a generic command for the controller * @dwc: pointer to the controller context * @cmd: the command to be issued * @param: command parameter * * Caller should take care of locking. Issue @cmd with a given @param to @dwc * and wait for its completion. */ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd, u32 param) { … } static int __dwc3_gadget_wakeup(struct dwc3 *dwc, bool async); /** * dwc3_send_gadget_ep_cmd - issue an endpoint command * @dep: the endpoint to which the command is going to be issued * @cmd: the command to be issued * @params: parameters to the command * * Caller should handle locking. This function will issue @cmd with given * @params to @dep and wait for its completion. * * According to the programming guide, if the link state is in L1/L2/U3, * then sending the Start Transfer command may not complete. The * programming guide suggested to bring the link state back to ON/U0 by * performing remote wakeup prior to sending the command. However, don't * initiate remote wakeup when the user/function does not send wakeup * request via wakeup ops. Send the command when it's allowed. * * Notes: * For L1 link state, issuing a command requires the clearing of * GUSB2PHYCFG.SUSPENDUSB2, which turns on the signal required to complete * the given command (usually within 50us). This should happen within the * command timeout set by driver. No additional step is needed. * * For L2 or U3 link state, the gadget is in USB suspend. Care should be * taken when sending Start Transfer command to ensure that it's done after * USB resume. */ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, struct dwc3_gadget_ep_cmd_params *params) { … } static int dwc3_send_clear_stall_ep_cmd(struct dwc3_ep *dep) { … } static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep, struct dwc3_trb *trb) { … } static int dwc3_alloc_trb_pool(struct dwc3_ep *dep) { … } static void dwc3_free_trb_pool(struct dwc3_ep *dep) { … } static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep) { … } /** * dwc3_gadget_start_config - reset endpoint resources * @dwc: pointer to the DWC3 context * @resource_index: DEPSTARTCFG.XferRscIdx value (must be 0 or 2) * * Set resource_index=0 to reset all endpoints' resources allocation. Do this as * part of the power-on/soft-reset initialization. * * Set resource_index=2 to reset only non-control endpoints' resources. Do this * on receiving the SET_CONFIGURATION request or hibernation resume. */ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index) { … } static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action) { … } /** * dwc3_gadget_calc_tx_fifo_size - calculates the txfifo size value * @dwc: pointer to the DWC3 context * @mult: multiplier to be used when calculating the fifo_size * * Calculates the size value based on the equation below: * * DWC3 revision 280A and prior: * fifo_size = mult * (max_packet / mdwidth) + 1; * * DWC3 revision 290A and onwards: * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 * * The max packet size is set to 1024, as the txfifo requirements mainly apply * to super speed USB use cases. However, it is safe to overestimate the fifo * allocations for other scenarios, i.e. high speed USB. */ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult) { … } /** * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation * @dwc: pointer to the DWC3 context * * Iterates through all the endpoint registers and clears the previous txfifo * allocations. */ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) { … } /* * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case * @dwc: pointer to our context structure * * This function will a best effort FIFO allocation in order * to improve FIFO usage and throughput, while still allowing * us to enable as many endpoints as possible. * * Keep in mind that this operation will be highly dependent * on the configured size for RAM1 - which contains TxFifo -, * the amount of endpoints enabled on coreConsultant tool, and * the width of the Master Bus. * * In general, FIFO depths are represented with the following equation: * * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 * * In conjunction with dwc3_gadget_check_config(), this resizing logic will * ensure that all endpoints will have enough internal memory for one max * packet per endpoint. */ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) { … } /** * __dwc3_gadget_ep_enable - initializes a hw endpoint * @dep: endpoint to be initialized * @action: one of INIT, MODIFY or RESTORE * * Caller should take care of locking. Execute all necessary commands to * initialize a HW endpoint so it can be used by a gadget driver. */ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) { … } void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status) { … } /** * __dwc3_gadget_ep_disable - disables a hw endpoint * @dep: the endpoint to disable * * This function undoes what __dwc3_gadget_ep_enable did and also removes * requests which are currently being processed by the hardware and those which * are not yet scheduled. * * Caller should take care of locking. */ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) { … } /* -------------------------------------------------------------------------- */ static int dwc3_gadget_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { … } static int dwc3_gadget_ep0_disable(struct usb_ep *ep) { … } /* -------------------------------------------------------------------------- */ static int dwc3_gadget_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { … } static int dwc3_gadget_ep_disable(struct usb_ep *ep) { … } static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { … } static void dwc3_gadget_ep_free_request(struct usb_ep *ep, struct usb_request *request) { … } /** * dwc3_ep_prev_trb - returns the previous TRB in the ring * @dep: The endpoint with the TRB ring * @index: The index of the current TRB in the ring * * Returns the TRB prior to the one pointed to by the index. If the * index is 0, we will wrap backwards, skip the link TRB, and return * the one just before that. */ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) { … } static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) { … } /** * dwc3_prepare_one_trb - setup one TRB from one request * @dep: endpoint for which this request is prepared * @req: dwc3_request pointer * @trb_length: buffer size of the TRB * @chain: should this TRB be chained to the next? * @node: only for isochronous endpoints. First TRB needs different type. * @use_bounce_buffer: set to use bounce buffer * @must_interrupt: set to interrupt on TRB completion */ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int trb_length, unsigned int chain, unsigned int node, bool use_bounce_buffer, bool must_interrupt) { … } static bool dwc3_needs_extra_trb(struct dwc3_ep *dep, struct dwc3_request *req) { … } /** * dwc3_prepare_last_sg - prepare TRBs for the last SG entry * @dep: The endpoint that the request belongs to * @req: The request to prepare * @entry_length: The last SG entry size * @node: Indicates whether this is not the first entry (for isoc only) * * Return the number of TRBs prepared. */ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int entry_length, unsigned int node) { … } static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, struct dwc3_request *req) { … } static int dwc3_prepare_trbs_linear(struct dwc3_ep *dep, struct dwc3_request *req) { … } /* * dwc3_prepare_trbs - setup TRBs from requests * @dep: endpoint for which requests are being prepared * * The function goes through the requests list and sets up TRBs for the * transfers. The function returns once there are no more TRBs available or * it runs out of requests. * * Returns the number of TRBs prepared or negative errno. */ static int dwc3_prepare_trbs(struct dwc3_ep *dep) { … } static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) { … } static int __dwc3_gadget_get_frame(struct dwc3 *dwc) { … } /** * __dwc3_stop_active_transfer - stop the current active transfer * @dep: isoc endpoint * @force: set forcerm bit in the command * @interrupt: command complete interrupt after End Transfer command * * When setting force, the ForceRM bit will be set. In that case * the controller won't update the TRB progress on command * completion. It also won't clear the HWO bit in the TRB. * The command will also not complete immediately in that case. */ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { … } /** * dwc3_gadget_start_isoc_quirk - workaround invalid frame number * @dep: isoc endpoint * * This function tests for the correct combination of BIT[15:14] from the 16-bit * microframe number reported by the XferNotReady event for the future frame * number to start the isoc transfer. * * In DWC_usb31 version 1.70a-ea06 and prior, for highspeed and fullspeed * isochronous IN, BIT[15:14] of the 16-bit microframe number reported by the * XferNotReady event are invalid. The driver uses this number to schedule the * isochronous transfer and passes it to the START TRANSFER command. Because * this number is invalid, the command may fail. If BIT[15:14] matches the * internal 16-bit microframe, the START TRANSFER command will pass and the * transfer will start at the scheduled time, if it is off by 1, the command * will still pass, but the transfer will start 2 seconds in the future. For all * other conditions, the START TRANSFER command will fail with bus-expiry. * * In order to workaround this issue, we can test for the correct combination of * BIT[15:14] by sending START TRANSFER commands with different values of * BIT[15:14]: 'b00, 'b01, 'b10, and 'b11. Each combination is 2^14 uframe apart * (or 2 seconds). 4 seconds into the future will result in a bus-expiry status. * As the result, within the 4 possible combinations for BIT[15:14], there will * be 2 successful and 2 failure START COMMAND status. One of the 2 successful * command status will result in a 2-second delay start. The smaller BIT[15:14] * value is the correct combination. * * Since there are only 4 outcomes and the results are ordered, we can simply * test 2 START TRANSFER commands with BIT[15:14] combinations 'b00 and 'b01 to * deduce the smaller successful combination. * * Let test0 = test status for combination 'b00 and test1 = test status for 'b01 * of BIT[15:14]. The correct combination is as follow: * * if test0 fails and test1 passes, BIT[15:14] is 'b01 * if test0 fails and test1 fails, BIT[15:14] is 'b10 * if test0 passes and test1 fails, BIT[15:14] is 'b11 * if test0 passes and test1 passes, BIT[15:14] is 'b00 * * Synopsys STAR 9001202023: Wrong microframe number for isochronous IN * endpoints. */ static int dwc3_gadget_start_isoc_quirk(struct dwc3_ep *dep) { … } static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) { … } static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) { … } static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags) { … } static void dwc3_gadget_ep_skip_trbs(struct dwc3_ep *dep, struct dwc3_request *req) { … } static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep) { … } static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request) { … } int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) { … } static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) { … } static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) { … } /* -------------------------------------------------------------------------- */ static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = …; static const struct usb_ep_ops dwc3_gadget_ep0_ops = …; static const struct usb_ep_ops dwc3_gadget_ep_ops = …; /* -------------------------------------------------------------------------- */ static void dwc3_gadget_enable_linksts_evts(struct dwc3 *dwc, bool set) { … } static int dwc3_gadget_get_frame(struct usb_gadget *g) { … } static int __dwc3_gadget_wakeup(struct dwc3 *dwc, bool async) { … } static int dwc3_gadget_wakeup(struct usb_gadget *g) { … } static void dwc3_resume_gadget(struct dwc3 *dwc); static int dwc3_gadget_func_wakeup(struct usb_gadget *g, int intf_id) { … } static int dwc3_gadget_set_remote_wakeup(struct usb_gadget *g, int set) { … } static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, int is_selfpowered) { … } static void dwc3_stop_active_transfers(struct dwc3 *dwc) { … } static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc) { … } static void __dwc3_gadget_set_speed(struct dwc3 *dwc) { … } static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) { … } static void dwc3_gadget_disable_irq(struct dwc3 *dwc); static void __dwc3_gadget_stop(struct dwc3 *dwc); static int __dwc3_gadget_start(struct dwc3 *dwc); static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) { … } static int dwc3_gadget_soft_connect(struct dwc3 *dwc) { … } static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) { … } static void dwc3_gadget_enable_irq(struct dwc3 *dwc) { … } static void dwc3_gadget_disable_irq(struct dwc3 *dwc) { … } static irqreturn_t dwc3_interrupt(int irq, void *_dwc); static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc); /** * dwc3_gadget_setup_nump - calculate and initialize NUMP field of %DWC3_DCFG * @dwc: pointer to our context structure * * The following looks like complex but it's actually very simple. In order to * calculate the number of packets we can burst at once on OUT transfers, we're * gonna use RxFIFO size. * * To calculate RxFIFO size we need two numbers: * MDWIDTH = size, in bits, of the internal memory bus * RAM2_DEPTH = depth, in MDWIDTH, of internal RAM2 (where RxFIFO sits) * * Given these two numbers, the formula is simple: * * RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16; * * 24 bytes is for 3x SETUP packets * 16 bytes is a clock domain crossing tolerance * * Given RxFIFO Size, NUMP = RxFIFOSize / 1024; */ static void dwc3_gadget_setup_nump(struct dwc3 *dwc) { … } static int __dwc3_gadget_start(struct dwc3 *dwc) { … } static int dwc3_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { … } static void __dwc3_gadget_stop(struct dwc3 *dwc) { … } static int dwc3_gadget_stop(struct usb_gadget *g) { … } static void dwc3_gadget_config_params(struct usb_gadget *g, struct usb_dcd_config_params *params) { … } static void dwc3_gadget_set_speed(struct usb_gadget *g, enum usb_device_speed speed) { … } static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g, enum usb_ssp_rate rate) { … } static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) { … } /** * dwc3_gadget_check_config - ensure dwc3 can support the USB configuration * @g: pointer to the USB gadget * * Used to record the maximum number of endpoints being used in a USB composite * device. (across all configurations) This is to be used in the calculation * of the TXFIFO sizes when resizing internal memory for individual endpoints. * It will help ensured that the resizing logic reserves enough space for at * least one max packet. */ static int dwc3_gadget_check_config(struct usb_gadget *g) { … } static void dwc3_gadget_async_callbacks(struct usb_gadget *g, bool enable) { … } static const struct usb_gadget_ops dwc3_gadget_ops = …; /* -------------------------------------------------------------------------- */ static int dwc3_gadget_init_control_endpoint(struct dwc3_ep *dep) { … } static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) { … } static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) { … } static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum) { … } static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total) { … } static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) { … } /* -------------------------------------------------------------------------- */ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, struct dwc3_request *req, struct dwc3_trb *trb, const struct dwc3_event_depevt *event, int status, int chain) { … } static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep, struct dwc3_request *req, const struct dwc3_event_depevt *event, int status) { … } static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, struct dwc3_request *req, const struct dwc3_event_depevt *event, int status) { … } static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) { … } static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, const struct dwc3_event_depevt *event, struct dwc3_request *req, int status) { … } static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep, const struct dwc3_event_depevt *event, int status) { … } static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep) { … } static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, const struct dwc3_event_depevt *event, int status) { … } static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { … } static void dwc3_endpoint_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { … } static void dwc3_disconnect_gadget(struct dwc3 *dwc) { … } static void dwc3_suspend_gadget(struct dwc3 *dwc) { … } static void dwc3_resume_gadget(struct dwc3 *dwc) { … } static void dwc3_reset_gadget(struct dwc3 *dwc) { … } void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { … } static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) { … } static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) { … } static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) { … } static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) { … } static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { … } static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { … } static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { … } static void dwc3_gadget_interrupt(struct dwc3 *dwc, const struct dwc3_event_devt *event) { … } static void dwc3_process_event_entry(struct dwc3 *dwc, const union dwc3_event *event) { … } static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt) { … } static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt) { … } static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) { … } static irqreturn_t dwc3_interrupt(int irq, void *_evt) { … } static int dwc3_gadget_get_irq(struct dwc3 *dwc) { … } static void dwc_gadget_release(struct device *dev) { … } /** * dwc3_gadget_init - initializes gadget related registers * @dwc: pointer to our controller context structure * * Returns 0 on success otherwise negative errno. */ int dwc3_gadget_init(struct dwc3 *dwc) { … } /* -------------------------------------------------------------------------- */ void dwc3_gadget_exit(struct dwc3 *dwc) { … } int dwc3_gadget_suspend(struct dwc3 *dwc) { … } int dwc3_gadget_resume(struct dwc3 *dwc) { … }