OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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 | @@ -277,6 +277,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; |