blob: eb0b203ab6f81cf6bfc83837daf41014a27b0ec3 [file] [log] [blame]
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +05301/* ehci-msm-hsic.c - HSUSB Host Controller Driver Implementation
2 *
3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 *
5 * Partly derived from ehci-fsl.c and ehci-hcd.c
6 * Copyright (c) 2000-2004 by David Brownell
7 * Copyright (c) 2005 MontaVista Software
8 *
9 * All source code in this file is licensed under the following license except
10 * where indicated.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * See the GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, you can find it at http://www.fsf.org
23 */
24
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28#include <linux/wakelock.h>
29#include <linux/pm_runtime.h>
30#include <linux/regulator/consumer.h>
31
32#include <linux/usb/msm_hsusb_hw.h>
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +053033#include <linux/usb/msm_hsusb.h>
34#include <linux/gpio.h>
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053035#include <mach/clk.h>
36#include <mach/msm_iomap.h>
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +053037#include <mach/msm_xo.h>
Vamsi Krishna34f01582011-12-14 19:54:42 -080038#include <linux/spinlock.h>
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053039
40#define MSM_USB_BASE (hcd->regs)
41
42struct msm_hsic_hcd {
43 struct ehci_hcd ehci;
44 struct device *dev;
45 struct clk *ahb_clk;
46 struct clk *sys_clk;
47 struct clk *fs_xcvr_clk;
48 struct clk *hsic_clk;
49 struct clk *cal_clk;
50 struct regulator *hsic_vddcx;
51 bool async_int;
52 atomic_t in_lpm;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +053053 struct msm_xo_voter *xo_handle;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053054 struct wake_lock wlock;
Vamsi Krishna34f01582011-12-14 19:54:42 -080055 int peripheral_status_irq;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053056};
57
58static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
59{
60 return (struct msm_hsic_hcd *) (hcd->hcd_priv);
61}
62
63static inline struct usb_hcd *hsic_to_hcd(struct msm_hsic_hcd *mehci)
64{
65 return container_of((void *) mehci, struct usb_hcd, hcd_priv);
66}
67
68#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
69
Vamsi Krishna45d88fa2011-11-02 13:28:42 -070070#define USB_PHY_VDD_DIG_VOL_SUSP_MIN 500000 /* uV */
71#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */
72#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
73#define USB_PHY_VDD_DIG_LOAD 49360 /* uA */
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053074
75static int msm_hsic_init_vddcx(struct msm_hsic_hcd *mehci, int init)
76{
77 int ret = 0;
78
79 if (!init)
80 goto disable_reg;
81
82 mehci->hsic_vddcx = regulator_get(mehci->dev, "HSIC_VDDCX");
83 if (IS_ERR(mehci->hsic_vddcx)) {
84 dev_err(mehci->dev, "unable to get hsic vddcx\n");
85 return PTR_ERR(mehci->hsic_vddcx);
86 }
87
88 ret = regulator_set_voltage(mehci->hsic_vddcx,
89 USB_PHY_VDD_DIG_VOL_MIN,
90 USB_PHY_VDD_DIG_VOL_MAX);
91 if (ret) {
92 dev_err(mehci->dev, "unable to set the voltage"
93 "for hsic vddcx\n");
94 goto reg_set_voltage_err;
95 }
96
97 ret = regulator_set_optimum_mode(mehci->hsic_vddcx,
98 USB_PHY_VDD_DIG_LOAD);
99 if (ret < 0) {
100 pr_err("%s: Unable to set optimum mode of the regulator:"
101 "VDDCX\n", __func__);
102 goto reg_optimum_mode_err;
103 }
104
105 ret = regulator_enable(mehci->hsic_vddcx);
106 if (ret) {
107 dev_err(mehci->dev, "unable to enable hsic vddcx\n");
108 goto reg_enable_err;
109 }
110
111 return 0;
112
113disable_reg:
114 regulator_disable(mehci->hsic_vddcx);
115reg_enable_err:
116 regulator_set_optimum_mode(mehci->hsic_vddcx, 0);
117reg_optimum_mode_err:
118 regulator_set_voltage(mehci->hsic_vddcx, 0,
119 USB_PHY_VDD_DIG_VOL_MIN);
120reg_set_voltage_err:
121 regulator_put(mehci->hsic_vddcx);
122
123 return ret;
124
125}
126
127static int ulpi_write(struct msm_hsic_hcd *mehci, u32 val, u32 reg)
128{
129 struct usb_hcd *hcd = hsic_to_hcd(mehci);
130 int cnt = 0;
131
132 /* initiate write operation */
133 writel_relaxed(ULPI_RUN | ULPI_WRITE |
134 ULPI_ADDR(reg) | ULPI_DATA(val),
135 USB_ULPI_VIEWPORT);
136
137 /* wait for completion */
138 while (cnt < ULPI_IO_TIMEOUT_USEC) {
139 if (!(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN))
140 break;
141 udelay(1);
142 cnt++;
143 }
144
145 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
146 dev_err(mehci->dev, "ulpi_write: timeout\n");
147 return -ETIMEDOUT;
148 }
149
150 return 0;
151}
152
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530153#define HSIC_HUB_VDD_VOL_MIN 1650000 /* uV */
154#define HSIC_HUB_VDD_VOL_MAX 1950000 /* uV */
155#define HSIC_HUB_VDD_LOAD 36000 /* uA */
156static int msm_hsic_config_hub(struct msm_hsic_hcd *mehci, int init)
157{
158 int ret = 0;
159 struct msm_hsic_host_platform_data *pdata;
160 static struct regulator *hsic_hub_reg;
161
162 pdata = mehci->dev->platform_data;
163 if (!pdata->hub_reset)
164 return ret;
165
166 if (!init)
167 goto disable_reg;
168
169 hsic_hub_reg = regulator_get(mehci->dev, "EXT_HUB_VDDIO");
170 if (IS_ERR(hsic_hub_reg)) {
171 dev_err(mehci->dev, "unable to get ext hub vddcx\n");
172 return PTR_ERR(hsic_hub_reg);
173 }
174
175 ret = gpio_request(pdata->hub_reset, "HSIC_HUB_RESET_GPIO");
176 if (ret < 0) {
177 dev_err(mehci->dev, "gpio request failed for GPIO%d\n",
178 pdata->hub_reset);
179 goto gpio_req_fail;
180 }
181
182 ret = regulator_set_voltage(hsic_hub_reg,
183 HSIC_HUB_VDD_VOL_MIN,
184 HSIC_HUB_VDD_VOL_MAX);
185 if (ret) {
186 dev_err(mehci->dev, "unable to set the voltage"
187 "for hsic hub reg\n");
188 goto reg_set_voltage_fail;
189 }
190
191 ret = regulator_set_optimum_mode(hsic_hub_reg,
192 HSIC_HUB_VDD_LOAD);
193 if (ret < 0) {
194 pr_err("%s: Unable to set optimum mode of the regulator:"
195 "VDDCX\n", __func__);
196 goto reg_optimum_mode_fail;
197 }
198
199 ret = regulator_enable(hsic_hub_reg);
200 if (ret) {
201 dev_err(mehci->dev, "unable to enable ext hub vddcx\n");
202 goto reg_enable_fail;
203 }
204
205 gpio_direction_output(pdata->hub_reset, 0);
206 /* Hub reset should be asserted for minimum 2usec before deasserting */
207 udelay(5);
208 gpio_direction_output(pdata->hub_reset, 1);
209
210 return 0;
211
212disable_reg:
213 regulator_disable(hsic_hub_reg);
214reg_enable_fail:
215 regulator_set_optimum_mode(hsic_hub_reg, 0);
216reg_optimum_mode_fail:
217 regulator_set_voltage(hsic_hub_reg, 0,
218 HSIC_HUB_VDD_VOL_MIN);
219reg_set_voltage_fail:
220 gpio_free(pdata->hub_reset);
221gpio_req_fail:
222 regulator_put(hsic_hub_reg);
223
224 return ret;
225
226}
227
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530228static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en)
229{
230 int rc = 0;
231 struct msm_hsic_host_platform_data *pdata;
Vamsi Krishna34f01582011-12-14 19:54:42 -0800232 static int gpio_status;
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530233
234 pdata = mehci->dev->platform_data;
Vamsi Krishna34f01582011-12-14 19:54:42 -0800235
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530236 if (!pdata->strobe || !pdata->data)
237 return rc;
238
Vamsi Krishna34f01582011-12-14 19:54:42 -0800239 if (gpio_status == gpio_en)
240 return 0;
241
242 gpio_status = gpio_en;
243
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530244 if (!gpio_en)
245 goto free_gpio;
246
247 rc = gpio_request(pdata->strobe, "HSIC_STROBE_GPIO");
248 if (rc < 0) {
249 dev_err(mehci->dev, "gpio request failed for HSIC STROBE\n");
250 return rc;
251 }
252
253 rc = gpio_request(pdata->data, "HSIC_DATA_GPIO");
254 if (rc < 0) {
255 dev_err(mehci->dev, "gpio request failed for HSIC DATA\n");
256 goto free_strobe;
257 }
258
259 return 0;
260
261free_gpio:
262 gpio_free(pdata->data);
263free_strobe:
264 gpio_free(pdata->strobe);
265
266 return rc;
267}
268
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530269static int msm_hsic_phy_clk_reset(struct msm_hsic_hcd *mehci)
270{
271 int ret;
272
273 clk_enable(mehci->fs_xcvr_clk);
274
275 ret = clk_reset(mehci->sys_clk, CLK_RESET_ASSERT);
276 if (ret) {
277 clk_disable(mehci->fs_xcvr_clk);
278 dev_err(mehci->dev, "usb phy clk assert failed\n");
279 return ret;
280 }
281 usleep_range(10000, 12000);
282 clk_disable(mehci->fs_xcvr_clk);
283
284 ret = clk_reset(mehci->sys_clk, CLK_RESET_DEASSERT);
285 if (ret)
286 dev_err(mehci->dev, "usb phy clk deassert failed\n");
287
288 return ret;
289}
290
291static int msm_hsic_phy_reset(struct msm_hsic_hcd *mehci)
292{
293 struct usb_hcd *hcd = hsic_to_hcd(mehci);
294 u32 val;
295 int ret;
296
297 ret = msm_hsic_phy_clk_reset(mehci);
298 if (ret)
299 return ret;
300
301 val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
302 writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);
303
304 /* Ensure that RESET operation is completed before turning off clock */
305 mb();
306 dev_dbg(mehci->dev, "phy_reset: success\n");
307
308 return 0;
309}
310
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530311#define HSIC_GPIO150_PAD_CTL (MSM_TLMM_BASE+0x20C0)
312#define HSIC_GPIO151_PAD_CTL (MSM_TLMM_BASE+0x20C4)
313#define HSIC_CAL_PAD_CTL (MSM_TLMM_BASE+0x20C8)
314#define HSIC_LV_MODE 0x04
315#define HSIC_PAD_CALIBRATION 0xA8
316#define HSIC_GPIO_PAD_VAL 0x0A0AAA10
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530317#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
318static int msm_hsic_reset(struct msm_hsic_hcd *mehci)
319{
320 struct usb_hcd *hcd = hsic_to_hcd(mehci);
321 int cnt = 0;
322 int ret;
323
324 ret = msm_hsic_phy_reset(mehci);
325 if (ret) {
326 dev_err(mehci->dev, "phy_reset failed\n");
327 return ret;
328 }
329
330 writel_relaxed(USBCMD_RESET, USB_USBCMD);
331 while (cnt < LINK_RESET_TIMEOUT_USEC) {
332 if (!(readl_relaxed(USB_USBCMD) & USBCMD_RESET))
333 break;
334 udelay(1);
335 cnt++;
336 }
337 if (cnt >= LINK_RESET_TIMEOUT_USEC)
338 return -ETIMEDOUT;
339
340 /* select ULPI phy */
341 writel_relaxed(0x80000000, USB_PORTSC);
342
343 /* TODO: Need to confirm if HSIC PHY also requires delay after RESET */
344 msleep(100);
345
346 /* HSIC PHY Initialization */
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530347 /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */
348 writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL);
349
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530350 /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
351 ulpi_write(mehci, 0xFF, 0x33);
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530352
353 /* Enable periodic IO calibration in HSIC_CFG register */
354 ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30);
355
356 /* Configure GPIO 150/151 pins for HSIC functionality mode */
357 ret = msm_hsic_config_gpios(mehci, 1);
358 if (ret) {
359 dev_err(mehci->dev, " gpio configuarion failed\n");
360 return ret;
361 }
362
363 /* Set LV_MODE=0x1 and DCC=0x2 in HSIC_GPIO150/151_PAD_CTL register */
364 writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO150_PAD_CTL);
365 writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO151_PAD_CTL);
366
367 /* Enable HSIC mode in HSIC_CFG register */
368 ulpi_write(mehci, 0x01, 0x31);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530369
370 return 0;
371}
372
373#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
374#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
375
376#ifdef CONFIG_PM_SLEEP
377static int msm_hsic_suspend(struct msm_hsic_hcd *mehci)
378{
379 struct usb_hcd *hcd = hsic_to_hcd(mehci);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530380 int cnt = 0, ret;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530381 u32 val;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530382 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530383
384 if (atomic_read(&mehci->in_lpm)) {
385 dev_dbg(mehci->dev, "%s called in lpm\n", __func__);
386 return 0;
387 }
388
389 disable_irq(hcd->irq);
390 /*
391 * PHY may take some time or even fail to enter into low power
392 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
393 * in failure case.
394 */
395 val = readl_relaxed(USB_PORTSC) | PORTSC_PHCD;
396 writel_relaxed(val, USB_PORTSC);
397 while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
398 if (readl_relaxed(USB_PORTSC) & PORTSC_PHCD)
399 break;
400 udelay(1);
401 cnt++;
402 }
403
404 if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
405 dev_err(mehci->dev, "Unable to suspend PHY\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530406 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530407 msm_hsic_reset(mehci);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530408 }
409
410 /*
411 * PHY has capability to generate interrupt asynchronously in low
412 * power mode (LPM). This interrupt is level triggered. So USB IRQ
413 * line must be disabled till async interrupt enable bit is cleared
414 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
415 * block data communication from PHY.
416 */
417 writel_relaxed(readl_relaxed(USB_USBCMD) | ASYNC_INTR_CTRL |
418 ULPI_STP_CTRL, USB_USBCMD);
419
420 /*
421 * Ensure that hardware is put in low power mode before
422 * clocks are turned OFF and VDD is allowed to minimize.
423 */
424 mb();
425
426 clk_disable(mehci->sys_clk);
427 clk_disable(mehci->hsic_clk);
428 clk_disable(mehci->cal_clk);
429 clk_disable(mehci->ahb_clk);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530430 pdata = mehci->dev->platform_data;
431 if (pdata->hub_reset) {
432 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_OFF);
433 if (ret)
434 pr_err("%s failed to devote for"
435 "TCXO D1 buffer%d\n", __func__, ret);
436 }
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530437
Vamsi Krishna45d88fa2011-11-02 13:28:42 -0700438 ret = regulator_set_voltage(mehci->hsic_vddcx,
439 USB_PHY_VDD_DIG_VOL_SUSP_MIN,
440 USB_PHY_VDD_DIG_VOL_MAX);
441 if (ret < 0)
442 dev_err(mehci->dev, "unable to set vddcx voltage: min:0.5v max:1.3v\n");
443
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530444 atomic_set(&mehci->in_lpm, 1);
445 enable_irq(hcd->irq);
446 wake_unlock(&mehci->wlock);
447
448 dev_info(mehci->dev, "HSIC-USB in low power mode\n");
449
450 return 0;
451}
452
453static int msm_hsic_resume(struct msm_hsic_hcd *mehci)
454{
455 struct usb_hcd *hcd = hsic_to_hcd(mehci);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530456 int cnt = 0, ret;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530457 unsigned temp;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530458 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530459
460 if (!atomic_read(&mehci->in_lpm)) {
461 dev_dbg(mehci->dev, "%s called in !in_lpm\n", __func__);
462 return 0;
463 }
464
465 wake_lock(&mehci->wlock);
466
Vamsi Krishna45d88fa2011-11-02 13:28:42 -0700467 ret = regulator_set_voltage(mehci->hsic_vddcx,
468 USB_PHY_VDD_DIG_VOL_MIN,
469 USB_PHY_VDD_DIG_VOL_MAX);
470 if (ret < 0)
471 dev_err(mehci->dev, "unable to set vddcx voltage: min:1v max:1.3v\n");
472
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530473 pdata = mehci->dev->platform_data;
474 if (pdata->hub_reset) {
475 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
476 if (ret)
477 pr_err("%s failed to vote for"
478 "TCXO D1 buffer%d\n", __func__, ret);
479 }
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530480 clk_enable(mehci->sys_clk);
481 clk_enable(mehci->hsic_clk);
482 clk_enable(mehci->cal_clk);
483 clk_enable(mehci->ahb_clk);
484
485 temp = readl_relaxed(USB_USBCMD);
486 temp &= ~ASYNC_INTR_CTRL;
487 temp &= ~ULPI_STP_CTRL;
488 writel_relaxed(temp, USB_USBCMD);
489
490 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD))
491 goto skip_phy_resume;
492
493 temp = readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD;
494 writel_relaxed(temp, USB_PORTSC);
495 while (cnt < PHY_RESUME_TIMEOUT_USEC) {
496 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD) &&
497 (readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_SYNC_STATE))
498 break;
499 udelay(1);
500 cnt++;
501 }
502
503 if (cnt >= PHY_RESUME_TIMEOUT_USEC) {
504 /*
505 * This is a fatal error. Reset the link and
506 * PHY to make hsic working.
507 */
508 dev_err(mehci->dev, "Unable to resume USB. Reset the hsic\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530509 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530510 msm_hsic_reset(mehci);
511 }
512
513skip_phy_resume:
514
515 atomic_set(&mehci->in_lpm, 0);
516
517 if (mehci->async_int) {
518 mehci->async_int = false;
519 pm_runtime_put_noidle(mehci->dev);
520 enable_irq(hcd->irq);
521 }
522
523 dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
524
525 return 0;
526}
527#endif
528
529static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd)
530{
531 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
532
533 if (atomic_read(&mehci->in_lpm)) {
534 disable_irq_nosync(hcd->irq);
535 mehci->async_int = true;
536 pm_runtime_get(mehci->dev);
537 return IRQ_HANDLED;
538 }
539
540 return ehci_irq(hcd);
541}
542
543static int ehci_hsic_reset(struct usb_hcd *hcd)
544{
545 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
546 int retval;
547
548 ehci->caps = USB_CAPLENGTH;
549 ehci->regs = USB_CAPLENGTH +
550 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
551 dbg_hcs_params(ehci, "reset");
552 dbg_hcc_params(ehci, "reset");
553
554 /* cache the data to minimize the chip reads*/
555 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
556
557 hcd->has_tt = 1;
558 ehci->sbrn = HCD_USB2;
559
560 retval = ehci_halt(ehci);
561 if (retval)
562 return retval;
563
564 /* data structure init */
565 retval = ehci_init(hcd);
566 if (retval)
567 return retval;
568
569 retval = ehci_reset(ehci);
570 if (retval)
571 return retval;
572
573 /* bursts of unspecified length. */
574 writel_relaxed(0, USB_AHBBURST);
575 /* Use the AHB transactor */
576 writel_relaxed(0, USB_AHBMODE);
577 /* Disable streaming mode and select host mode */
578 writel_relaxed(0x13, USB_USBMODE);
579
580 ehci_port_power(ehci, 1);
581 return 0;
582}
583
584static struct hc_driver msm_hsic_driver = {
585 .description = hcd_name,
586 .product_desc = "Qualcomm EHCI Host Controller using HSIC",
587 .hcd_priv_size = sizeof(struct msm_hsic_hcd),
588
589 /*
590 * generic hardware linkage
591 */
592 .irq = msm_hsic_irq,
593 .flags = HCD_USB2 | HCD_MEMORY,
594
595 .reset = ehci_hsic_reset,
596 .start = ehci_run,
597
598 .stop = ehci_stop,
599 .shutdown = ehci_shutdown,
600
601 /*
602 * managing i/o requests and associated device resources
603 */
604 .urb_enqueue = ehci_urb_enqueue,
605 .urb_dequeue = ehci_urb_dequeue,
606 .endpoint_disable = ehci_endpoint_disable,
607 .endpoint_reset = ehci_endpoint_reset,
608 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
609
610 /*
611 * scheduling support
612 */
613 .get_frame_number = ehci_get_frame,
614
615 /*
616 * root hub support
617 */
618 .hub_status_data = ehci_hub_status_data,
619 .hub_control = ehci_hub_control,
620 .relinquish_port = ehci_relinquish_port,
621 .port_handed_over = ehci_port_handed_over,
622
623 /*
624 * PM support
625 */
626 .bus_suspend = ehci_bus_suspend,
627 .bus_resume = ehci_bus_resume,
628};
629
630static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
631{
632 int ret = 0;
633
634 if (!init)
635 goto put_clocks;
636
637 /*sys_clk is required for LINK protocol engine,it should be at 60MHz */
638 mehci->sys_clk = clk_get(mehci->dev, "usb_hsic_system_clk");
639 if (IS_ERR(mehci->sys_clk)) {
640 dev_err(mehci->dev, "failed to get hsic_sys_clk\n");
641 ret = PTR_ERR(mehci->sys_clk);
642 return ret;
643 }
644 clk_set_rate(mehci->sys_clk, 60000000);
645
646 /* 60MHz fs_xcvr_clk is for LINK to be used during PHY RESET */
647 mehci->fs_xcvr_clk = clk_get(mehci->dev, "usb_hsic_xcvr_fs_clk");
648 if (IS_ERR(mehci->fs_xcvr_clk)) {
649 dev_err(mehci->dev, "failed to get fs_xcvr_clk\n");
650 ret = PTR_ERR(mehci->fs_xcvr_clk);
651 goto put_sys_clk;
652 }
653 clk_set_rate(mehci->fs_xcvr_clk, 60000000);
654
655 /* 480MHz hsic_clk is required for HSIC PHY operation */
656 mehci->hsic_clk = clk_get(mehci->dev, "usb_hsic_hsic_clk");
657 if (IS_ERR(mehci->hsic_clk)) {
658 dev_err(mehci->dev, "failed to get hsic_clk\n");
659 ret = PTR_ERR(mehci->hsic_clk);
660 goto put_fs_xcvr_clk;
661 }
662 clk_set_rate(mehci->hsic_clk, 480000000);
663
664 /* 10MHz cal_clk is required for calibration of I/O pads */
665 mehci->cal_clk = clk_get(mehci->dev, "usb_hsic_hsio_cal_clk");
666 if (IS_ERR(mehci->cal_clk)) {
667 dev_err(mehci->dev, "failed to get hsic_cal_clk\n");
668 ret = PTR_ERR(mehci->cal_clk);
669 goto put_hsic_clk;
670 }
671 clk_set_rate(mehci->cal_clk, 10000000);
672
673 /* ahb_clk is required for data transfers */
674 mehci->ahb_clk = clk_get(mehci->dev, "usb_hsic_p_clk");
675 if (IS_ERR(mehci->ahb_clk)) {
676 dev_err(mehci->dev, "failed to get hsic_ahb_clk\n");
677 ret = PTR_ERR(mehci->ahb_clk);
678 goto put_cal_clk;
679 }
680
681 clk_enable(mehci->sys_clk);
682 clk_enable(mehci->hsic_clk);
683 clk_enable(mehci->cal_clk);
684 clk_enable(mehci->ahb_clk);
685
686 return 0;
687
688put_clocks:
689 clk_disable(mehci->sys_clk);
690 clk_disable(mehci->hsic_clk);
691 clk_disable(mehci->cal_clk);
692 clk_disable(mehci->ahb_clk);
693 clk_put(mehci->ahb_clk);
694put_cal_clk:
695 clk_put(mehci->cal_clk);
696put_hsic_clk:
697 clk_put(mehci->hsic_clk);
698put_fs_xcvr_clk:
699 clk_put(mehci->fs_xcvr_clk);
700put_sys_clk:
701 clk_put(mehci->sys_clk);
702
703 return ret;
704}
Vamsi Krishna34f01582011-12-14 19:54:42 -0800705static irqreturn_t hsic_peripheral_status_change(int irq, void *dev_id)
706{
707 struct msm_hsic_hcd *mehci = dev_id;
708
709 pr_debug("%s: mechi:%p dev_id:%p\n", __func__, mehci, dev_id);
710
711 if (mehci)
712 msm_hsic_config_gpios(mehci, 0);
713
714 return IRQ_HANDLED;
715}
716
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530717static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
718{
719 struct usb_hcd *hcd;
720 struct resource *res;
721 struct msm_hsic_hcd *mehci;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530722 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530723 int ret;
724
725 dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");
726
727 hcd = usb_create_hcd(&msm_hsic_driver, &pdev->dev,
728 dev_name(&pdev->dev));
729 if (!hcd) {
730 dev_err(&pdev->dev, "Unable to create HCD\n");
731 return -ENOMEM;
732 }
733
734 hcd->irq = platform_get_irq(pdev, 0);
735 if (hcd->irq < 0) {
736 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
737 ret = hcd->irq;
738 goto put_hcd;
739 }
740
741 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
742 if (!res) {
743 dev_err(&pdev->dev, "Unable to get memory resource\n");
744 ret = -ENODEV;
745 goto put_hcd;
746 }
747
748 hcd->rsrc_start = res->start;
749 hcd->rsrc_len = resource_size(res);
750 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
751 if (!hcd->regs) {
752 dev_err(&pdev->dev, "ioremap failed\n");
753 ret = -ENOMEM;
754 goto put_hcd;
755 }
756
757 mehci = hcd_to_hsic(hcd);
758 mehci->dev = &pdev->dev;
759
Vamsi Krishna34f01582011-12-14 19:54:42 -0800760 res = platform_get_resource_byname(pdev,
761 IORESOURCE_IRQ,
762 "peripheral_status_irq");
763 if (res)
764 mehci->peripheral_status_irq = res->start;
765
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530766 ret = msm_hsic_init_clocks(mehci, 1);
767 if (ret) {
768 dev_err(&pdev->dev, "unable to initialize clocks\n");
769 ret = -ENODEV;
770 goto unmap;
771 }
772
773 ret = msm_hsic_init_vddcx(mehci, 1);
774 if (ret) {
775 dev_err(&pdev->dev, "unable to initialize VDDCX\n");
776 ret = -ENODEV;
777 goto deinit_clocks;
778 }
779
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530780 pdata = mehci->dev->platform_data;
781 if (pdata->hub_reset) {
782 mehci->xo_handle = msm_xo_get(MSM_XO_TCXO_D1, "hsic");
783 if (IS_ERR(mehci->xo_handle)) {
784 pr_err(" %s not able to get the handle"
785 "to vote for TCXO D1 buffer\n", __func__);
786 ret = PTR_ERR(mehci->xo_handle);
787 goto deinit_vddcx;
788 }
789
790 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
791 if (ret) {
792 pr_err("%s failed to vote for TCXO"
793 "D1 buffer%d\n", __func__, ret);
794 goto free_xo_handle;
795 }
796 }
797
798 ret = msm_hsic_config_hub(mehci, 1);
799 if (ret) {
800 dev_err(&pdev->dev, "unable to initialize hsic hub");
801 goto free_xo_handle;
802 }
803
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530804 ret = msm_hsic_reset(mehci);
805 if (ret) {
806 dev_err(&pdev->dev, "unable to initialize PHY\n");
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530807 goto deinit_hub;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530808 }
809
810 ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
811 if (ret) {
812 dev_err(&pdev->dev, "unable to register HCD\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530813 goto unconfig_gpio;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530814 }
815
816 device_init_wakeup(&pdev->dev, 1);
817 wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
818 wake_lock(&mehci->wlock);
Vamsi Krishna34f01582011-12-14 19:54:42 -0800819
820 if (mehci->peripheral_status_irq) {
821 ret = request_threaded_irq(mehci->peripheral_status_irq,
822 NULL, hsic_peripheral_status_change,
823 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
824 | IRQF_SHARED,
825 "hsic_peripheral_status", mehci);
826 if (ret)
827 dev_err(&pdev->dev, "%s:request_irq:%d failed:%d",
828 __func__, mehci->peripheral_status_irq, ret);
829 }
830
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530831 /*
832 * This pdev->dev is assigned parent of root-hub by USB core,
833 * hence, runtime framework automatically calls this driver's
834 * runtime APIs based on root-hub's state.
835 */
836 pm_runtime_set_active(&pdev->dev);
837 pm_runtime_enable(&pdev->dev);
838
839 return 0;
840
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530841unconfig_gpio:
842 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530843deinit_hub:
844 msm_hsic_config_hub(mehci, 0);
845free_xo_handle:
846 if (pdata->hub_reset)
847 msm_xo_put(mehci->xo_handle);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530848deinit_vddcx:
849 msm_hsic_init_vddcx(mehci, 0);
850deinit_clocks:
851 msm_hsic_init_clocks(mehci, 0);
852unmap:
853 iounmap(hcd->regs);
854put_hcd:
855 usb_put_hcd(hcd);
856
857 return ret;
858}
859
860static int __devexit ehci_hsic_msm_remove(struct platform_device *pdev)
861{
862 struct usb_hcd *hcd = platform_get_drvdata(pdev);
863 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530864 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530865
Vamsi Krishna34f01582011-12-14 19:54:42 -0800866 if (mehci->peripheral_status_irq)
867 free_irq(mehci->peripheral_status_irq, mehci);
868
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530869 device_init_wakeup(&pdev->dev, 0);
870 pm_runtime_disable(&pdev->dev);
871 pm_runtime_set_suspended(&pdev->dev);
872
873 usb_remove_hcd(hcd);
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530874 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530875 msm_hsic_config_hub(mehci, 0);
876 pdata = mehci->dev->platform_data;
877 if (pdata->hub_reset)
878 msm_xo_put(mehci->xo_handle);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530879 msm_hsic_init_vddcx(mehci, 0);
880
881 msm_hsic_init_clocks(mehci, 0);
882 wake_lock_destroy(&mehci->wlock);
883 iounmap(hcd->regs);
884 usb_put_hcd(hcd);
885
886 return 0;
887}
888
889#ifdef CONFIG_PM_SLEEP
890static int msm_hsic_pm_suspend(struct device *dev)
891{
892 struct usb_hcd *hcd = dev_get_drvdata(dev);
893 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
894
895 dev_dbg(dev, "ehci-msm-hsic PM suspend\n");
896
897 if (device_may_wakeup(dev))
898 enable_irq_wake(hcd->irq);
899
900 return msm_hsic_suspend(mehci);
901
902}
903
904static int msm_hsic_pm_resume(struct device *dev)
905{
906 int ret;
907 struct usb_hcd *hcd = dev_get_drvdata(dev);
908 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
909
910 dev_dbg(dev, "ehci-msm-hsic PM resume\n");
911
912 if (device_may_wakeup(dev))
913 disable_irq_wake(hcd->irq);
914
915 ret = msm_hsic_resume(mehci);
916 if (ret)
917 return ret;
918
919 /* Bring the device to full powered state upon system resume */
920 pm_runtime_disable(dev);
921 pm_runtime_set_active(dev);
922 pm_runtime_enable(dev);
923
924 return 0;
925}
926#endif
927
928#ifdef CONFIG_PM_RUNTIME
929static int msm_hsic_runtime_idle(struct device *dev)
930{
931 dev_dbg(dev, "EHCI runtime idle\n");
932
933 return 0;
934}
935
936static int msm_hsic_runtime_suspend(struct device *dev)
937{
938 struct usb_hcd *hcd = dev_get_drvdata(dev);
939 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
940
941 dev_dbg(dev, "EHCI runtime suspend\n");
942 return msm_hsic_suspend(mehci);
943}
944
945static int msm_hsic_runtime_resume(struct device *dev)
946{
947 struct usb_hcd *hcd = dev_get_drvdata(dev);
948 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
949
950 dev_dbg(dev, "EHCI runtime resume\n");
951 return msm_hsic_resume(mehci);
952}
953#endif
954
955#ifdef CONFIG_PM
956static const struct dev_pm_ops msm_hsic_dev_pm_ops = {
957 SET_SYSTEM_SLEEP_PM_OPS(msm_hsic_pm_suspend, msm_hsic_pm_resume)
958 SET_RUNTIME_PM_OPS(msm_hsic_runtime_suspend, msm_hsic_runtime_resume,
959 msm_hsic_runtime_idle)
960};
961#endif
962
963static struct platform_driver ehci_msm_hsic_driver = {
964 .probe = ehci_hsic_msm_probe,
965 .remove = __devexit_p(ehci_hsic_msm_remove),
966 .driver = {
967 .name = "msm_hsic_host",
968#ifdef CONFIG_PM
969 .pm = &msm_hsic_dev_pm_ops,
970#endif
971 },
972};