mediatek: backport upstream mediatek patches
[openwrt/staging/hauke.git] / target / linux / mediatek / patches-4.14 / 0191-usb-xhci-allow-imod-interval-to-be-configurable.patch
1 From c5c72d252dc8e417388386d5767ea790ee8f5b44 Mon Sep 17 00:00:00 2001
2 From: Adam Wallis <awallis@codeaurora.org>
3 Date: Fri, 8 Dec 2017 17:59:13 +0200
4 Subject: [PATCH 191/224] usb: xhci: allow imod-interval to be configurable
5
6 The xHCI driver currently has the IMOD set to 160, which
7 translates to an IMOD interval of 40,000ns (160 * 250)ns
8
9 Commit 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller")
10 introduced a QUIRK for the MTK platform to adjust this interval to 20,
11 which translates to an IMOD interval of 5,000ns (20 * 250)ns. This is
12 due to the fact that the MTK controller IMOD interval is 8 times
13 as much as defined in xHCI spec.
14
15 Instead of adding more quirk bits for additional platforms, this patch
16 introduces the ability for vendors to set the IMOD_INTERVAL as is
17 optimal for their platform. By using device_property_read_u32() on
18 "imod-interval-ns", the IMOD INTERVAL can be specified in nano seconds.
19 If no interval is specified, the default of 40,000ns (IMOD=160) will be
20 used.
21
22 No bounds checking has been implemented due to the fact that a vendor
23 may have violated the spec and would need to specify a value outside of
24 the max 8,000 IRQs/second limit specified in the xHCI spec.
25
26 Tested-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
27 Reviewed-by: Rob Herring <robh@kernel.org>
28 Signed-off-by: Adam Wallis <awallis@codeaurora.org>
29 Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 ---
32 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt | 2 ++
33 Documentation/devicetree/bindings/usb/usb-xhci.txt | 1 +
34 drivers/usb/host/xhci-mtk.c | 9 +++++++++
35 drivers/usb/host/xhci-pci.c | 3 +++
36 drivers/usb/host/xhci-plat.c | 5 +++++
37 drivers/usb/host/xhci.c | 6 +-----
38 drivers/usb/host/xhci.h | 2 ++
39 7 files changed, 23 insertions(+), 5 deletions(-)
40
41 diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
42 index 30595964876a..9ff560298498 100644
43 --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
44 +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
45 @@ -46,6 +46,7 @@ Optional properties:
46 - pinctrl-names : a pinctrl state named "default" must be defined
47 - pinctrl-0 : pin control group
48 See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
49 + - imod-interval-ns: default interrupt moderation interval is 5000ns
50
51 Example:
52 usb30: usb@11270000 {
53 @@ -66,6 +67,7 @@ usb30: usb@11270000 {
54 usb3-lpm-capable;
55 mediatek,syscon-wakeup = <&pericfg>;
56 mediatek,wakeup-src = <1>;
57 + imod-interval-ns = <10000>;
58 };
59
60 2nd: dual-role mode with xHCI driver
61 diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
62 index 2d80b60eeabe..2390ae58636b 100644
63 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
64 +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
65 @@ -28,6 +28,7 @@ Optional properties:
66 - clocks: reference to a clock
67 - usb3-lpm-capable: determines if platform is USB3 LPM capable
68 - quirk-broken-port-ped: set if the controller has broken port disable mechanism
69 + - imod-interval-ns: default interrupt moderation interval is 5000ns
70
71 Example:
72 usb@f0931000 {
73 diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
74 index 8e51b3fec386..8e4495be6592 100644
75 --- a/drivers/usb/host/xhci-mtk.c
76 +++ b/drivers/usb/host/xhci-mtk.c
77 @@ -629,6 +629,15 @@ static int xhci_mtk_probe(struct platform_device *pdev)
78
79 xhci = hcd_to_xhci(hcd);
80 xhci->main_hcd = hcd;
81 +
82 + /*
83 + * imod_interval is the interrupt moderation value in nanoseconds.
84 + * The increment interval is 8 times as much as that defined in
85 + * the xHCI spec on MTK's controller.
86 + */
87 + xhci->imod_interval = 5000;
88 + device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval);
89 +
90 xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
91 dev_name(dev), hcd);
92 if (!xhci->shared_hcd) {
93 diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
94 index 8071c8fdd15e..cdd7d7bdfc0f 100644
95 --- a/drivers/usb/host/xhci-pci.c
96 +++ b/drivers/usb/host/xhci-pci.c
97 @@ -258,6 +258,9 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
98 if (!xhci->sbrn)
99 pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
100
101 + /* imod_interval is the interrupt moderation value in nanoseconds. */
102 + xhci->imod_interval = 40000;
103 +
104 retval = xhci_gen_setup(hcd, xhci_pci_quirks);
105 if (retval)
106 return retval;
107 diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
108 index 163bafde709f..47230453a876 100644
109 --- a/drivers/usb/host/xhci-plat.c
110 +++ b/drivers/usb/host/xhci-plat.c
111 @@ -265,6 +265,11 @@ static int xhci_plat_probe(struct platform_device *pdev)
112 if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
113 xhci->quirks |= XHCI_BROKEN_PORT_PED;
114
115 + /* imod_interval is the interrupt moderation value in nanoseconds. */
116 + xhci->imod_interval = 40000;
117 + device_property_read_u32(sysdev, "imod-interval-ns",
118 + &xhci->imod_interval);
119 +
120 hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
121 if (IS_ERR(hcd->usb_phy)) {
122 ret = PTR_ERR(hcd->usb_phy);
123 diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
124 index b2ff1ff1a02f..ac1b26a81e77 100644
125 --- a/drivers/usb/host/xhci.c
126 +++ b/drivers/usb/host/xhci.c
127 @@ -597,11 +597,7 @@ int xhci_run(struct usb_hcd *hcd)
128 "// Set the interrupt modulation register");
129 temp = readl(&xhci->ir_set->irq_control);
130 temp &= ~ER_IRQ_INTERVAL_MASK;
131 - /*
132 - * the increment interval is 8 times as much as that defined
133 - * in xHCI spec on MTK's controller
134 - */
135 - temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
136 + temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
137 writel(temp, &xhci->ir_set->irq_control);
138
139 /* Set the HCD state before we enable the irqs */
140 diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
141 index 2abaa4d6d39d..614380af0f96 100644
142 --- a/drivers/usb/host/xhci.h
143 +++ b/drivers/usb/host/xhci.h
144 @@ -1723,6 +1723,8 @@ struct xhci_hcd {
145 u8 max_interrupters;
146 u8 max_ports;
147 u8 isoc_threshold;
148 + /* imod_interval in ns (I * 250ns) */
149 + u32 imod_interval;
150 int event_ring_max;
151 /* 4KB min, 128MB max */
152 int page_size;
153 --
154 2.11.0
155