Skip to content

Commit 926d60a

Browse files
Chunfeng Yungregkh
authored andcommitted
usb: xhci-mtk: modify the SOF/ITP interval for mt8195
There are 4 USB controllers on MT8195, the controllers (IP1~IP3, exclude IP0) have a wrong default SOF/ITP interval which is calculated from the frame counter clock 24Mhz by default, but in fact, the frame counter clock is 48Mhz, so we should set the accurate interval according to 48Mhz for those controllers. Note: the first controller no need set it. Signed-off-by: Chunfeng Yun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 82799c8 commit 926d60a

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

drivers/usb/host/xhci-mtk.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@
5656
/* u2_phy_pll register */
5757
#define CTRL_U2_FORCE_PLL_STB BIT(28)
5858

59+
/* xHCI CSR */
60+
#define LS_EOF_CFG 0x930
61+
#define LSEOF_OFFSET 0x89
62+
63+
#define FS_EOF_CFG 0x934
64+
#define FSEOF_OFFSET 0x2e
65+
66+
#define SS_GEN1_EOF_CFG 0x93c
67+
#define SSG1EOF_OFFSET 0x78
68+
69+
#define HFCNTR_CFG 0x944
70+
#define ITP_DELTA_CLK (0xa << 1)
71+
#define ITP_DELTA_CLK_MASK GENMASK(5, 1)
72+
#define FRMCNT_LEV1_RANG (0x12b << 8)
73+
#define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8)
74+
75+
#define SS_GEN2_EOF_CFG 0x990
76+
#define SSG2EOF_OFFSET 0x3c
77+
78+
#define XSEOF_OFFSET_MASK GENMASK(11, 0)
79+
5980
/* usb remote wakeup registers in syscon */
6081

6182
/* mt8173 etc */
@@ -86,6 +107,46 @@ enum ssusb_uwk_vers {
86107
SSUSB_UWK_V1_2, /* specific revision 1.2 */
87108
};
88109

110+
/*
111+
* MT8195 has 4 controllers, the controller1~3's default SOF/ITP interval
112+
* is calculated from the frame counter clock 24M, but in fact, the clock
113+
* is 48M, add workaround for it.
114+
*/
115+
static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk)
116+
{
117+
struct device *dev = mtk->dev;
118+
struct usb_hcd *hcd = mtk->hcd;
119+
u32 value;
120+
121+
if (!of_device_is_compatible(dev->of_node, "mediatek,mt8195-xhci"))
122+
return;
123+
124+
value = readl(hcd->regs + HFCNTR_CFG);
125+
value &= ~(ITP_DELTA_CLK_MASK | FRMCNT_LEV1_RANG_MASK);
126+
value |= (ITP_DELTA_CLK | FRMCNT_LEV1_RANG);
127+
writel(value, hcd->regs + HFCNTR_CFG);
128+
129+
value = readl(hcd->regs + LS_EOF_CFG);
130+
value &= ~XSEOF_OFFSET_MASK;
131+
value |= LSEOF_OFFSET;
132+
writel(value, hcd->regs + LS_EOF_CFG);
133+
134+
value = readl(hcd->regs + FS_EOF_CFG);
135+
value &= ~XSEOF_OFFSET_MASK;
136+
value |= FSEOF_OFFSET;
137+
writel(value, hcd->regs + FS_EOF_CFG);
138+
139+
value = readl(hcd->regs + SS_GEN1_EOF_CFG);
140+
value &= ~XSEOF_OFFSET_MASK;
141+
value |= SSG1EOF_OFFSET;
142+
writel(value, hcd->regs + SS_GEN1_EOF_CFG);
143+
144+
value = readl(hcd->regs + SS_GEN2_EOF_CFG);
145+
value &= ~XSEOF_OFFSET_MASK;
146+
value |= SSG2EOF_OFFSET;
147+
writel(value, hcd->regs + SS_GEN2_EOF_CFG);
148+
}
149+
89150
static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
90151
{
91152
struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
@@ -367,6 +428,9 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
367428
ret = xhci_mtk_ssusb_config(mtk);
368429
if (ret)
369430
return ret;
431+
432+
/* workaround only for mt8195 */
433+
xhci_mtk_set_frame_interval(mtk);
370434
}
371435

372436
ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
@@ -712,6 +776,7 @@ static const struct dev_pm_ops xhci_mtk_pm_ops = {
712776

713777
static const struct of_device_id mtk_xhci_of_match[] = {
714778
{ .compatible = "mediatek,mt8173-xhci"},
779+
{ .compatible = "mediatek,mt8195-xhci"},
715780
{ .compatible = "mediatek,mtk-xhci"},
716781
{ },
717782
};

0 commit comments

Comments
 (0)