summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom <support@vamrs.com>2021-01-11 21:31:37 +0300
committerFu Wei <fu.wei@linaro.org>2021-02-24 22:46:57 +0300
commit066d2be4eb17b89269f1523cbd92dff5c879653b (patch)
treed6045578b6ddc28816cb97276d7fe6ad990a8f9f
parent7ccb16116e08446454dd21456319491163808aba (diff)
downloadlinux-066d2be4eb17b89269f1523cbd92dff5c879653b.tar.xz
Add USB data cache flush operations in cdns3 for VIC7100
-rw-r--r--drivers/usb/cdns3/debug.h3
-rw-r--r--drivers/usb/cdns3/ep0.c113
-rw-r--r--drivers/usb/cdns3/gadget.c129
-rw-r--r--drivers/usb/cdns3/trace.h7
4 files changed, 222 insertions, 30 deletions
diff --git a/drivers/usb/cdns3/debug.h b/drivers/usb/cdns3/debug.h
index a5c6a29e1340..ba4143280a23 100644
--- a/drivers/usb/cdns3/debug.h
+++ b/drivers/usb/cdns3/debug.h
@@ -152,6 +152,9 @@ static inline char *cdns3_dbg_ring(struct cdns3_endpoint *priv_ep,
le32_to_cpu(trb->buffer),
le32_to_cpu(trb->length),
le32_to_cpu(trb->control));
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(trb, sizeof(struct cdns3_trb));
+#endif
addr += sizeof(*trb);
}
diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c
index e6bea036bdd2..cb4237c60540 100644
--- a/drivers/usb/cdns3/ep0.c
+++ b/drivers/usb/cdns3/ep0.c
@@ -54,8 +54,8 @@ static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev,
}
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
- 2 * sizeof(struct cdns3_trb));
+ cdns_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
+ 2 * TRB_SIZE);
#endif
trace_cdns3_prepare_trb(priv_ep, priv_ep->trb_pool);
@@ -93,6 +93,9 @@ static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev,
spin_unlock(&priv_dev->lock);
priv_dev->setup_pending = 1;
ret = priv_dev->gadget_driver->setup(&priv_dev->gadget, ctrl_req);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
priv_dev->setup_pending = 0;
spin_lock(&priv_dev->lock);
return ret;
@@ -151,6 +154,9 @@ static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev,
u32 config = le16_to_cpu(ctrl_req->wValue);
int result = 0;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
switch (device_state) {
case USB_STATE_ADDRESS:
result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
@@ -196,7 +202,9 @@ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev,
u32 addr;
addr = le16_to_cpu(ctrl_req->wValue);
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
if (addr > USB_DEVICE_MAX_ADDRESS) {
dev_err(priv_dev->dev,
"Device address (%d) cannot be greater than %d\n",
@@ -236,9 +244,14 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
u16 usb_status = 0;
u32 recip;
u8 index;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ u32 tmp_ind;
+#endif
recip = ctrl->bRequestType & USB_RECIP_MASK;
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
switch (recip) {
case USB_RECIP_DEVICE:
/* self powered */
@@ -264,8 +277,17 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
index = cdns3_ep_addr_to_index(le16_to_cpu(ctrl->wIndex));
priv_ep = priv_dev->eps[index];
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ tmp_ind = ctrl->wIndex;
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+
+ /* check if endpoint is stalled or stall is pending */
+ cdns3_select_ep(priv_dev, tmp_ind);
+#else
+
/* check if endpoint is stalled or stall is pending */
cdns3_select_ep(priv_dev, le16_to_cpu(ctrl->wIndex));
+#endif
if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts)) ||
(priv_ep->flags & EP_STALL_PENDING))
usb_status = BIT(USB_ENDPOINT_HALT);
@@ -278,7 +300,7 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
*response_pkt = cpu_to_le16(usb_status);
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(priv_dev->setup_dma, sizeof(*response_pkt));
+ cdns_flush_dcache(priv_dev->setup_dma, sizeof(*response_pkt));
#endif
cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma,
@@ -297,6 +319,9 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev,
u16 tmode;
wValue = le16_to_cpu(ctrl->wValue);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
state = priv_dev->gadget.state;
speed = priv_dev->gadget.speed;
@@ -324,7 +349,9 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev,
return -EINVAL;
tmode = le16_to_cpu(ctrl->wIndex);
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
if (!set || (tmode & 0xff) != 0)
return -EINVAL;
@@ -357,7 +384,9 @@ static int cdns3_ep0_feature_handle_intf(struct cdns3_device *priv_dev,
int ret = 0;
wValue = le16_to_cpu(ctrl->wValue);
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
switch (wValue) {
case USB_INTRF_FUNC_SUSPEND:
break;
@@ -375,17 +404,38 @@ static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev,
struct cdns3_endpoint *priv_ep;
int ret = 0;
u8 index;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ u32 tmp_ind;
+#endif
- if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT)
+ if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) {
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
return -EINVAL;
+ }
- if (!(ctrl->wIndex & ~USB_DIR_IN))
+ if (!(ctrl->wIndex & ~USB_DIR_IN)) {
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
return 0;
+ }
+
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
index = cdns3_ep_addr_to_index(le16_to_cpu(ctrl->wIndex));
priv_ep = priv_dev->eps[index];
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ tmp_ind = ctrl->wIndex;
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+ cdns3_select_ep(priv_dev, tmp_ind);
+#else
cdns3_select_ep(priv_dev, le16_to_cpu(ctrl->wIndex));
+#endif
if (set)
__cdns3_gadget_ep_set_halt(priv_ep);
@@ -415,7 +465,9 @@ static int cdns3_req_ep0_handle_feature(struct cdns3_device *priv_dev,
u32 recip;
recip = ctrl->bRequestType & USB_RECIP_MASK;
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
switch (recip) {
case USB_RECIP_DEVICE:
ret = cdns3_ep0_feature_handle_device(priv_dev, ctrl, set);
@@ -449,11 +501,15 @@ static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev,
if (le16_to_cpu(ctrl_req->wLength) != 6) {
dev_err(priv_dev->dev, "Set SEL should be 6 bytes, got %d\n",
ctrl_req->wLength);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
return -EINVAL;
}
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(priv_dev->setup_dma, 6);
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+ cdns_flush_dcache(priv_dev->setup_dma, 6);
#endif
cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, 6, 1, 0);
@@ -471,11 +527,19 @@ static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev,
static int cdns3_req_ep0_set_isoch_delay(struct cdns3_device *priv_dev,
struct usb_ctrlrequest *ctrl_req)
{
- if (ctrl_req->wIndex || ctrl_req->wLength)
+ if (ctrl_req->wIndex || ctrl_req->wLength) {
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
return -EINVAL;
+ }
priv_dev->isoch_delay = le16_to_cpu(ctrl_req->wValue);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+#endif
+
return 0;
}
@@ -491,7 +555,13 @@ static int cdns3_ep0_standard_request(struct cdns3_device *priv_dev,
{
int ret;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ u8 bReq = ctrl_req->bRequest;
+ cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
+ switch (bReq) {
+#else
switch (ctrl_req->bRequest) {
+#endif
case USB_REQ_SET_ADDRESS:
ret = cdns3_req_ep0_set_address(priv_dev, ctrl_req);
break;
@@ -554,7 +624,9 @@ static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev)
int result;
priv_dev->ep0_data_dir = ctrl->bRequestType & USB_DIR_IN;
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
trace_cdns3_ctrl_req(ctrl);
if (!list_empty(&priv_ep->pending_req_list)) {
@@ -571,10 +643,17 @@ static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev)
else
priv_dev->ep0_stage = CDNS3_STATUS_STAGE;
- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
+ if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
result = cdns3_ep0_standard_request(priv_dev, ctrl);
- else
+ } else {
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
result = cdns3_ep0_delegate_req(priv_dev, ctrl);
+ }
if (result == USB_GADGET_DELAYED_STATUS)
return;
@@ -599,8 +678,8 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev)
TRB_LEN(le32_to_cpu(priv_ep->trb_pool->length));
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
- sizeof(struct cdns3_trb));
+ cdns_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
+ sizeof(struct cdns3_trb));
#endif
priv_ep->dir = priv_dev->ep0_data_dir;
cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), 0);
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 53d91de342c3..7279af6c4d3c 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -246,8 +246,7 @@ int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep)
memset(priv_ep->trb_pool, 0, ring_size);
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
- ring_size);
+ cdns_flush_dcache(priv_ep->trb_pool_dma, ring_size);
#endif
priv_ep->num_trbs = num_trbs;
@@ -269,9 +268,9 @@ int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep)
link_trb->control = cpu_to_le32(TRB_CYCLE | TRB_TYPE(TRB_LINK) | TRB_TOGGLE);
}
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
- link_trb)),
- TRB_SIZE);
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, link_trb)),
+ TRB_SIZE);
#endif
return 0;
}
@@ -488,6 +487,11 @@ static void __cdns3_descmiss_copy_data(struct usb_request *request,
memcpy(&((u8 *)request->buf)[request->actual],
descmiss_req->buf,
descmiss_req->actual);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(
+ &((u8 *)request->buf)[request->actual],
+ descmiss_req->actual);
+#endif
request->actual = length;
} else {
/* It should never occures */
@@ -843,9 +847,14 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep,
priv_ep->dir);
if ((priv_req->flags & REQUEST_UNALIGNED) &&
- priv_ep->dir == USB_DIR_OUT && !request->status)
+ priv_ep->dir == USB_DIR_OUT && !request->status) {
memcpy(request->buf, priv_req->aligned_buf->buf,
request->length);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(priv_req->aligned_buf->buf,
+ request->length);
+#endif
+ }
priv_req->flags &= ~(REQUEST_PENDING | REQUEST_UNALIGNED);
/* All TRBs have finished, clear the counter */
@@ -946,7 +955,7 @@ static int cdns3_prepare_aligned_request_buf(struct cdns3_request *priv_req)
}
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(buf->dma, buf->size);
+ cdns_flush_dcache(buf->dma, buf->size);
#endif
if (priv_req->aligned_buf) {
@@ -966,6 +975,10 @@ static int cdns3_prepare_aligned_request_buf(struct cdns3_request *priv_req)
if (priv_ep->dir == USB_DIR_IN) {
memcpy(buf->buf, priv_req->request.buf,
priv_req->request.length);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(buf->dma, buf->size);
+ cdns_virt_flush_dcache(priv_req->request.buf, buf->size);
+#endif
}
priv_req->flags |= REQUEST_UNALIGNED;
@@ -1055,10 +1068,19 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep,
if (!request->num_sgs) {
trb->buffer = cpu_to_le32(TRB_BUFFER(trb_dma));
length = request->length;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
} else {
trb->buffer = cpu_to_le32(TRB_BUFFER(request->sg[sg_idx].dma_address));
length = request->sg[sg_idx].length;
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(TRB_BUFFER(request->sg[sg_idx].dma_address),
+ request->sg[sg_idx].length);
+#endif
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
gadget_flush_dcache(TRB_BUFFER(request->sg[sg_idx].dma_address),
request->sg[sg_idx].length);
#endif
@@ -1068,6 +1090,12 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep,
trb->length = cpu_to_le32(TRB_BURST_LEN(16) | TRB_LEN(length));
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ trb)),
+ sizeof(struct cdns3_trb));
+#endif
+
/*
* For DEV_VER_V2 controller version we have enabled
* USB_CONF2_EN_TDL_TRB in DMULT configuration.
@@ -1080,6 +1108,11 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep,
priv_req->flags |= REQUEST_PENDING;
trb->control = cpu_to_le32(control);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ trb)),
+ sizeof(struct cdns3_trb));
+#endif
trace_cdns3_prepare_trb(priv_ep, priv_req->trb);
@@ -1223,6 +1256,12 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) |
TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ link_trb)),
+ sizeof(struct cdns3_trb));
+#endif
}
if (priv_dev->dev_ver <= DEV_VER_V2)
@@ -1259,6 +1298,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
}
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
if(request->num_sgs)
gadget_flush_dcache(request->sg[sg_iter].dma_address,
request->sg[sg_iter].length);
@@ -1270,6 +1312,11 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) |
TRB_LEN(length));
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
pcs = priv_ep->pcs ? TRB_CYCLE : 0;
/*
@@ -1301,12 +1348,23 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
s = sg_next(s);
}
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
+
control = 0;
++sg_iter;
priv_req->end_trb = priv_ep->enqueue;
cdns3_ep_inc_enq(priv_ep);
trb = priv_ep->trb_pool + priv_ep->enqueue;
trb->length = 0;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
} while (sg_iter < num_trb);
trb = priv_req->trb;
@@ -1316,6 +1374,11 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
if (sg_iter == 1)
trb->control |= cpu_to_le32(TRB_IOC | TRB_ISP);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
if (priv_dev->dev_ver < DEV_VER_V2 &&
(priv_ep->flags & EP_TDLCHK_EN)) {
@@ -1340,8 +1403,14 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
wmb();
/* give the TD to the consumer*/
- if (togle_pcs)
+ if (togle_pcs) {
trb->control = trb->control ^ cpu_to_le32(1);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
+ }
if (priv_dev->dev_ver <= DEV_VER_V2)
cdns3_wa1_tray_restore_cycle_bit(priv_dev, priv_ep);
@@ -1576,6 +1645,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
cdns3_move_deq_to_next_trb(priv_req);
}
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
if (!request->stream_id) {
/* Re-select endpoint. It could be changed by other CPU
* during handling usb_gadget_giveback_request.
@@ -1619,6 +1693,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
cdns3_select_ep(priv_dev, priv_ep->endpoint.address);
trb = priv_ep->trb_pool;
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
trace_cdns3_complete_trb(priv_ep, trb);
if (trb != priv_req->trb)
@@ -1628,8 +1707,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
request->actual += TRB_LEN(le32_to_cpu(trb->length));
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
- gadget_flush_dcache(EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
- sizeof(struct cdns3_trb));
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ trb)),
+ sizeof(struct cdns3_trb));
#endif
if (!request->num_sgs ||
@@ -2727,6 +2808,12 @@ found:
((priv_req->end_trb + 1) * TRB_SIZE)));
link_trb->control = cpu_to_le32((le32_to_cpu(link_trb->control) & TRB_CYCLE) |
TRB_TYPE(TRB_LINK) | TRB_CHAIN);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ link_trb)),
+ sizeof(struct cdns3_trb));
+#endif
if (priv_ep->wa1_trb == priv_req->trb)
cdns3_wa1_restore_cycle_bit(priv_ep);
@@ -2780,8 +2867,15 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
if (request) {
priv_req = to_cdns3_request(request);
trb = priv_req->trb;
- if (trb)
+ if (trb) {
trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ trb)),
+ sizeof(struct cdns3_trb));
+#endif
+ }
}
writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
@@ -2795,9 +2889,16 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING);
if (request) {
- if (trb)
+ if (trb) {
trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE);
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(
+ EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep,
+ trb)),
+ sizeof(struct cdns3_trb));
+#endif
+ }
cdns3_rearm_transfer(priv_ep, 1);
}
@@ -3285,7 +3386,9 @@ static int cdns3_gadget_start(struct cdns3 *cdns)
ret = -ENOMEM;
goto err2;
}
-
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(priv_dev->setup_dma, 8);
+#endif
priv_dev->dev_ver = readl(&priv_dev->regs->usb_cap6);
dev_dbg(priv_dev->dev, "Device Controller version: %08x\n",
diff --git a/drivers/usb/cdns3/trace.h b/drivers/usb/cdns3/trace.h
index 0a2a3269bfac..ca368bed1f01 100644
--- a/drivers/usb/cdns3/trace.h
+++ b/drivers/usb/cdns3/trace.h
@@ -187,6 +187,9 @@ DECLARE_EVENT_CLASS(cdns3_log_ctrl,
__entry->wIndex = le16_to_cpu(ctrl->wIndex);
__entry->wLength = le16_to_cpu(ctrl->wLength);
),
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
+#endif
TP_printk("%s", usb_decode_ctrl(__get_str(str), CDNS3_MSG_MAX,
__entry->bRequestType,
__entry->bRequest, __entry->wValue,
@@ -410,6 +413,10 @@ DECLARE_EVENT_CLASS(cdns3_log_trb,
__entry->type = usb_endpoint_type(priv_ep->endpoint.desc);
__entry->last_stream_id = priv_ep->last_stream_id;
),
+#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
+ cdns_flush_dcache(EP_TRADDR_TRADDR(cdns3_trb_virt_to_dma(priv_ep, trb)),
+ sizeof(struct cdns3_trb));
+#endif
TP_printk("%s: trb %p, dma buf: 0x%08x, size: %ld, burst: %d ctrl: 0x%08x (%s%s%s%s%s%s%s) SID:%lu LAST_SID:%u",
__get_str(name), __entry->trb, __entry->buffer,
TRB_LEN(__entry->length),