Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c99f669 authored by Mayank Rana's avatar Mayank Rana Committed by Hemant Kumar
Browse files

dwc3: resize txfifo of IN/INT endpoint before enabling it



USB IN/INT endpoint stalls when performing TX FIFO resize functionality
when IN/INT endpoint is already active i.e. usb endpoint is enabled and
usb request is pending with it. Fix this issue by making sure that TX
FIFO resize is performed before enabling endpoint which shall happen
after set_alt(1) and before any function queues request with its
allocated USB endpoint.

Change-Id: I13a590f87ab8492f7c95a15b2da9f00c9c63c4f9
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
[jackp@codeaurora.org: squashed with the following:
Revert "usb: dwc3: drop FIFO resizing logic"
dwc3: gadget: Improve TX FIFO resize functionality
dwc3: gadget: Use default TX FIFO size as 1024 bytes with each IN eps
usb: gadget: Use mult as 3 for GSI related USB IN endpoint always
USB: dwc3: gadget: Fix TxFIFO resizing logic
dwc3: Preserve TxFIFO of IN/INT EP for UDC without tx-fifo-resize
- modified resize loop to iterate over num_eps instead of num_in_eps ]
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 02957965
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ Optional properties:
 - phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy"
	or "usb3-phy".
 - resets: a single pair of phandle and reset specifier
 - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
 - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
 - snps,disable_scramble_quirk: true when SW should disable data scrambling.
	Only really useful for FPGA builds.
@@ -100,8 +101,6 @@ Optional properties:
 - snps,bus-suspend-enable: If present then controller supports low power mode
	during bus suspend.

 - <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.

 - in addition all properties from usb-xhci.txt from the current directory are
   supported as well

@@ -113,5 +112,6 @@ dwc3@4a030000 {
	reg = <0x4a030000 0xcfff>;
	interrupts = <0 92 4>
	usb-phy = <&usb2_phy>, <&usb3,phy>;
	tx-fifo-resize;
	snps,xhci-imod-value = <4000>;
};
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ Example device nodes:
				interrupts = <0 205 0x4>;
				phys = <&hs_phy>, <&ss_phy>;
				phy-names = "usb2-phy", "usb3-phy";
				tx-fifo-resize;
				dr_mode = "host";
			};
		};
+3 −0
Original line number Diff line number Diff line
@@ -1177,6 +1177,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
	device_property_read_u8(dev, "snps,tx-max-burst-prd",
				&tx_max_burst_prd);

	dwc->needs_fifo_resize = device_property_read_bool(dev,
				"tx-fifo-resize");

	dwc->disable_scramble_quirk = device_property_read_bool(dev,
				"snps,disable_scramble_quirk");
	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
+12 −0
Original line number Diff line number Diff line
@@ -697,6 +697,7 @@ struct dwc3_ep_events {
 * @dbg_ep_events: different events counter for endpoint
 * @dbg_ep_events_diff: differential events counter for endpoint
 * @dbg_ep_events_ts: timestamp for previous event counters
 * @fifo_depth: allocated TXFIFO depth
 */
struct dwc3_ep {
	struct usb_ep		endpoint;
@@ -751,6 +752,7 @@ struct dwc3_ep {
	struct dwc3_ep_events	dbg_ep_events;
	struct dwc3_ep_events	dbg_ep_events_diff;
	struct timespec		dbg_ep_events_ts;
	int			fifo_depth;
};

enum dwc3_phy {
@@ -1033,6 +1035,7 @@ struct dwc3_scratchpad_array {
 * 	1	- utmi_l1_suspend_n
 * @is_fpga: true when we are using the FPGA board
 * @pending_events: true when we have pending IRQs to be handled
 * @needs_fifo_resize: not all users might want fifo resizing, flag it
 * @pullups_connected: true when Run/Stop bit is set
 * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
 * @three_stage_setup: set if we perform a three phase setup
@@ -1079,6 +1082,8 @@ struct dwc3_scratchpad_array {
 * @core_id: usb core id to differentiate different controller
 * @index: dwc3's instance number
 * @dwc_ipc_log_ctxt: dwc3 ipc log context
 * @tx_fifo_size: Available RAM size for TX fifo allocation
 * @last_fifo_depth: total TXFIFO depth of all enabled USB IN/INT endpoints
 * @irq_cnt: total irq count
 * @bh_completion_time: time taken for taklet completion
 * @bh_handled_evt_cnt: no. of events handled by tasklet per interrupt
@@ -1229,6 +1234,7 @@ struct dwc3 {
	unsigned		is_utmi_l1_suspend:1;
	unsigned		is_fpga:1;
	unsigned		pending_events:1;
	unsigned		needs_fifo_resize:1;
	unsigned		pullups_connected:1;
	unsigned		setup_packet_pending:1;
	unsigned		three_stage_setup:1;
@@ -1275,6 +1281,8 @@ struct dwc3 {
	unsigned int		index;
	void			*dwc_ipc_log_ctxt;
	struct dwc3_gadget_events	dbg_gadget_events;
	int			tx_fifo_size;
	int			last_fifo_depth;

	/* IRQ timing statistics */
	int			irq;
@@ -1488,6 +1496,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
		struct dwc3_gadget_ep_cmd_params *params);
int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc, struct dwc3_ep *dep);
void dwc3_gadget_disable_irq(struct dwc3 *dwc);
int dwc3_core_init(struct dwc3 *dwc);
int dwc3_event_buffers_setup(struct dwc3 *dwc);
@@ -1512,6 +1521,9 @@ static inline int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
		int cmd, u32 param)
{ return 0; }
static inline int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc,
		struct dwc3_ep *dep)
{ return 0; }
static inline void dwc3_gadget_disable_irq(struct dwc3 *dwc)
{ }
static int dwc3_core_init(struct dwc3 *dwc)
+27 −1
Original line number Diff line number Diff line
@@ -619,8 +619,9 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
{
	enum usb_device_state state = dwc->gadget.state;
	u32 cfg;
	int ret;
	int ret, num;
	u32 reg;
	struct dwc3_ep	*dep;

	cfg = le16_to_cpu(ctrl->wValue);

@@ -629,6 +630,31 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
		return -EINVAL;

	case USB_STATE_ADDRESS:
		/*
		 * If tx-fifo-resize flag is not set for the controller, then
		 * do not clear existing allocated TXFIFO since we do not
		 * allocate it again in dwc3_gadget_resize_tx_fifos
		 */
		if (dwc->needs_fifo_resize && dwc->tx_fifo_size) {
			/* Read ep0IN related TXFIFO size */
			dep = dwc->eps[1];
			dwc->last_fifo_depth = dep->fifo_depth =
					(dwc3_readl(dwc->regs,
					    DWC3_GTXFIFOSIZ(0)) & 0xFFFF);
			/* Clear existing TXFIFO for all IN eps except ep0 */
			for (num = 3; num < min_t(int, dwc->num_eps,
						DWC3_ENDPOINTS_NUM); num += 2) {
				dep = dwc->eps[num];
				dwc3_writel(dwc->regs,
						DWC3_GTXFIFOSIZ(num >> 1), 0);
				dep->fifo_depth = 0;

				dev_dbg(dwc->dev, "%s(): %s fifo_depth:%x\n",
					__func__, dep->name, dep->fifo_depth);
				dbg_event(0xFF, "fifo_reset", dep->number);
			}
		}

		ret = dwc3_ep0_delegate_req(dwc, ctrl);
		/* if the cfg matches and the cfg is non zero */
		if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) {
Loading