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

Commit 80508b4f authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Sriharsha Allenki
Browse files

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: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: default avatarChandana Kishori Chiluveru <cchiluve@codeaurora.org>
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
parent d8136467
Loading
Loading
Loading
Loading
+2 −18
Original line number Diff line number Diff line
@@ -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;
}

+26 −26
Original line number Diff line number Diff line
@@ -697,11 +697,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)) {
@@ -733,23 +728,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));
@@ -1471,12 +1449,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*/
@@ -1489,7 +1474,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)
		return -ENOMEM;

@@ -1498,10 +1483,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;
}
+2 −2
Original line number Diff line number Diff line
@@ -2378,7 +2378,7 @@ static int gsi_update_function_bind_params(struct f_gsi *gsi,
		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 */
	}

@@ -2388,7 +2388,7 @@ static int gsi_update_function_bind_params(struct f_gsi *gsi,
		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 */
	}

+2 −2
Original line number Diff line number Diff line
@@ -478,7 +478,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");
			spin_unlock_irqrestore(&port->port_lock, flags);
@@ -503,7 +503,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");
			spin_unlock_irqrestore(&port->port_lock, flags);
+2 −1
Original line number Diff line number Diff line
@@ -131,11 +131,12 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)

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");

Loading