hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/usb/cdns3/gadget.c
....@@ -2041,7 +2041,7 @@
20412041 u8 mult = 0;
20422042 int ret;
20432043
2044
- buffering = CDNS3_EP_BUF_SIZE - 1;
2044
+ buffering = priv_dev->ep_buf_size - 1;
20452045
20462046 cdns3_configure_dmult(priv_dev, priv_ep);
20472047
....@@ -2060,7 +2060,7 @@
20602060 break;
20612061 default:
20622062 ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC);
2063
- mult = CDNS3_EP_ISO_HS_MULT - 1;
2063
+ mult = priv_dev->ep_iso_burst - 1;
20642064 buffering = mult + 1;
20652065 }
20662066
....@@ -2076,14 +2076,14 @@
20762076 mult = 0;
20772077 max_packet_size = 1024;
20782078 if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
2079
- maxburst = CDNS3_EP_ISO_SS_BURST - 1;
2079
+ maxburst = priv_dev->ep_iso_burst - 1;
20802080 buffering = (mult + 1) *
20812081 (maxburst + 1);
20822082
20832083 if (priv_ep->interval > 1)
20842084 buffering++;
20852085 } else {
2086
- maxburst = CDNS3_EP_BUF_SIZE - 1;
2086
+ maxburst = priv_dev->ep_buf_size - 1;
20872087 }
20882088 break;
20892089 default:
....@@ -2097,6 +2097,23 @@
20972097 priv_ep->trb_burst_size = 64;
20982098 else
20992099 priv_ep->trb_burst_size = 16;
2100
+
2101
+ /*
2102
+ * In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs
2103
+ * in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the
2104
+ * address is not aligned to 128 Bytes (which is a product of the 64-bit AXI
2105
+ * and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This
2106
+ * results in data corruption when it crosses the 4K border. The corruption
2107
+ * specifically occurs from the position (4K - (address & 0x7F)) to 4K.
2108
+ *
2109
+ * So force trb_burst_size to 16 at such platform.
2110
+ */
2111
+ if (priv_dev->dev_ver < DEV_VER_V2)
2112
+ priv_ep->trb_burst_size = 16;
2113
+
2114
+ mult = min_t(u8, mult, EP_CFG_MULT_MAX);
2115
+ buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
2116
+ maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);
21002117
21012118 /* onchip buffer is only allocated before configuration */
21022119 if (!priv_dev->hw_configured_flag) {
....@@ -2971,6 +2988,40 @@
29712988 return 0;
29722989 }
29732990
2991
+/**
2992
+ * cdns3_gadget_check_config - ensure cdns3 can support the USB configuration
2993
+ * @gadget: pointer to the USB gadget
2994
+ *
2995
+ * Used to record the maximum number of endpoints being used in a USB composite
2996
+ * device. (across all configurations) This is to be used in the calculation
2997
+ * of the TXFIFO sizes when resizing internal memory for individual endpoints.
2998
+ * It will help ensured that the resizing logic reserves enough space for at
2999
+ * least one max packet.
3000
+ */
3001
+static int cdns3_gadget_check_config(struct usb_gadget *gadget)
3002
+{
3003
+ struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
3004
+ struct usb_ep *ep;
3005
+ int n_in = 0;
3006
+ int total;
3007
+
3008
+ list_for_each_entry(ep, &gadget->ep_list, ep_list) {
3009
+ if (ep->claimed && (ep->address & USB_DIR_IN))
3010
+ n_in++;
3011
+ }
3012
+
3013
+ /* 2KB are reserved for EP0, 1KB for out*/
3014
+ total = 2 + n_in + 1;
3015
+
3016
+ if (total > priv_dev->onchip_buffers)
3017
+ return -ENOMEM;
3018
+
3019
+ priv_dev->ep_buf_size = priv_dev->ep_iso_burst =
3020
+ (priv_dev->onchip_buffers - 2) / (n_in + 1);
3021
+
3022
+ return 0;
3023
+}
3024
+
29743025 static const struct usb_gadget_ops cdns3_gadget_ops = {
29753026 .get_frame = cdns3_gadget_get_frame,
29763027 .wakeup = cdns3_gadget_wakeup,
....@@ -2979,6 +3030,7 @@
29793030 .udc_start = cdns3_gadget_udc_start,
29803031 .udc_stop = cdns3_gadget_udc_stop,
29813032 .match_ep = cdns3_gadget_match_ep,
3033
+ .check_config = cdns3_gadget_check_config,
29823034 };
29833035
29843036 static void cdns3_free_all_eps(struct cdns3_device *priv_dev)