9288144a1e11bd37d4339a8f65fa4eccc3108727
[linux-2.6.git] / arch / arm / mach-tegra / usb_phy.c
1 /*
2  * arch/arm/mach-tegra/usb_phy.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
6  *
7  * Author:
8  *      Erik Gilling <konkers@google.com>
9  *      Benoit Goby <benoit@android.com>
10  *
11  * This software is licensed under the terms of the GNU General Public
12  * License version 2, as published by the Free Software Foundation, and
13  * may be copied, distributed, and modified under those terms.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  */
21 #include <linux/resource.h>
22 #include <linux/delay.h>
23 #include <linux/interrupt.h>
24 #include <linux/slab.h>
25 #include <linux/err.h>
26 #include <linux/platform_device.h>
27 #include <linux/io.h>
28 #include <linux/gpio.h>
29 #include <linux/interrupt.h>
30 #include <linux/clk.h>
31 #include <linux/regulator/consumer.h>
32 #include <linux/platform_data/tegra_usb.h>
33 #include "tegra_usb_phy.h"
34 #include <mach/iomap.h>
35 #include "fuse.h"
36
37 #define ERR(stuff...)           pr_err("usb_phy: " stuff)
38 #define WARNING(stuff...)       pr_warning("usb_phy: " stuff)
39 #define INFO(stuff...)          pr_info("usb_phy: " stuff)
40
41 #define AHB_MEM_PREFETCH_CFG3           0xe0
42 #define AHB_MEM_PREFETCH_CFG4           0xe4
43 #define AHB_MEM_PREFETCH_CFG1           0xec
44 #define AHB_MEM_PREFETCH_CFG2           0xf0
45 #define PREFETCH_ENB                    (1 << 31)
46
47 #ifdef DEBUG
48 #define DBG(stuff...)           pr_info("usb_phy: " stuff)
49 #else
50 #define DBG(stuff...)           do {} while (0)
51 #endif
52
53 static void print_usb_plat_data_info(struct tegra_usb_phy *phy)
54 {
55         struct tegra_usb_platform_data *pdata = phy->pdata;
56         char op_mode[][50] = {
57                 "TEGRA_USB_OPMODE_DEVICE",
58                 "TEGRA_USB_OPMODE_HOST"
59         };
60         char phy_intf[][50] = {
61                 "USB_PHY_INTF_UTMI",
62                 "USB_PHY_INTF_ULPI_LINK",
63                 "USB_PHY_INTF_ULPI_NULL",
64                 "USB_PHY_INTF_HSIC",
65                 "USB_PHY_INTF_ICUSB"
66         };
67
68         pr_info("tegra USB phy - inst[%d] platform info:\n", phy->inst);
69         pr_info("port_otg: %s\n", pdata->port_otg ? "yes" : "no");
70         pr_info("has_hostpc: %s\n", pdata->has_hostpc ? "yes" : "no");
71         pr_info("phy_interface: %s\n", phy_intf[pdata->phy_intf]);
72         pr_info("op_mode: %s\n", op_mode[pdata->op_mode]);
73         if (pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
74                 pr_info("vbus_pmu_irq: %d\n", pdata->u_data.dev.vbus_pmu_irq);
75                 pr_info("vbus_gpio: %d\n", pdata->u_data.dev.vbus_gpio);
76                 pr_info("charging: %s\n", pdata->u_data.dev.charging_supported ?
77                                 "enabled" : "disabled");
78                 pr_info("remote_wakeup: %s\n", pdata->u_data.dev.remote_wakeup_supported
79                                 ? "enabled" : "disabled");
80         } else {
81                 pr_info("vbus_gpio: %d\n", pdata->u_data.host.vbus_gpio);
82                 pr_info("vbus_reg: %s\n", pdata->u_data.host.vbus_reg ?
83                                 pdata->u_data.host.vbus_reg : "NULL");
84                 pr_info("hot_plug: %s\n", pdata->u_data.host.hot_plug ?
85                                 "enabled" : "disabled");
86                 pr_info("remote_wakeup: %s\n", pdata->u_data.host.remote_wakeup_supported
87                                 ? "enabled" : "disabled");
88         }
89 }
90
91 static void usb_host_vbus_enable(struct tegra_usb_phy *phy, bool enable)
92 {
93         if (phy->vbus_reg) {
94                 if (enable)
95                         regulator_enable(phy->vbus_reg);
96                 else
97                         regulator_disable(phy->vbus_reg);
98         } else {
99                 int gpio = phy->pdata->u_data.host.vbus_gpio;
100                 if (gpio == -1)
101                         return;
102                 gpio_set_value_cansleep(gpio, enable ? 1 : 0);
103         }
104 }
105
106 int usb_phy_reg_status_wait(void __iomem *reg, u32 mask,
107                                         u32 result, u32 timeout)
108 {
109         do {
110                 if ((readl(reg) & mask) == result)
111                         return 0;
112                 udelay(1);
113                 timeout--;
114         } while (timeout);
115
116         return -1;
117 }
118
119 static int tegra_usb_phy_init_ops(struct tegra_usb_phy *phy)
120 {
121         int err = 0;
122
123         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
124
125         if (phy->pdata->has_hostpc)
126                 err = tegra3_usb_phy_init_ops(phy);
127         else
128                 err = tegra2_usb_phy_init_ops(phy);
129
130         return err;
131 }
132
133 static irqreturn_t usb_phy_dev_vbus_pmu_irq_thr(int irq, void *pdata)
134 {
135         struct tegra_usb_phy *phy = pdata;
136
137         if (phy->vdd_reg && !phy->vdd_reg_on) {
138                 regulator_enable(phy->vdd_reg);
139                 phy->vdd_reg_on = true;
140                 /*
141                  * Optimal time to get the regulator turned on
142                  * before detecting vbus interrupt.
143                  */
144                 mdelay(15);
145         }
146
147         /* clk is disabled during phy power off and not here*/
148         if (!phy->ctrl_clk_on) {
149                 clk_enable(phy->ctrlr_clk);
150                 phy->ctrl_clk_on = true;
151         }
152
153         return IRQ_HANDLED;
154 }
155
156 static void tegra_usb_phy_release_clocks(struct tegra_usb_phy *phy)
157 {
158         clk_put(phy->emc_clk);
159         clk_put(phy->sys_clk);
160         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST)
161                 if (phy->pdata->u_data.host.hot_plug ||
162                         phy->pdata->u_data.host.remote_wakeup_supported)
163                         clk_disable(phy->ctrlr_clk);
164         clk_put(phy->ctrlr_clk);
165         clk_disable(phy->pllu_clk);
166         clk_put(phy->pllu_clk);
167 }
168
169 static int tegra_usb_phy_get_clocks(struct tegra_usb_phy *phy)
170 {
171         int err = 0;
172
173         phy->pllu_clk = clk_get_sys(NULL, "pll_u");
174         if (IS_ERR(phy->pllu_clk)) {
175                 ERR("inst:[%d] Can't get pllu_clk clock\n", phy->inst);
176                 err = PTR_ERR(phy->pllu_clk);
177                 goto fail_pll;
178         }
179         clk_enable(phy->pllu_clk);
180
181         phy->ctrlr_clk = clk_get(&phy->pdev->dev, NULL);
182         if (IS_ERR(phy->ctrlr_clk)) {
183                 dev_err(&phy->pdev->dev, "Can't get controller clock\n");
184                 err = PTR_ERR(phy->ctrlr_clk);
185                 goto fail_ctrlr_clk;
186         }
187
188         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST)
189                 if (phy->pdata->u_data.host.hot_plug ||
190                         phy->pdata->u_data.host.remote_wakeup_supported)
191                         clk_enable(phy->ctrlr_clk);
192
193         phy->sys_clk = clk_get(&phy->pdev->dev, "sclk");
194         if (IS_ERR(phy->sys_clk)) {
195                 dev_err(&phy->pdev->dev, "Can't get sclk clock\n");
196                 err = PTR_ERR(phy->sys_clk);
197                 goto fail_sclk;
198         }
199         clk_set_rate(phy->sys_clk, 80000000);
200
201         phy->emc_clk = clk_get(&phy->pdev->dev, "emc");
202         if (IS_ERR(phy->emc_clk)) {
203                 dev_err(&phy->pdev->dev, "Can't get emc clock\n");
204                 err = PTR_ERR(phy->emc_clk);
205                 goto fail_emc;
206         }
207
208         if(phy->pdata->has_hostpc)
209                 clk_set_rate(phy->emc_clk, 100000000);
210         else
211                 clk_set_rate(phy->emc_clk, 300000000);
212
213         return err;
214
215 fail_emc:
216         clk_put(phy->sys_clk);
217
218 fail_sclk:
219         clk_put(phy->ctrlr_clk);
220
221 fail_ctrlr_clk:
222         clk_disable(phy->pllu_clk);
223         clk_put(phy->pllu_clk);
224
225 fail_pll:
226         return err;
227 }
228
229 struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
230 {
231         struct tegra_usb_phy *phy;
232         struct tegra_usb_platform_data *pdata;
233         struct resource *res;
234         int err;
235         int plat_data_size = sizeof(struct tegra_usb_platform_data);
236
237         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, pdev->id);
238         pdata = dev_get_platdata(&pdev->dev);
239         if (!pdata) {
240                 dev_err(&pdev->dev, "inst:[%d] Platform data missing\n",
241                                                                 pdev->id);
242                 err = -EINVAL;
243                 goto fail_inval;
244         }
245
246         phy = devm_kzalloc(&pdev->dev, sizeof(struct tegra_usb_phy), GFP_KERNEL);
247         if (!phy) {
248                 ERR("inst:[%d] malloc usb phy failed\n", pdev->id);
249                 err = -ENOMEM;
250                 goto fail_nomem;
251         }
252
253         phy->pdata = devm_kzalloc(&pdev->dev, plat_data_size, GFP_KERNEL);
254         if (!phy->pdata) {
255                 ERR("inst:[%d] malloc usb phy pdata failed\n", pdev->id);
256                 devm_kfree(&pdev->dev, phy);
257                 err = -ENOMEM;
258                 goto fail_nomem;
259         }
260
261         memcpy(phy->pdata, pdata, plat_data_size);
262
263         phy->pdev = pdev;
264         phy->inst = pdev->id;
265
266         print_usb_plat_data_info(phy);
267
268         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
269         if (!res) {
270                 ERR("inst:[%d] failed to get I/O memory\n", phy->inst);
271                 err = -ENXIO;
272                 goto fail_io;
273         }
274
275         phy->regs = ioremap(res->start, resource_size(res));
276         if (!phy->regs) {
277                 ERR("inst:[%d] Failed to remap I/O memory\n", phy->inst);
278                 err = -ENOMEM;
279                 goto fail_io;
280         }
281
282         phy->vdd_reg = regulator_get(&pdev->dev, "avdd_usb");
283         if (IS_ERR_OR_NULL(phy->vdd_reg)) {
284                 ERR("inst:[%d] couldn't get regulator avdd_usb: %ld\n",
285                         phy->inst, PTR_ERR(phy->vdd_reg));
286                 phy->vdd_reg = NULL;
287         }
288
289         err = tegra_usb_phy_get_clocks(phy);
290         if (err) {
291                 ERR("inst:[%d] Failed to init clocks\n", phy->inst);
292                 goto fail_clk;
293         }
294
295         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
296                 if (phy->pdata->u_data.dev.vbus_pmu_irq) {
297                         err = request_threaded_irq(
298                                         phy->pdata->u_data.dev.vbus_pmu_irq,
299                                         NULL, usb_phy_dev_vbus_pmu_irq_thr,
300                                         IRQF_SHARED, "usb_pmu_vbus_irq", phy);
301                         if (err) {
302                                 ERR("inst:[%d] Failed to register IRQ\n",
303                                                                 phy->inst);
304                                 goto fail_init;
305                         }
306                 } else {
307                         clk_enable(phy->ctrlr_clk);
308                 }
309         } else {
310                 if (phy->pdata->u_data.host.vbus_reg) {
311                         phy->vbus_reg = regulator_get(NULL,
312                                         phy->pdata->u_data.host.vbus_reg);
313                         if (WARN_ON(IS_ERR_OR_NULL(phy->vbus_reg))) {
314                                 ERR("failed to get regulator vdd_vbus_usb: %ld,\
315                                  instance : %d\n", PTR_ERR(phy->vbus_reg),
316                                                                 phy->inst);
317                                 err = PTR_ERR(phy->vbus_reg);
318                                 goto fail_init;
319                         }
320                 } else {
321                         int gpio = phy->pdata->u_data.host.vbus_gpio;
322                         if (gpio != -1) {
323                                 if (gpio_request(gpio, "usb_host_vbus") < 0) {
324                                         ERR("inst:[%d] host vbus gpio \
325                                                  req failed\n", phy->inst);
326                                         goto fail_init;
327                                 }
328                                 if (gpio_direction_output(gpio, 1) < 0) {
329                                         ERR("inst:[%d] host vbus gpio \
330                                                  dir failed\n", phy->inst);
331                                         goto fail_init;
332                                 }
333                         }
334                 }
335                 usb_host_vbus_enable(phy, true);
336         }
337
338         err = tegra_usb_phy_init_ops(phy);
339         if (err) {
340                 ERR("inst:[%d] Failed to init ops\n", phy->inst);
341                 goto fail_init;
342         }
343
344         if (phy->pdata->ops && phy->pdata->ops->open)
345                 phy->pdata->ops->open();
346
347         if (phy->ops && phy->ops->open) {
348                 err = phy->ops->open(phy);
349                 if (err) {
350                         ERR("inst:[%d] Failed to open hw ops\n", phy->inst);
351                         goto fail_init;
352                 }
353         }
354
355         return phy;
356
357 fail_init:
358         tegra_usb_phy_release_clocks(phy);
359
360         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
361                 if (phy->pdata->u_data.dev.vbus_pmu_irq)
362                         free_irq(phy->pdata->u_data.dev.vbus_pmu_irq, phy);
363         } else {
364                 usb_host_vbus_enable(phy, false);
365
366                 if (phy->vbus_reg)
367                         regulator_put(phy->vbus_reg);
368                 else {
369                         int gpio = phy->pdata->u_data.host.vbus_gpio;
370                         if (gpio != -1) {
371                                 gpio_set_value_cansleep(gpio, 0);
372                                 gpio_free(gpio);
373                         }
374                 }
375         }
376
377 fail_clk:
378         regulator_put(phy->vdd_reg);
379         iounmap(phy->regs);
380 fail_io:
381         devm_kfree(&pdev->dev, phy->pdata);
382         devm_kfree(&pdev->dev, phy);
383
384 fail_nomem:
385 fail_inval:
386         return ERR_PTR(err);
387 }
388
389 void tegra_usb_phy_close(struct tegra_usb_phy *phy)
390 {
391         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
392
393         if (phy->ops && phy->ops->close)
394                 phy->ops->close(phy);
395
396         if (phy->pdata->ops && phy->pdata->ops->close)
397                 phy->pdata->ops->close();
398
399         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
400                 if (phy->pdata->u_data.dev.vbus_pmu_irq)
401                         free_irq(phy->pdata->u_data.dev.vbus_pmu_irq, phy);
402                 else
403                         clk_disable(phy->ctrlr_clk);
404         } else {
405                 usb_host_vbus_enable(phy, false);
406
407                 if (phy->vbus_reg)
408                         regulator_put(phy->vbus_reg);
409                 else {
410                         int gpio = phy->pdata->u_data.host.vbus_gpio;
411                         if (gpio != -1) {
412                                 gpio_set_value_cansleep(gpio, 0);
413                                 gpio_free(gpio);
414                         }
415                 }
416         }
417
418         if (phy->vdd_reg) {
419                 if (phy->vdd_reg_on)
420                         regulator_disable(phy->vdd_reg);
421                 regulator_put(phy->vdd_reg);
422         }
423
424         tegra_usb_phy_release_clocks(phy);
425
426         devm_kfree(&phy->pdev->dev, phy->pdata);
427         devm_kfree(&phy->pdev->dev, phy);
428 }
429
430 irqreturn_t tegra_usb_phy_irq(struct tegra_usb_phy *phy)
431 {
432         irqreturn_t status = IRQ_HANDLED;
433
434         if (phy->ops && phy->ops->irq)
435                 status = phy->ops->irq(phy);
436
437         return status;
438 }
439
440 int tegra_usb_phy_init(struct tegra_usb_phy *phy)
441 {
442         int status = 0;
443
444         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
445
446         if (phy->pdata->ops && phy->pdata->ops->init)
447                 phy->pdata->ops->init();
448
449         if (phy->ops && phy->ops->init)
450                 status = phy->ops->init(phy);
451
452         return status;
453 }
454
455 int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
456 {
457         int err = 0;
458
459         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
460
461         if (!phy->phy_power_on)
462                 return err;
463
464         if (phy->ops && phy->ops->power_off) {
465                 if (phy->pdata->ops && phy->pdata->ops->pre_phy_off)
466                         phy->pdata->ops->pre_phy_off();
467                 err = phy->ops->power_off(phy);
468                 if (phy->pdata->ops && phy->pdata->ops->post_phy_off)
469                         phy->pdata->ops->post_phy_off();
470         }
471
472         clk_disable(phy->emc_clk);
473         clk_disable(phy->sys_clk);
474         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) {
475                 if (!phy->pdata->u_data.host.hot_plug &&
476                         !phy->pdata->u_data.host.remote_wakeup_supported) {
477                         clk_disable(phy->ctrlr_clk);
478                         phy->ctrl_clk_on = false;
479                         if (phy->vdd_reg && phy->vdd_reg_on) {
480                                 regulator_disable(phy->vdd_reg);
481                                 phy->vdd_reg_on = false;
482                         }
483                 }
484         } else {
485                 /* In device mode clock regulator/clocks will be turned off
486                  * only if pmu interrupt is present on the board and host mode
487                  * support through OTG is supported on the board.
488                  */
489                 if (phy->pdata->u_data.dev.vbus_pmu_irq &&
490                         phy->pdata->builtin_host_disabled) {
491                         clk_disable(phy->ctrlr_clk);
492                         phy->ctrl_clk_on = false;
493                         if (phy->vdd_reg && phy->vdd_reg_on) {
494                                 regulator_disable(phy->vdd_reg);
495                                 phy->vdd_reg_on = false;
496                         }
497                 }
498         }
499
500         phy->phy_power_on = false;
501
502         return err;
503 }
504
505 int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
506 {
507         int status = 0;
508
509         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
510
511         if (phy->phy_power_on)
512                 return status;
513
514         if (phy->vdd_reg && !phy->vdd_reg_on) {
515                 regulator_enable(phy->vdd_reg);
516                 phy->vdd_reg_on = true;
517         }
518
519         /* In device mode clock is turned on by pmu irq handler
520          * if pmu irq is not available clocks will not be turned off/on
521          */
522         if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) {
523                 if (!phy->pdata->u_data.host.hot_plug &&
524                         !phy->pdata->u_data.host.remote_wakeup_supported)
525                         clk_enable(phy->ctrlr_clk);
526         } else {
527                 if (phy->pdata->u_data.dev.vbus_pmu_irq &&
528                         !phy->ctrl_clk_on) {
529                         clk_enable(phy->ctrlr_clk);
530                         phy->ctrl_clk_on = true;
531                 }
532         }
533         clk_enable(phy->sys_clk);
534         clk_enable(phy->emc_clk);
535
536         if (phy->ops && phy->ops->power_on) {
537                 if (phy->pdata->ops && phy->pdata->ops->pre_phy_on)
538                         phy->pdata->ops->pre_phy_on();
539                 status = phy->ops->power_on(phy);
540                 if (phy->pdata->ops && phy->pdata->ops->post_phy_on)
541                         phy->pdata->ops->post_phy_on();
542         }
543
544         phy->phy_power_on = true;
545
546         return status;
547 }
548
549 int tegra_usb_phy_reset(struct tegra_usb_phy *phy)
550 {
551         int status = 0;
552
553         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
554         if (phy->ops && phy->ops->reset)
555                 status = phy->ops->reset(phy);
556
557         return status;
558 }
559
560 int tegra_usb_phy_pre_suspend(struct tegra_usb_phy *phy)
561 {
562         int status = 0;
563
564         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
565
566         if (phy->pdata->ops && phy->pdata->ops->pre_suspend)
567                 phy->pdata->ops->pre_suspend();
568
569         if (phy->ops && phy->ops->pre_suspend)
570                 status = phy->ops->pre_suspend(phy);
571
572         return status;
573 }
574
575 int tegra_usb_phy_suspend(struct tegra_usb_phy *phy)
576 {
577         int err = 0;
578
579         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
580
581         if (phy->ops && phy->ops->suspend)
582                 err = phy->ops->suspend(phy);
583
584         if (!err && phy->pdata->u_data.host.power_off_on_suspend) {
585                 tegra_usb_phy_power_off(phy);
586         }
587
588         return err;
589 }
590
591 int tegra_usb_phy_post_suspend(struct tegra_usb_phy *phy)
592 {
593         int status = 0;
594
595         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
596
597         if (phy->ops && phy->ops->post_suspend)
598                 status = phy->ops->post_suspend(phy);
599
600         if (phy->pdata->ops && phy->pdata->ops->post_suspend)
601                 phy->pdata->ops->post_suspend();
602
603         return status;
604 }
605
606 int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
607 {
608         int status = 0;
609
610         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
611
612         if (phy->pdata->ops && phy->pdata->ops->pre_resume)
613                 phy->pdata->ops->pre_resume();
614
615         if (phy->ops && phy->ops->pre_resume)
616                 status = phy->ops->pre_resume(phy, remote_wakeup);
617
618         return status;
619 }
620
621 int tegra_usb_phy_resume(struct tegra_usb_phy *phy)
622 {
623         int err = 0;
624
625         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
626
627         if (phy->pdata->u_data.host.power_off_on_suspend) {
628                 tegra_usb_phy_power_on(phy);
629         }
630
631         if (!err && phy->ops && phy->ops->resume)
632                 err = phy->ops->resume(phy);
633
634         return err;
635
636 }
637
638 int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy)
639 {
640         int status = 0;
641
642         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
643
644         if (phy->ops && phy->ops->post_resume)
645                 status = phy->ops->post_resume(phy);
646
647         if (phy->pdata->ops && phy->pdata->ops->post_resume)
648                 phy->pdata->ops->post_resume();
649
650         return status;
651 }
652
653 int tegra_usb_phy_port_power(struct tegra_usb_phy *phy)
654 {
655         int status = 0;
656
657         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
658
659         if (phy->ops && phy->ops->port_power)
660                 status = phy->ops->port_power(phy);
661
662         return status;
663 }
664
665 int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
666 {
667         int status = 0;
668
669         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
670
671         if (phy->ops && phy->ops->bus_reset)
672                 status = phy->ops->bus_reset(phy);
673
674         return status;
675 }
676
677 bool tegra_usb_phy_charger_detected(struct tegra_usb_phy *phy)
678 {
679         bool status = 0;
680
681         DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
682         if (phy->ops && phy->ops->charger_detect)
683                 status = phy->ops->charger_detect(phy);
684
685         return status;
686 }
687
688 bool tegra_usb_phy_hw_accessible(struct tegra_usb_phy *phy)
689 {
690         if (!phy->hw_accessible)
691                 DBG("%s(%d) inst:[%d] Not Accessible\n", __func__,
692                                                 __LINE__, phy->inst);
693
694         return phy->hw_accessible;
695 }
696
697 bool tegra_usb_phy_remote_wakeup(struct tegra_usb_phy *phy)
698 {
699         return phy->remote_wakeup;
700 }
701
702 bool tegra_usb_phy_has_hostpc(struct tegra_usb_phy *phy)
703 {
704         return phy->pdata->has_hostpc;
705 }
706
707 bool tegra_usb_phy_otg_supported(struct tegra_usb_phy *phy)
708 {
709         return phy->pdata->port_otg;
710 }
711
712 void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy)
713 {
714         void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE);
715         unsigned long val;
716
717         if (phy->inst == 0 && phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
718                 val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
719                 val |= PREFETCH_ENB;
720                 writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
721                 val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
722                 val |= PREFETCH_ENB;
723                 writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
724         }
725 }
726
727 void tegra_usb_phy_memory_prefetch_off(struct tegra_usb_phy *phy)
728 {
729         void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE);
730         unsigned long val;
731
732         if (phy->inst == 0 && phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
733                 val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
734                 val &= ~(PREFETCH_ENB);
735                 writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
736                 val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
737                 val &= ~(PREFETCH_ENB);
738                 writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
739         }
740 }