summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/core.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-01-20 14:01:31 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-01-20 14:01:31 -0300
commitb4b7ff4b08e691656c9d77c758fc355833128ac0 (patch)
tree82fcb00e6b918026dc9f2d1f05ed8eee83874cc0 /drivers/usb/dwc3/core.c
parent35acfa0fc609f2a2cd95cef4a6a9c3a5c38f1778 (diff)
Linux-libre 4.4-gnupck-4.4-gnu
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r--drivers/usb/dwc3/core.c88
1 files changed, 63 insertions, 25 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 51156ec91..22b479738 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -34,6 +34,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/acpi.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -143,6 +144,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc)
return 0;
}
+/*
+ * dwc3_frame_length_adjustment - Adjusts frame length if required
+ * @dwc3: Pointer to our controller context structure
+ * @fladj: Value of GFLADJ_30MHZ to adjust frame length
+ */
+static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
+{
+ u32 reg;
+ u32 dft;
+
+ if (dwc->revision < DWC3_REVISION_250A)
+ return;
+
+ if (fladj == 0)
+ return;
+
+ reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+ dft = reg & DWC3_GFLADJ_30MHZ_MASK;
+ if (!dev_WARN_ONCE(dwc->dev, dft == fladj,
+ "request value same as default, ignoring\n")) {
+ reg &= ~DWC3_GFLADJ_30MHZ_MASK;
+ reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj;
+ dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ }
+}
+
/**
* dwc3_free_one_event_buffer - Frees one event buffer
* @dwc: Pointer to our controller context structure
@@ -782,12 +809,12 @@ static int dwc3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dwc3_platform_data *pdata = dev_get_platdata(dev);
- struct device_node *node = dev->of_node;
struct resource *res;
struct dwc3 *dwc;
u8 lpm_nyet_threshold;
u8 tx_de_emphasis;
u8 hird_threshold;
+ u32 fladj = 0;
int ret;
@@ -851,53 +878,56 @@ static int dwc3_probe(struct platform_device *pdev)
*/
hird_threshold = 12;
- if (node) {
- dwc->maximum_speed = of_usb_get_maximum_speed(node);
- dwc->has_lpm_erratum = of_property_read_bool(node,
+ dwc->maximum_speed = usb_get_maximum_speed(dev);
+ dwc->dr_mode = usb_get_dr_mode(dev);
+
+ dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
- of_property_read_u8(node, "snps,lpm-nyet-threshold",
+ device_property_read_u8(dev, "snps,lpm-nyet-threshold",
&lpm_nyet_threshold);
- dwc->is_utmi_l1_suspend = of_property_read_bool(node,
+ dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
"snps,is-utmi-l1-suspend");
- of_property_read_u8(node, "snps,hird-threshold",
+ device_property_read_u8(dev, "snps,hird-threshold",
&hird_threshold);
- dwc->usb3_lpm_capable = of_property_read_bool(node,
+ dwc->usb3_lpm_capable = device_property_read_bool(dev,
"snps,usb3_lpm_capable");
- dwc->needs_fifo_resize = of_property_read_bool(node,
+ dwc->needs_fifo_resize = device_property_read_bool(dev,
"tx-fifo-resize");
- dwc->dr_mode = of_usb_get_dr_mode(node);
- dwc->disable_scramble_quirk = of_property_read_bool(node,
+ dwc->disable_scramble_quirk = device_property_read_bool(dev,
"snps,disable_scramble_quirk");
- dwc->u2exit_lfps_quirk = of_property_read_bool(node,
+ dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
"snps,u2exit_lfps_quirk");
- dwc->u2ss_inp3_quirk = of_property_read_bool(node,
+ dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
"snps,u2ss_inp3_quirk");
- dwc->req_p1p2p3_quirk = of_property_read_bool(node,
+ dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
"snps,req_p1p2p3_quirk");
- dwc->del_p1p2p3_quirk = of_property_read_bool(node,
+ dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
"snps,del_p1p2p3_quirk");
- dwc->del_phy_power_chg_quirk = of_property_read_bool(node,
+ dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
"snps,del_phy_power_chg_quirk");
- dwc->lfps_filter_quirk = of_property_read_bool(node,
+ dwc->lfps_filter_quirk = device_property_read_bool(dev,
"snps,lfps_filter_quirk");
- dwc->rx_detect_poll_quirk = of_property_read_bool(node,
+ dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
"snps,rx_detect_poll_quirk");
- dwc->dis_u3_susphy_quirk = of_property_read_bool(node,
+ dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
"snps,dis_u3_susphy_quirk");
- dwc->dis_u2_susphy_quirk = of_property_read_bool(node,
+ dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
"snps,dis_u2_susphy_quirk");
dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
"snps,dis_enblslpm_quirk");
- dwc->tx_de_emphasis_quirk = of_property_read_bool(node,
+ dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
- of_property_read_u8(node, "snps,tx_de_emphasis",
+ device_property_read_u8(dev, "snps,tx_de_emphasis",
&tx_de_emphasis);
- of_property_read_string(node, "snps,hsphy_interface",
- &dwc->hsphy_interface);
- } else if (pdata) {
+ device_property_read_string(dev, "snps,hsphy_interface",
+ &dwc->hsphy_interface);
+ device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
+ &fladj);
+
+ if (pdata) {
dwc->maximum_speed = pdata->maximum_speed;
dwc->has_lpm_erratum = pdata->has_lpm_erratum;
if (pdata->lpm_nyet_threshold)
@@ -927,6 +957,7 @@ static int dwc3_probe(struct platform_device *pdev)
tx_de_emphasis = pdata->tx_de_emphasis;
dwc->hsphy_interface = pdata->hsphy_interface;
+ fladj = pdata->fladj_value;
}
/* default to superspeed if no maximum_speed passed */
@@ -983,6 +1014,9 @@ static int dwc3_probe(struct platform_device *pdev)
goto err1;
}
+ /* Adjust Frame Length */
+ dwc3_frame_length_adjustment(dwc, fladj);
+
usb_phy_set_suspend(dwc->usb2_phy, 0);
usb_phy_set_suspend(dwc->usb3_phy, 0);
ret = phy_power_on(dwc->usb2_generic_phy);
@@ -1103,6 +1137,8 @@ static int dwc3_suspend(struct device *dev)
phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy);
+ pinctrl_pm_select_sleep_state(dev);
+
return 0;
}
@@ -1112,6 +1148,8 @@ static int dwc3_resume(struct device *dev)
unsigned long flags;
int ret;
+ pinctrl_pm_select_default_state(dev);
+
usb_phy_init(dwc->usb3_phy);
usb_phy_init(dwc->usb2_phy);
ret = phy_init(dwc->usb2_generic_phy);