diff mbox series

[03/11] usb: xhci: add quirks flag to support MediaTek xHCI 0.96

Message ID 1597289108-22936-3-git-send-email-chunfeng.yun@mediatek.com
State Superseded
Delegated to: Marek Vasut
Headers show
Series [01/11] usb: xhci: add a member hci_version in xhci_ctrl struct | expand

Commit Message

Chunfeng Yun Aug. 13, 2020, 3:25 a.m. UTC
There some vendor quirks for MTK xHCI 0.96 host controller:
1. It defines some extra SW scheduling parameters for HW
   to minimize the scheduling effort for synchronous and
   interrupt endpoints. The parameters are put into reseved
   DWs of slot context and endpoint context.
2. Its TDS in  Normal TRB defines a number of packets that
   remains to be transferred for a TD after processing all
   Max packets in all previous TRBs.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
 drivers/usb/host/xhci-mtk.c  | 1 +
 drivers/usb/host/xhci-ring.c | 9 +++++++--
 drivers/usb/host/xhci.c      | 2 +-
 include/usb/xhci.h           | 2 ++
 4 files changed, 11 insertions(+), 3 deletions(-)

Comments

Frank Wunderlich Aug. 13, 2020, 10:35 a.m. UTC | #1
> Gesendet: Donnerstag, 13. August 2020 um 05:25 Uhr
> Von: "Chunfeng Yun" <chunfeng.yun@mediatek.com>
> Betreff: [PATCH 03/11] usb: xhci: add quirks flag to support MediaTek xHCI 0.96
>
> There some vendor quirks for MTK xHCI 0.96 host controller:
> 1. It defines some extra SW scheduling parameters for HW
>    to minimize the scheduling effort for synchronous and
>    interrupt endpoints. The parameters are put into reseved
>    DWs of slot context and endpoint context.
> 2. Its TDS in  Normal TRB defines a number of packets that
>    remains to be transferred for a TD after processing all
>    Max packets in all previous TRBs.

Tested full series on Bananapi-R2 and R64 (can post DTS-nodes later or can be found here [1])

BPI-R2> usb start
starting USB...
Bus usb@1a1c0000: hcd: 0x1a1c0000, ippc: 0x1a1c4700
u2p:1, u3p:1
Register 200010f NbrPorts 2
Starting the controller
USB XHCI 0.96
Bus usb@1a240000: hcd: 0x1a240000, ippc: 0x1a244700
u2p:1, u3p:1
Register 200010f NbrPorts 2
Starting the controller
USB XHCI 0.96
scanning bus usb@1a1c0000 for devices... 1 USB Device(s) found
scanning bus usb@1a240000 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
BPI-R2> usb tree
USB device tree:
  1  Hub (5 Gb/s, 0mA)
     U-Boot XHCI Host Controller

  1  Hub (5 Gb/s, 0mA)
  |  U-Boot XHCI Host Controller
  |
  +-2  Mass Storage (480 Mb/s, 200mA)
       USB      Flash Disk       906B030002F4

BPI-R2> ls usb 0:1
            efi/
  4767728   kernel

1 file(s), 1 dir(s)

=========================================================

BPI-R64> usb start
starting USB...
Bus usb@1a0c0000: hcd: 0x1a0c0000, ippc: 0x1a0c4700
u2p:2, u3p:1
Register 300010f NbrPorts 3
Starting the controller
USB XHCI 0.96
scanning bus usb@1a0c0000 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
BPI-R64> ls usb 0:1
       91   mcurom.md5
            System Volume Information/

1 file(s), 1 dir(s)

BPI-R64>

Tested-By: Frank Wunderlich <frank-w@public-files.de>

