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

Commit 47636fc5 authored by Mayank Rana's avatar Mayank Rana Committed by Jack Pham
Browse files

usb: dwc3: Fix USB gadget initialization sequence



This change fixes below issues:
1. registering UDC driver with udc core with dwc3 probe itself, so USB
composition script can find UDC device while trying to select UDC.
2. creation of required USB endpoints related debugfs entries useful for
debugging.
3. USB high speed only functionality fallback mechanism when USB super
speed phy is not initialized.

Change-Id: I893e6221ceb6af448695f5399e857be0c25f41b1
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 7972f5f9
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -950,6 +950,7 @@ int dwc3_core_init(struct dwc3 *dwc)
	}

	dwc3_cache_hwparams(dwc);
	dwc3_check_params(dwc);
	ret = dwc3_get_dr_mode(dwc);
	if (ret) {
		ret = -EINVAL;
@@ -1102,7 +1103,7 @@ int dwc3_core_init(struct dwc3 *dwc)
		dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
	}

	dwc3_check_params(dwc);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0);

	return 0;

@@ -1625,9 +1626,14 @@ static int dwc3_probe(struct platform_device *pdev)
			dwc3_event_buffers_cleanup(dwc);
			goto err3;
		}
	} else if (dwc->dr_mode == USB_DR_MODE_OTG ||
		dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
		ret = dwc3_gadget_init(dwc);
		if (ret) {
			dev_err(dwc->dev, "gadget init failed %d\n", ret);
			goto err3;
		}
	}

	dwc3_debugfs_init(dwc);

	dwc->dwc_ipc_log_ctxt = ipc_log_context_create(NUM_LOG_PAGES,
					dev_name(dwc->dev), 0);
@@ -1639,6 +1645,7 @@ static int dwc3_probe(struct platform_device *pdev)
	count++;

	pm_runtime_allow(dev);
	dwc3_debugfs_init(dwc);
	return 0;

err3:
@@ -1662,7 +1669,7 @@ static int dwc3_remove(struct platform_device *pdev)
	struct dwc3	*dwc = platform_get_drvdata(pdev);

	dwc3_debugfs_exit(dwc);

	dwc3_gadget_exit(dwc);
	pm_runtime_allow(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

+16 −54
Original line number Diff line number Diff line
@@ -1949,7 +1949,7 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)

static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
{
	u32			reg;
	u32			reg, reg1;
	u32			timeout = 1500;

	dbg_event(0xFF, "run_stop", is_on);
@@ -1966,6 +1966,17 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
		dwc3_event_buffers_setup(dwc);
		__dwc3_gadget_start(dwc);

		reg1 = dwc3_readl(dwc->regs, DWC3_DCFG);
		reg1 &= ~(DWC3_DCFG_SPEED_MASK);

		if (dwc->maximum_speed == USB_SPEED_SUPER_PLUS)
			reg1 |= DWC3_DCFG_SUPERSPEED_PLUS;
		else if (dwc->maximum_speed == USB_SPEED_HIGH)
			reg1 |= DWC3_DCFG_HIGHSPEED;
		else
			reg1 |= DWC3_DCFG_SUPERSPEED;
		dwc3_writel(dwc->regs, DWC3_DCFG, reg1);

		reg |= DWC3_DCTL_RUN_STOP;

		if (dwc->has_hibernation)
@@ -2385,7 +2396,7 @@ static void dwc3_gadget_config_params(struct usb_gadget *g,
				cpu_to_le16(DWC3_DEFAULT_U2_DEV_EXIT_LAT);
}

static void dwc3_gadget_set_speed(struct usb_gadget *g,
static void __maybe_unused dwc3_gadget_set_speed(struct usb_gadget *g,
				  enum usb_device_speed speed)
{
	struct dwc3		*dwc = gadget_to_dwc(g);
@@ -2455,7 +2466,6 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
	.pullup			= dwc3_gadget_pullup,
	.udc_start		= dwc3_gadget_start,
	.udc_stop		= dwc3_gadget_stop,
	.udc_set_speed		= dwc3_gadget_set_speed,
	.get_config_params	= dwc3_gadget_config_params,
};

@@ -2480,52 +2490,7 @@ static int dwc3_gadget_init_control_endpoint(struct dwc3_ep *dep)
	return 0;
}

static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
{
	struct dwc3 *dwc = dep->dwc;
	int mdwidth;
	int kbytes;
	int size;

	mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
	/* MDWIDTH is represented in bits, we need it in bytes */
	mdwidth /= 8;

	size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
	if (dwc3_is_usb31(dwc))
		size = DWC31_GTXFIFOSIZ_TXFDEF(size);
	else
		size = DWC3_GTXFIFOSIZ_TXFDEF(size);

	/* FIFO Depth is in MDWDITH bytes. Multiply */
	size *= mdwidth;

	kbytes = size / 1024;
	if (kbytes == 0)
		kbytes = 1;

	/*
	 * FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for
	 * internal overhead. We don't really know how these are used,
	 * but documentation say it exists.
	 */
	size -= mdwidth * (kbytes + 1);
	size /= kbytes;

	usb_ep_set_maxpacket_limit(&dep->endpoint, size);

	dep->endpoint.max_streams = 15;
	dep->endpoint.ops = &dwc3_gadget_ep_ops;
	list_add_tail(&dep->endpoint.ep_list,
			&dwc->gadget.ep_list);
	dep->endpoint.caps.type_iso = true;
	dep->endpoint.caps.type_bulk = true;
	dep->endpoint.caps.type_int = true;

	return dwc3_alloc_trb_pool(dep);
}

static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
static int dwc3_gadget_init_in_out_endpoint(struct dwc3_ep *dep)
{
	struct dwc3 *dwc = dep->dwc;

@@ -2572,10 +2537,8 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)

	if (num == 0)
		ret = dwc3_gadget_init_control_endpoint(dep);
	else if (direction)
		ret = dwc3_gadget_init_in_endpoint(dep);
	else
		ret = dwc3_gadget_init_out_endpoint(dep);
		ret = dwc3_gadget_init_in_out_endpoint(dep);

	if (ret)
		return ret;
@@ -3816,6 +3779,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
	 * sure we're starting from a well known location.
	 */

	dwc->num_eps = DWC3_ENDPOINTS_NUM;
	ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps);
	if (ret)
		goto err3;
@@ -3826,8 +3790,6 @@ int dwc3_gadget_init(struct dwc3 *dwc)
		goto err4;
	}

	dwc3_gadget_set_speed(&dwc->gadget, dwc->maximum_speed);

	return 0;

err4: