diff options
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r-- | drivers/usb/phy/Kconfig | 7 | ||||
-rw-r--r-- | drivers/usb/phy/phy-am335x.c | 4 | ||||
-rw-r--r-- | drivers/usb/phy/phy-generic.c | 65 | ||||
-rw-r--r-- | drivers/usb/phy/phy-generic.h | 8 | ||||
-rw-r--r-- | drivers/usb/phy/phy-keystone.c | 4 | ||||
-rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 700 | ||||
-rw-r--r-- | drivers/usb/phy/phy-ulpi.c | 1 |
7 files changed, 437 insertions, 352 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 33dd6a6c320a..adccdeb996d9 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
@@ -163,11 +163,12 @@ config USB_ISP1301 | |||
163 | module will be called phy-isp1301. | 163 | module will be called phy-isp1301. |
164 | 164 | ||
165 | config USB_MSM_OTG | 165 | config USB_MSM_OTG |
166 | tristate "OTG support for Qualcomm on-chip USB controller" | 166 | tristate "Qualcomm on-chip USB OTG controller support" |
167 | depends on (USB || USB_GADGET) && ARCH_MSM | 167 | depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM || COMPILE_TEST) |
168 | depends on RESET_CONTROLLER | ||
168 | select USB_PHY | 169 | select USB_PHY |
169 | help | 170 | help |
170 | Enable this to support the USB OTG transceiver on MSM chips. It | 171 | Enable this to support the USB OTG transceiver on Qualcomm chips. It |
171 | handles PHY initialization, clock management, and workarounds | 172 | handles PHY initialization, clock management, and workarounds |
172 | required after resetting the hardware and power management. | 173 | required after resetting the hardware and power management. |
173 | This driver is required even for peripheral only or host only | 174 | This driver is required even for peripheral only or host only |
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 12fc3468a01e..585e50cb1980 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <linux/platform_device.h> | 2 | #include <linux/platform_device.h> |
3 | #include <linux/dma-mapping.h> | 3 | #include <linux/dma-mapping.h> |
4 | #include <linux/usb/otg.h> | 4 | #include <linux/usb/otg.h> |
5 | #include <linux/usb/usb_phy_gen_xceiv.h> | 5 | #include <linux/usb/usb_phy_generic.h> |
6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/regulator/consumer.h> | 8 | #include <linux/regulator/consumer.h> |
@@ -13,7 +13,7 @@ | |||
13 | #include "phy-generic.h" | 13 | #include "phy-generic.h" |
14 | 14 | ||
15 | struct am335x_phy { | 15 | struct am335x_phy { |
16 | struct usb_phy_gen_xceiv usb_phy_gen; | 16 | struct usb_phy_generic usb_phy_gen; |
17 | struct phy_control *phy_ctrl; | 17 | struct phy_control *phy_ctrl; |
18 | int id; | 18 | int id; |
19 | }; | 19 | }; |
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index bb394980532b..7594e5069ae5 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -30,7 +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/usb_phy_gen_xceiv.h> | 33 | #include <linux/usb/usb_phy_generic.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/regulator/consumer.h> | 36 | #include <linux/regulator/consumer.h> |
@@ -41,34 +41,25 @@ | |||
41 | 41 | ||
42 | #include "phy-generic.h" | 42 | #include "phy-generic.h" |
43 | 43 | ||
44 | static struct platform_device *pd; | 44 | struct platform_device *usb_phy_generic_register(void) |
45 | |||
46 | void usb_nop_xceiv_register(void) | ||
47 | { | 45 | { |
48 | if (pd) | 46 | return platform_device_register_simple("usb_phy_generic", |
49 | return; | 47 | PLATFORM_DEVID_AUTO, NULL, 0); |
50 | pd = platform_device_register_simple("usb_phy_gen_xceiv", -1, NULL, 0); | ||
51 | if (IS_ERR(pd)) { | ||
52 | pr_err("Unable to register generic usb transceiver\n"); | ||
53 | pd = NULL; | ||
54 | return; | ||
55 | } | ||
56 | } | 48 | } |
57 | EXPORT_SYMBOL(usb_nop_xceiv_register); | 49 | EXPORT_SYMBOL_GPL(usb_phy_generic_register); |
58 | 50 | ||
59 | void usb_nop_xceiv_unregister(void) | 51 | void usb_phy_generic_unregister(struct platform_device *pdev) |
60 | { | 52 | { |
61 | platform_device_unregister(pd); | 53 | platform_device_unregister(pdev); |
62 | pd = NULL; | ||
63 | } | 54 | } |
64 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); | 55 | EXPORT_SYMBOL_GPL(usb_phy_generic_unregister); |
65 | 56 | ||
66 | static int nop_set_suspend(struct usb_phy *x, int suspend) | 57 | static int nop_set_suspend(struct usb_phy *x, int suspend) |
67 | { | 58 | { |
68 | return 0; | 59 | return 0; |
69 | } | 60 | } |
70 | 61 | ||
71 | static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) | 62 | static void nop_reset_set(struct usb_phy_generic *nop, int asserted) |
72 | { | 63 | { |
73 | int value; | 64 | int value; |
74 | 65 | ||
@@ -87,7 +78,7 @@ static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) | |||
87 | 78 | ||
88 | int usb_gen_phy_init(struct usb_phy *phy) | 79 | int usb_gen_phy_init(struct usb_phy *phy) |
89 | { | 80 | { |
90 | struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); | 81 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); |
91 | 82 | ||
92 | if (!IS_ERR(nop->vcc)) { | 83 | if (!IS_ERR(nop->vcc)) { |
93 | if (regulator_enable(nop->vcc)) | 84 | if (regulator_enable(nop->vcc)) |
@@ -106,7 +97,7 @@ EXPORT_SYMBOL_GPL(usb_gen_phy_init); | |||
106 | 97 | ||
107 | void usb_gen_phy_shutdown(struct usb_phy *phy) | 98 | void usb_gen_phy_shutdown(struct usb_phy *phy) |
108 | { | 99 | { |
109 | struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); | 100 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); |
110 | 101 | ||
111 | /* Assert RESET */ | 102 | /* Assert RESET */ |
112 | nop_reset_set(nop, 1); | 103 | nop_reset_set(nop, 1); |
@@ -150,8 +141,8 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
150 | return 0; | 141 | return 0; |
151 | } | 142 | } |
152 | 143 | ||
153 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | 144 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, |
154 | struct usb_phy_gen_xceiv_platform_data *pdata) | 145 | struct usb_phy_generic_platform_data *pdata) |
155 | { | 146 | { |
156 | enum usb_phy_type type = USB_PHY_TYPE_USB2; | 147 | enum usb_phy_type type = USB_PHY_TYPE_USB2; |
157 | int err; | 148 | int err; |
@@ -245,10 +236,10 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | |||
245 | } | 236 | } |
246 | EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); | 237 | EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); |
247 | 238 | ||
248 | static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) | 239 | static int usb_phy_generic_probe(struct platform_device *pdev) |
249 | { | 240 | { |
250 | struct device *dev = &pdev->dev; | 241 | struct device *dev = &pdev->dev; |
251 | struct usb_phy_gen_xceiv *nop; | 242 | struct usb_phy_generic *nop; |
252 | int err; | 243 | int err; |
253 | 244 | ||
254 | nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); | 245 | nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); |
@@ -274,9 +265,9 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) | |||
274 | return 0; | 265 | return 0; |
275 | } | 266 | } |
276 | 267 | ||
277 | static int usb_phy_gen_xceiv_remove(struct platform_device *pdev) | 268 | static int usb_phy_generic_remove(struct platform_device *pdev) |
278 | { | 269 | { |
279 | struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev); | 270 | struct usb_phy_generic *nop = platform_get_drvdata(pdev); |
280 | 271 | ||
281 | usb_remove_phy(&nop->phy); | 272 | usb_remove_phy(&nop->phy); |
282 | 273 | ||
@@ -290,29 +281,29 @@ static const struct of_device_id nop_xceiv_dt_ids[] = { | |||
290 | 281 | ||
291 | MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); | 282 | MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); |
292 | 283 | ||
293 | static struct platform_driver usb_phy_gen_xceiv_driver = { | 284 | static struct platform_driver usb_phy_generic_driver = { |
294 | .probe = usb_phy_gen_xceiv_probe, | 285 | .probe = usb_phy_generic_probe, |
295 | .remove = usb_phy_gen_xceiv_remove, | 286 | .remove = usb_phy_generic_remove, |
296 | .driver = { | 287 | .driver = { |
297 | .name = "usb_phy_gen_xceiv", | 288 | .name = "usb_phy_generic", |
298 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
299 | .of_match_table = nop_xceiv_dt_ids, | 290 | .of_match_table = nop_xceiv_dt_ids, |
300 | }, | 291 | }, |
301 | }; | 292 | }; |
302 | 293 | ||
303 | static int __init usb_phy_gen_xceiv_init(void) | 294 | static int __init usb_phy_generic_init(void) |
304 | { | 295 | { |
305 | return platform_driver_register(&usb_phy_gen_xceiv_driver); | 296 | return platform_driver_register(&usb_phy_generic_driver); |
306 | } | 297 | } |
307 | subsys_initcall(usb_phy_gen_xceiv_init); | 298 | subsys_initcall(usb_phy_generic_init); |
308 | 299 | ||
309 | static void __exit usb_phy_gen_xceiv_exit(void) | 300 | static void __exit usb_phy_generic_exit(void) |
310 | { | 301 | { |
311 | platform_driver_unregister(&usb_phy_gen_xceiv_driver); | 302 | platform_driver_unregister(&usb_phy_generic_driver); |
312 | } | 303 | } |
313 | module_exit(usb_phy_gen_xceiv_exit); | 304 | module_exit(usb_phy_generic_exit); |
314 | 305 | ||
315 | MODULE_ALIAS("platform:usb_phy_gen_xceiv"); | 306 | MODULE_ALIAS("platform:usb_phy_generic"); |
316 | MODULE_AUTHOR("Texas Instruments Inc"); | 307 | MODULE_AUTHOR("Texas Instruments Inc"); |
317 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); | 308 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); |
318 | MODULE_LICENSE("GPL"); | 309 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index 38a81f307b82..d8feacc0b7fb 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #ifndef _PHY_GENERIC_H_ | 1 | #ifndef _PHY_GENERIC_H_ |
2 | #define _PHY_GENERIC_H_ | 2 | #define _PHY_GENERIC_H_ |
3 | 3 | ||
4 | #include <linux/usb/usb_phy_gen_xceiv.h> | 4 | #include <linux/usb/usb_phy_generic.h> |
5 | 5 | ||
6 | struct usb_phy_gen_xceiv { | 6 | struct usb_phy_generic { |
7 | struct usb_phy phy; | 7 | struct usb_phy phy; |
8 | struct device *dev; | 8 | struct device *dev; |
9 | struct clk *clk; | 9 | struct clk *clk; |
@@ -15,7 +15,7 @@ struct usb_phy_gen_xceiv { | |||
15 | int usb_gen_phy_init(struct usb_phy *phy); | 15 | int usb_gen_phy_init(struct usb_phy *phy); |
16 | void usb_gen_phy_shutdown(struct usb_phy *phy); | 16 | void usb_gen_phy_shutdown(struct usb_phy *phy); |
17 | 17 | ||
18 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | 18 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, |
19 | struct usb_phy_gen_xceiv_platform_data *pdata); | 19 | struct usb_phy_generic_platform_data *pdata); |
20 | 20 | ||
21 | #endif | 21 | #endif |
diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index d762003896c0..f4d722de912b 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/usb/usb_phy_gen_xceiv.h> | 21 | #include <linux/usb/usb_phy_generic.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | 24 | ||
@@ -35,7 +35,7 @@ | |||
35 | #define PHY_REF_SSP_EN BIT(29) | 35 | #define PHY_REF_SSP_EN BIT(29) |
36 | 36 | ||
37 | struct keystone_usbphy { | 37 | struct keystone_usbphy { |
38 | struct usb_phy_gen_xceiv usb_phy_gen; | 38 | struct usb_phy_generic usb_phy_gen; |
39 | void __iomem *phy_ctrl; | 39 | void __iomem *phy_ctrl; |
40 | }; | 40 | }; |
41 | 41 | ||
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 5b37b81f2ef6..4f88174aede5 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -30,9 +30,13 @@ | |||
30 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/of.h> | ||
34 | #include <linux/of_device.h> | ||
35 | #include <linux/reset.h> | ||
33 | 36 | ||
34 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
35 | #include <linux/usb/otg.h> | 38 | #include <linux/usb/otg.h> |
39 | #include <linux/usb/of.h> | ||
36 | #include <linux/usb/ulpi.h> | 40 | #include <linux/usb/ulpi.h> |
37 | #include <linux/usb/gadget.h> | 41 | #include <linux/usb/gadget.h> |
38 | #include <linux/usb/hcd.h> | 42 | #include <linux/usb/hcd.h> |
@@ -44,6 +48,7 @@ | |||
44 | #define DRIVER_NAME "msm_otg" | 48 | #define DRIVER_NAME "msm_otg" |
45 | 49 | ||
46 | #define ULPI_IO_TIMEOUT_USEC (10 * 1000) | 50 | #define ULPI_IO_TIMEOUT_USEC (10 * 1000) |
51 | #define LINK_RESET_TIMEOUT_USEC (250 * 1000) | ||
47 | 52 | ||
48 | #define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ | 53 | #define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ |
49 | #define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ | 54 | #define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ |
@@ -57,48 +62,38 @@ | |||
57 | 62 | ||
58 | #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ | 63 | #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ |
59 | #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ | 64 | #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ |
65 | #define USB_PHY_SUSP_DIG_VOL 500000 /* uV */ | ||
60 | 66 | ||
61 | static struct regulator *hsusb_3p3; | 67 | enum vdd_levels { |
62 | static struct regulator *hsusb_1p8; | 68 | VDD_LEVEL_NONE = 0, |
63 | static struct regulator *hsusb_vddcx; | 69 | VDD_LEVEL_MIN, |
70 | VDD_LEVEL_MAX, | ||
71 | }; | ||
64 | 72 | ||
65 | static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) | 73 | static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) |
66 | { | 74 | { |
67 | int ret = 0; | 75 | int ret = 0; |
68 | 76 | ||
69 | if (init) { | 77 | if (init) { |
70 | hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); | 78 | ret = regulator_set_voltage(motg->vddcx, |
71 | if (IS_ERR(hsusb_vddcx)) { | 79 | motg->vdd_levels[VDD_LEVEL_MIN], |
72 | dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); | 80 | motg->vdd_levels[VDD_LEVEL_MAX]); |
73 | return PTR_ERR(hsusb_vddcx); | ||
74 | } | ||
75 | |||
76 | ret = regulator_set_voltage(hsusb_vddcx, | ||
77 | USB_PHY_VDD_DIG_VOL_MIN, | ||
78 | USB_PHY_VDD_DIG_VOL_MAX); | ||
79 | if (ret) { | 81 | if (ret) { |
80 | dev_err(motg->phy.dev, "unable to set the voltage " | 82 | dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); |
81 | "for hsusb vddcx\n"); | ||
82 | regulator_put(hsusb_vddcx); | ||
83 | return ret; | 83 | return ret; |
84 | } | 84 | } |
85 | 85 | ||
86 | ret = regulator_enable(hsusb_vddcx); | 86 | ret = regulator_enable(motg->vddcx); |
87 | if (ret) { | 87 | if (ret) |
88 | dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); | 88 | dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); |
89 | regulator_put(hsusb_vddcx); | ||
90 | } | ||
91 | } else { | 89 | } else { |
92 | ret = regulator_set_voltage(hsusb_vddcx, 0, | 90 | ret = regulator_set_voltage(motg->vddcx, 0, |
93 | USB_PHY_VDD_DIG_VOL_MAX); | 91 | motg->vdd_levels[VDD_LEVEL_MAX]); |
94 | if (ret) | 92 | if (ret) |
95 | dev_err(motg->phy.dev, "unable to set the voltage " | 93 | dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); |
96 | "for hsusb vddcx\n"); | 94 | ret = regulator_disable(motg->vddcx); |
97 | ret = regulator_disable(hsusb_vddcx); | ||
98 | if (ret) | 95 | if (ret) |
99 | dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); | 96 | dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); |
100 | |||
101 | regulator_put(hsusb_vddcx); | ||
102 | } | 97 | } |
103 | 98 | ||
104 | return ret; | 99 | return ret; |
@@ -109,98 +104,67 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) | |||
109 | int rc = 0; | 104 | int rc = 0; |
110 | 105 | ||
111 | if (init) { | 106 | if (init) { |
112 | hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); | 107 | rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, |
113 | if (IS_ERR(hsusb_3p3)) { | ||
114 | dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); | ||
115 | return PTR_ERR(hsusb_3p3); | ||
116 | } | ||
117 | |||
118 | rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, | ||
119 | USB_PHY_3P3_VOL_MAX); | 108 | USB_PHY_3P3_VOL_MAX); |
120 | if (rc) { | 109 | if (rc) { |
121 | dev_err(motg->phy.dev, "unable to set voltage level " | 110 | dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); |
122 | "for hsusb 3p3\n"); | 111 | goto exit; |
123 | goto put_3p3; | ||
124 | } | 112 | } |
125 | rc = regulator_enable(hsusb_3p3); | 113 | rc = regulator_enable(motg->v3p3); |
126 | if (rc) { | 114 | if (rc) { |
127 | dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); | 115 | dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); |
128 | goto put_3p3; | 116 | goto exit; |
129 | } | 117 | } |
130 | hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); | 118 | rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, |
131 | if (IS_ERR(hsusb_1p8)) { | ||
132 | dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); | ||
133 | rc = PTR_ERR(hsusb_1p8); | ||
134 | goto disable_3p3; | ||
135 | } | ||
136 | rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, | ||
137 | USB_PHY_1P8_VOL_MAX); | 119 | USB_PHY_1P8_VOL_MAX); |
138 | if (rc) { | 120 | if (rc) { |
139 | dev_err(motg->phy.dev, "unable to set voltage level " | 121 | dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); |
140 | "for hsusb 1p8\n"); | 122 | goto disable_3p3; |
141 | goto put_1p8; | ||
142 | } | 123 | } |
143 | rc = regulator_enable(hsusb_1p8); | 124 | rc = regulator_enable(motg->v1p8); |
144 | if (rc) { | 125 | if (rc) { |
145 | dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); | 126 | dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); |
146 | goto put_1p8; | 127 | goto disable_3p3; |
147 | } | 128 | } |
148 | 129 | ||
149 | return 0; | 130 | return 0; |
150 | } | 131 | } |
151 | 132 | ||
152 | regulator_disable(hsusb_1p8); | 133 | regulator_disable(motg->v1p8); |
153 | put_1p8: | ||
154 | regulator_put(hsusb_1p8); | ||
155 | disable_3p3: | 134 | disable_3p3: |
156 | regulator_disable(hsusb_3p3); | 135 | regulator_disable(motg->v3p3); |
157 | put_3p3: | 136 | exit: |
158 | regulator_put(hsusb_3p3); | ||
159 | return rc; | 137 | return rc; |
160 | } | 138 | } |
161 | 139 | ||
162 | static int msm_hsusb_ldo_set_mode(int on) | 140 | static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) |
163 | { | 141 | { |
164 | int ret = 0; | 142 | int ret = 0; |
165 | 143 | ||
166 | if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { | ||
167 | pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); | ||
168 | return -ENODEV; | ||
169 | } | ||
170 | |||
171 | if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { | ||
172 | pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); | ||
173 | return -ENODEV; | ||
174 | } | ||
175 | |||
176 | if (on) { | 144 | if (on) { |
177 | ret = regulator_set_optimum_mode(hsusb_1p8, | 145 | ret = regulator_set_optimum_mode(motg->v1p8, |
178 | USB_PHY_1P8_HPM_LOAD); | 146 | USB_PHY_1P8_HPM_LOAD); |
179 | if (ret < 0) { | 147 | if (ret < 0) { |
180 | pr_err("%s: Unable to set HPM of the regulator " | 148 | pr_err("Could not set HPM for v1p8\n"); |
181 | "HSUSB_1p8\n", __func__); | ||
182 | return ret; | 149 | return ret; |
183 | } | 150 | } |
184 | ret = regulator_set_optimum_mode(hsusb_3p3, | 151 | ret = regulator_set_optimum_mode(motg->v3p3, |
185 | USB_PHY_3P3_HPM_LOAD); | 152 | USB_PHY_3P3_HPM_LOAD); |
186 | if (ret < 0) { | 153 | if (ret < 0) { |
187 | pr_err("%s: Unable to set HPM of the regulator " | 154 | pr_err("Could not set HPM for v3p3\n"); |
188 | "HSUSB_3p3\n", __func__); | 155 | regulator_set_optimum_mode(motg->v1p8, |
189 | regulator_set_optimum_mode(hsusb_1p8, | ||
190 | USB_PHY_1P8_LPM_LOAD); | 156 | USB_PHY_1P8_LPM_LOAD); |
191 | return ret; | 157 | return ret; |
192 | } | 158 | } |
193 | } else { | 159 | } else { |
194 | ret = regulator_set_optimum_mode(hsusb_1p8, | 160 | ret = regulator_set_optimum_mode(motg->v1p8, |
195 | USB_PHY_1P8_LPM_LOAD); | 161 | USB_PHY_1P8_LPM_LOAD); |
196 | if (ret < 0) | 162 | if (ret < 0) |
197 | pr_err("%s: Unable to set LPM of the regulator " | 163 | pr_err("Could not set LPM for v1p8\n"); |
198 | "HSUSB_1p8\n", __func__); | 164 | ret = regulator_set_optimum_mode(motg->v3p3, |
199 | ret = regulator_set_optimum_mode(hsusb_3p3, | ||
200 | USB_PHY_3P3_LPM_LOAD); | 165 | USB_PHY_3P3_LPM_LOAD); |
201 | if (ret < 0) | 166 | if (ret < 0) |
202 | pr_err("%s: Unable to set LPM of the regulator " | 167 | pr_err("Could not set LPM for v3p3\n"); |
203 | "HSUSB_3p3\n", __func__); | ||
204 | } | 168 | } |
205 | 169 | ||
206 | pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); | 170 | pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); |
@@ -265,27 +229,47 @@ static struct usb_phy_io_ops msm_otg_io_ops = { | |||
265 | static void ulpi_init(struct msm_otg *motg) | 229 | static void ulpi_init(struct msm_otg *motg) |
266 | { | 230 | { |
267 | struct msm_otg_platform_data *pdata = motg->pdata; | 231 | struct msm_otg_platform_data *pdata = motg->pdata; |
268 | int *seq = pdata->phy_init_seq; | 232 | int *seq = pdata->phy_init_seq, idx; |
233 | u32 addr = ULPI_EXT_VENDOR_SPECIFIC; | ||
269 | 234 | ||
270 | if (!seq) | 235 | for (idx = 0; idx < pdata->phy_init_sz; idx++) { |
271 | return; | 236 | if (seq[idx] == -1) |
237 | continue; | ||
272 | 238 | ||
273 | while (seq[0] >= 0) { | ||
274 | dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", | 239 | dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", |
275 | seq[0], seq[1]); | 240 | seq[idx], addr + idx); |
276 | ulpi_write(&motg->phy, seq[0], seq[1]); | 241 | ulpi_write(&motg->phy, seq[idx], addr + idx); |
277 | seq += 2; | ||
278 | } | 242 | } |
279 | } | 243 | } |
280 | 244 | ||
245 | static int msm_phy_notify_disconnect(struct usb_phy *phy, | ||
246 | enum usb_device_speed speed) | ||
247 | { | ||
248 | int val; | ||
249 | |||
250 | /* | ||
251 | * Put the transceiver in non-driving mode. Otherwise host | ||
252 | * may not detect soft-disconnection. | ||
253 | */ | ||
254 | val = ulpi_read(phy, ULPI_FUNC_CTRL); | ||
255 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
256 | val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; | ||
257 | ulpi_write(phy, val, ULPI_FUNC_CTRL); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
281 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | 262 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) |
282 | { | 263 | { |
283 | int ret = 0; | 264 | int ret; |
284 | 265 | ||
285 | if (!motg->pdata->link_clk_reset) | 266 | if (motg->pdata->link_clk_reset) |
286 | return ret; | 267 | ret = motg->pdata->link_clk_reset(motg->clk, assert); |
268 | else if (assert) | ||
269 | ret = reset_control_assert(motg->link_rst); | ||
270 | else | ||
271 | ret = reset_control_deassert(motg->link_rst); | ||
287 | 272 | ||
288 | ret = motg->pdata->link_clk_reset(motg->clk, assert); | ||
289 | if (ret) | 273 | if (ret) |
290 | dev_err(motg->phy.dev, "usb link clk reset %s failed\n", | 274 | dev_err(motg->phy.dev, "usb link clk reset %s failed\n", |
291 | assert ? "assert" : "deassert"); | 275 | assert ? "assert" : "deassert"); |
@@ -295,111 +279,150 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | |||
295 | 279 | ||
296 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) |
297 | { | 281 | { |
298 | int ret = 0; | 282 | int ret; |
299 | 283 | ||
300 | if (!motg->pdata->phy_clk_reset) | 284 | if (motg->pdata->phy_clk_reset) |
301 | return ret; | 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); |
286 | else | ||
287 | ret = reset_control_reset(motg->phy_rst); | ||
302 | 288 | ||
303 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); | ||
304 | if (ret) | 289 | if (ret) |
305 | dev_err(motg->phy.dev, "usb phy clk reset failed\n"); | 290 | dev_err(motg->phy.dev, "usb phy clk reset failed\n"); |
306 | 291 | ||
307 | return ret; | 292 | return ret; |
308 | } | 293 | } |
309 | 294 | ||
310 | static int msm_otg_phy_reset(struct msm_otg *motg) | 295 | static int msm_link_reset(struct msm_otg *motg) |
311 | { | 296 | { |
312 | u32 val; | 297 | u32 val; |
313 | int ret; | 298 | int ret; |
314 | int retries; | ||
315 | 299 | ||
316 | ret = msm_otg_link_clk_reset(motg, 1); | 300 | ret = msm_otg_link_clk_reset(motg, 1); |
317 | if (ret) | 301 | if (ret) |
318 | return ret; | 302 | return ret; |
319 | ret = msm_otg_phy_clk_reset(motg); | 303 | |
320 | if (ret) | 304 | /* wait for 1ms delay as suggested in HPG. */ |
321 | return ret; | 305 | usleep_range(1000, 1200); |
306 | |||
322 | ret = msm_otg_link_clk_reset(motg, 0); | 307 | ret = msm_otg_link_clk_reset(motg, 0); |
323 | if (ret) | 308 | if (ret) |
324 | return ret; | 309 | return ret; |
325 | 310 | ||
311 | if (motg->phy_number) | ||
312 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
313 | |||
314 | /* put transceiver in serial mode as part of reset */ | ||
326 | val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; | 315 | val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; |
327 | writel(val | PORTSC_PTS_ULPI, USB_PORTSC); | 316 | writel(val | PORTSC_PTS_SERIAL, USB_PORTSC); |
328 | 317 | ||
329 | for (retries = 3; retries > 0; retries--) { | 318 | return 0; |
330 | ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, | 319 | } |
331 | ULPI_CLR(ULPI_FUNC_CTRL)); | ||
332 | if (!ret) | ||
333 | break; | ||
334 | ret = msm_otg_phy_clk_reset(motg); | ||
335 | if (ret) | ||
336 | return ret; | ||
337 | } | ||
338 | if (!retries) | ||
339 | return -ETIMEDOUT; | ||
340 | 320 | ||
341 | /* This reset calibrates the phy, if the above write succeeded */ | 321 | static int msm_otg_reset(struct usb_phy *phy) |
342 | ret = msm_otg_phy_clk_reset(motg); | 322 | { |
343 | if (ret) | 323 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); |
344 | return ret; | 324 | int cnt = 0; |
345 | 325 | ||
346 | for (retries = 3; retries > 0; retries--) { | 326 | writel(USBCMD_RESET, USB_USBCMD); |
347 | ret = ulpi_read(&motg->phy, ULPI_DEBUG); | 327 | while (cnt < LINK_RESET_TIMEOUT_USEC) { |
348 | if (ret != -ETIMEDOUT) | 328 | if (!(readl(USB_USBCMD) & USBCMD_RESET)) |
349 | break; | 329 | break; |
350 | ret = msm_otg_phy_clk_reset(motg); | 330 | udelay(1); |
351 | if (ret) | 331 | cnt++; |
352 | return ret; | ||
353 | } | 332 | } |
354 | if (!retries) | 333 | if (cnt >= LINK_RESET_TIMEOUT_USEC) |
355 | return -ETIMEDOUT; | 334 | return -ETIMEDOUT; |
356 | 335 | ||
357 | dev_info(motg->phy.dev, "phy_reset: success\n"); | 336 | /* select ULPI phy and clear other status/control bits in PORTSC */ |
337 | writel(PORTSC_PTS_ULPI, USB_PORTSC); | ||
338 | |||
339 | writel(0x0, USB_AHBBURST); | ||
340 | writel(0x08, USB_AHBMODE); | ||
341 | |||
342 | if (motg->phy_number) | ||
343 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
358 | return 0; | 344 | return 0; |
359 | } | 345 | } |
360 | 346 | ||
361 | #define LINK_RESET_TIMEOUT_USEC (250 * 1000) | 347 | static void msm_phy_reset(struct msm_otg *motg) |
362 | static int msm_otg_reset(struct usb_phy *phy) | 348 | { |
349 | void __iomem *addr; | ||
350 | |||
351 | if (motg->pdata->phy_type != SNPS_28NM_INTEGRATED_PHY) { | ||
352 | msm_otg_phy_clk_reset(motg); | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | addr = USB_PHY_CTRL; | ||
357 | if (motg->phy_number) | ||
358 | addr = USB_PHY_CTRL2; | ||
359 | |||
360 | /* Assert USB PHY_POR */ | ||
361 | writel(readl(addr) | PHY_POR_ASSERT, addr); | ||
362 | |||
363 | /* | ||
364 | * wait for minimum 10 microseconds as suggested in HPG. | ||
365 | * Use a slightly larger value since the exact value didn't | ||
366 | * work 100% of the time. | ||
367 | */ | ||
368 | udelay(12); | ||
369 | |||
370 | /* Deassert USB PHY_POR */ | ||
371 | writel(readl(addr) & ~PHY_POR_ASSERT, addr); | ||
372 | } | ||
373 | |||
374 | static int msm_usb_reset(struct usb_phy *phy) | ||
363 | { | 375 | { |
364 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); | 376 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); |
365 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
366 | int cnt = 0; | ||
367 | int ret; | 377 | int ret; |
368 | u32 val = 0; | ||
369 | u32 ulpi_val = 0; | ||
370 | 378 | ||
371 | ret = msm_otg_phy_reset(motg); | 379 | if (!IS_ERR(motg->core_clk)) |
380 | clk_prepare_enable(motg->core_clk); | ||
381 | |||
382 | ret = msm_link_reset(motg); | ||
372 | if (ret) { | 383 | if (ret) { |
373 | dev_err(phy->dev, "phy_reset failed\n"); | 384 | dev_err(phy->dev, "phy_reset failed\n"); |
374 | return ret; | 385 | return ret; |
375 | } | 386 | } |
376 | 387 | ||
377 | ulpi_init(motg); | 388 | ret = msm_otg_reset(&motg->phy); |
378 | 389 | if (ret) { | |
379 | writel(USBCMD_RESET, USB_USBCMD); | 390 | dev_err(phy->dev, "link reset failed\n"); |
380 | while (cnt < LINK_RESET_TIMEOUT_USEC) { | 391 | return ret; |
381 | if (!(readl(USB_USBCMD) & USBCMD_RESET)) | ||
382 | break; | ||
383 | udelay(1); | ||
384 | cnt++; | ||
385 | } | 392 | } |
386 | if (cnt >= LINK_RESET_TIMEOUT_USEC) | ||
387 | return -ETIMEDOUT; | ||
388 | |||
389 | /* select ULPI phy */ | ||
390 | writel(0x80000000, USB_PORTSC); | ||
391 | 393 | ||
392 | msleep(100); | 394 | msleep(100); |
393 | 395 | ||
394 | writel(0x0, USB_AHBBURST); | 396 | /* Reset USB PHY after performing USB Link RESET */ |
395 | writel(0x00, USB_AHBMODE); | 397 | msm_phy_reset(motg); |
398 | |||
399 | if (!IS_ERR(motg->core_clk)) | ||
400 | clk_disable_unprepare(motg->core_clk); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int msm_phy_init(struct usb_phy *phy) | ||
406 | { | ||
407 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); | ||
408 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
409 | u32 val, ulpi_val = 0; | ||
410 | |||
411 | /* Program USB PHY Override registers. */ | ||
412 | ulpi_init(motg); | ||
413 | |||
414 | /* | ||
415 | * It is recommended in HPG to reset USB PHY after programming | ||
416 | * USB PHY Override registers. | ||
417 | */ | ||
418 | msm_phy_reset(motg); | ||
396 | 419 | ||
397 | if (pdata->otg_control == OTG_PHY_CONTROL) { | 420 | if (pdata->otg_control == OTG_PHY_CONTROL) { |
398 | val = readl(USB_OTGSC); | 421 | val = readl(USB_OTGSC); |
399 | if (pdata->mode == USB_OTG) { | 422 | if (pdata->mode == USB_DR_MODE_OTG) { |
400 | ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; | 423 | ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; |
401 | val |= OTGSC_IDIE | OTGSC_BSVIE; | 424 | val |= OTGSC_IDIE | OTGSC_BSVIE; |
402 | } else if (pdata->mode == USB_PERIPHERAL) { | 425 | } else if (pdata->mode == USB_DR_MODE_PERIPHERAL) { |
403 | ulpi_val = ULPI_INT_SESS_VALID; | 426 | ulpi_val = ULPI_INT_SESS_VALID; |
404 | val |= OTGSC_BSVIE; | 427 | val |= OTGSC_BSVIE; |
405 | } | 428 | } |
@@ -408,6 +431,9 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
408 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); | 431 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); |
409 | } | 432 | } |
410 | 433 | ||
434 | if (motg->phy_number) | ||
435 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
436 | |||
411 | return 0; | 437 | return 0; |
412 | } | 438 | } |
413 | 439 | ||
@@ -416,22 +442,20 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
416 | 442 | ||
417 | #ifdef CONFIG_PM | 443 | #ifdef CONFIG_PM |
418 | 444 | ||
419 | #define USB_PHY_SUSP_DIG_VOL 500000 | 445 | static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) |
420 | static int msm_hsusb_config_vddcx(int high) | ||
421 | { | 446 | { |
422 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | 447 | int max_vol = motg->vdd_levels[VDD_LEVEL_MAX]; |
423 | int min_vol; | 448 | int min_vol; |
424 | int ret; | 449 | int ret; |
425 | 450 | ||
426 | if (high) | 451 | if (high) |
427 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | 452 | min_vol = motg->vdd_levels[VDD_LEVEL_MIN]; |
428 | else | 453 | else |
429 | min_vol = USB_PHY_SUSP_DIG_VOL; | 454 | min_vol = motg->vdd_levels[VDD_LEVEL_NONE]; |
430 | 455 | ||
431 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | 456 | ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); |
432 | if (ret) { | 457 | if (ret) { |
433 | pr_err("%s: unable to set the voltage for regulator " | 458 | pr_err("Cannot set vddcx voltage\n"); |
434 | "HSUSB_VDDCX\n", __func__); | ||
435 | return ret; | 459 | return ret; |
436 | } | 460 | } |
437 | 461 | ||
@@ -445,6 +469,7 @@ static int msm_otg_suspend(struct msm_otg *motg) | |||
445 | struct usb_phy *phy = &motg->phy; | 469 | struct usb_phy *phy = &motg->phy; |
446 | struct usb_bus *bus = phy->otg->host; | 470 | struct usb_bus *bus = phy->otg->host; |
447 | struct msm_otg_platform_data *pdata = motg->pdata; | 471 | struct msm_otg_platform_data *pdata = motg->pdata; |
472 | void __iomem *addr; | ||
448 | int cnt = 0; | 473 | int cnt = 0; |
449 | 474 | ||
450 | if (atomic_read(&motg->in_lpm)) | 475 | if (atomic_read(&motg->in_lpm)) |
@@ -504,22 +529,23 @@ static int msm_otg_suspend(struct msm_otg *motg) | |||
504 | */ | 529 | */ |
505 | writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); | 530 | writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); |
506 | 531 | ||
532 | addr = USB_PHY_CTRL; | ||
533 | if (motg->phy_number) | ||
534 | addr = USB_PHY_CTRL2; | ||
535 | |||
507 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 536 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
508 | motg->pdata->otg_control == OTG_PMIC_CONTROL) | 537 | motg->pdata->otg_control == OTG_PMIC_CONTROL) |
509 | writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); | 538 | writel(readl(addr) | PHY_RETEN, addr); |
510 | 539 | ||
511 | clk_disable_unprepare(motg->pclk); | 540 | clk_disable_unprepare(motg->pclk); |
512 | clk_disable_unprepare(motg->clk); | 541 | clk_disable_unprepare(motg->clk); |
513 | if (motg->core_clk) | 542 | if (!IS_ERR(motg->core_clk)) |
514 | clk_disable_unprepare(motg->core_clk); | 543 | clk_disable_unprepare(motg->core_clk); |
515 | 544 | ||
516 | if (!IS_ERR(motg->pclk_src)) | ||
517 | clk_disable_unprepare(motg->pclk_src); | ||
518 | |||
519 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 545 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
520 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { | 546 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { |
521 | msm_hsusb_ldo_set_mode(0); | 547 | msm_hsusb_ldo_set_mode(motg, 0); |
522 | msm_hsusb_config_vddcx(0); | 548 | msm_hsusb_config_vddcx(motg, 0); |
523 | } | 549 | } |
524 | 550 | ||
525 | if (device_may_wakeup(phy->dev)) | 551 | if (device_may_wakeup(phy->dev)) |
@@ -539,25 +565,28 @@ static int msm_otg_resume(struct msm_otg *motg) | |||
539 | { | 565 | { |
540 | struct usb_phy *phy = &motg->phy; | 566 | struct usb_phy *phy = &motg->phy; |
541 | struct usb_bus *bus = phy->otg->host; | 567 | struct usb_bus *bus = phy->otg->host; |
568 | void __iomem *addr; | ||
542 | int cnt = 0; | 569 | int cnt = 0; |
543 | unsigned temp; | 570 | unsigned temp; |
544 | 571 | ||
545 | if (!atomic_read(&motg->in_lpm)) | 572 | if (!atomic_read(&motg->in_lpm)) |
546 | return 0; | 573 | return 0; |
547 | 574 | ||
548 | if (!IS_ERR(motg->pclk_src)) | ||
549 | clk_prepare_enable(motg->pclk_src); | ||
550 | |||
551 | clk_prepare_enable(motg->pclk); | 575 | clk_prepare_enable(motg->pclk); |
552 | clk_prepare_enable(motg->clk); | 576 | clk_prepare_enable(motg->clk); |
553 | if (motg->core_clk) | 577 | if (!IS_ERR(motg->core_clk)) |
554 | clk_prepare_enable(motg->core_clk); | 578 | clk_prepare_enable(motg->core_clk); |
555 | 579 | ||
556 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 580 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
557 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { | 581 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { |
558 | msm_hsusb_ldo_set_mode(1); | 582 | |
559 | msm_hsusb_config_vddcx(1); | 583 | addr = USB_PHY_CTRL; |
560 | writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); | 584 | if (motg->phy_number) |
585 | addr = USB_PHY_CTRL2; | ||
586 | |||
587 | msm_hsusb_ldo_set_mode(motg, 1); | ||
588 | msm_hsusb_config_vddcx(motg, 1); | ||
589 | writel(readl(addr) & ~PHY_RETEN, addr); | ||
561 | } | 590 | } |
562 | 591 | ||
563 | temp = readl(USB_USBCMD); | 592 | temp = readl(USB_USBCMD); |
@@ -586,8 +615,7 @@ static int msm_otg_resume(struct msm_otg *motg) | |||
586 | * PHY. USB state can not be restored. Re-insertion | 615 | * PHY. USB state can not be restored. Re-insertion |
587 | * of USB cable is the only way to get USB working. | 616 | * of USB cable is the only way to get USB working. |
588 | */ | 617 | */ |
589 | dev_err(phy->dev, "Unable to resume USB." | 618 | dev_err(phy->dev, "Unable to resume USB. Re-plugin the cable\n"); |
590 | "Re-plugin the cable\n"); | ||
591 | msm_otg_reset(phy); | 619 | msm_otg_reset(phy); |
592 | } | 620 | } |
593 | 621 | ||
@@ -687,7 +715,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
687 | * Fail host registration if this board can support | 715 | * Fail host registration if this board can support |
688 | * only peripheral configuration. | 716 | * only peripheral configuration. |
689 | */ | 717 | */ |
690 | if (motg->pdata->mode == USB_PERIPHERAL) { | 718 | if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) { |
691 | dev_info(otg->phy->dev, "Host mode is not supported\n"); | 719 | dev_info(otg->phy->dev, "Host mode is not supported\n"); |
692 | return -ENODEV; | 720 | return -ENODEV; |
693 | } | 721 | } |
@@ -716,7 +744,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
716 | * Kick the state machine work, if peripheral is not supported | 744 | * Kick the state machine work, if peripheral is not supported |
717 | * or peripheral is already registered with us. | 745 | * or peripheral is already registered with us. |
718 | */ | 746 | */ |
719 | if (motg->pdata->mode == USB_HOST || otg->gadget) { | 747 | if (motg->pdata->mode == USB_DR_MODE_HOST || otg->gadget) { |
720 | pm_runtime_get_sync(otg->phy->dev); | 748 | pm_runtime_get_sync(otg->phy->dev); |
721 | schedule_work(&motg->sm_work); | 749 | schedule_work(&motg->sm_work); |
722 | } | 750 | } |
@@ -760,7 +788,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, | |||
760 | * Fail peripheral registration if this board can support | 788 | * Fail peripheral registration if this board can support |
761 | * only host configuration. | 789 | * only host configuration. |
762 | */ | 790 | */ |
763 | if (motg->pdata->mode == USB_HOST) { | 791 | if (motg->pdata->mode == USB_DR_MODE_HOST) { |
764 | dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); | 792 | dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); |
765 | return -ENODEV; | 793 | return -ENODEV; |
766 | } | 794 | } |
@@ -785,7 +813,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, | |||
785 | * Kick the state machine work, if host is not supported | 813 | * Kick the state machine work, if host is not supported |
786 | * or host is already registered with us. | 814 | * or host is already registered with us. |
787 | */ | 815 | */ |
788 | if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { | 816 | if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL || otg->host) { |
789 | pm_runtime_get_sync(otg->phy->dev); | 817 | pm_runtime_get_sync(otg->phy->dev); |
790 | schedule_work(&motg->sm_work); | 818 | schedule_work(&motg->sm_work); |
791 | } | 819 | } |
@@ -1106,7 +1134,7 @@ static void msm_otg_init_sm(struct msm_otg *motg) | |||
1106 | u32 otgsc = readl(USB_OTGSC); | 1134 | u32 otgsc = readl(USB_OTGSC); |
1107 | 1135 | ||
1108 | switch (pdata->mode) { | 1136 | switch (pdata->mode) { |
1109 | case USB_OTG: | 1137 | case USB_DR_MODE_OTG: |
1110 | if (pdata->otg_control == OTG_PHY_CONTROL) { | 1138 | if (pdata->otg_control == OTG_PHY_CONTROL) { |
1111 | if (otgsc & OTGSC_ID) | 1139 | if (otgsc & OTGSC_ID) |
1112 | set_bit(ID, &motg->inputs); | 1140 | set_bit(ID, &motg->inputs); |
@@ -1118,21 +1146,14 @@ static void msm_otg_init_sm(struct msm_otg *motg) | |||
1118 | else | 1146 | else |
1119 | clear_bit(B_SESS_VLD, &motg->inputs); | 1147 | clear_bit(B_SESS_VLD, &motg->inputs); |
1120 | } else if (pdata->otg_control == OTG_USER_CONTROL) { | 1148 | } else if (pdata->otg_control == OTG_USER_CONTROL) { |
1121 | if (pdata->default_mode == USB_HOST) { | ||
1122 | clear_bit(ID, &motg->inputs); | ||
1123 | } else if (pdata->default_mode == USB_PERIPHERAL) { | ||
1124 | set_bit(ID, &motg->inputs); | ||
1125 | set_bit(B_SESS_VLD, &motg->inputs); | ||
1126 | } else { | ||
1127 | set_bit(ID, &motg->inputs); | 1149 | set_bit(ID, &motg->inputs); |
1128 | clear_bit(B_SESS_VLD, &motg->inputs); | 1150 | clear_bit(B_SESS_VLD, &motg->inputs); |
1129 | } | ||
1130 | } | 1151 | } |
1131 | break; | 1152 | break; |
1132 | case USB_HOST: | 1153 | case USB_DR_MODE_HOST: |
1133 | clear_bit(ID, &motg->inputs); | 1154 | clear_bit(ID, &motg->inputs); |
1134 | break; | 1155 | break; |
1135 | case USB_PERIPHERAL: | 1156 | case USB_DR_MODE_PERIPHERAL: |
1136 | set_bit(ID, &motg->inputs); | 1157 | set_bit(ID, &motg->inputs); |
1137 | if (otgsc & OTGSC_BSV) | 1158 | if (otgsc & OTGSC_BSV) |
1138 | set_bit(B_SESS_VLD, &motg->inputs); | 1159 | set_bit(B_SESS_VLD, &motg->inputs); |
@@ -1282,13 +1303,13 @@ static int msm_otg_mode_show(struct seq_file *s, void *unused) | |||
1282 | 1303 | ||
1283 | switch (otg->phy->state) { | 1304 | switch (otg->phy->state) { |
1284 | case OTG_STATE_A_HOST: | 1305 | case OTG_STATE_A_HOST: |
1285 | seq_printf(s, "host\n"); | 1306 | seq_puts(s, "host\n"); |
1286 | break; | 1307 | break; |
1287 | case OTG_STATE_B_PERIPHERAL: | 1308 | case OTG_STATE_B_PERIPHERAL: |
1288 | seq_printf(s, "peripheral\n"); | 1309 | seq_puts(s, "peripheral\n"); |
1289 | break; | 1310 | break; |
1290 | default: | 1311 | default: |
1291 | seq_printf(s, "none\n"); | 1312 | seq_puts(s, "none\n"); |
1292 | break; | 1313 | break; |
1293 | } | 1314 | } |
1294 | 1315 | ||
@@ -1308,7 +1329,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1308 | char buf[16]; | 1329 | char buf[16]; |
1309 | struct usb_otg *otg = motg->phy.otg; | 1330 | struct usb_otg *otg = motg->phy.otg; |
1310 | int status = count; | 1331 | int status = count; |
1311 | enum usb_mode_type req_mode; | 1332 | enum usb_dr_mode req_mode; |
1312 | 1333 | ||
1313 | memset(buf, 0x00, sizeof(buf)); | 1334 | memset(buf, 0x00, sizeof(buf)); |
1314 | 1335 | ||
@@ -1318,18 +1339,18 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1318 | } | 1339 | } |
1319 | 1340 | ||
1320 | if (!strncmp(buf, "host", 4)) { | 1341 | if (!strncmp(buf, "host", 4)) { |
1321 | req_mode = USB_HOST; | 1342 | req_mode = USB_DR_MODE_HOST; |
1322 | } else if (!strncmp(buf, "peripheral", 10)) { | 1343 | } else if (!strncmp(buf, "peripheral", 10)) { |
1323 | req_mode = USB_PERIPHERAL; | 1344 | req_mode = USB_DR_MODE_PERIPHERAL; |
1324 | } else if (!strncmp(buf, "none", 4)) { | 1345 | } else if (!strncmp(buf, "none", 4)) { |
1325 | req_mode = USB_NONE; | 1346 | req_mode = USB_DR_MODE_UNKNOWN; |
1326 | } else { | 1347 | } else { |
1327 | status = -EINVAL; | 1348 | status = -EINVAL; |
1328 | goto out; | 1349 | goto out; |
1329 | } | 1350 | } |
1330 | 1351 | ||
1331 | switch (req_mode) { | 1352 | switch (req_mode) { |
1332 | case USB_NONE: | 1353 | case USB_DR_MODE_UNKNOWN: |
1333 | switch (otg->phy->state) { | 1354 | switch (otg->phy->state) { |
1334 | case OTG_STATE_A_HOST: | 1355 | case OTG_STATE_A_HOST: |
1335 | case OTG_STATE_B_PERIPHERAL: | 1356 | case OTG_STATE_B_PERIPHERAL: |
@@ -1340,7 +1361,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1340 | goto out; | 1361 | goto out; |
1341 | } | 1362 | } |
1342 | break; | 1363 | break; |
1343 | case USB_PERIPHERAL: | 1364 | case USB_DR_MODE_PERIPHERAL: |
1344 | switch (otg->phy->state) { | 1365 | switch (otg->phy->state) { |
1345 | case OTG_STATE_B_IDLE: | 1366 | case OTG_STATE_B_IDLE: |
1346 | case OTG_STATE_A_HOST: | 1367 | case OTG_STATE_A_HOST: |
@@ -1351,7 +1372,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1351 | goto out; | 1372 | goto out; |
1352 | } | 1373 | } |
1353 | break; | 1374 | break; |
1354 | case USB_HOST: | 1375 | case USB_DR_MODE_HOST: |
1355 | switch (otg->phy->state) { | 1376 | switch (otg->phy->state) { |
1356 | case OTG_STATE_B_IDLE: | 1377 | case OTG_STATE_B_IDLE: |
1357 | case OTG_STATE_B_PERIPHERAL: | 1378 | case OTG_STATE_B_PERIPHERAL: |
@@ -1406,74 +1427,154 @@ static void msm_otg_debugfs_cleanup(void) | |||
1406 | debugfs_remove(msm_otg_dbg_root); | 1427 | debugfs_remove(msm_otg_dbg_root); |
1407 | } | 1428 | } |
1408 | 1429 | ||
1409 | static int __init msm_otg_probe(struct platform_device *pdev) | 1430 | static struct of_device_id msm_otg_dt_match[] = { |
1431 | { | ||
1432 | .compatible = "qcom,usb-otg-ci", | ||
1433 | .data = (void *) CI_45NM_INTEGRATED_PHY | ||
1434 | }, | ||
1435 | { | ||
1436 | .compatible = "qcom,usb-otg-snps", | ||
1437 | .data = (void *) SNPS_28NM_INTEGRATED_PHY | ||
1438 | }, | ||
1439 | { } | ||
1440 | }; | ||
1441 | MODULE_DEVICE_TABLE(of, msm_otg_dt_match); | ||
1442 | |||
1443 | static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) | ||
1410 | { | 1444 | { |
1445 | struct msm_otg_platform_data *pdata; | ||
1446 | const struct of_device_id *id; | ||
1447 | struct device_node *node = pdev->dev.of_node; | ||
1448 | struct property *prop; | ||
1449 | int len, ret, words; | ||
1450 | u32 val, tmp[3]; | ||
1451 | |||
1452 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1453 | if (!pdata) | ||
1454 | return -ENOMEM; | ||
1455 | |||
1456 | motg->pdata = pdata; | ||
1457 | |||
1458 | id = of_match_device(msm_otg_dt_match, &pdev->dev); | ||
1459 | pdata->phy_type = (enum msm_usb_phy_type) id->data; | ||
1460 | |||
1461 | motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); | ||
1462 | if (IS_ERR(motg->link_rst)) | ||
1463 | return PTR_ERR(motg->link_rst); | ||
1464 | |||
1465 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); | ||
1466 | if (IS_ERR(motg->phy_rst)) | ||
1467 | return PTR_ERR(motg->phy_rst); | ||
1468 | |||
1469 | pdata->mode = of_usb_get_dr_mode(node); | ||
1470 | if (pdata->mode == USB_DR_MODE_UNKNOWN) | ||
1471 | pdata->mode = USB_DR_MODE_OTG; | ||
1472 | |||
1473 | pdata->otg_control = OTG_PHY_CONTROL; | ||
1474 | if (!of_property_read_u32(node, "qcom,otg-control", &val)) | ||
1475 | if (val == OTG_PMIC_CONTROL) | ||
1476 | pdata->otg_control = val; | ||
1477 | |||
1478 | if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) | ||
1479 | motg->phy_number = val; | ||
1480 | |||
1481 | motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL; | ||
1482 | motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN; | ||
1483 | motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX; | ||
1484 | |||
1485 | if (of_get_property(node, "qcom,vdd-levels", &len) && | ||
1486 | len == sizeof(tmp)) { | ||
1487 | of_property_read_u32_array(node, "qcom,vdd-levels", | ||
1488 | tmp, len / sizeof(*tmp)); | ||
1489 | motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE]; | ||
1490 | motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN]; | ||
1491 | motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; | ||
1492 | } | ||
1493 | |||
1494 | prop = of_find_property(node, "qcom,phy-init-sequence", &len); | ||
1495 | if (!prop || !len) | ||
1496 | return 0; | ||
1497 | |||
1498 | words = len / sizeof(u32); | ||
1499 | |||
1500 | if (words >= ULPI_EXT_VENDOR_SPECIFIC) { | ||
1501 | dev_warn(&pdev->dev, "Too big PHY init sequence %d\n", words); | ||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); | ||
1506 | if (!pdata->phy_init_seq) { | ||
1507 | dev_warn(&pdev->dev, "No space for PHY init sequence\n"); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | ret = of_property_read_u32_array(node, "qcom,phy-init-sequence", | ||
1512 | pdata->phy_init_seq, words); | ||
1513 | if (!ret) | ||
1514 | pdata->phy_init_sz = words; | ||
1515 | |||
1516 | return 0; | ||
1517 | } | ||
1518 | |||
1519 | static int msm_otg_probe(struct platform_device *pdev) | ||
1520 | { | ||
1521 | struct regulator_bulk_data regs[3]; | ||
1411 | int ret = 0; | 1522 | int ret = 0; |
1523 | struct device_node *np = pdev->dev.of_node; | ||
1524 | struct msm_otg_platform_data *pdata; | ||
1412 | struct resource *res; | 1525 | struct resource *res; |
1413 | struct msm_otg *motg; | 1526 | struct msm_otg *motg; |
1414 | struct usb_phy *phy; | 1527 | struct usb_phy *phy; |
1528 | void __iomem *phy_select; | ||
1415 | 1529 | ||
1416 | dev_info(&pdev->dev, "msm_otg probe\n"); | 1530 | motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); |
1417 | if (!dev_get_platdata(&pdev->dev)) { | ||
1418 | dev_err(&pdev->dev, "No platform data given. Bailing out\n"); | ||
1419 | return -ENODEV; | ||
1420 | } | ||
1421 | |||
1422 | motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); | ||
1423 | if (!motg) { | 1531 | if (!motg) { |
1424 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | 1532 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); |
1425 | return -ENOMEM; | 1533 | return -ENOMEM; |
1426 | } | 1534 | } |
1427 | 1535 | ||
1428 | motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | 1536 | pdata = dev_get_platdata(&pdev->dev); |
1537 | if (!pdata) { | ||
1538 | if (!np) | ||
1539 | return -ENXIO; | ||
1540 | ret = msm_otg_read_dt(pdev, motg); | ||
1541 | if (ret) | ||
1542 | return ret; | ||
1543 | } | ||
1544 | |||
1545 | motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), | ||
1546 | GFP_KERNEL); | ||
1429 | if (!motg->phy.otg) { | 1547 | if (!motg->phy.otg) { |
1430 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | 1548 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); |
1431 | ret = -ENOMEM; | 1549 | return -ENOMEM; |
1432 | goto free_motg; | ||
1433 | } | 1550 | } |
1434 | 1551 | ||
1435 | motg->pdata = dev_get_platdata(&pdev->dev); | ||
1436 | phy = &motg->phy; | 1552 | phy = &motg->phy; |
1437 | phy->dev = &pdev->dev; | 1553 | phy->dev = &pdev->dev; |
1438 | 1554 | ||
1439 | motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); | 1555 | motg->phy_reset_clk = devm_clk_get(&pdev->dev, |
1556 | np ? "phy" : "usb_phy_clk"); | ||
1440 | if (IS_ERR(motg->phy_reset_clk)) { | 1557 | if (IS_ERR(motg->phy_reset_clk)) { |
1441 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); | 1558 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); |
1442 | ret = PTR_ERR(motg->phy_reset_clk); | 1559 | return PTR_ERR(motg->phy_reset_clk); |
1443 | goto free_motg; | ||
1444 | } | 1560 | } |
1445 | 1561 | ||
1446 | motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); | 1562 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); |
1447 | if (IS_ERR(motg->clk)) { | 1563 | if (IS_ERR(motg->clk)) { |
1448 | dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); | 1564 | dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); |
1449 | ret = PTR_ERR(motg->clk); | 1565 | return PTR_ERR(motg->clk); |
1450 | goto put_phy_reset_clk; | ||
1451 | } | 1566 | } |
1452 | clk_set_rate(motg->clk, 60000000); | ||
1453 | 1567 | ||
1454 | /* | 1568 | /* |
1455 | * If USB Core is running its protocol engine based on CORE CLK, | 1569 | * If USB Core is running its protocol engine based on CORE CLK, |
1456 | * CORE CLK must be running at >55Mhz for correct HSUSB | 1570 | * CORE CLK must be running at >55Mhz for correct HSUSB |
1457 | * operation and USB core cannot tolerate frequency changes on | 1571 | * operation and USB core cannot tolerate frequency changes on |
1458 | * CORE CLK. For such USB cores, vote for maximum clk frequency | 1572 | * CORE CLK. |
1459 | * on pclk source | ||
1460 | */ | 1573 | */ |
1461 | if (motg->pdata->pclk_src_name) { | 1574 | motg->pclk = devm_clk_get(&pdev->dev, np ? "iface" : "usb_hs_pclk"); |
1462 | motg->pclk_src = clk_get(&pdev->dev, | ||
1463 | motg->pdata->pclk_src_name); | ||
1464 | if (IS_ERR(motg->pclk_src)) | ||
1465 | goto put_clk; | ||
1466 | clk_set_rate(motg->pclk_src, INT_MAX); | ||
1467 | clk_prepare_enable(motg->pclk_src); | ||
1468 | } else | ||
1469 | motg->pclk_src = ERR_PTR(-ENOENT); | ||
1470 | |||
1471 | |||
1472 | motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); | ||
1473 | if (IS_ERR(motg->pclk)) { | 1575 | if (IS_ERR(motg->pclk)) { |
1474 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); | 1576 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); |
1475 | ret = PTR_ERR(motg->pclk); | 1577 | return PTR_ERR(motg->pclk); |
1476 | goto put_pclk_src; | ||
1477 | } | 1578 | } |
1478 | 1579 | ||
1479 | /* | 1580 | /* |
@@ -1481,69 +1582,88 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1481 | * clock is introduced to remove the dependency on AXI | 1582 | * clock is introduced to remove the dependency on AXI |
1482 | * bus frequency. | 1583 | * bus frequency. |
1483 | */ | 1584 | */ |
1484 | motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); | 1585 | motg->core_clk = devm_clk_get(&pdev->dev, |
1485 | if (IS_ERR(motg->core_clk)) | 1586 | np ? "alt_core" : "usb_hs_core_clk"); |
1486 | motg->core_clk = NULL; | ||
1487 | 1587 | ||
1488 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1588 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1489 | if (!res) { | 1589 | motg->regs = devm_ioremap_resource(&pdev->dev, res); |
1490 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | 1590 | if (IS_ERR(motg->regs)) |
1491 | ret = -ENODEV; | 1591 | return PTR_ERR(motg->regs); |
1492 | goto put_core_clk; | ||
1493 | } | ||
1494 | 1592 | ||
1495 | motg->regs = ioremap(res->start, resource_size(res)); | 1593 | /* |
1496 | if (!motg->regs) { | 1594 | * NOTE: The PHYs can be multiplexed between the chipidea controller |
1497 | dev_err(&pdev->dev, "ioremap failed\n"); | 1595 | * and the dwc3 controller, using a single bit. It is important that |
1498 | ret = -ENOMEM; | 1596 | * the dwc3 driver does not set this bit in an incompatible way. |
1499 | goto put_core_clk; | 1597 | */ |
1598 | if (motg->phy_number) { | ||
1599 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); | ||
1600 | if (IS_ERR(phy_select)) | ||
1601 | return PTR_ERR(phy_select); | ||
1602 | /* Enable second PHY with the OTG port */ | ||
1603 | writel(0x1, phy_select); | ||
1500 | } | 1604 | } |
1605 | |||
1501 | dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); | 1606 | dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); |
1502 | 1607 | ||
1503 | motg->irq = platform_get_irq(pdev, 0); | 1608 | motg->irq = platform_get_irq(pdev, 0); |
1504 | if (!motg->irq) { | 1609 | if (motg->irq < 0) { |
1505 | dev_err(&pdev->dev, "platform_get_irq failed\n"); | 1610 | dev_err(&pdev->dev, "platform_get_irq failed\n"); |
1506 | ret = -ENODEV; | 1611 | return motg->irq; |
1507 | goto free_regs; | ||
1508 | } | 1612 | } |
1509 | 1613 | ||
1614 | regs[0].supply = "vddcx"; | ||
1615 | regs[1].supply = "v3p3"; | ||
1616 | regs[2].supply = "v1p8"; | ||
1617 | |||
1618 | ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); | ||
1619 | if (ret) | ||
1620 | return ret; | ||
1621 | |||
1622 | motg->vddcx = regs[0].consumer; | ||
1623 | motg->v3p3 = regs[1].consumer; | ||
1624 | motg->v1p8 = regs[2].consumer; | ||
1625 | |||
1626 | clk_set_rate(motg->clk, 60000000); | ||
1627 | |||
1510 | clk_prepare_enable(motg->clk); | 1628 | clk_prepare_enable(motg->clk); |
1511 | clk_prepare_enable(motg->pclk); | 1629 | clk_prepare_enable(motg->pclk); |
1512 | 1630 | ||
1631 | if (!IS_ERR(motg->core_clk)) | ||
1632 | clk_prepare_enable(motg->core_clk); | ||
1633 | |||
1513 | ret = msm_hsusb_init_vddcx(motg, 1); | 1634 | ret = msm_hsusb_init_vddcx(motg, 1); |
1514 | if (ret) { | 1635 | if (ret) { |
1515 | dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); | 1636 | dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); |
1516 | goto free_regs; | 1637 | goto disable_clks; |
1517 | } | 1638 | } |
1518 | 1639 | ||
1519 | ret = msm_hsusb_ldo_init(motg, 1); | 1640 | ret = msm_hsusb_ldo_init(motg, 1); |
1520 | if (ret) { | 1641 | if (ret) { |
1521 | dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); | 1642 | dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); |
1522 | goto vddcx_exit; | 1643 | goto disable_vddcx; |
1523 | } | 1644 | } |
1524 | ret = msm_hsusb_ldo_set_mode(1); | 1645 | ret = msm_hsusb_ldo_set_mode(motg, 1); |
1525 | if (ret) { | 1646 | if (ret) { |
1526 | dev_err(&pdev->dev, "hsusb vreg enable failed\n"); | 1647 | dev_err(&pdev->dev, "hsusb vreg enable failed\n"); |
1527 | goto ldo_exit; | 1648 | goto disable_ldo; |
1528 | } | 1649 | } |
1529 | 1650 | ||
1530 | if (motg->core_clk) | ||
1531 | clk_prepare_enable(motg->core_clk); | ||
1532 | |||
1533 | writel(0, USB_USBINTR); | 1651 | writel(0, USB_USBINTR); |
1534 | writel(0, USB_OTGSC); | 1652 | writel(0, USB_OTGSC); |
1535 | 1653 | ||
1536 | INIT_WORK(&motg->sm_work, msm_otg_sm_work); | 1654 | INIT_WORK(&motg->sm_work, msm_otg_sm_work); |
1537 | INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); | 1655 | INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); |
1538 | ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, | 1656 | ret = devm_request_irq(&pdev->dev, motg->irq, msm_otg_irq, IRQF_SHARED, |
1539 | "msm_otg", motg); | 1657 | "msm_otg", motg); |
1540 | if (ret) { | 1658 | if (ret) { |
1541 | dev_err(&pdev->dev, "request irq failed\n"); | 1659 | dev_err(&pdev->dev, "request irq failed\n"); |
1542 | goto disable_clks; | 1660 | goto disable_ldo; |
1543 | } | 1661 | } |
1544 | 1662 | ||
1545 | phy->init = msm_otg_reset; | 1663 | phy->init = msm_phy_init; |
1546 | phy->set_power = msm_otg_set_power; | 1664 | phy->set_power = msm_otg_set_power; |
1665 | phy->notify_disconnect = msm_phy_notify_disconnect; | ||
1666 | phy->type = USB_PHY_TYPE_USB2; | ||
1547 | 1667 | ||
1548 | phy->io_ops = &msm_otg_io_ops; | 1668 | phy->io_ops = &msm_otg_io_ops; |
1549 | 1669 | ||
@@ -1551,54 +1671,38 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1551 | phy->otg->set_host = msm_otg_set_host; | 1671 | phy->otg->set_host = msm_otg_set_host; |
1552 | phy->otg->set_peripheral = msm_otg_set_peripheral; | 1672 | phy->otg->set_peripheral = msm_otg_set_peripheral; |
1553 | 1673 | ||
1554 | ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); | 1674 | msm_usb_reset(phy); |
1675 | |||
1676 | ret = usb_add_phy_dev(&motg->phy); | ||
1555 | if (ret) { | 1677 | if (ret) { |
1556 | dev_err(&pdev->dev, "usb_add_phy failed\n"); | 1678 | dev_err(&pdev->dev, "usb_add_phy failed\n"); |
1557 | goto free_irq; | 1679 | goto disable_ldo; |
1558 | } | 1680 | } |
1559 | 1681 | ||
1560 | platform_set_drvdata(pdev, motg); | 1682 | platform_set_drvdata(pdev, motg); |
1561 | device_init_wakeup(&pdev->dev, 1); | 1683 | device_init_wakeup(&pdev->dev, 1); |
1562 | 1684 | ||
1563 | if (motg->pdata->mode == USB_OTG && | 1685 | if (motg->pdata->mode == USB_DR_MODE_OTG && |
1564 | motg->pdata->otg_control == OTG_USER_CONTROL) { | 1686 | motg->pdata->otg_control == OTG_USER_CONTROL) { |
1565 | ret = msm_otg_debugfs_init(motg); | 1687 | ret = msm_otg_debugfs_init(motg); |
1566 | if (ret) | 1688 | if (ret) |
1567 | dev_dbg(&pdev->dev, "mode debugfs file is" | 1689 | dev_dbg(&pdev->dev, "Can not create mode change file\n"); |
1568 | "not available\n"); | ||
1569 | } | 1690 | } |
1570 | 1691 | ||
1571 | pm_runtime_set_active(&pdev->dev); | 1692 | pm_runtime_set_active(&pdev->dev); |
1572 | pm_runtime_enable(&pdev->dev); | 1693 | pm_runtime_enable(&pdev->dev); |
1573 | 1694 | ||
1574 | return 0; | 1695 | return 0; |
1575 | free_irq: | 1696 | |
1576 | free_irq(motg->irq, motg); | 1697 | disable_ldo: |
1698 | msm_hsusb_ldo_init(motg, 0); | ||
1699 | disable_vddcx: | ||
1700 | msm_hsusb_init_vddcx(motg, 0); | ||
1577 | disable_clks: | 1701 | disable_clks: |
1578 | clk_disable_unprepare(motg->pclk); | 1702 | clk_disable_unprepare(motg->pclk); |
1579 | clk_disable_unprepare(motg->clk); | 1703 | clk_disable_unprepare(motg->clk); |
1580 | ldo_exit: | 1704 | if (!IS_ERR(motg->core_clk)) |
1581 | msm_hsusb_ldo_init(motg, 0); | 1705 | clk_disable_unprepare(motg->core_clk); |
1582 | vddcx_exit: | ||
1583 | msm_hsusb_init_vddcx(motg, 0); | ||
1584 | free_regs: | ||
1585 | iounmap(motg->regs); | ||
1586 | put_core_clk: | ||
1587 | if (motg->core_clk) | ||
1588 | clk_put(motg->core_clk); | ||
1589 | clk_put(motg->pclk); | ||
1590 | put_pclk_src: | ||
1591 | if (!IS_ERR(motg->pclk_src)) { | ||
1592 | clk_disable_unprepare(motg->pclk_src); | ||
1593 | clk_put(motg->pclk_src); | ||
1594 | } | ||
1595 | put_clk: | ||
1596 | clk_put(motg->clk); | ||
1597 | put_phy_reset_clk: | ||
1598 | clk_put(motg->phy_reset_clk); | ||
1599 | free_motg: | ||
1600 | kfree(motg->phy.otg); | ||
1601 | kfree(motg); | ||
1602 | return ret; | 1706 | return ret; |
1603 | } | 1707 | } |
1604 | 1708 | ||
@@ -1621,7 +1725,7 @@ static int msm_otg_remove(struct platform_device *pdev) | |||
1621 | pm_runtime_disable(&pdev->dev); | 1725 | pm_runtime_disable(&pdev->dev); |
1622 | 1726 | ||
1623 | usb_remove_phy(phy); | 1727 | usb_remove_phy(phy); |
1624 | free_irq(motg->irq, motg); | 1728 | disable_irq(motg->irq); |
1625 | 1729 | ||
1626 | /* | 1730 | /* |
1627 | * Put PHY in low power mode. | 1731 | * Put PHY in low power mode. |
@@ -1641,26 +1745,12 @@ static int msm_otg_remove(struct platform_device *pdev) | |||
1641 | 1745 | ||
1642 | clk_disable_unprepare(motg->pclk); | 1746 | clk_disable_unprepare(motg->pclk); |
1643 | clk_disable_unprepare(motg->clk); | 1747 | clk_disable_unprepare(motg->clk); |
1644 | if (motg->core_clk) | 1748 | if (!IS_ERR(motg->core_clk)) |
1645 | clk_disable_unprepare(motg->core_clk); | 1749 | clk_disable_unprepare(motg->core_clk); |
1646 | if (!IS_ERR(motg->pclk_src)) { | ||
1647 | clk_disable_unprepare(motg->pclk_src); | ||
1648 | clk_put(motg->pclk_src); | ||
1649 | } | ||
1650 | msm_hsusb_ldo_init(motg, 0); | 1750 | msm_hsusb_ldo_init(motg, 0); |
1651 | 1751 | ||
1652 | iounmap(motg->regs); | ||
1653 | pm_runtime_set_suspended(&pdev->dev); | 1752 | pm_runtime_set_suspended(&pdev->dev); |
1654 | 1753 | ||
1655 | clk_put(motg->phy_reset_clk); | ||
1656 | clk_put(motg->pclk); | ||
1657 | clk_put(motg->clk); | ||
1658 | if (motg->core_clk) | ||
1659 | clk_put(motg->core_clk); | ||
1660 | |||
1661 | kfree(motg->phy.otg); | ||
1662 | kfree(motg); | ||
1663 | |||
1664 | return 0; | 1754 | return 0; |
1665 | } | 1755 | } |
1666 | 1756 | ||
@@ -1740,15 +1830,17 @@ static const struct dev_pm_ops msm_otg_dev_pm_ops = { | |||
1740 | }; | 1830 | }; |
1741 | 1831 | ||
1742 | static struct platform_driver msm_otg_driver = { | 1832 | static struct platform_driver msm_otg_driver = { |
1833 | .probe = msm_otg_probe, | ||
1743 | .remove = msm_otg_remove, | 1834 | .remove = msm_otg_remove, |
1744 | .driver = { | 1835 | .driver = { |
1745 | .name = DRIVER_NAME, | 1836 | .name = DRIVER_NAME, |
1746 | .owner = THIS_MODULE, | 1837 | .owner = THIS_MODULE, |
1747 | .pm = &msm_otg_dev_pm_ops, | 1838 | .pm = &msm_otg_dev_pm_ops, |
1839 | .of_match_table = msm_otg_dt_match, | ||
1748 | }, | 1840 | }, |
1749 | }; | 1841 | }; |
1750 | 1842 | ||
1751 | module_platform_driver_probe(msm_otg_driver, msm_otg_probe); | 1843 | module_platform_driver(msm_otg_driver); |
1752 | 1844 | ||
1753 | MODULE_LICENSE("GPL v2"); | 1845 | MODULE_LICENSE("GPL v2"); |
1754 | MODULE_DESCRIPTION("MSM USB transceiver driver"); | 1846 | MODULE_DESCRIPTION("MSM USB transceiver driver"); |
diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 17ea3f271bd8..4e3877c329f2 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c | |||
@@ -48,6 +48,7 @@ static struct ulpi_info ulpi_ids[] = { | |||
48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), | 48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), |
49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), | 49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), |
50 | ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), | 50 | ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), |
51 | ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"), | ||
51 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), | 52 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), |
52 | }; | 53 | }; |
53 | 54 | ||