USB: dwc3-msm: Initialize DBM ep before BAM pipe reset
On new platforms, endpoint clock gating is added for dbm endpoints with Synopsys USB3.0 controller. This hardware feature requires initialization of DBM endpoint before BAM pipe reset for bam2bam mode data transfers working. Hence change sequence such that do DBM endpoint initialization first followed by BAM pipe reset and do start transfer as last operation. CRs-Fixed: 965207 Change-Id: Ib5bfd1a7d258fe336a4c9924850fc9223c1c81f6 Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org> Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
This commit is contained in:
parent
a80e267a8c
commit
58c91d96b2
6 changed files with 39 additions and 52 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -312,9 +312,6 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* First, reset the dbm endpoint */
|
||||
ep_soft_reset(dbm, dbm_ep, 0);
|
||||
|
||||
/* Set ioc bit for dbm_ep if needed */
|
||||
msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
|
||||
DBM_ENABLE_IOC_MASK & 1 << dbm_ep, ioc ? 1 : 0);
|
||||
|
@ -391,23 +388,10 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep)
|
|||
data &= (~0x1);
|
||||
msm_dbm_write_ep_reg(dbm, DBM_EP_CFG, dbm_ep, data);
|
||||
|
||||
/* Reset the dbm endpoint */
|
||||
ep_soft_reset(dbm, dbm_ep, true);
|
||||
/*
|
||||
* The necessary delay between asserting and deasserting the dbm ep
|
||||
* reset is based on the number of active endpoints. If there is more
|
||||
* than one endpoint, a 1 msec delay is required. Otherwise, a shorter
|
||||
* delay will suffice.
|
||||
*
|
||||
* As this function can be called in atomic context, sleeping variants
|
||||
* for delay are not possible - albeit a 1ms delay.
|
||||
* ep_soft_reset is not required during disconnect as pipe reset on
|
||||
* next connect will take care of the same.
|
||||
*/
|
||||
if (dbm_get_num_of_eps_configured(dbm) > 1)
|
||||
udelay(1000);
|
||||
else
|
||||
udelay(10);
|
||||
ep_soft_reset(dbm, dbm_ep, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -622,11 +622,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
|||
struct dwc3_msm_req_complete *req_complete;
|
||||
unsigned long flags;
|
||||
int ret = 0, size;
|
||||
u8 bam_pipe;
|
||||
bool producer;
|
||||
bool disable_wb;
|
||||
bool internal_mem;
|
||||
bool ioc;
|
||||
bool superspeed;
|
||||
|
||||
if (!(request->udc_priv & MSM_SPS_MODE)) {
|
||||
|
@ -659,23 +654,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
|||
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
|
||||
request->complete = dwc3_msm_req_complete_func;
|
||||
|
||||
/*
|
||||
* Configure the DBM endpoint
|
||||
*/
|
||||
bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
|
||||
producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
|
||||
disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
|
||||
internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
|
||||
ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
|
||||
|
||||
ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
|
||||
disable_wb, internal_mem, ioc);
|
||||
if (ret < 0) {
|
||||
dev_err(mdwc->dev,
|
||||
"error %d after calling dbm_ep_config\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
|
||||
__func__, request, ep->name, request->length);
|
||||
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
|
||||
|
@ -1346,12 +1324,19 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
|
|||
*
|
||||
* @return int - 0 on success, negetive on error.
|
||||
*/
|
||||
int msm_ep_config(struct usb_ep *ep)
|
||||
int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct dwc3_ep *dep = to_dwc3_ep(ep);
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
|
||||
struct usb_ep_ops *new_ep_ops;
|
||||
int ret = 0;
|
||||
u8 bam_pipe;
|
||||
bool producer;
|
||||
bool disable_wb;
|
||||
bool internal_mem;
|
||||
bool ioc;
|
||||
|
||||
|
||||
/* Save original ep ops for future restore*/
|
||||
|
@ -1364,7 +1349,7 @@ int msm_ep_config(struct usb_ep *ep)
|
|||
mdwc->original_ep_ops[dep->number] = ep->ops;
|
||||
|
||||
/* Set new usb ops as we like */
|
||||
new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_ATOMIC);
|
||||
new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), gfp_flags);
|
||||
if (!new_ep_ops) {
|
||||
dev_err(mdwc->dev,
|
||||
"%s: unable to allocate mem for new usb ep ops\n",
|
||||
|
@ -1376,10 +1361,25 @@ int msm_ep_config(struct usb_ep *ep)
|
|||
new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
|
||||
ep->ops = new_ep_ops;
|
||||
|
||||
if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Do HERE more usb endpoint configurations
|
||||
* which are specific to MSM.
|
||||
* Configure the DBM endpoint if required.
|
||||
*/
|
||||
bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
|
||||
producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
|
||||
disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
|
||||
internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
|
||||
ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
|
||||
|
||||
ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
|
||||
disable_wb, internal_mem, ioc);
|
||||
if (ret < 0) {
|
||||
dev_err(mdwc->dev,
|
||||
"error %d after calling dbm_ep_config\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2245,7 +2245,7 @@ skip_string_id_alloc:
|
|||
if (!ep)
|
||||
goto fail;
|
||||
gsi->d_port.in_ep = ep;
|
||||
msm_ep_config(gsi->d_port.in_ep);
|
||||
msm_ep_config(gsi->d_port.in_ep, NULL, GFP_KERNEL);
|
||||
ep->driver_data = cdev; /* claim */
|
||||
}
|
||||
|
||||
|
@ -2255,7 +2255,7 @@ skip_string_id_alloc:
|
|||
if (!ep)
|
||||
goto fail;
|
||||
gsi->d_port.out_ep = ep;
|
||||
msm_ep_config(gsi->d_port.out_ep);
|
||||
msm_ep_config(gsi->d_port.out_ep, NULL, GFP_KERNEL);
|
||||
ep->driver_data = cdev; /* claim */
|
||||
}
|
||||
|
||||
|
|
|
@ -457,7 +457,7 @@ static void ipa_data_connect_work(struct work_struct *w)
|
|||
configure_fifo(port->usb_bam_type,
|
||||
port->src_connection_idx,
|
||||
port->port_usb->out);
|
||||
ret = msm_ep_config(gport->out);
|
||||
ret = msm_ep_config(gport->out, port->rx_req, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
pr_err("msm_ep_config() failed for OUT EP\n");
|
||||
usb_bam_free_fifos(port->usb_bam_type,
|
||||
|
@ -475,7 +475,7 @@ static void ipa_data_connect_work(struct work_struct *w)
|
|||
port->tx_req->udc_priv = sps_params;
|
||||
configure_fifo(port->usb_bam_type,
|
||||
port->dst_connection_idx, gport->in);
|
||||
ret = msm_ep_config(gport->in);
|
||||
ret = msm_ep_config(gport->in, port->tx_req, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
pr_err("msm_ep_config() failed for IN EP\n");
|
||||
goto unconfig_msm_ep_out;
|
||||
|
|
|
@ -94,11 +94,12 @@ int set_qdss_data_connection(struct usb_gadget *gadget,
|
|||
|
||||
static int init_data(struct usb_ep *ep)
|
||||
{
|
||||
struct f_qdss *qdss = ep->driver_data;
|
||||
int res = 0;
|
||||
|
||||
pr_debug("init_data\n");
|
||||
|
||||
res = msm_ep_config(ep);
|
||||
res = msm_ep_config(ep, qdss->endless_req, GFP_ATOMIC);
|
||||
if (res)
|
||||
pr_err("msm_ep_config failed\n");
|
||||
|
||||
|
|
|
@ -296,7 +296,8 @@ static inline void msm_usb_irq_disable(bool disable)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_DWC3_QCOM
|
||||
int msm_ep_config(struct usb_ep *ep);
|
||||
int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||
gfp_t gfp_flags);
|
||||
int msm_ep_unconfig(struct usb_ep *ep);
|
||||
void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable);
|
||||
int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, u32 size,
|
||||
|
@ -311,7 +312,8 @@ static inline int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int msm_ep_config(struct usb_ep *ep)
|
||||
static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue