aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorHuang Rui <ray.huang@amd.com>2014-10-28 07:54:26 -0400
committerFelipe Balbi <balbi@ti.com>2014-11-03 11:03:36 -0500
commit80caf7d21adca10c4621d511f6eb01f7ed2b342c (patch)
tree097bf706580823890264c4bb319f87fa1521a93a /drivers/usb/dwc3
parent3b81221a529c087171557d7c4aec02b0ba029bb1 (diff)
usb: dwc3: add lpm erratum support
When parameter DWC_USB3_LPM_ERRATA_ENABLE is enabled in Andvanced Configuration of coreConsultant, it supports of xHCI BESL Errata Dated 10/19/2011 is enabled in host mode. In device mode it adds the capability to send NYET response threshold based on the BESL value received in the LPM token, and the threhold is configurable for each soc platform. This patch adds an entry that soc platform is able to define the lpm capacity with their own device tree or bus glue layer. [ balbi@ti.com : added devicetree documentation, spelled threshold completely, made sure threshold is only applied to proper core revisions. ] Signed-off-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.c16
-rw-r--r--drivers/usb/dwc3/core.h26
-rw-r--r--drivers/usb/dwc3/gadget.c13
-rw-r--r--drivers/usb/dwc3/platform_data.h3
4 files changed, 48 insertions, 10 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a0ae1326b7e3..6f9e5b85977a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -657,6 +657,7 @@ static int dwc3_probe(struct platform_device *pdev)
657 struct device_node *node = dev->of_node; 657 struct device_node *node = dev->of_node;
658 struct resource *res; 658 struct resource *res;
659 struct dwc3 *dwc; 659 struct dwc3 *dwc;
660 u8 lpm_nyet_threshold;
660 661
661 int ret; 662 int ret;
662 663
@@ -712,16 +713,27 @@ static int dwc3_probe(struct platform_device *pdev)
712 */ 713 */
713 res->start -= DWC3_GLOBALS_REGS_START; 714 res->start -= DWC3_GLOBALS_REGS_START;
714 715
716 /* default to highest possible threshold */
717 lpm_nyet_threshold = 0xff;
718
715 if (node) { 719 if (node) {
716 dwc->maximum_speed = of_usb_get_maximum_speed(node); 720 dwc->maximum_speed = of_usb_get_maximum_speed(node);
721 dwc->has_lpm_erratum = of_property_read_bool(node,
722 "snps,has-lpm-erratum");
723 of_property_read_u8(node, "snps,lpm-nyet-threshold",
724 &lpm_nyet_threshold);
717 725
718 dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); 726 dwc->needs_fifo_resize = of_property_read_bool(node,
727 "tx-fifo-resize");
719 dwc->dr_mode = of_usb_get_dr_mode(node); 728 dwc->dr_mode = of_usb_get_dr_mode(node);
720 729
721 dwc->disable_scramble_quirk = of_property_read_bool(node, 730 dwc->disable_scramble_quirk = of_property_read_bool(node,
722 "snps,disable_scramble_quirk"); 731 "snps,disable_scramble_quirk");
723 } else if (pdata) { 732 } else if (pdata) {
724 dwc->maximum_speed = pdata->maximum_speed; 733 dwc->maximum_speed = pdata->maximum_speed;
734 dwc->has_lpm_erratum = pdata->has_lpm_erratum;
735 if (pdata->lpm_nyet_threshold)
736 lpm_nyet_threshold = pdata->lpm_nyet_threshold;
725 737
726 dwc->needs_fifo_resize = pdata->tx_fifo_resize; 738 dwc->needs_fifo_resize = pdata->tx_fifo_resize;
727 dwc->dr_mode = pdata->dr_mode; 739 dwc->dr_mode = pdata->dr_mode;
@@ -733,6 +745,8 @@ static int dwc3_probe(struct platform_device *pdev)
733 if (dwc->maximum_speed == USB_SPEED_UNKNOWN) 745 if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
734 dwc->maximum_speed = USB_SPEED_SUPER; 746 dwc->maximum_speed = USB_SPEED_SUPER;
735 747
748 dwc->lpm_nyet_threshold = lpm_nyet_threshold;
749
736 ret = dwc3_core_get_phy(dwc); 750 ret = dwc3_core_get_phy(dwc);
737 if (ret) 751 if (ret)
738 return ret; 752 return ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 56bada6c8604..34f1e08988fe 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -246,16 +246,19 @@
246#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) 246#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6))
247 247
248/* These apply for core versions 1.94a and later */ 248/* These apply for core versions 1.94a and later */
249#define DWC3_DCTL_KEEP_CONNECT (1 << 19) 249#define DWC3_DCTL_LPM_ERRATA_MASK DWC3_DCTL_LPM_ERRATA(0xf)
250#define DWC3_DCTL_L1_HIBER_EN (1 << 18) 250#define DWC3_DCTL_LPM_ERRATA(n) ((n) << 20)
251#define DWC3_DCTL_CRS (1 << 17)
252#define DWC3_DCTL_CSS (1 << 16)
253 251
254#define DWC3_DCTL_INITU2ENA (1 << 12) 252#define DWC3_DCTL_KEEP_CONNECT (1 << 19)
255#define DWC3_DCTL_ACCEPTU2ENA (1 << 11) 253#define DWC3_DCTL_L1_HIBER_EN (1 << 18)
256#define DWC3_DCTL_INITU1ENA (1 << 10) 254#define DWC3_DCTL_CRS (1 << 17)
257#define DWC3_DCTL_ACCEPTU1ENA (1 << 9) 255#define DWC3_DCTL_CSS (1 << 16)
258#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) 256
257#define DWC3_DCTL_INITU2ENA (1 << 12)
258#define DWC3_DCTL_ACCEPTU2ENA (1 << 11)
259#define DWC3_DCTL_INITU1ENA (1 << 10)
260#define DWC3_DCTL_ACCEPTU1ENA (1 << 9)
261#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1)
259 262
260#define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5) 263#define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5)
261#define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK) 264#define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK)
@@ -660,10 +663,13 @@ struct dwc3_scratchpad_array {
660 * @regset: debugfs pointer to regdump file 663 * @regset: debugfs pointer to regdump file
661 * @test_mode: true when we're entering a USB test mode 664 * @test_mode: true when we're entering a USB test mode
662 * @test_mode_nr: test feature selector 665 * @test_mode_nr: test feature selector
666 * @lpm_nyet_threshold: LPM NYET response threshold
663 * @delayed_status: true when gadget driver asks for delayed status 667 * @delayed_status: true when gadget driver asks for delayed status
664 * @ep0_bounced: true when we used bounce buffer 668 * @ep0_bounced: true when we used bounce buffer
665 * @ep0_expect_in: true when we expect a DATA IN transfer 669 * @ep0_expect_in: true when we expect a DATA IN transfer
666 * @has_hibernation: true when dwc3 was configured with Hibernation 670 * @has_hibernation: true when dwc3 was configured with Hibernation
671 * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that
672 * there's now way for software to detect this in runtime.
667 * @is_selfpowered: true when we are selfpowered 673 * @is_selfpowered: true when we are selfpowered
668 * @is_fpga: true when we are using the FPGA board 674 * @is_fpga: true when we are using the FPGA board
669 * @needs_fifo_resize: not all users might want fifo resizing, flag it 675 * @needs_fifo_resize: not all users might want fifo resizing, flag it
@@ -764,11 +770,13 @@ struct dwc3 {
764 770
765 u8 test_mode; 771 u8 test_mode;
766 u8 test_mode_nr; 772 u8 test_mode_nr;
773 u8 lpm_nyet_threshold;
767 774
768 unsigned delayed_status:1; 775 unsigned delayed_status:1;
769 unsigned ep0_bounced:1; 776 unsigned ep0_bounced:1;
770 unsigned ep0_expect_in:1; 777 unsigned ep0_expect_in:1;
771 unsigned has_hibernation:1; 778 unsigned has_hibernation:1;
779 unsigned has_lpm_erratum:1;
772 unsigned is_selfpowered:1; 780 unsigned is_selfpowered:1;
773 unsigned is_fpga:1; 781 unsigned is_fpga:1;
774 unsigned needs_fifo_resize:1; 782 unsigned needs_fifo_resize:1;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 20dda60b27c3..88a065f61150 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2301,6 +2301,19 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
2301 */ 2301 */
2302 reg |= DWC3_DCTL_HIRD_THRES(12); 2302 reg |= DWC3_DCTL_HIRD_THRES(12);
2303 2303
2304 /*
2305 * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and
2306 * DCFG.LPMCap is set, core responses with an ACK and the
2307 * BESL value in the LPM token is less than or equal to LPM
2308 * NYET threshold.
2309 */
2310 WARN_ONCE(dwc->revision < DWC3_REVISION_240A
2311 && dwc->has_lpm_erratum,
2312 "LPM Erratum not available on dwc3 revisisions < 2.40a\n");
2313
2314 if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A)
2315 reg |= DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold);
2316
2304 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 2317 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
2305 } else { 2318 } else {
2306 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 2319 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index 9209d025597b..e1283080a49f 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -25,5 +25,8 @@ struct dwc3_platform_data {
25 enum usb_dr_mode dr_mode; 25 enum usb_dr_mode dr_mode;
26 bool tx_fifo_resize; 26 bool tx_fifo_resize;
27 27
28 u8 lpm_nyet_threshold;
29
28 unsigned disable_scramble_quirk:1; 30 unsigned disable_scramble_quirk:1;
31 unsigned has_lpm_erratum:1;
29}; 32};