d28993ae38ce11a453d010ec57381f14f4130951
[openwrt/openwrt.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 --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
42 +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
43 @@ -46,6 +46,7 @@ Optional properties:
44 - pinctrl-names : a pinctrl state named "default" must be defined
45 - pinctrl-0 : pin control group
46 See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
47 + - imod-interval-ns: default interrupt moderation interval is 5000ns
48
49 Example:
50 usb30: usb@11270000 {
51 @@ -66,6 +67,7 @@ usb30: usb@11270000 {
52 usb3-lpm-capable;
53 mediatek,syscon-wakeup = <&pericfg>;
54 mediatek,wakeup-src = <1>;
55 + imod-interval-ns = <10000>;
56 };
57
58 2nd: dual-role mode with xHCI driver
59 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
60 +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
61 @@ -29,6 +29,7 @@ Optional properties:
62 - clocks: reference to a clock
63 - usb3-lpm-capable: determines if platform is USB3 LPM capable
64 - quirk-broken-port-ped: set if the controller has broken port disable mechanism
65 + - imod-interval-ns: default interrupt moderation interval is 5000ns
66
67 Example:
68 usb@f0931000 {
69 --- a/drivers/usb/host/xhci-mtk.c
70 +++ b/drivers/usb/host/xhci-mtk.c
71 @@ -629,6 +629,15 @@ static int xhci_mtk_probe(struct platfor
72
73 xhci = hcd_to_xhci(hcd);
74 xhci->main_hcd = hcd;
75 +
76 + /*
77 + * imod_interval is the interrupt moderation value in nanoseconds.
78 + * The increment interval is 8 times as much as that defined in
79 + * the xHCI spec on MTK's controller.
80 + */
81 + xhci->imod_interval = 5000;
82 + device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval);
83 +
84 xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
85 dev_name(dev), hcd);
86 if (!xhci->shared_hcd) {
87 --- a/drivers/usb/host/xhci-pci.c
88 +++ b/drivers/usb/host/xhci-pci.c
89 @@ -273,6 +273,9 @@ static int xhci_pci_setup(struct usb_hcd
90 if (!xhci->sbrn)
91 pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
92
93 + /* imod_interval is the interrupt moderation value in nanoseconds. */
94 + xhci->imod_interval = 40000;
95 +
96 retval = xhci_gen_setup(hcd, xhci_pci_quirks);
97 if (retval)
98 return retval;
99 --- a/drivers/usb/host/xhci-plat.c
100 +++ b/drivers/usb/host/xhci-plat.c
101 @@ -269,6 +269,11 @@ static int xhci_plat_probe(struct platfo
102 if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
103 xhci->quirks |= XHCI_BROKEN_PORT_PED;
104
105 + /* imod_interval is the interrupt moderation value in nanoseconds. */
106 + xhci->imod_interval = 40000;
107 + device_property_read_u32(sysdev, "imod-interval-ns",
108 + &xhci->imod_interval);
109 +
110 hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
111 if (IS_ERR(hcd->usb_phy)) {
112 ret = PTR_ERR(hcd->usb_phy);
113 --- a/drivers/usb/host/xhci.c
114 +++ b/drivers/usb/host/xhci.c
115 @@ -612,11 +612,7 @@ int xhci_run(struct usb_hcd *hcd)
116 "// Set the interrupt modulation register");
117 temp = readl(&xhci->ir_set->irq_control);
118 temp &= ~ER_IRQ_INTERVAL_MASK;
119 - /*
120 - * the increment interval is 8 times as much as that defined
121 - * in xHCI spec on MTK's controller
122 - */
123 - temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
124 + temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
125 writel(temp, &xhci->ir_set->irq_control);
126
127 /* Set the HCD state before we enable the irqs */
128 --- a/drivers/usb/host/xhci.h
129 +++ b/drivers/usb/host/xhci.h
130 @@ -1730,6 +1730,8 @@ struct xhci_hcd {
131 u8 max_interrupters;
132 u8 max_ports;
133 u8 isoc_threshold;
134 + /* imod_interval in ns (I * 250ns) */
135 + u32 imod_interval;
136 int event_ring_max;
137 /* 4KB min, 128MB max */
138 int page_size;