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

Commit 47d3946e authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Felipe Balbi
Browse files

usb: dwc3: refactor gadget endpoint count calculation



- DWC_USB3_NUM indicates the number of Device mode single directional
  endpoints, including OUT and IN endpoint 0.

- DWC_USB3_NUM_IN_EPS indicates the maximum number of Device mode IN
  endpoints active at any time, including control endpoint 0.

It's possible to configure RTL such that DWC_USB3_NUM_EPS is equal to
DWC_USB3_NUM_IN_EPS.

dwc3-core calculates the number of OUT endpoints as DWC_USB3_NUM minus
DWC_USB3_NUM_IN_EPS. If RTL has been configured with DWC_USB3_NUM_IN_EPS
equal to DWC_USB3_NUM then dwc3-core will calculate the number of OUT
endpoints as zero.

For example a from dwc3_core_num_eps() shows:
[    1.565000]  /usb0@f01d0000: found 8 IN and 0 OUT endpoints

This patch refactors the endpoint calculation down to one variable
dwc->num_eps taking care to maintain the current mapping of endpoints for
fixed FPGA configurations as described in Table 4-7 of version 2.60a of the
DWC USB3 databook.

The endpoint mapping will then be EP-OUT, EP-IN etc, up to DWC_USB3_NUM.
If DWC_USB3_NUM is odd then OUT will take the extra endpoint.

Suggested-by: default avatarFelipe Balbi <balbi@kernel.org>
Signed-off-by: default avatarBryan O'Donoghue <pure.logic@nexus-software.ie>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 8261bd4e
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -397,8 +397,7 @@ static void dwc3_core_num_eps(struct dwc3 *dwc)
{
	struct dwc3_hwparams	*parms = &dwc->hwparams;

	dwc->num_in_eps = DWC3_NUM_IN_EPS(parms);
	dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps;
	dwc->num_eps = DWC3_NUM_EPS(parms);
}

static void dwc3_cache_hwparams(struct dwc3 *dwc)
+2 −4
Original line number Diff line number Diff line
@@ -800,8 +800,7 @@ struct dwc3_scratchpad_array {
 * @u2pel: parameter from Set SEL request.
 * @u1sel: parameter from Set SEL request.
 * @u1pel: parameter from Set SEL request.
 * @num_out_eps: number of out endpoints
 * @num_in_eps: number of in endpoints
 * @num_eps: number of endpoints
 * @ep0_next_event: hold the next expected event
 * @ep0state: state of endpoint zero
 * @link_state: link state
@@ -961,8 +960,7 @@ struct dwc3 {

	u8			speed;

	u8			num_out_eps;
	u8			num_in_eps;
	u8			num_eps;

	struct dwc3_hwparams	hwparams;
	struct dentry		*root;
+2 −13
Original line number Diff line number Diff line
@@ -822,19 +822,8 @@ static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
{
	int			i;

	for (i = 0; i < dwc->num_in_eps; i++) {
		u8		epnum = (i << 1) | 1;
		struct dwc3_ep	*dep = dwc->eps[epnum];

		if (!dep)
			continue;

		dwc3_debugfs_create_endpoint_dir(dep, parent);
	}

	for (i = 0; i < dwc->num_out_eps; i++) {
		u8		epnum = (i << 1);
		struct dwc3_ep	*dep = dwc->eps[epnum];
	for (i = 0; i < dwc->num_eps; i++) {
		struct dwc3_ep	*dep = dwc->eps[i];

		if (!dep)
			continue;
+9 −24
Original line number Diff line number Diff line
@@ -2006,14 +2006,13 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {

/* -------------------------------------------------------------------------- */

static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
		u8 num, u32 direction)
static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, u8 num)
{
	struct dwc3_ep			*dep;
	u8				i;
	u8				epnum;

	for (i = 0; i < num; i++) {
		u8 epnum = (i << 1) | (direction ? 1 : 0);
	for (epnum = 0; epnum < num; epnum++) {
		bool			direction = epnum & 1;

		dep = kzalloc(sizeof(*dep), GFP_KERNEL);
		if (!dep)
@@ -2021,12 +2020,12 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,

		dep->dwc = dwc;
		dep->number = epnum;
		dep->direction = !!direction;
		dep->direction = direction;
		dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
		dwc->eps[epnum] = dep;

		snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
				(epnum & 1) ? "in" : "out");
				direction ? "in" : "out");

		dep->endpoint.name = dep->name;

@@ -2053,7 +2052,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
			/* MDWIDTH is represented in bits, we need it in bytes */
			mdwidth /= 8;

			size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(i));
			size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(epnum >> 1));
			size = DWC3_GTXFIFOSIZ_TXFDEF(size);

			/* FIFO Depth is in MDWDITH bytes. Multiply */
@@ -2103,7 +2102,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
			dep->endpoint.caps.type_int = true;
		}

		dep->endpoint.caps.dir_in = !!direction;
		dep->endpoint.caps.dir_in = direction;
		dep->endpoint.caps.dir_out = !direction;

		INIT_LIST_HEAD(&dep->pending_list);
@@ -2115,23 +2114,9 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,

static int dwc3_gadget_init_endpoints(struct dwc3 *dwc)
{
	int				ret;

	INIT_LIST_HEAD(&dwc->gadget.ep_list);

	ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0);
	if (ret < 0) {
		dev_err(dwc->dev, "failed to initialize OUT endpoints\n");
		return ret;
	}

	ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1);
	if (ret < 0) {
		dev_err(dwc->dev, "failed to initialize IN endpoints\n");
		return ret;
	}

	return 0;
	return dwc3_gadget_init_hw_endpoints(dwc, dwc->num_eps);
}

static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)