[1] https://github.com/frank-w/u-boot/commits/2020-10-bpi
Chunfeng Yun Aug. 17, 2020, 2:37 a.m. UTC | #2
On Thu, 2020-08-13 at 12:35 +0200, Frank Wunderlich wrote:
> > Gesendet: Donnerstag, 13. August 2020 um 05:25 Uhr
> > Von: "Chunfeng Yun" <chunfeng.yun@mediatek.com>
> > Betreff: [PATCH 03/11] usb: xhci: add quirks flag to support MediaTek xHCI 0.96
> >
> > There some vendor quirks for MTK xHCI 0.96 host controller:
> > 1. It defines some extra SW scheduling parameters for HW
> >    to minimize the scheduling effort for synchronous and
> >    interrupt endpoints. The parameters are put into reseved
> >    DWs of slot context and endpoint context.
> > 2. Its TDS in  Normal TRB defines a number of packets that
> >    remains to be transferred for a TD after processing all
> >    Max packets in all previous TRBs.
> 
> Tested full series on Bananapi-R2 and R64 (can post DTS-nodes later or can be found here [1])
> 
> BPI-R2> usb start
> starting USB...
> Bus usb@1a1c0000: hcd: 0x1a1c0000, ippc: 0x1a1c4700
> u2p:1, u3p:1
> Register 200010f NbrPorts 2
> Starting the controller
> USB XHCI 0.96
> Bus usb@1a240000: hcd: 0x1a240000, ippc: 0x1a244700
> u2p:1, u3p:1
> Register 200010f NbrPorts 2
> Starting the controller
> USB XHCI 0.96
> scanning bus usb@1a1c0000 for devices... 1 USB Device(s) found
> scanning bus usb@1a240000 for devices... 2 USB Device(s) found
>        scanning usb for storage devices... 1 Storage Device(s) found
> BPI-R2> usb tree
> USB device tree:
>   1  Hub (5 Gb/s, 0mA)
>      U-Boot XHCI Host Controller
> 
>   1  Hub (5 Gb/s, 0mA)
>   |  U-Boot XHCI Host Controller
>   |
>   +-2  Mass Storage (480 Mb/s, 200mA)
>        USB      Flash Disk       906B030002F4
> 
> BPI-R2> ls usb 0:1
>             efi/
>   4767728   kernel
> 
> 1 file(s), 1 dir(s)
> 
> =========================================================
> 
> BPI-R64> usb start
> starting USB...
> Bus usb@1a0c0000: hcd: 0x1a0c0000, ippc: 0x1a0c4700
> u2p:2, u3p:1
> Register 300010f NbrPorts 3
> Starting the controller
> USB XHCI 0.96
> scanning bus usb@1a0c0000 for devices... 2 USB Device(s) found
>        scanning usb for storage devices... 1 Storage Device(s) found
> BPI-R64> ls usb 0:1
>        91   mcurom.md5
>             System Volume Information/
> 
> 1 file(s), 1 dir(s)
> 
> BPI-R64>
> 
> Tested-By: Frank Wunderlich <frank-w@public-files.de>
Thanks a lot

> 
> [1] https://github.com/frank-w/u-boot/commits/2020-10-bpi
diff mbox series

Patch

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 8ff7185..f3f181d 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -258,6 +258,7 @@  static int xhci_mtk_probe(struct udevice *dev)
 	if (ret)
 		goto ssusb_init_err;
 
+	mtk->ctrl.quirks = XHCI_MTK_HOST;
 	hcor = (struct xhci_hcor *)((uintptr_t)mtk->hcd +
 			HC_LENGTH(xhci_readl(&mtk->hcd->cr_capbase)));
 
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0f86b01..cf8b9d2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -332,7 +332,8 @@  static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
 {
 	u32 total_packet_count;
 
-	if (ctrl->hci_version < 0x100)
+	/* MTK xHCI 0.96 contains some features from 1.0 */
+	if (ctrl->hci_version < 0x100 && !(ctrl->quirks & XHCI_MTK_HOST))
 		return ((td_total_len - transferred) >> 10);
 
 	/* One TRB with a zero-length data packet. */
@@ -340,6 +341,10 @@  static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
 	    trb_buff_len == td_total_len)
 		return 0;
 
+	/* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */
+	if ((ctrl->quirks & XHCI_MTK_HOST) && (ctrl->hci_version < 0x100))
+		trb_buff_len = 0;
+
 	total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
 
 	/* Queueing functions don't count the current TRB into transferred */
@@ -823,7 +828,7 @@  int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
 		field |= 0x1;
 
 	/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
-	if (ctrl->hci_version >= 0x100) {
+	if (ctrl->hci_version >= 0x100 || ctrl->quirks & XHCI_MTK_HOST) {
 		if (length > 0) {
 			if (req->requesttype & USB_DIR_IN)
 				field |= (TRB_DATA_IN << TRB_TX_TYPE_SHIFT);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 4be1411..51edeb2 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -650,7 +650,7 @@  static int xhci_set_configuration(struct usb_device *udev)
 		 * are put into reserved DWs in Slot and Endpoint Contexts
 		 * for synchronous endpoints.
 		 */
-		if (IS_ENABLED(CONFIG_USB_XHCI_MTK)) {
+		if (ctrl->quirks & XHCI_MTK_HOST) {
 			ep_ctx[ep_index]->reserved[0] =
 				cpu_to_le32(EP_BPKTS(1) | EP_BBM(1));
 		}
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index 15926eb..3de46cd 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -1230,6 +1230,8 @@  struct xhci_ctrl {
 	struct xhci_virt_device *devs[MAX_HC_SLOTS];
 	int rootdev;
 	u16 hci_version;
+	u32 quirks;
+#define XHCI_MTK_HOST		BIT(0)
 };
 
 unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);