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: Felipe Balbi <balbi@kernel.org> Signed-off-by: Bryan O'Donoghue <pure.logic@nexus-software.ie> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
8261bd4e91
commit
47d3946ea2
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue