aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c15
-rw-r--r--drivers/usb/dwc3/core.h5
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c66
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c66
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c67
-rw-r--r--drivers/usb/host/ehci-tegra.c14
-rw-r--r--drivers/usb/musb/am35x.c1
-rw-r--r--drivers/usb/musb/blackfin.c1
-rw-r--r--drivers/usb/musb/da8xx.c1
-rw-r--r--drivers/usb/musb/davinci.c1
-rw-r--r--drivers/usb/musb/musb_dsps.c1
-rw-r--r--drivers/usb/musb/tusb6010.c1
-rw-r--r--drivers/usb/otg/Kconfig2
-rw-r--r--drivers/usb/otg/fsl_otg.c34
-rw-r--r--drivers/usb/otg/mxs-phy.c38
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c8
-rw-r--r--drivers/usb/otg/otg.c2
-rw-r--r--drivers/usb/otg/twl4030-usb.c26
-rw-r--r--drivers/usb/otg/twl6030-usb.c157
-rw-r--r--drivers/usb/phy/Kconfig17
-rw-r--r--drivers/usb/phy/Makefile3
-rw-r--r--drivers/usb/phy/isp1301.c6
-rw-r--r--drivers/usb/phy/mv_u3d_phy.c345
-rw-r--r--drivers/usb/phy/mv_u3d_phy.h105
-rw-r--r--drivers/usb/phy/omap-usb2.c271
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c839
26 files changed, 1945 insertions, 147 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a68ff53124dc..66d15c2d6b62 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -50,6 +50,7 @@
50#include <linux/dma-mapping.h> 50#include <linux/dma-mapping.h>
51#include <linux/of.h> 51#include <linux/of.h>
52 52
53#include <linux/usb/otg.h>
53#include <linux/usb/ch9.h> 54#include <linux/usb/ch9.h>
54#include <linux/usb/gadget.h> 55#include <linux/usb/gadget.h>
55 56
@@ -136,6 +137,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
136 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; 137 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
137 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 138 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
138 139
140 usb_phy_init(dwc->usb2_phy);
141 usb_phy_init(dwc->usb3_phy);
139 mdelay(100); 142 mdelay(100);
140 143
141 /* Clear USB3 PHY reset */ 144 /* Clear USB3 PHY reset */
@@ -470,6 +473,18 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
470 return -ENOMEM; 473 return -ENOMEM;
471 } 474 }
472 475
476 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
477 if (IS_ERR_OR_NULL(dwc->usb2_phy)) {
478 dev_err(dev, "no usb2 phy configured\n");
479 return -EPROBE_DEFER;
480 }
481
482 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
483 if (IS_ERR_OR_NULL(dwc->usb3_phy)) {
484 dev_err(dev, "no usb3 phy configured\n");
485 return -EPROBE_DEFER;
486 }
487
473 spin_lock_init(&dwc->lock); 488 spin_lock_init(&dwc->lock);
474 platform_set_drvdata(pdev, dwc); 489 platform_set_drvdata(pdev, dwc);
475 490
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 151eca876dfd..dbc5713d84fb 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -624,6 +624,8 @@ struct dwc3_scratchpad_array {
624 * @maximum_speed: maximum speed requested (mainly for testing purposes) 624 * @maximum_speed: maximum speed requested (mainly for testing purposes)
625 * @revision: revision register contents 625 * @revision: revision register contents
626 * @mode: mode of operation 626 * @mode: mode of operation
627 * @usb2_phy: pointer to USB2 PHY
628 * @usb3_phy: pointer to USB3 PHY
627 * @is_selfpowered: true when we are selfpowered 629 * @is_selfpowered: true when we are selfpowered
628 * @three_stage_setup: set if we perform a three phase setup 630 * @three_stage_setup: set if we perform a three phase setup
629 * @ep0_bounced: true when we used bounce buffer 631 * @ep0_bounced: true when we used bounce buffer
@@ -667,6 +669,9 @@ struct dwc3 {
667 struct usb_gadget gadget; 669 struct usb_gadget gadget;
668 struct usb_gadget_driver *gadget_driver; 670 struct usb_gadget_driver *gadget_driver;
669 671
672 struct usb_phy *usb2_phy;
673 struct usb_phy *usb3_phy;
674
670 void __iomem *regs; 675 void __iomem *regs;
671 size_t regs_size; 676 size_t regs_size;
672 677
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index b8f00389fa34..ca6597853f90 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -19,16 +19,74 @@
19#include <linux/platform_data/dwc3-exynos.h> 19#include <linux/platform_data/dwc3-exynos.h>
20#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/usb/otg.h>
23#include <linux/usb/nop-usb-xceiv.h>
22 24
23#include "core.h" 25#include "core.h"
24 26
25struct dwc3_exynos { 27struct dwc3_exynos {
26 struct platform_device *dwc3; 28 struct platform_device *dwc3;
29 struct platform_device *usb2_phy;
30 struct platform_device *usb3_phy;
27 struct device *dev; 31 struct device *dev;
28 32
29 struct clk *clk; 33 struct clk *clk;
30}; 34};
31 35
36static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
37{
38 struct nop_usb_xceiv_platform_data pdata;
39 struct platform_device *pdev;
40 int ret;
41
42 memset(&pdata, 0x00, sizeof(pdata));
43
44 pdev = platform_device_alloc("nop_usb_xceiv", 0);
45 if (!pdev)
46 return -ENOMEM;
47
48 exynos->usb2_phy = pdev;
49 pdata.type = USB_PHY_TYPE_USB2;
50
51 ret = platform_device_add_data(exynos->usb2_phy, &pdata, sizeof(pdata));
52 if (ret)
53 goto err1;
54
55 pdev = platform_device_alloc("nop_usb_xceiv", 1);
56 if (!pdev) {
57 ret = -ENOMEM;
58 goto err1;
59 }
60
61 exynos->usb3_phy = pdev;
62 pdata.type = USB_PHY_TYPE_USB3;
63
64 ret = platform_device_add_data(exynos->usb3_phy, &pdata, sizeof(pdata));
65 if (ret)
66 goto err2;
67
68 ret = platform_device_add(exynos->usb2_phy);
69 if (ret)
70 goto err2;
71
72 ret = platform_device_add(exynos->usb3_phy);
73 if (ret)
74 goto err3;
75
76 return 0;
77
78err3:
79 platform_device_del(exynos->usb2_phy);
80
81err2:
82 platform_device_put(exynos->usb3_phy);
83
84err1:
85 platform_device_put(exynos->usb2_phy);
86
87 return ret;
88}
89
32static int __devinit dwc3_exynos_probe(struct platform_device *pdev) 90static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
33{ 91{
34 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 92 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
@@ -51,6 +109,12 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
51 if (devid < 0) 109 if (devid < 0)
52 goto err1; 110 goto err1;
53 111
112 ret = dwc3_exynos_register_phys(exynos);
113 if (ret) {
114 dev_err(&pdev->dev, "couldn't register PHYs\n");
115 goto err1;
116 }
117
54 dwc3 = platform_device_alloc("dwc3", devid); 118 dwc3 = platform_device_alloc("dwc3", devid);
55 if (!dwc3) { 119 if (!dwc3) {
56 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); 120 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
@@ -120,6 +184,8 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
120 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 184 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
121 185
122 platform_device_unregister(exynos->dwc3); 186 platform_device_unregister(exynos->dwc3);
187 platform_device_unregister(exynos->usb2_phy);
188 platform_device_unregister(exynos->usb3_phy);
123 189
124 dwc3_put_device_id(exynos->dwc3->id); 190 dwc3_put_device_id(exynos->dwc3->id);
125 191
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 479dc047da3a..ee57a10d90d0 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -48,6 +48,9 @@
48#include <linux/io.h> 48#include <linux/io.h>
49#include <linux/of.h> 49#include <linux/of.h>
50 50
51#include <linux/usb/otg.h>
52#include <linux/usb/nop-usb-xceiv.h>
53
51#include "core.h" 54#include "core.h"
52 55
53/* 56/*
@@ -131,6 +134,8 @@ struct dwc3_omap {
131 spinlock_t lock; 134 spinlock_t lock;
132 135
133 struct platform_device *dwc3; 136 struct platform_device *dwc3;
137 struct platform_device *usb2_phy;
138 struct platform_device *usb3_phy;
134 struct device *dev; 139 struct device *dev;
135 140
136 int irq; 141 int irq;
@@ -152,6 +157,59 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
152 writel(value, base + offset); 157 writel(value, base + offset);
153} 158}
154 159
160static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap)
161{
162 struct nop_usb_xceiv_platform_data pdata;
163 struct platform_device *pdev;
164 int ret;
165
166 memset(&pdata, 0x00, sizeof(pdata));
167
168 pdev = platform_device_alloc("nop_usb_xceiv", 0);
169 if (!pdev)
170 return -ENOMEM;
171
172 omap->usb2_phy = pdev;
173 pdata.type = USB_PHY_TYPE_USB2;
174
175 ret = platform_device_add_data(omap->usb2_phy, &pdata, sizeof(pdata));
176 if (ret)
177 goto err1;
178
179 pdev = platform_device_alloc("nop_usb_xceiv", 1);
180 if (!pdev) {
181 ret = -ENOMEM;
182 goto err1;
183 }
184
185 omap->usb3_phy = pdev;
186 pdata.type = USB_PHY_TYPE_USB3;
187
188 ret = platform_device_add_data(omap->usb3_phy, &pdata, sizeof(pdata));
189 if (ret)
190 goto err2;
191
192 ret = platform_device_add(omap->usb2_phy);
193 if (ret)
194 goto err2;
195
196 ret = platform_device_add(omap->usb3_phy);
197 if (ret)
198 goto err3;
199
200 return 0;
201
202err3:
203 platform_device_del(omap->usb2_phy);
204
205err2:
206 platform_device_put(omap->usb3_phy);
207
208err1:
209 platform_device_put(omap->usb2_phy);
210
211 return ret;
212}
155 213
156static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) 214static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
157{ 215{
@@ -251,6 +309,12 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
251 return -ENOMEM; 309 return -ENOMEM;
252 } 310 }
253 311
312 ret = dwc3_omap_register_phys(omap);
313 if (ret) {
314 dev_err(dev, "couldn't register PHYs\n");
315 return ret;
316 }
317
254 devid = dwc3_get_device_id(); 318 devid = dwc3_get_device_id();
255 if (devid < 0) 319 if (devid < 0)
256 return -ENODEV; 320 return -ENODEV;
@@ -371,6 +435,8 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev)
371 struct dwc3_omap *omap = platform_get_drvdata(pdev); 435 struct dwc3_omap *omap = platform_get_drvdata(pdev);
372 436
373 platform_device_unregister(omap->dwc3); 437 platform_device_unregister(omap->dwc3);
438 platform_device_unregister(omap->usb2_phy);
439 platform_device_unregister(omap->usb3_phy);
374 440
375 dwc3_put_device_id(omap->dwc3->id); 441 dwc3_put_device_id(omap->dwc3->id);
376 442
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index a9ca9adba391..94f550e37f98 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -42,6 +42,9 @@
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44 44
45#include <linux/usb/otg.h>
46#include <linux/usb/nop-usb-xceiv.h>
47
45#include "core.h" 48#include "core.h"
46 49
47/* FIXME define these in <linux/pci_ids.h> */ 50/* FIXME define these in <linux/pci_ids.h> */
@@ -51,8 +54,64 @@
51struct dwc3_pci { 54struct dwc3_pci {
52 struct device *dev; 55 struct device *dev;
53 struct platform_device *dwc3; 56 struct platform_device *dwc3;
57 struct platform_device *usb2_phy;
58 struct platform_device *usb3_phy;
54}; 59};
55 60
61static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue)
62{
63 struct nop_usb_xceiv_platform_data pdata;
64 struct platform_device *pdev;
65 int ret;
66
67 memset(&pdata, 0x00, sizeof(pdata));
68
69 pdev = platform_device_alloc("nop_usb_xceiv", 0);
70 if (!pdev)
71 return -ENOMEM;
72
73 glue->usb2_phy = pdev;
74 pdata.type = USB_PHY_TYPE_USB2;
75
76 ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata));
77 if (ret)
78 goto err1;
79
80 pdev = platform_device_alloc("nop_usb_xceiv", 1);
81 if (!pdev) {
82 ret = -ENOMEM;
83 goto err1;
84 }
85
86 glue->usb3_phy = pdev;
87 pdata.type = USB_PHY_TYPE_USB3;
88
89 ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata));
90 if (ret)
91 goto err2;
92
93 ret = platform_device_add(glue->usb2_phy);
94 if (ret)
95 goto err2;
96
97 ret = platform_device_add(glue->usb3_phy);
98 if (ret)
99 goto err3;
100
101 return 0;
102
103err3:
104 platform_device_del(glue->usb2_phy);
105
106err2:
107 platform_device_put(glue->usb3_phy);
108
109err1:
110 platform_device_put(glue->usb2_phy);
111
112 return ret;
113}
114
56static int __devinit dwc3_pci_probe(struct pci_dev *pci, 115static int __devinit dwc3_pci_probe(struct pci_dev *pci,
57 const struct pci_device_id *id) 116 const struct pci_device_id *id)
58{ 117{
@@ -80,6 +139,12 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
80 pci_set_power_state(pci, PCI_D0); 139 pci_set_power_state(pci, PCI_D0);
81 pci_set_master(pci); 140 pci_set_master(pci);
82 141
142 ret = dwc3_pci_register_phys(glue);
143 if (ret) {
144 dev_err(dev, "couldn't register PHYs\n");
145 return ret;
146 }
147
83 devid = dwc3_get_device_id(); 148 devid = dwc3_get_device_id();
84 if (devid < 0) { 149 if (devid < 0) {
85 ret = -ENOMEM; 150 ret = -ENOMEM;
@@ -144,6 +209,8 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci)
144{ 209{
145 struct dwc3_pci *glue = pci_get_drvdata(pci); 210 struct dwc3_pci *glue = pci_get_drvdata(pci);
146 211
212 platform_device_unregister(glue->usb2_phy);
213 platform_device_unregister(glue->usb3_phy);
147 dwc3_put_device_id(glue->dwc3->id); 214 dwc3_put_device_id(glue->dwc3->id);
148 platform_device_unregister(glue->dwc3); 215 platform_device_unregister(glue->dwc3);
149 pci_set_drvdata(pci, NULL); 216 pci_set_drvdata(pci, NULL);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 26dedb30ad0b..c0d47323b52a 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -27,7 +27,7 @@
27#include <linux/of_gpio.h> 27#include <linux/of_gpio.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29 29
30#include <mach/usb_phy.h> 30#include <linux/usb/tegra_usb_phy.h>
31#include <mach/iomap.h> 31#include <mach/iomap.h>
32 32
33#define TEGRA_USB_DMA_ALIGN 32 33#define TEGRA_USB_DMA_ALIGN 32
@@ -49,7 +49,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
49 49
50 clk_prepare_enable(tegra->emc_clk); 50 clk_prepare_enable(tegra->emc_clk);
51 clk_prepare_enable(tegra->clk); 51 clk_prepare_enable(tegra->clk);
52 tegra_usb_phy_power_on(tegra->phy); 52 usb_phy_set_suspend(&tegra->phy->u_phy, 0);
53 tegra->host_resumed = 1; 53 tegra->host_resumed = 1;
54} 54}
55 55
@@ -58,7 +58,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
58 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 58 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
59 59
60 tegra->host_resumed = 0; 60 tegra->host_resumed = 0;
61 tegra_usb_phy_power_off(tegra->phy); 61 usb_phy_set_suspend(&tegra->phy->u_phy, 1);
62 clk_disable_unprepare(tegra->clk); 62 clk_disable_unprepare(tegra->clk);
63 clk_disable_unprepare(tegra->emc_clk); 63 clk_disable_unprepare(tegra->emc_clk);
64} 64}
@@ -715,7 +715,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
715 goto fail_phy; 715 goto fail_phy;
716 } 716 }
717 717
718 err = tegra_usb_phy_power_on(tegra->phy); 718 usb_phy_init(&tegra->phy->u_phy);
719
720 err = usb_phy_set_suspend(&tegra->phy->u_phy, 0);
719 if (err) { 721 if (err) {
720 dev_err(&pdev->dev, "Failed to power on the phy\n"); 722 dev_err(&pdev->dev, "Failed to power on the phy\n");
721 goto fail; 723 goto fail;
@@ -762,7 +764,7 @@ fail:
762 usb_put_phy(tegra->transceiver); 764 usb_put_phy(tegra->transceiver);
763 } 765 }
764#endif 766#endif
765 tegra_usb_phy_close(tegra->phy); 767 usb_phy_shutdown(&tegra->phy->u_phy);
766fail_phy: 768fail_phy:
767 iounmap(hcd->regs); 769 iounmap(hcd->regs);
768fail_io: 770fail_io:
@@ -800,7 +802,7 @@ static int tegra_ehci_remove(struct platform_device *pdev)
800 802
801 usb_remove_hcd(hcd); 803 usb_remove_hcd(hcd);
802 804
803 tegra_usb_phy_close(tegra->phy); 805 usb_phy_shutdown(&tegra->phy->u_phy);
804 iounmap(hcd->regs); 806 iounmap(hcd->regs);
805 807
806 usb_put_hcd(hcd); 808 usb_put_hcd(hcd);
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 7a95ab87ac00..5d64c5b5ef52 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <plat/usb.h> 38#include <plat/usb.h>
38 39
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 428e6aa3e78a..b562623a8971 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
21#include <linux/prefetch.h> 21#include <linux/prefetch.h>
22#include <linux/usb/nop-usb-xceiv.h>
22 23
23#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
24 25
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 0f9fcec4e1d3..16798c9e6f38 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <mach/da8xx.h> 38#include <mach/da8xx.h>
38#include <mach/usb.h> 39#include <mach/usb.h>
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 472c8b42d38b..863a9b6286c3 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -33,6 +33,7 @@
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <mach/cputype.h> 38#include <mach/cputype.h>
38#include <mach/hardware.h> 39#include <mach/hardware.h>
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 494772fc9e23..c20b8776aafa 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -36,6 +36,7 @@
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/pm_runtime.h> 37#include <linux/pm_runtime.h>
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/usb/nop-usb-xceiv.h>
39 40
40#include <linux/of.h> 41#include <linux/of.h>
41#include <linux/of_device.h> 42#include <linux/of_device.h>
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 341625442377..c38dab190c9b 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -24,6 +24,7 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/usb/nop-usb-xceiv.h>
27 28
28#include "musb_core.h" 29#include "musb_core.h"
29 30
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 13fd1ddf742f..d8c8a42bff3e 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -68,7 +68,7 @@ config TWL4030_USB
68 68
69config TWL6030_USB 69config TWL6030_USB
70 tristate "TWL6030 USB Transceiver Driver" 70 tristate "TWL6030 USB Transceiver Driver"
71 depends on TWL4030_CORE 71 depends on TWL4030_CORE && OMAP_USB2
72 select USB_OTG_UTILS 72 select USB_OTG_UTILS
73 help 73 help
74 Enable this to support the USB OTG transceiver on TWL6030 74 Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c
index 23c798cb2d7f..c19d1d7173a9 100644
--- a/drivers/usb/otg/fsl_otg.c
+++ b/drivers/usb/otg/fsl_otg.c
@@ -544,9 +544,13 @@ int fsl_otg_start_gadget(struct otg_fsm *fsm, int on)
544 */ 544 */
545static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) 545static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
546{ 546{
547 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 547 struct fsl_otg *otg_dev;
548
549 if (!otg)
550 return -ENODEV;
548 551
549 if (!otg || otg_dev != fsl_otg_dev) 552 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
553 if (otg_dev != fsl_otg_dev)
550 return -ENODEV; 554 return -ENODEV;
551 555
552 otg->host = host; 556 otg->host = host;
@@ -590,12 +594,15 @@ static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
590static int fsl_otg_set_peripheral(struct usb_otg *otg, 594static int fsl_otg_set_peripheral(struct usb_otg *otg,
591 struct usb_gadget *gadget) 595 struct usb_gadget *gadget)
592{ 596{
593 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 597 struct fsl_otg *otg_dev;
594 598
599 if (!otg)
600 return -ENODEV;
601
602 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
595 VDBG("otg_dev 0x%x\n", (int)otg_dev); 603 VDBG("otg_dev 0x%x\n", (int)otg_dev);
596 VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); 604 VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev);
597 605 if (otg_dev != fsl_otg_dev)
598 if (!otg || otg_dev != fsl_otg_dev)
599 return -ENODEV; 606 return -ENODEV;
600 607
601 if (!gadget) { 608 if (!gadget) {
@@ -660,10 +667,13 @@ static void fsl_otg_event(struct work_struct *work)
660/* B-device start SRP */ 667/* B-device start SRP */
661static int fsl_otg_start_srp(struct usb_otg *otg) 668static int fsl_otg_start_srp(struct usb_otg *otg)
662{ 669{
663 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 670 struct fsl_otg *otg_dev;
671
672 if (!otg || otg->phy->state != OTG_STATE_B_IDLE)
673 return -ENODEV;
664 674
665 if (!otg || otg_dev != fsl_otg_dev 675 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
666 || otg->phy->state != OTG_STATE_B_IDLE) 676 if (otg_dev != fsl_otg_dev)
667 return -ENODEV; 677 return -ENODEV;
668 678
669 otg_dev->fsm.b_bus_req = 1; 679 otg_dev->fsm.b_bus_req = 1;
@@ -675,9 +685,13 @@ static int fsl_otg_start_srp(struct usb_otg *otg)
675/* A_host suspend will call this function to start hnp */ 685/* A_host suspend will call this function to start hnp */
676static int fsl_otg_start_hnp(struct usb_otg *otg) 686static int fsl_otg_start_hnp(struct usb_otg *otg)
677{ 687{
678 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 688 struct fsl_otg *otg_dev;
689
690 if (!otg)
691 return -ENODEV;
679 692
680 if (!otg || otg_dev != fsl_otg_dev) 693 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
694 if (otg_dev != fsl_otg_dev)
681 return -ENODEV; 695 return -ENODEV;
682 696
683 DBG("start_hnp...n"); 697 DBG("start_hnp...n");
diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index c1a67cb8e244..88db976647cf 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/workqueue.h>
23 24
24#define DRIVER_NAME "mxs_phy" 25#define DRIVER_NAME "mxs_phy"
25 26
@@ -34,9 +35,16 @@
34#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) 35#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
35#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) 36#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
36 37
38/*
39 * Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit
40 * so that connection and reset processing can be completed for the root hub.
41 */
42#define MXY_PHY_ENHOSTDISCONDETECT_DELAY 250
43
37struct mxs_phy { 44struct mxs_phy {
38 struct usb_phy phy; 45 struct usb_phy phy;
39 struct clk *clk; 46 struct clk *clk;
47 struct delayed_work enhostdiscondetect_work;
40}; 48};
41 49
42#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) 50#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
@@ -62,6 +70,7 @@ static int mxs_phy_init(struct usb_phy *phy)
62 70
63 clk_prepare_enable(mxs_phy->clk); 71 clk_prepare_enable(mxs_phy->clk);
64 mxs_phy_hw_init(mxs_phy); 72 mxs_phy_hw_init(mxs_phy);
73 INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
65 74
66 return 0; 75 return 0;
67} 76}
@@ -76,13 +85,34 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
76 clk_disable_unprepare(mxs_phy->clk); 85 clk_disable_unprepare(mxs_phy->clk);
77} 86}
78 87
88static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws)
89{
90 struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy,
91 enhostdiscondetect_work.work);
92
93 /* Enable HOSTDISCONDETECT after delay. */
94 dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n");
95 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
96 mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET);
97}
98
79static int mxs_phy_on_connect(struct usb_phy *phy, int port) 99static int mxs_phy_on_connect(struct usb_phy *phy, int port)
80{ 100{
101 struct mxs_phy *mxs_phy = to_mxs_phy(phy);
102
81 dev_dbg(phy->dev, "Connect on port %d\n", port); 103 dev_dbg(phy->dev, "Connect on port %d\n", port);
82 104
83 mxs_phy_hw_init(to_mxs_phy(phy)); 105 mxs_phy_hw_init(mxs_phy);
84 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 106
85 phy->io_priv + HW_USBPHY_CTRL_SET); 107 /*
108 * Delay enabling ENHOSTDISCONDETECT so that connection and
109 * reset processing can be completed for the root hub.
110 */
111 dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n");
112 PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work,
113 mxs_phy_enhostdiscondetect_delay);
114 schedule_delayed_work(&mxs_phy->enhostdiscondetect_work,
115 msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY));
86 116
87 return 0; 117 return 0;
88} 118}
@@ -91,6 +121,8 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, int port)
91{ 121{
92 dev_dbg(phy->dev, "Disconnect on port %d\n", port); 122 dev_dbg(phy->dev, "Disconnect on port %d\n", port);
93 123
124 /* No need to delay before clearing ENHOSTDISCONDETECT. */
125 dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n");
94 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 126 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
95 phy->io_priv + HW_USBPHY_CTRL_CLR); 127 phy->io_priv + HW_USBPHY_CTRL_CLR);
96 128
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index 803f958f4133..e52e35e7adaf 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -30,6 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/usb/otg.h> 32#include <linux/usb/otg.h>
33#include <linux/usb/nop-usb-xceiv.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34 35
35struct nop_usb_xceiv { 36struct nop_usb_xceiv {
@@ -94,7 +95,9 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
94 95
95static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) 96static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
96{ 97{
98 struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
97 struct nop_usb_xceiv *nop; 99 struct nop_usb_xceiv *nop;
100 enum usb_phy_type type = USB_PHY_TYPE_USB2;
98 int err; 101 int err;
99 102
100 nop = kzalloc(sizeof *nop, GFP_KERNEL); 103 nop = kzalloc(sizeof *nop, GFP_KERNEL);
@@ -107,6 +110,9 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
107 return -ENOMEM; 110 return -ENOMEM;
108 } 111 }
109 112
113 if (pdata)
114 type = pdata->type;
115
110 nop->dev = &pdev->dev; 116 nop->dev = &pdev->dev;
111 nop->phy.dev = nop->dev; 117 nop->phy.dev = nop->dev;
112 nop->phy.label = "nop-xceiv"; 118 nop->phy.label = "nop-xceiv";
@@ -117,7 +123,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
117 nop->phy.otg->set_host = nop_set_host; 123 nop->phy.otg->set_host = nop_set_host;
118 nop->phy.otg->set_peripheral = nop_set_peripheral; 124 nop->phy.otg->set_peripheral = nop_set_peripheral;
119 125
120 err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2); 126 err = usb_add_phy(&nop->phy, type);
121 if (err) { 127 if (err) {
122 dev_err(&pdev->dev, "can't register transceiver, err: %d\n", 128 dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
123 err); 129 err);
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index 1bf60a22595c..a30c04115115 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -159,7 +159,7 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
159 unsigned long flags; 159 unsigned long flags;
160 struct usb_phy *phy; 160 struct usb_phy *phy;
161 161
162 if (x && x->type != USB_PHY_TYPE_UNDEFINED) { 162 if (x->type != USB_PHY_TYPE_UNDEFINED) {
163 dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); 163 dev_err(x->dev, "not accepting initialized PHY %s\n", x->label);
164 return -EINVAL; 164 return -EINVAL;
165 } 165 }
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 523cad5bfea9..f0d2e7530cfe 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -585,23 +585,28 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
585 struct twl4030_usb *twl; 585 struct twl4030_usb *twl;
586 int status, err; 586 int status, err;
587 struct usb_otg *otg; 587 struct usb_otg *otg;
588 588 struct device_node *np = pdev->dev.of_node;
589 if (!pdata) {
590 dev_dbg(&pdev->dev, "platform_data not available\n");
591 return -EINVAL;
592 }
593 589
594 twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); 590 twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
595 if (!twl) 591 if (!twl)
596 return -ENOMEM; 592 return -ENOMEM;
597 593
594 if (np)
595 of_property_read_u32(np, "usb_mode",
596 (enum twl4030_usb_mode *)&twl->usb_mode);
597 else if (pdata)
598 twl->usb_mode = pdata->usb_mode;
599 else {
600 dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
601 return -EINVAL;
602 }
603
598 otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); 604 otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL);
599 if (!otg) 605 if (!otg)
600 return -ENOMEM; 606 return -ENOMEM;
601 607
602 twl->dev = &pdev->dev; 608 twl->dev = &pdev->dev;
603 twl->irq = platform_get_irq(pdev, 0); 609 twl->irq = platform_get_irq(pdev, 0);
604 twl->usb_mode = pdata->usb_mode;
605 twl->vbus_supplied = false; 610 twl->vbus_supplied = false;
606 twl->asleep = 1; 611 twl->asleep = 1;
607 twl->linkstat = OMAP_MUSB_UNKNOWN; 612 twl->linkstat = OMAP_MUSB_UNKNOWN;
@@ -690,12 +695,21 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
690 return 0; 695 return 0;
691} 696}
692 697
698#ifdef CONFIG_OF
699static const struct of_device_id twl4030_usb_id_table[] = {
700 { .compatible = "ti,twl4030-usb" },
701 {}
702};
703MODULE_DEVICE_TABLE(of, twl4030_usb_id_table);
704#endif
705
693static struct platform_driver twl4030_usb_driver = { 706static struct platform_driver twl4030_usb_driver = {
694 .probe = twl4030_usb_probe, 707 .probe = twl4030_usb_probe,
695 .remove = __exit_p(twl4030_usb_remove), 708 .remove = __exit_p(twl4030_usb_remove),
696 .driver = { 709 .driver = {
697 .name = "twl4030_usb", 710 .name = "twl4030_usb",
698 .owner = THIS_MODULE, 711 .owner = THIS_MODULE,
712 .of_match_table = of_match_ptr(twl4030_usb_id_table),
699 }, 713 },
700}; 714};
701 715
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c
index 6907d8df7a27..fcadef7864f1 100644
--- a/drivers/usb/otg/twl6030-usb.c
+++ b/drivers/usb/otg/twl6030-usb.c
@@ -25,8 +25,9 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/usb/otg.h>
29#include <linux/usb/musb-omap.h> 28#include <linux/usb/musb-omap.h>
29#include <linux/usb/phy_companion.h>
30#include <linux/usb/omap_usb.h>
30#include <linux/i2c/twl.h> 31#include <linux/i2c/twl.h>
31#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
32#include <linux/err.h> 33#include <linux/err.h>
@@ -87,7 +88,7 @@
87#define VBUS_DET BIT(2) 88#define VBUS_DET BIT(2)
88 89
89struct twl6030_usb { 90struct twl6030_usb {
90 struct usb_phy phy; 91 struct phy_companion comparator;
91 struct device *dev; 92 struct device *dev;
92 93
93 /* for vbus reporting with irqs disabled */ 94 /* for vbus reporting with irqs disabled */
@@ -104,10 +105,10 @@ struct twl6030_usb {
104 u8 asleep; 105 u8 asleep;
105 bool irq_enabled; 106 bool irq_enabled;
106 bool vbus_enable; 107 bool vbus_enable;
107 unsigned long features; 108 const char *regulator;
108}; 109};
109 110
110#define phy_to_twl(x) container_of((x), struct twl6030_usb, phy) 111#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator)
111 112
112/*-------------------------------------------------------------------------*/ 113/*-------------------------------------------------------------------------*/
113 114
@@ -137,50 +138,9 @@ static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address)
137 return ret; 138 return ret;
138} 139}
139 140
140static int twl6030_phy_init(struct usb_phy *x) 141static int twl6030_start_srp(struct phy_companion *comparator)
141{ 142{
142 struct twl6030_usb *twl; 143 struct twl6030_usb *twl = comparator_to_twl(comparator);
143 struct device *dev;
144 struct twl4030_usb_data *pdata;
145
146 twl = phy_to_twl(x);
147 dev = twl->dev;
148 pdata = dev->platform_data;
149
150 if (twl->linkstat == OMAP_MUSB_ID_GROUND)
151 pdata->phy_power(twl->dev, 1, 1);
152 else
153 pdata->phy_power(twl->dev, 0, 1);
154
155 return 0;
156}
157
158static void twl6030_phy_shutdown(struct usb_phy *x)
159{
160 struct twl6030_usb *twl;
161 struct device *dev;
162 struct twl4030_usb_data *pdata;
163
164 twl = phy_to_twl(x);
165 dev = twl->dev;
166 pdata = dev->platform_data;
167 pdata->phy_power(twl->dev, 0, 0);
168}
169
170static int twl6030_phy_suspend(struct usb_phy *x, int suspend)
171{
172 struct twl6030_usb *twl = phy_to_twl(x);
173 struct device *dev = twl->dev;
174 struct twl4030_usb_data *pdata = dev->platform_data;
175
176 pdata->phy_suspend(dev, suspend);
177
178 return 0;
179}
180
181static int twl6030_start_srp(struct usb_otg *otg)
182{
183 struct twl6030_usb *twl = phy_to_twl(otg->phy);
184 144
185 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); 145 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET);
186 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); 146 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET);
@@ -193,13 +153,6 @@ static int twl6030_start_srp(struct usb_otg *otg)
193 153
194static int twl6030_usb_ldo_init(struct twl6030_usb *twl) 154static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
195{ 155{
196 char *regulator_name;
197
198 if (twl->features & TWL6025_SUBCLASS)
199 regulator_name = "ldousb";
200 else
201 regulator_name = "vusb";
202
203 /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ 156 /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */
204 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); 157 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);
205 158
@@ -209,7 +162,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
209 /* Program MISC2 register and set bit VUSB_IN_VBAT */ 162 /* Program MISC2 register and set bit VUSB_IN_VBAT */
210 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); 163 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2);
211 164
212 twl->usb3v3 = regulator_get(twl->dev, regulator_name); 165 twl->usb3v3 = regulator_get(twl->dev, twl->regulator);
213 if (IS_ERR(twl->usb3v3)) 166 if (IS_ERR(twl->usb3v3))
214 return -ENODEV; 167 return -ENODEV;
215 168
@@ -313,23 +266,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
313 return IRQ_HANDLED; 266 return IRQ_HANDLED;
314} 267}
315 268
316static int twl6030_set_peripheral(struct usb_otg *otg, 269static int twl6030_enable_irq(struct twl6030_usb *twl)
317 struct usb_gadget *gadget)
318{
319 if (!otg)
320 return -ENODEV;
321
322 otg->gadget = gadget;
323 if (!gadget)
324 otg->phy->state = OTG_STATE_UNDEFINED;
325
326 return 0;
327}
328
329static int twl6030_enable_irq(struct usb_phy *x)
330{ 270{
331 struct twl6030_usb *twl = phy_to_twl(x);
332
333 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); 271 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
334 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); 272 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C);
335 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); 273 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C);
@@ -362,9 +300,9 @@ static void otg_set_vbus_work(struct work_struct *data)
362 CHARGERUSB_CTRL1); 300 CHARGERUSB_CTRL1);
363} 301}
364 302
365static int twl6030_set_vbus(struct usb_otg *otg, bool enabled) 303static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
366{ 304{
367 struct twl6030_usb *twl = phy_to_twl(otg->phy); 305 struct twl6030_usb *twl = comparator_to_twl(comparator);
368 306
369 twl->vbus_enable = enabled; 307 twl->vbus_enable = enabled;
370 schedule_work(&twl->set_vbus_work); 308 schedule_work(&twl->set_vbus_work);
@@ -372,52 +310,44 @@ static int twl6030_set_vbus(struct usb_otg *otg, bool enabled)
372 return 0; 310 return 0;
373} 311}
374 312
375static int twl6030_set_host(struct usb_otg *otg, struct usb_bus *host)
376{
377 if (!otg)
378 return -ENODEV;
379
380 otg->host = host;
381 if (!host)
382 otg->phy->state = OTG_STATE_UNDEFINED;
383 return 0;
384}
385
386static int __devinit twl6030_usb_probe(struct platform_device *pdev) 313static int __devinit twl6030_usb_probe(struct platform_device *pdev)
387{ 314{
315 u32 ret;
388 struct twl6030_usb *twl; 316 struct twl6030_usb *twl;
389 int status, err; 317 int status, err;
390 struct twl4030_usb_data *pdata; 318 struct device_node *np = pdev->dev.of_node;
391 struct usb_otg *otg; 319 struct device *dev = &pdev->dev;
392 struct device *dev = &pdev->dev; 320 struct twl4030_usb_data *pdata = dev->platform_data;
393 pdata = dev->platform_data;
394 321
395 twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); 322 twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL);
396 if (!twl) 323 if (!twl)
397 return -ENOMEM; 324 return -ENOMEM;
398 325
399 otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL);
400 if (!otg)
401 return -ENOMEM;
402
403 twl->dev = &pdev->dev; 326 twl->dev = &pdev->dev;
404 twl->irq1 = platform_get_irq(pdev, 0); 327 twl->irq1 = platform_get_irq(pdev, 0);
405 twl->irq2 = platform_get_irq(pdev, 1); 328 twl->irq2 = platform_get_irq(pdev, 1);
406 twl->features = pdata->features;
407 twl->linkstat = OMAP_MUSB_UNKNOWN; 329 twl->linkstat = OMAP_MUSB_UNKNOWN;
408 330
409 twl->phy.dev = twl->dev; 331 twl->comparator.set_vbus = twl6030_set_vbus;
410 twl->phy.label = "twl6030"; 332 twl->comparator.start_srp = twl6030_start_srp;
411 twl->phy.otg = otg; 333
412 twl->phy.init = twl6030_phy_init; 334 ret = omap_usb2_set_comparator(&twl->comparator);
413 twl->phy.shutdown = twl6030_phy_shutdown; 335 if (ret == -ENODEV) {
414 twl->phy.set_suspend = twl6030_phy_suspend; 336 dev_info(&pdev->dev, "phy not ready, deferring probe");
337 return -EPROBE_DEFER;
338 }
415 339
416 otg->phy = &twl->phy; 340 if (np) {
417 otg->set_host = twl6030_set_host; 341 twl->regulator = "usb";
418 otg->set_peripheral = twl6030_set_peripheral; 342 } else if (pdata) {
419 otg->set_vbus = twl6030_set_vbus; 343 if (pdata->features & TWL6025_SUBCLASS)
420 otg->start_srp = twl6030_start_srp; 344 twl->regulator = "ldousb";
345 else
346 twl->regulator = "vusb";
347 } else {
348 dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
349 return -EINVAL;
350 }
421 351
422 /* init spinlock for workqueue */ 352 /* init spinlock for workqueue */
423 spin_lock_init(&twl->lock); 353 spin_lock_init(&twl->lock);
@@ -427,7 +357,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
427 dev_err(&pdev->dev, "ldo init failed\n"); 357 dev_err(&pdev->dev, "ldo init failed\n");
428 return err; 358 return err;
429 } 359 }
430 usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);
431 360
432 platform_set_drvdata(pdev, twl); 361 platform_set_drvdata(pdev, twl);
433 if (device_create_file(&pdev->dev, &dev_attr_vbus)) 362 if (device_create_file(&pdev->dev, &dev_attr_vbus))
@@ -458,9 +387,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
458 } 387 }
459 388
460 twl->asleep = 0; 389 twl->asleep = 0;
461 pdata->phy_init(dev); 390 twl6030_enable_irq(twl);
462 twl6030_phy_suspend(&twl->phy, 0);
463 twl6030_enable_irq(&twl->phy);
464 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); 391 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
465 392
466 return 0; 393 return 0;
@@ -470,10 +397,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
470{ 397{
471 struct twl6030_usb *twl = platform_get_drvdata(pdev); 398 struct twl6030_usb *twl = platform_get_drvdata(pdev);
472 399
473 struct twl4030_usb_data *pdata;
474 struct device *dev = &pdev->dev;
475 pdata = dev->platform_data;
476
477 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 400 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
478 REG_INT_MSK_LINE_C); 401 REG_INT_MSK_LINE_C);
479 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 402 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
@@ -481,19 +404,27 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
481 free_irq(twl->irq1, twl); 404 free_irq(twl->irq1, twl);
482 free_irq(twl->irq2, twl); 405 free_irq(twl->irq2, twl);
483 regulator_put(twl->usb3v3); 406 regulator_put(twl->usb3v3);
484 pdata->phy_exit(twl->dev);
485 device_remove_file(twl->dev, &dev_attr_vbus); 407 device_remove_file(twl->dev, &dev_attr_vbus);
486 cancel_work_sync(&twl->set_vbus_work); 408 cancel_work_sync(&twl->set_vbus_work);
487 409
488 return 0; 410 return 0;
489} 411}
490 412
413#ifdef CONFIG_OF
414static const struct of_device_id twl6030_usb_id_table[] = {
415 { .compatible = "ti,twl6030-usb" },
416 {}
417};
418MODULE_DEVICE_TABLE(of, twl6030_usb_id_table);
419#endif
420
491static struct platform_driver twl6030_usb_driver = { 421static struct platform_driver twl6030_usb_driver = {
492 .probe = twl6030_usb_probe, 422 .probe = twl6030_usb_probe,
493 .remove = __exit_p(twl6030_usb_remove), 423 .remove = __exit_p(twl6030_usb_remove),
494 .driver = { 424 .driver = {
495 .name = "twl6030_usb", 425 .name = "twl6030_usb",
496 .owner = THIS_MODULE, 426 .owner = THIS_MODULE,
427 .of_match_table = of_match_ptr(twl6030_usb_id_table),
497 }, 428 },
498}; 429};
499 430
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index e7cf84f0751a..63c339b3e676 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -4,6 +4,15 @@
4comment "USB Physical Layer drivers" 4comment "USB Physical Layer drivers"
5 depends on USB || USB_GADGET 5 depends on USB || USB_GADGET
6 6
7config OMAP_USB2
8 tristate "OMAP USB2 PHY Driver"
9 select USB_OTG_UTILS
10 help
11 Enable this to support the transceiver that is part of SOC. This
12 driver takes care of all the PHY functionality apart from comparator.
13 The USB OTG controller communicates with the comparator using this
14 driver.
15
7config USB_ISP1301 16config USB_ISP1301
8 tristate "NXP ISP1301 USB transceiver support" 17 tristate "NXP ISP1301 USB transceiver support"
9 depends on USB || USB_GADGET 18 depends on USB || USB_GADGET
@@ -15,3 +24,11 @@ config USB_ISP1301
15 24
16 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
17 module will be called isp1301. 26 module will be called isp1301.
27
28config MV_U3D_PHY
29 bool "Marvell USB 3.0 PHY controller Driver"
30 depends on USB_MV_U3D
31 select USB_OTG_UTILS
32 help
33 Enable this to support Marvell USB 3.0 phy controller for Marvell
34 SoC.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index eca095b1a890..b069f29f1225 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -4,4 +4,7 @@
4 4
5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG 5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
6 6
7obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
7obj-$(CONFIG_USB_ISP1301) += isp1301.o 8obj-$(CONFIG_USB_ISP1301) += isp1301.o
9obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
10obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
diff --git a/drivers/usb/phy/isp1301.c b/drivers/usb/phy/isp1301.c
index b19f4932a037..18dbf7e37607 100644
--- a/drivers/usb/phy/isp1301.c
+++ b/drivers/usb/phy/isp1301.c
@@ -15,12 +15,6 @@
15 15
16#define DRV_NAME "isp1301" 16#define DRV_NAME "isp1301"
17 17
18#define ISP1301_I2C_ADDR 0x2C
19
20static const unsigned short normal_i2c[] = {
21 ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END
22};
23
24static const struct i2c_device_id isp1301_id[] = { 18static const struct i2c_device_id isp1301_id[] = {
25 { "isp1301", 0 }, 19 { "isp1301", 0 },
26 { } 20 { }
diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c
new file mode 100644
index 000000000000..9f1c5d3c60ec
--- /dev/null
+++ b/drivers/usb/phy/mv_u3d_phy.c
@@ -0,0 +1,345 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/platform_device.h>
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/usb/otg.h>
16#include <linux/platform_data/mv_usb.h>
17
18#include "mv_u3d_phy.h"
19
20/*
21 * struct mv_u3d_phy - transceiver driver state
22 * @phy: transceiver structure
23 * @dev: The parent device supplied to the probe function
24 * @clk: usb phy clock
25 * @base: usb phy register memory base
26 */
27struct mv_u3d_phy {
28 struct usb_phy phy;
29 struct mv_usb_platform_data *plat;
30 struct device *dev;
31 struct clk *clk;
32 void __iomem *base;
33};
34
35static u32 mv_u3d_phy_read(void __iomem *base, u32 reg)
36{
37 void __iomem *addr, *data;
38
39 addr = base;
40 data = base + 0x4;
41
42 writel_relaxed(reg, addr);
43 return readl_relaxed(data);
44}
45
46static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value)
47{
48 void __iomem *addr, *data;
49 u32 tmp;
50
51 addr = base;
52 data = base + 0x4;
53
54 writel_relaxed(reg, addr);
55 tmp = readl_relaxed(data);
56 tmp |= value;
57 writel_relaxed(tmp, data);
58}
59
60static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value)
61{
62 void __iomem *addr, *data;
63 u32 tmp;
64
65 addr = base;
66 data = base + 0x4;
67
68 writel_relaxed(reg, addr);
69 tmp = readl_relaxed(data);
70 tmp &= ~value;
71 writel_relaxed(tmp, data);
72}
73
74static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value)
75{
76 void __iomem *addr, *data;
77
78 addr = base;
79 data = base + 0x4;
80
81 writel_relaxed(reg, addr);
82 writel_relaxed(value, data);
83}
84
85void mv_u3d_phy_shutdown(struct usb_phy *phy)
86{
87 struct mv_u3d_phy *mv_u3d_phy;
88 void __iomem *base;
89 u32 val;
90
91 mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy);
92 base = mv_u3d_phy->base;
93
94 /* Power down Reference Analog current, bit 15
95 * Power down PLL, bit 14
96 * Power down Receiver, bit 13
97 * Power down Transmitter, bit 12
98 * of USB3_POWER_PLL_CONTROL register
99 */
100 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
101 val &= ~(USB3_POWER_PLL_CONTROL_PU);
102 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
103
104 if (mv_u3d_phy->clk)
105 clk_disable(mv_u3d_phy->clk);
106}
107
108static int mv_u3d_phy_init(struct usb_phy *phy)
109{
110 struct mv_u3d_phy *mv_u3d_phy;
111 void __iomem *base;
112 u32 val, count;
113
114 /* enable usb3 phy */
115 mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy);
116
117 if (mv_u3d_phy->clk)
118 clk_enable(mv_u3d_phy->clk);
119
120 base = mv_u3d_phy->base;
121
122 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
123 val &= ~(USB3_POWER_PLL_CONTROL_PU_MASK);
124 val |= 0xF << USB3_POWER_PLL_CONTROL_PU_SHIFT;
125 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
126 udelay(100);
127
128 mv_u3d_phy_write(base, USB3_RESET_CONTROL,
129 USB3_RESET_CONTROL_RESET_PIPE);
130 udelay(100);
131
132 mv_u3d_phy_write(base, USB3_RESET_CONTROL,
133 USB3_RESET_CONTROL_RESET_PIPE
134 | USB3_RESET_CONTROL_RESET_PHY);
135 udelay(100);
136
137 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
138 val &= ~(USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK
139 | USB3_POWER_PLL_CONTROL_PHY_MODE_MASK);
140 val |= (USB3_PLL_25MHZ << USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT)
141 | (0x5 << USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT);
142 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
143 udelay(100);
144
145 mv_u3d_phy_clear(base, USB3_KVCO_CALI_CONTROL,
146 USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK);
147 udelay(100);
148
149 val = mv_u3d_phy_read(base, USB3_SQUELCH_FFE);
150 val &= ~(USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK
151 | USB3_SQUELCH_FFE_FFE_RES_SEL_MASK
152 | USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK);
153 val |= ((0xD << USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT)
154 | (0x7 << USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT)
155 | (0x8 << USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT));
156 mv_u3d_phy_write(base, USB3_SQUELCH_FFE, val);
157 udelay(100);
158
159 val = mv_u3d_phy_read(base, USB3_GEN1_SET0);
160 val &= ~USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK;
161 val |= 1 << USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT;
162 mv_u3d_phy_write(base, USB3_GEN1_SET0, val);
163 udelay(100);
164
165 val = mv_u3d_phy_read(base, USB3_GEN2_SET0);
166 val &= ~(USB3_GEN2_SET0_G2_TX_AMP_MASK
167 | USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK
168 | USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK);
169 val |= ((0x14 << USB3_GEN2_SET0_G2_TX_AMP_SHIFT)
170 | (1 << USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT)
171 | (0xA << USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT)
172 | (1 << USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT));
173 mv_u3d_phy_write(base, USB3_GEN2_SET0, val);
174 udelay(100);
175
176 mv_u3d_phy_read(base, USB3_TX_EMPPH);
177 val &= ~(USB3_TX_EMPPH_AMP_MASK
178 | USB3_TX_EMPPH_EN_MASK
179 | USB3_TX_EMPPH_AMP_FORCE_MASK
180 | USB3_TX_EMPPH_PAR1_MASK
181 | USB3_TX_EMPPH_PAR2_MASK);
182 val |= ((0xB << USB3_TX_EMPPH_AMP_SHIFT)
183 | (1 << USB3_TX_EMPPH_EN_SHIFT)
184 | (1 << USB3_TX_EMPPH_AMP_FORCE_SHIFT)
185 | (0x1C << USB3_TX_EMPPH_PAR1_SHIFT)
186 | (1 << USB3_TX_EMPPH_PAR2_SHIFT));
187
188 mv_u3d_phy_write(base, USB3_TX_EMPPH, val);
189 udelay(100);
190
191 val = mv_u3d_phy_read(base, USB3_GEN2_SET1);
192 val &= ~(USB3_GEN2_SET1_G2_RX_SELMUPI_MASK
193 | USB3_GEN2_SET1_G2_RX_SELMUPF_MASK
194 | USB3_GEN2_SET1_G2_RX_SELMUFI_MASK
195 | USB3_GEN2_SET1_G2_RX_SELMUFF_MASK);
196 val |= ((1 << USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT)
197 | (1 << USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT)
198 | (1 << USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT)
199 | (1 << USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT));
200 mv_u3d_phy_write(base, USB3_GEN2_SET1, val);
201 udelay(100);
202
203 val = mv_u3d_phy_read(base, USB3_DIGITAL_LOOPBACK_EN);
204 val &= ~USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK;
205 val |= 1 << USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT;
206 mv_u3d_phy_write(base, USB3_DIGITAL_LOOPBACK_EN, val);
207 udelay(100);
208
209 val = mv_u3d_phy_read(base, USB3_IMPEDANCE_TX_SSC);
210 val &= ~USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK;
211 val |= 0xC << USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT;
212 mv_u3d_phy_write(base, USB3_IMPEDANCE_TX_SSC, val);
213 udelay(100);
214
215 val = mv_u3d_phy_read(base, USB3_IMPEDANCE_CALI_CTRL);
216 val &= ~USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK;
217 val |= 0x4 << USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT;
218 mv_u3d_phy_write(base, USB3_IMPEDANCE_CALI_CTRL, val);
219 udelay(100);
220
221 val = mv_u3d_phy_read(base, USB3_PHY_ISOLATION_MODE);
222 val &= ~(USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK
223 | USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK
224 | USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK);
225 val |= ((1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT)
226 | (1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT));
227 mv_u3d_phy_write(base, USB3_PHY_ISOLATION_MODE, val);
228 udelay(100);
229
230 val = mv_u3d_phy_read(base, USB3_TXDETRX);
231 val &= ~(USB3_TXDETRX_VTHSEL_MASK);
232 val |= 0x1 << USB3_TXDETRX_VTHSEL_SHIFT;
233 mv_u3d_phy_write(base, USB3_TXDETRX, val);
234 udelay(100);
235
236 dev_dbg(mv_u3d_phy->dev, "start calibration\n");
237
238calstart:
239 /* Perform Manual Calibration */
240 mv_u3d_phy_set(base, USB3_KVCO_CALI_CONTROL,
241 1 << USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT);
242
243 mdelay(1);
244
245 count = 0;
246 while (1) {
247 val = mv_u3d_phy_read(base, USB3_KVCO_CALI_CONTROL);
248 if (val & (1 << USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT))
249 break;
250 else if (count > 50) {
251 dev_dbg(mv_u3d_phy->dev, "calibration failure, retry...\n");
252 goto calstart;
253 }
254 count++;
255 mdelay(1);
256 }
257
258 /* active PIPE interface */
259 mv_u3d_phy_write(base, USB3_PIPE_SM_CTRL,
260 1 << USB3_PIPE_SM_CTRL_PHY_INIT_DONE);
261
262 return 0;
263}
264
265static int __devinit mv_u3d_phy_probe(struct platform_device *pdev)
266{
267 struct mv_u3d_phy *mv_u3d_phy;
268 struct mv_usb_platform_data *pdata;
269 struct device *dev = &pdev->dev;
270 struct resource *res;
271 void __iomem *phy_base;
272 int ret;
273
274 pdata = pdev->dev.platform_data;
275 if (!pdata) {
276 dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
277 return -EINVAL;
278 }
279
280 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281 if (!res) {
282 dev_err(dev, "missing mem resource\n");
283 return -ENODEV;
284 }
285
286 phy_base = devm_request_and_ioremap(dev, res);
287 if (!phy_base) {
288 dev_err(dev, "%s: register mapping failed\n", __func__);
289 return -ENXIO;
290 }
291
292 mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL);
293 if (!mv_u3d_phy)
294 return -ENOMEM;
295
296 mv_u3d_phy->dev = &pdev->dev;
297 mv_u3d_phy->plat = pdata;
298 mv_u3d_phy->base = phy_base;
299 mv_u3d_phy->phy.dev = mv_u3d_phy->dev;
300 mv_u3d_phy->phy.label = "mv-u3d-phy";
301 mv_u3d_phy->phy.init = mv_u3d_phy_init;
302 mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown;
303
304 ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3);
305 if (ret)
306 goto err;
307
308 if (!mv_u3d_phy->clk)
309 mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy");
310
311 platform_set_drvdata(pdev, mv_u3d_phy);
312
313 dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n");
314err:
315 return ret;
316}
317
318static int __exit mv_u3d_phy_remove(struct platform_device *pdev)
319{
320 struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev);
321
322 usb_remove_phy(&mv_u3d_phy->phy);
323
324 if (mv_u3d_phy->clk) {
325 clk_put(mv_u3d_phy->clk);
326 mv_u3d_phy->clk = NULL;
327 }
328
329 return 0;
330}
331
332static struct platform_driver mv_u3d_phy_driver = {
333 .probe = mv_u3d_phy_probe,
334 .remove = __devexit_p(mv_u3d_phy_remove),
335 .driver = {
336 .name = "mv-u3d-phy",
337 .owner = THIS_MODULE,
338 },
339};
340
341module_platform_driver(mv_u3d_phy_driver);
342MODULE_DESCRIPTION("Marvell USB 3.0 PHY controller");
343MODULE_AUTHOR("Yu Xu <yuxu@marvell.com>");
344MODULE_LICENSE("GPL");
345MODULE_ALIAS("platform:mv-u3d-phy");
diff --git a/drivers/usb/phy/mv_u3d_phy.h b/drivers/usb/phy/mv_u3d_phy.h
new file mode 100644
index 000000000000..2a658cb9a527
--- /dev/null
+++ b/drivers/usb/phy/mv_u3d_phy.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 */
8
9#ifndef __MV_U3D_PHY_H
10#define __MV_U3D_PHY_H
11
12#define USB3_POWER_PLL_CONTROL 0x1
13#define USB3_KVCO_CALI_CONTROL 0x2
14#define USB3_IMPEDANCE_CALI_CTRL 0x3
15#define USB3_IMPEDANCE_TX_SSC 0x4
16#define USB3_SQUELCH_FFE 0x6
17#define USB3_GEN1_SET0 0xD
18#define USB3_GEN2_SET0 0xF
19#define USB3_GEN2_SET1 0x10
20#define USB3_DIGITAL_LOOPBACK_EN 0x23
21#define USB3_PHY_ISOLATION_MODE 0x26
22#define USB3_TXDETRX 0x48
23#define USB3_TX_EMPPH 0x5E
24#define USB3_RESET_CONTROL 0x90
25#define USB3_PIPE_SM_CTRL 0x91
26
27#define USB3_RESET_CONTROL_RESET_PIPE 0x1
28#define USB3_RESET_CONTROL_RESET_PHY 0x2
29
30#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK (0x1F << 0)
31#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT 0
32#define USB3_PLL_25MHZ 0x2
33#define USB3_PLL_26MHZ 0x5
34#define USB3_POWER_PLL_CONTROL_PHY_MODE_MASK (0x7 << 5)
35#define USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT 5
36#define USB3_POWER_PLL_CONTROL_PU_MASK (0xF << 12)
37#define USB3_POWER_PLL_CONTROL_PU_SHIFT 12
38#define USB3_POWER_PLL_CONTROL_PU (0xF << 12)
39
40#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK (0x1 << 12)
41#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_SHIFT 12
42#define USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT 14
43#define USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT 15
44
45#define USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK 0xF
46#define USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT 0
47#define USB3_SQUELCH_FFE_FFE_RES_SEL_MASK (0x7 << 4)
48#define USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT 4
49#define USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK (0x1F << 8)
50#define USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT 8
51
52#define USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK (0x1 << 15)
53#define USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT 11
54
55#define USB3_GEN2_SET0_G2_TX_AMP_MASK (0x1F << 1)
56#define USB3_GEN2_SET0_G2_TX_AMP_SHIFT 1
57#define USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT 6
58#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK (0xF << 7)
59#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT 7
60#define USB3_GEN2_SET0_G2_TX_EMPH_EN_MASK (0x1 << 11)
61#define USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT 11
62#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK (0x1 << 15)
63#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_SHIFT 15
64
65#define USB3_GEN2_SET1_G2_RX_SELMUPI_MASK (0x7 << 0)
66#define USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT 0
67#define USB3_GEN2_SET1_G2_RX_SELMUPF_MASK (0x7 << 3)
68#define USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT 3
69#define USB3_GEN2_SET1_G2_RX_SELMUFI_MASK (0x3 << 6)
70#define USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT 6
71#define USB3_GEN2_SET1_G2_RX_SELMUFF_MASK (0x3 << 8)
72#define USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT 8
73
74#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK (0x3 << 10)
75#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT 10
76
77#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK (0x7 << 12)
78#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT 12
79
80#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK (0x3F << 0)
81#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT 0
82
83#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK 0xF
84#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT 0
85#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK (0xF << 4)
86#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT 4
87#define USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK (0x1 << 8)
88
89#define USB3_TXDETRX_VTHSEL_MASK (0x3 << 4)
90#define USB3_TXDETRX_VTHSEL_SHIFT 4
91
92#define USB3_TX_EMPPH_AMP_MASK (0xF << 0)
93#define USB3_TX_EMPPH_AMP_SHIFT 0
94#define USB3_TX_EMPPH_EN_MASK (0x1 << 6)
95#define USB3_TX_EMPPH_EN_SHIFT 6
96#define USB3_TX_EMPPH_AMP_FORCE_MASK (0x1 << 7)
97#define USB3_TX_EMPPH_AMP_FORCE_SHIFT 7
98#define USB3_TX_EMPPH_PAR1_MASK (0x1F << 8)
99#define USB3_TX_EMPPH_PAR1_SHIFT 8
100#define USB3_TX_EMPPH_PAR2_MASK (0x1 << 13)
101#define USB3_TX_EMPPH_PAR2_SHIFT 13
102
103#define USB3_PIPE_SM_CTRL_PHY_INIT_DONE 15
104
105#endif /* __MV_U3D_PHY_H */
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
new file mode 100644
index 000000000000..15ab3d6f2e8c
--- /dev/null
+++ b/drivers/usb/phy/omap-usb2.c
@@ -0,0 +1,271 @@
1/*
2 * omap-usb2.c - USB PHY, talking to musb controller in OMAP.
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/of.h>
23#include <linux/io.h>
24#include <linux/usb/omap_usb.h>
25#include <linux/usb/phy_companion.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28#include <linux/pm_runtime.h>
29#include <linux/delay.h>
30
31/**
32 * omap_usb2_set_comparator - links the comparator present in the sytem with
33 * this phy
34 * @comparator - the companion phy(comparator) for this phy
35 *
36 * The phy companion driver should call this API passing the phy_companion
37 * filled with set_vbus and start_srp to be used by usb phy.
38 *
39 * For use by phy companion driver
40 */
41int omap_usb2_set_comparator(struct phy_companion *comparator)
42{
43 struct omap_usb *phy;
44 struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2);
45
46 if (IS_ERR(x))
47 return -ENODEV;
48
49 phy = phy_to_omapusb(x);
50 phy->comparator = comparator;
51 return 0;
52}
53EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
54
55/**
56 * omap_usb_phy_power - power on/off the phy using control module reg
57 * @phy: struct omap_usb *
58 * @on: 0 or 1, based on powering on or off the PHY
59 *
60 * XXX: Remove this function once control module driver gets merged
61 */
62static void omap_usb_phy_power(struct omap_usb *phy, int on)
63{
64 u32 val;
65
66 if (on) {
67 val = readl(phy->control_dev);
68 if (val & PHY_PD) {
69 writel(~PHY_PD, phy->control_dev);
70 /* XXX: add proper documentation for this delay */
71 mdelay(200);
72 }
73 } else {
74 writel(PHY_PD, phy->control_dev);
75 }
76}
77
78static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
79{
80 struct omap_usb *phy = phy_to_omapusb(otg->phy);
81
82 if (!phy->comparator)
83 return -ENODEV;
84
85 return phy->comparator->set_vbus(phy->comparator, enabled);
86}
87
88static int omap_usb_start_srp(struct usb_otg *otg)
89{
90 struct omap_usb *phy = phy_to_omapusb(otg->phy);
91
92 if (!phy->comparator)
93 return -ENODEV;
94
95 return phy->comparator->start_srp(phy->comparator);
96}
97
98static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
99{
100 struct usb_phy *phy = otg->phy;
101
102 otg->host = host;
103 if (!host)
104 phy->state = OTG_STATE_UNDEFINED;
105
106 return 0;
107}
108
109static int omap_usb_set_peripheral(struct usb_otg *otg,
110 struct usb_gadget *gadget)
111{
112 struct usb_phy *phy = otg->phy;
113
114 otg->gadget = gadget;
115 if (!gadget)
116 phy->state = OTG_STATE_UNDEFINED;
117
118 return 0;
119}
120
121static int omap_usb2_suspend(struct usb_phy *x, int suspend)
122{
123 u32 ret;
124 struct omap_usb *phy = phy_to_omapusb(x);
125
126 if (suspend && !phy->is_suspended) {
127 omap_usb_phy_power(phy, 0);
128 pm_runtime_put_sync(phy->dev);
129 phy->is_suspended = 1;
130 } else if (!suspend && phy->is_suspended) {
131 ret = pm_runtime_get_sync(phy->dev);
132 if (ret < 0) {
133 dev_err(phy->dev, "get_sync failed with err %d\n",
134 ret);
135 return ret;
136 }
137 omap_usb_phy_power(phy, 1);
138 phy->is_suspended = 0;
139 }
140
141 return 0;
142}
143
144static int __devinit omap_usb2_probe(struct platform_device *pdev)
145{
146 struct omap_usb *phy;
147 struct usb_otg *otg;
148 struct resource *res;
149
150 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
151 if (!phy) {
152 dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
153 return -ENOMEM;
154 }
155
156 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
157 if (!otg) {
158 dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
159 return -ENOMEM;
160 }
161
162 phy->dev = &pdev->dev;
163
164 phy->phy.dev = phy->dev;
165 phy->phy.label = "omap-usb2";
166 phy->phy.set_suspend = omap_usb2_suspend;
167 phy->phy.otg = otg;
168
169 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
170
171 phy->control_dev = devm_request_and_ioremap(&pdev->dev, res);
172 if (phy->control_dev == NULL) {
173 dev_err(&pdev->dev, "Failed to obtain io memory\n");
174 return -ENXIO;
175 }
176
177 phy->is_suspended = 1;
178 omap_usb_phy_power(phy, 0);
179
180 otg->set_host = omap_usb_set_host;
181 otg->set_peripheral = omap_usb_set_peripheral;
182 otg->set_vbus = omap_usb_set_vbus;
183 otg->start_srp = omap_usb_start_srp;
184 otg->phy = &phy->phy;
185
186 phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
187 if (IS_ERR(phy->wkupclk)) {
188 dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
189 return PTR_ERR(phy->wkupclk);
190 }
191 clk_prepare(phy->wkupclk);
192
193 usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2);
194
195 platform_set_drvdata(pdev, phy);
196
197 pm_runtime_enable(phy->dev);
198
199 return 0;
200}
201
202static int __devexit omap_usb2_remove(struct platform_device *pdev)
203{
204 struct omap_usb *phy = platform_get_drvdata(pdev);
205
206 clk_unprepare(phy->wkupclk);
207 usb_remove_phy(&phy->phy);
208
209 return 0;
210}
211
212#ifdef CONFIG_PM_RUNTIME
213
214static int omap_usb2_runtime_suspend(struct device *dev)
215{
216 struct platform_device *pdev = to_platform_device(dev);
217 struct omap_usb *phy = platform_get_drvdata(pdev);
218
219 clk_disable(phy->wkupclk);
220
221 return 0;
222}
223
224static int omap_usb2_runtime_resume(struct device *dev)
225{
226 u32 ret = 0;
227 struct platform_device *pdev = to_platform_device(dev);
228 struct omap_usb *phy = platform_get_drvdata(pdev);
229
230 ret = clk_enable(phy->wkupclk);
231 if (ret < 0)
232 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
233
234 return ret;
235}
236
237static const struct dev_pm_ops omap_usb2_pm_ops = {
238 SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
239 NULL)
240};
241
242#define DEV_PM_OPS (&omap_usb2_pm_ops)
243#else
244#define DEV_PM_OPS NULL
245#endif
246
247#ifdef CONFIG_OF
248static const struct of_device_id omap_usb2_id_table[] = {
249 { .compatible = "ti,omap-usb2" },
250 {}
251};
252MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
253#endif
254
255static struct platform_driver omap_usb2_driver = {
256 .probe = omap_usb2_probe,
257 .remove = __devexit_p(omap_usb2_remove),
258 .driver = {
259 .name = "omap-usb2",
260 .owner = THIS_MODULE,
261 .pm = DEV_PM_OPS,
262 .of_match_table = of_match_ptr(omap_usb2_id_table),
263 },
264};
265
266module_platform_driver(omap_usb2_driver);
267
268MODULE_ALIAS("platform: omap_usb2");
269MODULE_AUTHOR("Texas Instruments Inc.");
270MODULE_DESCRIPTION("OMAP USB2 phy driver");
271MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
new file mode 100644
index 000000000000..4739903245e8
--- /dev/null
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -0,0 +1,839 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 *
4 * Author:
5 * Erik Gilling <konkers@google.com>
6 * Benoit Goby <benoit@android.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/resource.h>
20#include <linux/delay.h>
21#include <linux/slab.h>
22#include <linux/err.h>
23#include <linux/export.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <linux/of_gpio.h>
28#include <linux/usb/otg.h>
29#include <linux/usb/ulpi.h>
30#include <asm/mach-types.h>
31#include <mach/gpio-tegra.h>
32#include <linux/usb/tegra_usb_phy.h>
33#include <mach/iomap.h>
34
35#define ULPI_VIEWPORT 0x170
36
37#define USB_PORTSC1 0x184
38#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
39#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26)
40#define USB_PORTSC1_PHCD (1 << 23)
41#define USB_PORTSC1_WKOC (1 << 22)
42#define USB_PORTSC1_WKDS (1 << 21)
43#define USB_PORTSC1_WKCN (1 << 20)
44#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
45#define USB_PORTSC1_PP (1 << 12)
46#define USB_PORTSC1_SUSP (1 << 7)
47#define USB_PORTSC1_PE (1 << 2)
48#define USB_PORTSC1_CCS (1 << 0)
49
50#define USB_SUSP_CTRL 0x400
51#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
52#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
53#define USB_SUSP_CLR (1 << 5)
54#define USB_PHY_CLK_VALID (1 << 7)
55#define UTMIP_RESET (1 << 11)
56#define UHSIC_RESET (1 << 11)
57#define UTMIP_PHY_ENABLE (1 << 12)
58#define ULPI_PHY_ENABLE (1 << 13)
59#define USB_SUSP_SET (1 << 14)
60#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
61
62#define USB1_LEGACY_CTRL 0x410
63#define USB1_NO_LEGACY_MODE (1 << 0)
64#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
65#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1)
66#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \
67 (1 << 1)
68#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1)
69#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1)
70
71#define ULPI_TIMING_CTRL_0 0x424
72#define ULPI_OUTPUT_PINMUX_BYP (1 << 10)
73#define ULPI_CLKOUT_PINMUX_BYP (1 << 11)
74
75#define ULPI_TIMING_CTRL_1 0x428
76#define ULPI_DATA_TRIMMER_LOAD (1 << 0)
77#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1)
78#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16)
79#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17)
80#define ULPI_DIR_TRIMMER_LOAD (1 << 24)
81#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25)
82
83#define UTMIP_PLL_CFG1 0x804
84#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
85#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
86
87#define UTMIP_XCVR_CFG0 0x808
88#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
89#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
90#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
91#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
92#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
93#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
94#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25)
95
96#define UTMIP_BIAS_CFG0 0x80c
97#define UTMIP_OTGPD (1 << 11)
98#define UTMIP_BIASPD (1 << 10)
99
100#define UTMIP_HSRX_CFG0 0x810
101#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
102#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
103
104#define UTMIP_HSRX_CFG1 0x814
105#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
106
107#define UTMIP_TX_CFG0 0x820
108#define UTMIP_FS_PREABMLE_J (1 << 19)
109#define UTMIP_HS_DISCON_DISABLE (1 << 8)
110
111#define UTMIP_MISC_CFG0 0x824
112#define UTMIP_DPDM_OBSERVE (1 << 26)
113#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27)
114#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf)
115#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe)
116#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd)
117#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc)
118#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22)
119
120#define UTMIP_MISC_CFG1 0x828
121#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18)
122#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6)
123
124#define UTMIP_DEBOUNCE_CFG0 0x82c
125#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
126
127#define UTMIP_BAT_CHRG_CFG0 0x830
128#define UTMIP_PD_CHRG (1 << 0)
129
130#define UTMIP_SPARE_CFG0 0x834
131#define FUSE_SETUP_SEL (1 << 3)
132
133#define UTMIP_XCVR_CFG1 0x838
134#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
135#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
136#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
137#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
138
139#define UTMIP_BIAS_CFG1 0x83c
140#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
141
142static DEFINE_SPINLOCK(utmip_pad_lock);
143static int utmip_pad_count;
144
145struct tegra_xtal_freq {
146 int freq;
147 u8 enable_delay;
148 u8 stable_count;
149 u8 active_delay;
150 u8 xtal_freq_count;
151 u16 debounce;
152};
153
154static const struct tegra_xtal_freq tegra_freq_table[] = {
155 {
156 .freq = 12000000,
157 .enable_delay = 0x02,
158 .stable_count = 0x2F,
159 .active_delay = 0x04,
160 .xtal_freq_count = 0x76,
161 .debounce = 0x7530,
162 },
163 {
164 .freq = 13000000,
165 .enable_delay = 0x02,
166 .stable_count = 0x33,
167 .active_delay = 0x05,
168 .xtal_freq_count = 0x7F,
169 .debounce = 0x7EF4,
170 },
171 {
172 .freq = 19200000,
173 .enable_delay = 0x03,
174 .stable_count = 0x4B,
175 .active_delay = 0x06,
176 .xtal_freq_count = 0xBB,
177 .debounce = 0xBB80,
178 },
179 {
180 .freq = 26000000,
181 .enable_delay = 0x04,
182 .stable_count = 0x66,
183 .active_delay = 0x09,
184 .xtal_freq_count = 0xFE,
185 .debounce = 0xFDE8,
186 },
187};
188
189static struct tegra_utmip_config utmip_default[] = {
190 [0] = {
191 .hssync_start_delay = 9,
192 .idle_wait_delay = 17,
193 .elastic_limit = 16,
194 .term_range_adj = 6,
195 .xcvr_setup = 9,
196 .xcvr_lsfslew = 1,
197 .xcvr_lsrslew = 1,
198 },
199 [2] = {
200 .hssync_start_delay = 9,
201 .idle_wait_delay = 17,
202 .elastic_limit = 16,
203 .term_range_adj = 6,
204 .xcvr_setup = 9,
205 .xcvr_lsfslew = 2,
206 .xcvr_lsrslew = 2,
207 },
208};
209
210static inline bool phy_is_ulpi(struct tegra_usb_phy *phy)
211{
212 return (phy->instance == 1);
213}
214
215static int utmip_pad_open(struct tegra_usb_phy *phy)
216{
217 phy->pad_clk = clk_get_sys("utmip-pad", NULL);
218 if (IS_ERR(phy->pad_clk)) {
219 pr_err("%s: can't get utmip pad clock\n", __func__);
220 return PTR_ERR(phy->pad_clk);
221 }
222
223 if (phy->instance == 0) {
224 phy->pad_regs = phy->regs;
225 } else {
226 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
227 if (!phy->pad_regs) {
228 pr_err("%s: can't remap usb registers\n", __func__);
229 clk_put(phy->pad_clk);
230 return -ENOMEM;
231 }
232 }
233 return 0;
234}
235
236static void utmip_pad_close(struct tegra_usb_phy *phy)
237{
238 if (phy->instance != 0)
239 iounmap(phy->pad_regs);
240 clk_put(phy->pad_clk);
241}
242
243static void utmip_pad_power_on(struct tegra_usb_phy *phy)
244{
245 unsigned long val, flags;
246 void __iomem *base = phy->pad_regs;
247
248 clk_prepare_enable(phy->pad_clk);
249
250 spin_lock_irqsave(&utmip_pad_lock, flags);
251
252 if (utmip_pad_count++ == 0) {
253 val = readl(base + UTMIP_BIAS_CFG0);
254 val &= ~(UTMIP_OTGPD | UTMIP_BIASPD);
255 writel(val, base + UTMIP_BIAS_CFG0);
256 }
257
258 spin_unlock_irqrestore(&utmip_pad_lock, flags);
259
260 clk_disable_unprepare(phy->pad_clk);
261}
262
263static int utmip_pad_power_off(struct tegra_usb_phy *phy)
264{
265 unsigned long val, flags;
266 void __iomem *base = phy->pad_regs;
267
268 if (!utmip_pad_count) {
269 pr_err("%s: utmip pad already powered off\n", __func__);
270 return -EINVAL;
271 }
272
273 clk_prepare_enable(phy->pad_clk);
274
275 spin_lock_irqsave(&utmip_pad_lock, flags);
276
277 if (--utmip_pad_count == 0) {
278 val = readl(base + UTMIP_BIAS_CFG0);
279 val |= UTMIP_OTGPD | UTMIP_BIASPD;
280 writel(val, base + UTMIP_BIAS_CFG0);
281 }
282
283 spin_unlock_irqrestore(&utmip_pad_lock, flags);
284
285 clk_disable_unprepare(phy->pad_clk);
286
287 return 0;
288}
289
290static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)
291{
292 unsigned long timeout = 2000;
293 do {
294 if ((readl(reg) & mask) == result)
295 return 0;
296 udelay(1);
297 timeout--;
298 } while (timeout);
299 return -1;
300}
301
302static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
303{
304 unsigned long val;
305 void __iomem *base = phy->regs;
306
307 if (phy->instance == 0) {
308 val = readl(base + USB_SUSP_CTRL);
309 val |= USB_SUSP_SET;
310 writel(val, base + USB_SUSP_CTRL);
311
312 udelay(10);
313
314 val = readl(base + USB_SUSP_CTRL);
315 val &= ~USB_SUSP_SET;
316 writel(val, base + USB_SUSP_CTRL);
317 }
318
319 if (phy->instance == 2) {
320 val = readl(base + USB_PORTSC1);
321 val |= USB_PORTSC1_PHCD;
322 writel(val, base + USB_PORTSC1);
323 }
324
325 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
326 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
327}
328
329static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
330{
331 unsigned long val;
332 void __iomem *base = phy->regs;
333
334 if (phy->instance == 0) {
335 val = readl(base + USB_SUSP_CTRL);
336 val |= USB_SUSP_CLR;
337 writel(val, base + USB_SUSP_CTRL);
338
339 udelay(10);
340
341 val = readl(base + USB_SUSP_CTRL);
342 val &= ~USB_SUSP_CLR;
343 writel(val, base + USB_SUSP_CTRL);
344 }
345
346 if (phy->instance == 2) {
347 val = readl(base + USB_PORTSC1);
348 val &= ~USB_PORTSC1_PHCD;
349 writel(val, base + USB_PORTSC1);
350 }
351
352 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
353 USB_PHY_CLK_VALID))
354 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
355}
356
357static int utmi_phy_power_on(struct tegra_usb_phy *phy)
358{
359 unsigned long val;
360 void __iomem *base = phy->regs;
361 struct tegra_utmip_config *config = phy->config;
362
363 val = readl(base + USB_SUSP_CTRL);
364 val |= UTMIP_RESET;
365 writel(val, base + USB_SUSP_CTRL);
366
367 if (phy->instance == 0) {
368 val = readl(base + USB1_LEGACY_CTRL);
369 val |= USB1_NO_LEGACY_MODE;
370 writel(val, base + USB1_LEGACY_CTRL);
371 }
372
373 val = readl(base + UTMIP_TX_CFG0);
374 val &= ~UTMIP_FS_PREABMLE_J;
375 writel(val, base + UTMIP_TX_CFG0);
376
377 val = readl(base + UTMIP_HSRX_CFG0);
378 val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0));
379 val |= UTMIP_IDLE_WAIT(config->idle_wait_delay);
380 val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit);
381 writel(val, base + UTMIP_HSRX_CFG0);
382
383 val = readl(base + UTMIP_HSRX_CFG1);
384 val &= ~UTMIP_HS_SYNC_START_DLY(~0);
385 val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay);
386 writel(val, base + UTMIP_HSRX_CFG1);
387
388 val = readl(base + UTMIP_DEBOUNCE_CFG0);
389 val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
390 val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce);
391 writel(val, base + UTMIP_DEBOUNCE_CFG0);
392
393 val = readl(base + UTMIP_MISC_CFG0);
394 val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
395 writel(val, base + UTMIP_MISC_CFG0);
396
397 val = readl(base + UTMIP_MISC_CFG1);
398 val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0));
399 val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) |
400 UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count);
401 writel(val, base + UTMIP_MISC_CFG1);
402
403 val = readl(base + UTMIP_PLL_CFG1);
404 val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0));
405 val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) |
406 UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
407 writel(val, base + UTMIP_PLL_CFG1);
408
409 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
410 val = readl(base + USB_SUSP_CTRL);
411 val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
412 writel(val, base + USB_SUSP_CTRL);
413 }
414
415 utmip_pad_power_on(phy);
416
417 val = readl(base + UTMIP_XCVR_CFG0);
418 val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
419 UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) |
420 UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) |
421 UTMIP_XCVR_HSSLEW_MSB(~0));
422 val |= UTMIP_XCVR_SETUP(config->xcvr_setup);
423 val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
424 val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);
425 writel(val, base + UTMIP_XCVR_CFG0);
426
427 val = readl(base + UTMIP_XCVR_CFG1);
428 val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
429 UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0));
430 val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj);
431 writel(val, base + UTMIP_XCVR_CFG1);
432
433 val = readl(base + UTMIP_BAT_CHRG_CFG0);
434 val &= ~UTMIP_PD_CHRG;
435 writel(val, base + UTMIP_BAT_CHRG_CFG0);
436
437 val = readl(base + UTMIP_BIAS_CFG1);
438 val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
439 val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
440 writel(val, base + UTMIP_BIAS_CFG1);
441
442 if (phy->instance == 0) {
443 val = readl(base + UTMIP_SPARE_CFG0);
444 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)
445 val &= ~FUSE_SETUP_SEL;
446 else
447 val |= FUSE_SETUP_SEL;
448 writel(val, base + UTMIP_SPARE_CFG0);
449 }
450
451 if (phy->instance == 2) {
452 val = readl(base + USB_SUSP_CTRL);
453 val |= UTMIP_PHY_ENABLE;
454 writel(val, base + USB_SUSP_CTRL);
455 }
456
457 val = readl(base + USB_SUSP_CTRL);
458 val &= ~UTMIP_RESET;
459 writel(val, base + USB_SUSP_CTRL);
460
461 if (phy->instance == 0) {
462 val = readl(base + USB1_LEGACY_CTRL);
463 val &= ~USB1_VBUS_SENSE_CTL_MASK;
464 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD;
465 writel(val, base + USB1_LEGACY_CTRL);
466
467 val = readl(base + USB_SUSP_CTRL);
468 val &= ~USB_SUSP_SET;
469 writel(val, base + USB_SUSP_CTRL);
470 }
471
472 utmi_phy_clk_enable(phy);
473
474 if (phy->instance == 2) {
475 val = readl(base + USB_PORTSC1);
476 val &= ~USB_PORTSC1_PTS(~0);
477 writel(val, base + USB_PORTSC1);
478 }
479
480 return 0;
481}
482
483static int utmi_phy_power_off(struct tegra_usb_phy *phy)
484{
485 unsigned long val;
486 void __iomem *base = phy->regs;
487
488 utmi_phy_clk_disable(phy);
489
490 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
491 val = readl(base + USB_SUSP_CTRL);
492 val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
493 val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5);
494 writel(val, base + USB_SUSP_CTRL);
495 }
496
497 val = readl(base + USB_SUSP_CTRL);
498 val |= UTMIP_RESET;
499 writel(val, base + USB_SUSP_CTRL);
500
501 val = readl(base + UTMIP_BAT_CHRG_CFG0);
502 val |= UTMIP_PD_CHRG;
503 writel(val, base + UTMIP_BAT_CHRG_CFG0);
504
505 val = readl(base + UTMIP_XCVR_CFG0);
506 val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
507 UTMIP_FORCE_PDZI_POWERDOWN;
508 writel(val, base + UTMIP_XCVR_CFG0);
509
510 val = readl(base + UTMIP_XCVR_CFG1);
511 val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
512 UTMIP_FORCE_PDDR_POWERDOWN;
513 writel(val, base + UTMIP_XCVR_CFG1);
514
515 return utmip_pad_power_off(phy);
516}
517
518static void utmi_phy_preresume(struct tegra_usb_phy *phy)
519{
520 unsigned long val;
521 void __iomem *base = phy->regs;
522
523 val = readl(base + UTMIP_TX_CFG0);
524 val |= UTMIP_HS_DISCON_DISABLE;
525 writel(val, base + UTMIP_TX_CFG0);
526}
527
528static void utmi_phy_postresume(struct tegra_usb_phy *phy)
529{
530 unsigned long val;
531 void __iomem *base = phy->regs;
532
533 val = readl(base + UTMIP_TX_CFG0);
534 val &= ~UTMIP_HS_DISCON_DISABLE;
535 writel(val, base + UTMIP_TX_CFG0);
536}
537
538static void utmi_phy_restore_start(struct tegra_usb_phy *phy,
539 enum tegra_usb_phy_port_speed port_speed)
540{
541 unsigned long val;
542 void __iomem *base = phy->regs;
543
544 val = readl(base + UTMIP_MISC_CFG0);
545 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
546 if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
547 val |= UTMIP_DPDM_OBSERVE_SEL_FS_K;
548 else
549 val |= UTMIP_DPDM_OBSERVE_SEL_FS_J;
550 writel(val, base + UTMIP_MISC_CFG0);
551 udelay(1);
552
553 val = readl(base + UTMIP_MISC_CFG0);
554 val |= UTMIP_DPDM_OBSERVE;
555 writel(val, base + UTMIP_MISC_CFG0);
556 udelay(10);
557}
558
559static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
560{
561 unsigned long val;
562 void __iomem *base = phy->regs;
563
564 val = readl(base + UTMIP_MISC_CFG0);
565 val &= ~UTMIP_DPDM_OBSERVE;
566 writel(val, base + UTMIP_MISC_CFG0);
567 udelay(10);
568}
569
570static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
571{
572 int ret;
573 unsigned long val;
574 void __iomem *base = phy->regs;
575 struct tegra_ulpi_config *config = phy->config;
576
577 gpio_direction_output(config->reset_gpio, 0);
578 msleep(5);
579 gpio_direction_output(config->reset_gpio, 1);
580
581 clk_prepare_enable(phy->clk);
582 msleep(1);
583
584 val = readl(base + USB_SUSP_CTRL);
585 val |= UHSIC_RESET;
586 writel(val, base + USB_SUSP_CTRL);
587
588 val = readl(base + ULPI_TIMING_CTRL_0);
589 val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
590 writel(val, base + ULPI_TIMING_CTRL_0);
591
592 val = readl(base + USB_SUSP_CTRL);
593 val |= ULPI_PHY_ENABLE;
594 writel(val, base + USB_SUSP_CTRL);
595
596 val = 0;
597 writel(val, base + ULPI_TIMING_CTRL_1);
598
599 val |= ULPI_DATA_TRIMMER_SEL(4);
600 val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
601 val |= ULPI_DIR_TRIMMER_SEL(4);
602 writel(val, base + ULPI_TIMING_CTRL_1);
603 udelay(10);
604
605 val |= ULPI_DATA_TRIMMER_LOAD;
606 val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
607 val |= ULPI_DIR_TRIMMER_LOAD;
608 writel(val, base + ULPI_TIMING_CTRL_1);
609
610 /* Fix VbusInvalid due to floating VBUS */
611 ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08);
612 if (ret) {
613 pr_err("%s: ulpi write failed\n", __func__);
614 return ret;
615 }
616
617 ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B);
618 if (ret) {
619 pr_err("%s: ulpi write failed\n", __func__);
620 return ret;
621 }
622
623 val = readl(base + USB_PORTSC1);
624 val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
625 writel(val, base + USB_PORTSC1);
626
627 val = readl(base + USB_SUSP_CTRL);
628 val |= USB_SUSP_CLR;
629 writel(val, base + USB_SUSP_CTRL);
630 udelay(100);
631
632 val = readl(base + USB_SUSP_CTRL);
633 val &= ~USB_SUSP_CLR;
634 writel(val, base + USB_SUSP_CTRL);
635
636 return 0;
637}
638
639static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
640{
641 unsigned long val;
642 void __iomem *base = phy->regs;
643 struct tegra_ulpi_config *config = phy->config;
644
645 /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB
646 * Controller to immediately bring the ULPI PHY out of low power
647 */
648 val = readl(base + USB_PORTSC1);
649 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
650 writel(val, base + USB_PORTSC1);
651
652 clk_disable(phy->clk);
653 return gpio_direction_output(config->reset_gpio, 0);
654}
655
656static int tegra_phy_init(struct usb_phy *x)
657{
658 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
659 struct tegra_ulpi_config *ulpi_config;
660 int err;
661
662 if (phy_is_ulpi(phy)) {
663 ulpi_config = phy->config;
664 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
665 if (IS_ERR(phy->clk)) {
666 pr_err("%s: can't get ulpi clock\n", __func__);
667 err = -ENXIO;
668 goto err1;
669 }
670 if (!gpio_is_valid(ulpi_config->reset_gpio))
671 ulpi_config->reset_gpio =
672 of_get_named_gpio(phy->dev->of_node,
673 "nvidia,phy-reset-gpio", 0);
674 if (!gpio_is_valid(ulpi_config->reset_gpio)) {
675 pr_err("%s: invalid reset gpio: %d\n", __func__,
676 ulpi_config->reset_gpio);
677 err = -EINVAL;
678 goto err1;
679 }
680 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
681 gpio_direction_output(ulpi_config->reset_gpio, 0);
682 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
683 phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT;
684 } else {
685 err = utmip_pad_open(phy);
686 if (err < 0)
687 goto err1;
688 }
689 return 0;
690err1:
691 clk_disable_unprepare(phy->pll_u);
692 clk_put(phy->pll_u);
693 return err;
694}
695
696static void tegra_usb_phy_close(struct usb_phy *x)
697{
698 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
699
700 if (phy_is_ulpi(phy))
701 clk_put(phy->clk);
702 else
703 utmip_pad_close(phy);
704 clk_disable_unprepare(phy->pll_u);
705 clk_put(phy->pll_u);
706 kfree(phy);
707}
708
709static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
710{
711 if (phy_is_ulpi(phy))
712 return ulpi_phy_power_on(phy);
713 else
714 return utmi_phy_power_on(phy);
715}
716
717static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
718{
719 if (phy_is_ulpi(phy))
720 return ulpi_phy_power_off(phy);
721 else
722 return utmi_phy_power_off(phy);
723}
724
725static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend)
726{
727 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
728 if (suspend)
729 return tegra_usb_phy_power_off(phy);
730 else
731 return tegra_usb_phy_power_on(phy);
732}
733
734struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
735 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
736{
737 struct tegra_usb_phy *phy;
738 unsigned long parent_rate;
739 int i;
740 int err;
741
742 phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
743 if (!phy)
744 return ERR_PTR(-ENOMEM);
745
746 phy->instance = instance;
747 phy->regs = regs;
748 phy->config = config;
749 phy->mode = phy_mode;
750 phy->dev = dev;
751
752 if (!phy->config) {
753 if (phy_is_ulpi(phy)) {
754 pr_err("%s: ulpi phy configuration missing", __func__);
755 err = -EINVAL;
756 goto err0;
757 } else {
758 phy->config = &utmip_default[instance];
759 }
760 }
761
762 phy->pll_u = clk_get_sys(NULL, "pll_u");
763 if (IS_ERR(phy->pll_u)) {
764 pr_err("Can't get pll_u clock\n");
765 err = PTR_ERR(phy->pll_u);
766 goto err0;
767 }
768 clk_prepare_enable(phy->pll_u);
769
770 parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
771 for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) {
772 if (tegra_freq_table[i].freq == parent_rate) {
773 phy->freq = &tegra_freq_table[i];
774 break;
775 }
776 }
777 if (!phy->freq) {
778 pr_err("invalid pll_u parent rate %ld\n", parent_rate);
779 err = -EINVAL;
780 goto err1;
781 }
782
783 phy->u_phy.init = tegra_phy_init;
784 phy->u_phy.shutdown = tegra_usb_phy_close;
785 phy->u_phy.set_suspend = tegra_usb_phy_suspend;
786
787 return phy;
788
789err1:
790 clk_disable_unprepare(phy->pll_u);
791 clk_put(phy->pll_u);
792err0:
793 kfree(phy);
794 return ERR_PTR(err);
795}
796EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
797
798void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
799{
800 if (!phy_is_ulpi(phy))
801 utmi_phy_preresume(phy);
802}
803EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume);
804
805void tegra_usb_phy_postresume(struct tegra_usb_phy *phy)
806{
807 if (!phy_is_ulpi(phy))
808 utmi_phy_postresume(phy);
809}
810EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume);
811
812void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
813 enum tegra_usb_phy_port_speed port_speed)
814{
815 if (!phy_is_ulpi(phy))
816 utmi_phy_restore_start(phy, port_speed);
817}
818EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start);
819
820void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy)
821{
822 if (!phy_is_ulpi(phy))
823 utmi_phy_restore_end(phy);
824}
825EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end);
826
827void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
828{
829 if (!phy_is_ulpi(phy))
830 utmi_phy_clk_disable(phy);
831}
832EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable);
833
834void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
835{
836 if (!phy_is_ulpi(phy))
837 utmi_phy_clk_enable(phy);
838}
839EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);