aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorAustin Beam <austinbeam@ti.com>2014-03-06 07:41:53 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2014-03-09 03:15:07 -0400
commit7e472402ca308287a2474d4c9011f69f33fa19cb (patch)
tree6d209c68dff18d6ee80daae357217f5e3f208dae /drivers/phy
parent09a0168de11a4a487c2d1c78366491b695e0c15a (diff)
phy: omap-usb2: Provide workaround for USB2PHY false disconnect
Enable the dra7x errata workaround for false disconnect problem with USB2PHY. False disconnects were detected with some of the devices. Reduce the sensitivity of the disconnect logic within the USB2PHY subsystem to enusre these false disconnects are not registered. [george.cherian@ti.com] While at that, pass proper flags for each SoC's. This is a common driver used across OMAP4,OMAP5,DRA7xx and AM437x USB2PHY. False disconnect workaround is currently applicable for only DRA7x. Signed-off-by: Austin Beam <austinbeam@ti.com> Signed-off-by: George Cherian <george.cherian@ti.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-omap-usb2.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 0c78f54d0650..b220202a3f30 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -31,6 +31,9 @@
31#include <linux/phy/phy.h> 31#include <linux/phy/phy.h>
32#include <linux/of_platform.h> 32#include <linux/of_platform.h>
33 33
34#define USB2PHY_DISCON_BYP_LATCH (1 << 31)
35#define USB2PHY_ANA_CONFIG1 0x4c
36
34/** 37/**
35 * omap_usb2_set_comparator - links the comparator present in the sytem with 38 * omap_usb2_set_comparator - links the comparator present in the sytem with
36 * this phy 39 * this phy
@@ -116,7 +119,30 @@ static int omap_usb_power_on(struct phy *x)
116 return 0; 119 return 0;
117} 120}
118 121
122static int omap_usb_init(struct phy *x)
123{
124 struct omap_usb *phy = phy_get_drvdata(x);
125 u32 val;
126
127 if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
128 /*
129 *
130 * Reduce the sensitivity of internal PHY by enabling the
131 * DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This
132 * resolves issues with certain devices which can otherwise
133 * be prone to false disconnects.
134 *
135 */
136 val = omap_usb_readl(phy->phy_base, USB2PHY_ANA_CONFIG1);
137 val |= USB2PHY_DISCON_BYP_LATCH;
138 omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val);
139 }
140
141 return 0;
142}
143
119static struct phy_ops ops = { 144static struct phy_ops ops = {
145 .init = omap_usb_init,
120 .power_on = omap_usb_power_on, 146 .power_on = omap_usb_power_on,
121 .power_off = omap_usb_power_off, 147 .power_off = omap_usb_power_off,
122 .owner = THIS_MODULE, 148 .owner = THIS_MODULE,
@@ -128,6 +154,11 @@ static const struct usb_phy_data omap_usb2_data = {
128 .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, 154 .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS,
129}; 155};
130 156
157static const struct usb_phy_data dra7x_usb2_data = {
158 .label = "dra7x_usb2",
159 .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT,
160};
161
131static const struct usb_phy_data am437x_usb2_data = { 162static const struct usb_phy_data am437x_usb2_data = {
132 .label = "am437x_usb2", 163 .label = "am437x_usb2",
133 .flags = 0, 164 .flags = 0,
@@ -139,6 +170,10 @@ static const struct of_device_id omap_usb2_id_table[] = {
139 .data = &omap_usb2_data, 170 .data = &omap_usb2_data,
140 }, 171 },
141 { 172 {
173 .compatible = "ti,dra7x-usb2",
174 .data = &dra7x_usb2_data,
175 },
176 {
142 .compatible = "ti,am437x-usb2", 177 .compatible = "ti,am437x-usb2",
143 .data = &am437x_usb2_data, 178 .data = &am437x_usb2_data,
144 }, 179 },
@@ -151,6 +186,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
151{ 186{
152 struct omap_usb *phy; 187 struct omap_usb *phy;
153 struct phy *generic_phy; 188 struct phy *generic_phy;
189 struct resource *res;
154 struct phy_provider *phy_provider; 190 struct phy_provider *phy_provider;
155 struct usb_otg *otg; 191 struct usb_otg *otg;
156 struct device_node *node = pdev->dev.of_node; 192 struct device_node *node = pdev->dev.of_node;
@@ -185,6 +221,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
185 phy->phy.otg = otg; 221 phy->phy.otg = otg;
186 phy->phy.type = USB_PHY_TYPE_USB2; 222 phy->phy.type = USB_PHY_TYPE_USB2;
187 223
224 if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
225 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
226 phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
227 if (!phy->phy_base)
228 return -ENOMEM;
229 phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
230 }
231
188 control_node = of_parse_phandle(node, "ctrl-module", 0); 232 control_node = of_parse_phandle(node, "ctrl-module", 0);
189 if (!control_node) { 233 if (!control_node) {
190 dev_err(&pdev->dev, "Failed to get control device phandle\n"); 234 dev_err(&pdev->dev, "Failed to get control device phandle\n");