blob: 093a170034fde10d48429788f19ddd9599adba9f [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>
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053038
39#define MSM_USB_BASE (hcd->regs)
40
41struct msm_hsic_hcd {
42 struct ehci_hcd ehci;
43 struct device *dev;
44 struct clk *ahb_clk;
45 struct clk *sys_clk;
46 struct clk *fs_xcvr_clk;
47 struct clk *hsic_clk;
48 struct clk *cal_clk;
49 struct regulator *hsic_vddcx;
50 bool async_int;
51 atomic_t in_lpm;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +053052 struct msm_xo_voter *xo_handle;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +053053 struct wake_lock wlock;
54};
55
56static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
57{
58 return (struct msm_hsic_hcd *) (hcd->hcd_priv);
59}
60
61static inline struct usb_hcd *hsic_to_hcd(struct msm_hsic_hcd *mehci)
62{
63 return container_of((void *) mehci, struct usb_hcd, hcd_priv);
64}
65
66#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
67
68#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */
69#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
70#define USB_PHY_VDD_DIG_LOAD 49360 /* uA */
71
72static int msm_hsic_init_vddcx(struct msm_hsic_hcd *mehci, int init)
73{
74 int ret = 0;
75
76 if (!init)
77 goto disable_reg;
78
79 mehci->hsic_vddcx = regulator_get(mehci->dev, "HSIC_VDDCX");
80 if (IS_ERR(mehci->hsic_vddcx)) {
81 dev_err(mehci->dev, "unable to get hsic vddcx\n");
82 return PTR_ERR(mehci->hsic_vddcx);
83 }
84
85 ret = regulator_set_voltage(mehci->hsic_vddcx,
86 USB_PHY_VDD_DIG_VOL_MIN,
87 USB_PHY_VDD_DIG_VOL_MAX);
88 if (ret) {
89 dev_err(mehci->dev, "unable to set the voltage"
90 "for hsic vddcx\n");
91 goto reg_set_voltage_err;
92 }
93
94 ret = regulator_set_optimum_mode(mehci->hsic_vddcx,
95 USB_PHY_VDD_DIG_LOAD);
96 if (ret < 0) {
97 pr_err("%s: Unable to set optimum mode of the regulator:"
98 "VDDCX\n", __func__);
99 goto reg_optimum_mode_err;
100 }
101
102 ret = regulator_enable(mehci->hsic_vddcx);
103 if (ret) {
104 dev_err(mehci->dev, "unable to enable hsic vddcx\n");
105 goto reg_enable_err;
106 }
107
108 return 0;
109
110disable_reg:
111 regulator_disable(mehci->hsic_vddcx);
112reg_enable_err:
113 regulator_set_optimum_mode(mehci->hsic_vddcx, 0);
114reg_optimum_mode_err:
115 regulator_set_voltage(mehci->hsic_vddcx, 0,
116 USB_PHY_VDD_DIG_VOL_MIN);
117reg_set_voltage_err:
118 regulator_put(mehci->hsic_vddcx);
119
120 return ret;
121
122}
123
124static int ulpi_write(struct msm_hsic_hcd *mehci, u32 val, u32 reg)
125{
126 struct usb_hcd *hcd = hsic_to_hcd(mehci);
127 int cnt = 0;
128
129 /* initiate write operation */
130 writel_relaxed(ULPI_RUN | ULPI_WRITE |
131 ULPI_ADDR(reg) | ULPI_DATA(val),
132 USB_ULPI_VIEWPORT);
133
134 /* wait for completion */
135 while (cnt < ULPI_IO_TIMEOUT_USEC) {
136 if (!(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN))
137 break;
138 udelay(1);
139 cnt++;
140 }
141
142 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
143 dev_err(mehci->dev, "ulpi_write: timeout\n");
144 return -ETIMEDOUT;
145 }
146
147 return 0;
148}
149
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530150#define HSIC_HUB_VDD_VOL_MIN 1650000 /* uV */
151#define HSIC_HUB_VDD_VOL_MAX 1950000 /* uV */
152#define HSIC_HUB_VDD_LOAD 36000 /* uA */
153static int msm_hsic_config_hub(struct msm_hsic_hcd *mehci, int init)
154{
155 int ret = 0;
156 struct msm_hsic_host_platform_data *pdata;
157 static struct regulator *hsic_hub_reg;
158
159 pdata = mehci->dev->platform_data;
160 if (!pdata->hub_reset)
161 return ret;
162
163 if (!init)
164 goto disable_reg;
165
166 hsic_hub_reg = regulator_get(mehci->dev, "EXT_HUB_VDDIO");
167 if (IS_ERR(hsic_hub_reg)) {
168 dev_err(mehci->dev, "unable to get ext hub vddcx\n");
169 return PTR_ERR(hsic_hub_reg);
170 }
171
172 ret = gpio_request(pdata->hub_reset, "HSIC_HUB_RESET_GPIO");
173 if (ret < 0) {
174 dev_err(mehci->dev, "gpio request failed for GPIO%d\n",
175 pdata->hub_reset);
176 goto gpio_req_fail;
177 }
178
179 ret = regulator_set_voltage(hsic_hub_reg,
180 HSIC_HUB_VDD_VOL_MIN,
181 HSIC_HUB_VDD_VOL_MAX);
182 if (ret) {
183 dev_err(mehci->dev, "unable to set the voltage"
184 "for hsic hub reg\n");
185 goto reg_set_voltage_fail;
186 }
187
188 ret = regulator_set_optimum_mode(hsic_hub_reg,
189 HSIC_HUB_VDD_LOAD);
190 if (ret < 0) {
191 pr_err("%s: Unable to set optimum mode of the regulator:"
192 "VDDCX\n", __func__);
193 goto reg_optimum_mode_fail;
194 }
195
196 ret = regulator_enable(hsic_hub_reg);
197 if (ret) {
198 dev_err(mehci->dev, "unable to enable ext hub vddcx\n");
199 goto reg_enable_fail;
200 }
201
202 gpio_direction_output(pdata->hub_reset, 0);
203 /* Hub reset should be asserted for minimum 2usec before deasserting */
204 udelay(5);
205 gpio_direction_output(pdata->hub_reset, 1);
206
207 return 0;
208
209disable_reg:
210 regulator_disable(hsic_hub_reg);
211reg_enable_fail:
212 regulator_set_optimum_mode(hsic_hub_reg, 0);
213reg_optimum_mode_fail:
214 regulator_set_voltage(hsic_hub_reg, 0,
215 HSIC_HUB_VDD_VOL_MIN);
216reg_set_voltage_fail:
217 gpio_free(pdata->hub_reset);
218gpio_req_fail:
219 regulator_put(hsic_hub_reg);
220
221 return ret;
222
223}
224
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530225static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en)
226{
227 int rc = 0;
228 struct msm_hsic_host_platform_data *pdata;
229
230 pdata = mehci->dev->platform_data;
231 /*
232 * In future versions, dedicated lines might be used for HSIC
233 * strobe and data instead of gpios. Hence returning zero value.
234 */
235 if (!pdata->strobe || !pdata->data)
236 return rc;
237
238 if (!gpio_en)
239 goto free_gpio;
240
241 rc = gpio_request(pdata->strobe, "HSIC_STROBE_GPIO");
242 if (rc < 0) {
243 dev_err(mehci->dev, "gpio request failed for HSIC STROBE\n");
244 return rc;
245 }
246
247 rc = gpio_request(pdata->data, "HSIC_DATA_GPIO");
248 if (rc < 0) {
249 dev_err(mehci->dev, "gpio request failed for HSIC DATA\n");
250 goto free_strobe;
251 }
252
253 return 0;
254
255free_gpio:
256 gpio_free(pdata->data);
257free_strobe:
258 gpio_free(pdata->strobe);
259
260 return rc;
261}
262
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530263static int msm_hsic_phy_clk_reset(struct msm_hsic_hcd *mehci)
264{
265 int ret;
266
267 clk_enable(mehci->fs_xcvr_clk);
268
269 ret = clk_reset(mehci->sys_clk, CLK_RESET_ASSERT);
270 if (ret) {
271 clk_disable(mehci->fs_xcvr_clk);
272 dev_err(mehci->dev, "usb phy clk assert failed\n");
273 return ret;
274 }
275 usleep_range(10000, 12000);
276 clk_disable(mehci->fs_xcvr_clk);
277
278 ret = clk_reset(mehci->sys_clk, CLK_RESET_DEASSERT);
279 if (ret)
280 dev_err(mehci->dev, "usb phy clk deassert failed\n");
281
282 return ret;
283}
284
285static int msm_hsic_phy_reset(struct msm_hsic_hcd *mehci)
286{
287 struct usb_hcd *hcd = hsic_to_hcd(mehci);
288 u32 val;
289 int ret;
290
291 ret = msm_hsic_phy_clk_reset(mehci);
292 if (ret)
293 return ret;
294
295 val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
296 writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);
297
298 /* Ensure that RESET operation is completed before turning off clock */
299 mb();
300 dev_dbg(mehci->dev, "phy_reset: success\n");
301
302 return 0;
303}
304
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530305#define HSIC_GPIO150_PAD_CTL (MSM_TLMM_BASE+0x20C0)
306#define HSIC_GPIO151_PAD_CTL (MSM_TLMM_BASE+0x20C4)
307#define HSIC_CAL_PAD_CTL (MSM_TLMM_BASE+0x20C8)
308#define HSIC_LV_MODE 0x04
309#define HSIC_PAD_CALIBRATION 0xA8
310#define HSIC_GPIO_PAD_VAL 0x0A0AAA10
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530311#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
312static int msm_hsic_reset(struct msm_hsic_hcd *mehci)
313{
314 struct usb_hcd *hcd = hsic_to_hcd(mehci);
315 int cnt = 0;
316 int ret;
317
318 ret = msm_hsic_phy_reset(mehci);
319 if (ret) {
320 dev_err(mehci->dev, "phy_reset failed\n");
321 return ret;
322 }
323
324 writel_relaxed(USBCMD_RESET, USB_USBCMD);
325 while (cnt < LINK_RESET_TIMEOUT_USEC) {
326 if (!(readl_relaxed(USB_USBCMD) & USBCMD_RESET))
327 break;
328 udelay(1);
329 cnt++;
330 }
331 if (cnt >= LINK_RESET_TIMEOUT_USEC)
332 return -ETIMEDOUT;
333
334 /* select ULPI phy */
335 writel_relaxed(0x80000000, USB_PORTSC);
336
337 /* TODO: Need to confirm if HSIC PHY also requires delay after RESET */
338 msleep(100);
339
340 /* HSIC PHY Initialization */
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530341 /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */
342 writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL);
343
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530344 /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
345 ulpi_write(mehci, 0xFF, 0x33);
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530346
347 /* Enable periodic IO calibration in HSIC_CFG register */
348 ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30);
349
350 /* Configure GPIO 150/151 pins for HSIC functionality mode */
351 ret = msm_hsic_config_gpios(mehci, 1);
352 if (ret) {
353 dev_err(mehci->dev, " gpio configuarion failed\n");
354 return ret;
355 }
356
357 /* Set LV_MODE=0x1 and DCC=0x2 in HSIC_GPIO150/151_PAD_CTL register */
358 writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO150_PAD_CTL);
359 writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO151_PAD_CTL);
360
361 /* Enable HSIC mode in HSIC_CFG register */
362 ulpi_write(mehci, 0x01, 0x31);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530363
364 return 0;
365}
366
367#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
368#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
369
370#ifdef CONFIG_PM_SLEEP
371static int msm_hsic_suspend(struct msm_hsic_hcd *mehci)
372{
373 struct usb_hcd *hcd = hsic_to_hcd(mehci);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530374 int cnt = 0, ret;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530375 u32 val;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530376 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530377
378 if (atomic_read(&mehci->in_lpm)) {
379 dev_dbg(mehci->dev, "%s called in lpm\n", __func__);
380 return 0;
381 }
382
383 disable_irq(hcd->irq);
384 /*
385 * PHY may take some time or even fail to enter into low power
386 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
387 * in failure case.
388 */
389 val = readl_relaxed(USB_PORTSC) | PORTSC_PHCD;
390 writel_relaxed(val, USB_PORTSC);
391 while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
392 if (readl_relaxed(USB_PORTSC) & PORTSC_PHCD)
393 break;
394 udelay(1);
395 cnt++;
396 }
397
398 if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
399 dev_err(mehci->dev, "Unable to suspend PHY\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530400 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530401 msm_hsic_reset(mehci);
402 enable_irq(hcd->irq);
403 return -ETIMEDOUT;
404 }
405
406 /*
407 * PHY has capability to generate interrupt asynchronously in low
408 * power mode (LPM). This interrupt is level triggered. So USB IRQ
409 * line must be disabled till async interrupt enable bit is cleared
410 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
411 * block data communication from PHY.
412 */
413 writel_relaxed(readl_relaxed(USB_USBCMD) | ASYNC_INTR_CTRL |
414 ULPI_STP_CTRL, USB_USBCMD);
415
416 /*
417 * Ensure that hardware is put in low power mode before
418 * clocks are turned OFF and VDD is allowed to minimize.
419 */
420 mb();
421
422 clk_disable(mehci->sys_clk);
423 clk_disable(mehci->hsic_clk);
424 clk_disable(mehci->cal_clk);
425 clk_disable(mehci->ahb_clk);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530426 pdata = mehci->dev->platform_data;
427 if (pdata->hub_reset) {
428 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_OFF);
429 if (ret)
430 pr_err("%s failed to devote for"
431 "TCXO D1 buffer%d\n", __func__, ret);
432 }
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530433
434 atomic_set(&mehci->in_lpm, 1);
435 enable_irq(hcd->irq);
436 wake_unlock(&mehci->wlock);
437
438 dev_info(mehci->dev, "HSIC-USB in low power mode\n");
439
440 return 0;
441}
442
443static int msm_hsic_resume(struct msm_hsic_hcd *mehci)
444{
445 struct usb_hcd *hcd = hsic_to_hcd(mehci);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530446 int cnt = 0, ret;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530447 unsigned temp;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530448 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530449
450 if (!atomic_read(&mehci->in_lpm)) {
451 dev_dbg(mehci->dev, "%s called in !in_lpm\n", __func__);
452 return 0;
453 }
454
455 wake_lock(&mehci->wlock);
456
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530457 pdata = mehci->dev->platform_data;
458 if (pdata->hub_reset) {
459 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
460 if (ret)
461 pr_err("%s failed to vote for"
462 "TCXO D1 buffer%d\n", __func__, ret);
463 }
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530464 clk_enable(mehci->sys_clk);
465 clk_enable(mehci->hsic_clk);
466 clk_enable(mehci->cal_clk);
467 clk_enable(mehci->ahb_clk);
468
469 temp = readl_relaxed(USB_USBCMD);
470 temp &= ~ASYNC_INTR_CTRL;
471 temp &= ~ULPI_STP_CTRL;
472 writel_relaxed(temp, USB_USBCMD);
473
474 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD))
475 goto skip_phy_resume;
476
477 temp = readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD;
478 writel_relaxed(temp, USB_PORTSC);
479 while (cnt < PHY_RESUME_TIMEOUT_USEC) {
480 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD) &&
481 (readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_SYNC_STATE))
482 break;
483 udelay(1);
484 cnt++;
485 }
486
487 if (cnt >= PHY_RESUME_TIMEOUT_USEC) {
488 /*
489 * This is a fatal error. Reset the link and
490 * PHY to make hsic working.
491 */
492 dev_err(mehci->dev, "Unable to resume USB. Reset the hsic\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530493 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530494 msm_hsic_reset(mehci);
495 }
496
497skip_phy_resume:
498
499 atomic_set(&mehci->in_lpm, 0);
500
501 if (mehci->async_int) {
502 mehci->async_int = false;
503 pm_runtime_put_noidle(mehci->dev);
504 enable_irq(hcd->irq);
505 }
506
507 dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
508
509 return 0;
510}
511#endif
512
513static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd)
514{
515 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
516
517 if (atomic_read(&mehci->in_lpm)) {
518 disable_irq_nosync(hcd->irq);
519 mehci->async_int = true;
520 pm_runtime_get(mehci->dev);
521 return IRQ_HANDLED;
522 }
523
524 return ehci_irq(hcd);
525}
526
527static int ehci_hsic_reset(struct usb_hcd *hcd)
528{
529 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
530 int retval;
531
532 ehci->caps = USB_CAPLENGTH;
533 ehci->regs = USB_CAPLENGTH +
534 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
535 dbg_hcs_params(ehci, "reset");
536 dbg_hcc_params(ehci, "reset");
537
538 /* cache the data to minimize the chip reads*/
539 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
540
541 hcd->has_tt = 1;
542 ehci->sbrn = HCD_USB2;
543
544 retval = ehci_halt(ehci);
545 if (retval)
546 return retval;
547
548 /* data structure init */
549 retval = ehci_init(hcd);
550 if (retval)
551 return retval;
552
553 retval = ehci_reset(ehci);
554 if (retval)
555 return retval;
556
557 /* bursts of unspecified length. */
558 writel_relaxed(0, USB_AHBBURST);
559 /* Use the AHB transactor */
560 writel_relaxed(0, USB_AHBMODE);
561 /* Disable streaming mode and select host mode */
562 writel_relaxed(0x13, USB_USBMODE);
563
564 ehci_port_power(ehci, 1);
565 return 0;
566}
567
568static struct hc_driver msm_hsic_driver = {
569 .description = hcd_name,
570 .product_desc = "Qualcomm EHCI Host Controller using HSIC",
571 .hcd_priv_size = sizeof(struct msm_hsic_hcd),
572
573 /*
574 * generic hardware linkage
575 */
576 .irq = msm_hsic_irq,
577 .flags = HCD_USB2 | HCD_MEMORY,
578
579 .reset = ehci_hsic_reset,
580 .start = ehci_run,
581
582 .stop = ehci_stop,
583 .shutdown = ehci_shutdown,
584
585 /*
586 * managing i/o requests and associated device resources
587 */
588 .urb_enqueue = ehci_urb_enqueue,
589 .urb_dequeue = ehci_urb_dequeue,
590 .endpoint_disable = ehci_endpoint_disable,
591 .endpoint_reset = ehci_endpoint_reset,
592 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
593
594 /*
595 * scheduling support
596 */
597 .get_frame_number = ehci_get_frame,
598
599 /*
600 * root hub support
601 */
602 .hub_status_data = ehci_hub_status_data,
603 .hub_control = ehci_hub_control,
604 .relinquish_port = ehci_relinquish_port,
605 .port_handed_over = ehci_port_handed_over,
606
607 /*
608 * PM support
609 */
610 .bus_suspend = ehci_bus_suspend,
611 .bus_resume = ehci_bus_resume,
612};
613
614static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
615{
616 int ret = 0;
617
618 if (!init)
619 goto put_clocks;
620
621 /*sys_clk is required for LINK protocol engine,it should be at 60MHz */
622 mehci->sys_clk = clk_get(mehci->dev, "usb_hsic_system_clk");
623 if (IS_ERR(mehci->sys_clk)) {
624 dev_err(mehci->dev, "failed to get hsic_sys_clk\n");
625 ret = PTR_ERR(mehci->sys_clk);
626 return ret;
627 }
628 clk_set_rate(mehci->sys_clk, 60000000);
629
630 /* 60MHz fs_xcvr_clk is for LINK to be used during PHY RESET */
631 mehci->fs_xcvr_clk = clk_get(mehci->dev, "usb_hsic_xcvr_fs_clk");
632 if (IS_ERR(mehci->fs_xcvr_clk)) {
633 dev_err(mehci->dev, "failed to get fs_xcvr_clk\n");
634 ret = PTR_ERR(mehci->fs_xcvr_clk);
635 goto put_sys_clk;
636 }
637 clk_set_rate(mehci->fs_xcvr_clk, 60000000);
638
639 /* 480MHz hsic_clk is required for HSIC PHY operation */
640 mehci->hsic_clk = clk_get(mehci->dev, "usb_hsic_hsic_clk");
641 if (IS_ERR(mehci->hsic_clk)) {
642 dev_err(mehci->dev, "failed to get hsic_clk\n");
643 ret = PTR_ERR(mehci->hsic_clk);
644 goto put_fs_xcvr_clk;
645 }
646 clk_set_rate(mehci->hsic_clk, 480000000);
647
648 /* 10MHz cal_clk is required for calibration of I/O pads */
649 mehci->cal_clk = clk_get(mehci->dev, "usb_hsic_hsio_cal_clk");
650 if (IS_ERR(mehci->cal_clk)) {
651 dev_err(mehci->dev, "failed to get hsic_cal_clk\n");
652 ret = PTR_ERR(mehci->cal_clk);
653 goto put_hsic_clk;
654 }
655 clk_set_rate(mehci->cal_clk, 10000000);
656
657 /* ahb_clk is required for data transfers */
658 mehci->ahb_clk = clk_get(mehci->dev, "usb_hsic_p_clk");
659 if (IS_ERR(mehci->ahb_clk)) {
660 dev_err(mehci->dev, "failed to get hsic_ahb_clk\n");
661 ret = PTR_ERR(mehci->ahb_clk);
662 goto put_cal_clk;
663 }
664
665 clk_enable(mehci->sys_clk);
666 clk_enable(mehci->hsic_clk);
667 clk_enable(mehci->cal_clk);
668 clk_enable(mehci->ahb_clk);
669
670 return 0;
671
672put_clocks:
673 clk_disable(mehci->sys_clk);
674 clk_disable(mehci->hsic_clk);
675 clk_disable(mehci->cal_clk);
676 clk_disable(mehci->ahb_clk);
677 clk_put(mehci->ahb_clk);
678put_cal_clk:
679 clk_put(mehci->cal_clk);
680put_hsic_clk:
681 clk_put(mehci->hsic_clk);
682put_fs_xcvr_clk:
683 clk_put(mehci->fs_xcvr_clk);
684put_sys_clk:
685 clk_put(mehci->sys_clk);
686
687 return ret;
688}
689static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
690{
691 struct usb_hcd *hcd;
692 struct resource *res;
693 struct msm_hsic_hcd *mehci;
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530694 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530695 int ret;
696
697 dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");
698
699 hcd = usb_create_hcd(&msm_hsic_driver, &pdev->dev,
700 dev_name(&pdev->dev));
701 if (!hcd) {
702 dev_err(&pdev->dev, "Unable to create HCD\n");
703 return -ENOMEM;
704 }
705
706 hcd->irq = platform_get_irq(pdev, 0);
707 if (hcd->irq < 0) {
708 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
709 ret = hcd->irq;
710 goto put_hcd;
711 }
712
713 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
714 if (!res) {
715 dev_err(&pdev->dev, "Unable to get memory resource\n");
716 ret = -ENODEV;
717 goto put_hcd;
718 }
719
720 hcd->rsrc_start = res->start;
721 hcd->rsrc_len = resource_size(res);
722 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
723 if (!hcd->regs) {
724 dev_err(&pdev->dev, "ioremap failed\n");
725 ret = -ENOMEM;
726 goto put_hcd;
727 }
728
729 mehci = hcd_to_hsic(hcd);
730 mehci->dev = &pdev->dev;
731
732 ret = msm_hsic_init_clocks(mehci, 1);
733 if (ret) {
734 dev_err(&pdev->dev, "unable to initialize clocks\n");
735 ret = -ENODEV;
736 goto unmap;
737 }
738
739 ret = msm_hsic_init_vddcx(mehci, 1);
740 if (ret) {
741 dev_err(&pdev->dev, "unable to initialize VDDCX\n");
742 ret = -ENODEV;
743 goto deinit_clocks;
744 }
745
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530746 pdata = mehci->dev->platform_data;
747 if (pdata->hub_reset) {
748 mehci->xo_handle = msm_xo_get(MSM_XO_TCXO_D1, "hsic");
749 if (IS_ERR(mehci->xo_handle)) {
750 pr_err(" %s not able to get the handle"
751 "to vote for TCXO D1 buffer\n", __func__);
752 ret = PTR_ERR(mehci->xo_handle);
753 goto deinit_vddcx;
754 }
755
756 ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
757 if (ret) {
758 pr_err("%s failed to vote for TCXO"
759 "D1 buffer%d\n", __func__, ret);
760 goto free_xo_handle;
761 }
762 }
763
764 ret = msm_hsic_config_hub(mehci, 1);
765 if (ret) {
766 dev_err(&pdev->dev, "unable to initialize hsic hub");
767 goto free_xo_handle;
768 }
769
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530770 ret = msm_hsic_reset(mehci);
771 if (ret) {
772 dev_err(&pdev->dev, "unable to initialize PHY\n");
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530773 goto deinit_hub;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530774 }
775
776 ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
777 if (ret) {
778 dev_err(&pdev->dev, "unable to register HCD\n");
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530779 goto unconfig_gpio;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530780 }
781
782 device_init_wakeup(&pdev->dev, 1);
783 wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
784 wake_lock(&mehci->wlock);
785 /*
786 * This pdev->dev is assigned parent of root-hub by USB core,
787 * hence, runtime framework automatically calls this driver's
788 * runtime APIs based on root-hub's state.
789 */
790 pm_runtime_set_active(&pdev->dev);
791 pm_runtime_enable(&pdev->dev);
792
793 return 0;
794
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530795unconfig_gpio:
796 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530797deinit_hub:
798 msm_hsic_config_hub(mehci, 0);
799free_xo_handle:
800 if (pdata->hub_reset)
801 msm_xo_put(mehci->xo_handle);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530802deinit_vddcx:
803 msm_hsic_init_vddcx(mehci, 0);
804deinit_clocks:
805 msm_hsic_init_clocks(mehci, 0);
806unmap:
807 iounmap(hcd->regs);
808put_hcd:
809 usb_put_hcd(hcd);
810
811 return ret;
812}
813
814static int __devexit ehci_hsic_msm_remove(struct platform_device *pdev)
815{
816 struct usb_hcd *hcd = platform_get_drvdata(pdev);
817 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530818 struct msm_hsic_host_platform_data *pdata;
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530819
820 device_init_wakeup(&pdev->dev, 0);
821 pm_runtime_disable(&pdev->dev);
822 pm_runtime_set_suspended(&pdev->dev);
823
824 usb_remove_hcd(hcd);
Vijayavardhan Vennapusae3316a12011-10-15 06:05:17 +0530825 msm_hsic_config_gpios(mehci, 0);
Vijayavardhan Vennapusa2b592824f2011-11-02 19:51:32 +0530826 msm_hsic_config_hub(mehci, 0);
827 pdata = mehci->dev->platform_data;
828 if (pdata->hub_reset)
829 msm_xo_put(mehci->xo_handle);
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +0530830 msm_hsic_init_vddcx(mehci, 0);
831
832 msm_hsic_init_clocks(mehci, 0);
833 wake_lock_destroy(&mehci->wlock);
834 iounmap(hcd->regs);
835 usb_put_hcd(hcd);
836
837 return 0;
838}
839
840#ifdef CONFIG_PM_SLEEP
841static int msm_hsic_pm_suspend(struct device *dev)
842{
843 struct usb_hcd *hcd = dev_get_drvdata(dev);
844 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
845
846 dev_dbg(dev, "ehci-msm-hsic PM suspend\n");
847
848 if (device_may_wakeup(dev))
849 enable_irq_wake(hcd->irq);
850
851 return msm_hsic_suspend(mehci);
852
853}
854
855static int msm_hsic_pm_resume(struct device *dev)
856{
857 int ret;
858 struct usb_hcd *hcd = dev_get_drvdata(dev);
859 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
860
861 dev_dbg(dev, "ehci-msm-hsic PM resume\n");
862
863 if (device_may_wakeup(dev))
864 disable_irq_wake(hcd->irq);
865
866 ret = msm_hsic_resume(mehci);
867 if (ret)
868 return ret;
869
870 /* Bring the device to full powered state upon system resume */
871 pm_runtime_disable(dev);
872 pm_runtime_set_active(dev);
873 pm_runtime_enable(dev);
874
875 return 0;
876}
877#endif
878
879#ifdef CONFIG_PM_RUNTIME
880static int msm_hsic_runtime_idle(struct device *dev)
881{
882 dev_dbg(dev, "EHCI runtime idle\n");
883
884 return 0;
885}
886
887static int msm_hsic_runtime_suspend(struct device *dev)
888{
889 struct usb_hcd *hcd = dev_get_drvdata(dev);
890 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
891
892 dev_dbg(dev, "EHCI runtime suspend\n");
893 return msm_hsic_suspend(mehci);
894}
895
896static int msm_hsic_runtime_resume(struct device *dev)
897{
898 struct usb_hcd *hcd = dev_get_drvdata(dev);
899 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
900
901 dev_dbg(dev, "EHCI runtime resume\n");
902 return msm_hsic_resume(mehci);
903}
904#endif
905
906#ifdef CONFIG_PM
907static const struct dev_pm_ops msm_hsic_dev_pm_ops = {
908 SET_SYSTEM_SLEEP_PM_OPS(msm_hsic_pm_suspend, msm_hsic_pm_resume)
909 SET_RUNTIME_PM_OPS(msm_hsic_runtime_suspend, msm_hsic_runtime_resume,
910 msm_hsic_runtime_idle)
911};
912#endif
913
914static struct platform_driver ehci_msm_hsic_driver = {
915 .probe = ehci_hsic_msm_probe,
916 .remove = __devexit_p(ehci_hsic_msm_remove),
917 .driver = {
918 .name = "msm_hsic_host",
919#ifdef CONFIG_PM
920 .pm = &msm_hsic_dev_pm_ops,
921#endif
922 },
923};