0191-usb-xhci-allow-imod-interval-to-be-configurable.patch 5.4 KB

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