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 reserved
   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>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Chunfeng Yun 2020-09-08 18:59:57 +02:00 committed by Marek Vasut
parent e3ea481bee
commit 740820519c
4 changed files with 11 additions and 3 deletions

View File

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

View File

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

View File

@ -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));
}

View File

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