aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 18:27:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 18:27:22 -0500
commitbab588fcfb6335c767d811a8955979f5440328e0 (patch)
tree2a862ddf47a82be885a8e7945a17cc3ff7a658b9 /drivers/usb/host
parent3298a3511f1e73255a8dc023efd909e569eea037 (diff)
parent9cb0d1babfcb1b4ac248c09425f7d5de1e771133 (diff)
Merge tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC-specific updates from Arnd Bergmann: "This is a larger set of new functionality for the existing SoC families, including: - vt8500 gains support for new CPU cores, notably the Cortex-A9 based wm8850 - prima2 gains support for the "marco" SoC family, its SMP based cousin - tegra gains support for the new Tegra4 (Tegra114) family - socfpga now supports a newer version of the hardware including SMP - i.mx31 and bcm2835 are now using DT probing for their clocks - lots of updates for sh-mobile - OMAP updates for clocks, power management and USB - i.mx6q and tegra now support cpuidle - kirkwood now supports PCIe hot plugging - tegra clock support is updated - tegra USB PHY probing gets implemented diffently" * tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (148 commits) ARM: prima2: remove duplicate v7_invalidate_l1 ARM: shmobile: r8a7779: Correct TMU clock support again ARM: prima2: fix __init section for cpu hotplug ARM: OMAP: Consolidate OMAP USB-HS platform data (part 3/3) ARM: OMAP: Consolidate OMAP USB-HS platform data (part 1/3) arm: socfpga: Add SMP support for actual socfpga harware arm: Add v7_invalidate_l1 to cache-v7.S arm: socfpga: Add entries to enable make dtbs socfpga arm: socfpga: Add new device tree source for actual socfpga HW ARM: tegra: sort Kconfig selects for Tegra114 ARM: tegra: enable ARCH_REQUIRE_GPIOLIB for Tegra114 ARM: tegra: Fix build error w/ ARCH_TEGRA_114_SOC w/o ARCH_TEGRA_3x_SOC ARM: tegra: Fix build error for gic update ARM: tegra: remove empty tegra_smp_init_cpus() ARM: shmobile: Register ARM architected timer ARM: MARCO: fix the build issue due to gic-vic-to-irqchip move ARM: shmobile: r8a7779: Correct TMU clock support ARM: mxs_defconfig: Select CONFIG_DEVTMPFS_MOUNT ARM: mxs: decrease mxs_clockevent_device.min_delta_ns to 2 clock cycles ARM: mxs: use apbx bus clock to drive the timers on timrotv2 ...
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-tegra.c97
1 files changed, 65 insertions, 32 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index acf17556bd87..568aecc7075b 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -2,7 +2,7 @@
2 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs 2 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2009 NVIDIA Corporation 5 * Copyright (C) 2009 - 2013 NVIDIA Corporation
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -26,23 +26,28 @@
26#include <linux/of.h> 26#include <linux/of.h>
27#include <linux/of_gpio.h> 27#include <linux/of_gpio.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29 29#include <linux/usb/ehci_def.h>
30#include <linux/usb/tegra_usb_phy.h> 30#include <linux/usb/tegra_usb_phy.h>
31 31
32#define TEGRA_USB_BASE 0xC5000000 32#define TEGRA_USB_BASE 0xC5000000
33#define TEGRA_USB2_BASE 0xC5004000 33#define TEGRA_USB2_BASE 0xC5004000
34#define TEGRA_USB3_BASE 0xC5008000 34#define TEGRA_USB3_BASE 0xC5008000
35 35
36/* PORTSC registers */
37#define TEGRA_USB_PORTSC1 0x184
38#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
39#define TEGRA_USB_PORTSC1_PHCD (1 << 23)
40
36#define TEGRA_USB_DMA_ALIGN 32 41#define TEGRA_USB_DMA_ALIGN 32
37 42
38struct tegra_ehci_hcd { 43struct tegra_ehci_hcd {
39 struct ehci_hcd *ehci; 44 struct ehci_hcd *ehci;
40 struct tegra_usb_phy *phy; 45 struct tegra_usb_phy *phy;
41 struct clk *clk; 46 struct clk *clk;
42 struct clk *emc_clk;
43 struct usb_phy *transceiver; 47 struct usb_phy *transceiver;
44 int host_resumed; 48 int host_resumed;
45 int port_resuming; 49 int port_resuming;
50 bool needs_double_reset;
46 enum tegra_usb_phy_port_speed port_speed; 51 enum tegra_usb_phy_port_speed port_speed;
47}; 52};
48 53
@@ -50,9 +55,8 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
50{ 55{
51 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 56 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
52 57
53 clk_prepare_enable(tegra->emc_clk);
54 clk_prepare_enable(tegra->clk); 58 clk_prepare_enable(tegra->clk);
55 usb_phy_set_suspend(&tegra->phy->u_phy, 0); 59 usb_phy_set_suspend(hcd->phy, 0);
56 tegra->host_resumed = 1; 60 tegra->host_resumed = 1;
57} 61}
58 62
@@ -61,9 +65,8 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
61 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 65 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
62 66
63 tegra->host_resumed = 0; 67 tegra->host_resumed = 0;
64 usb_phy_set_suspend(&tegra->phy->u_phy, 1); 68 usb_phy_set_suspend(hcd->phy, 1);
65 clk_disable_unprepare(tegra->clk); 69 clk_disable_unprepare(tegra->clk);
66 clk_disable_unprepare(tegra->emc_clk);
67} 70}
68 71
69static int tegra_ehci_internal_port_reset( 72static int tegra_ehci_internal_port_reset(
@@ -156,7 +159,7 @@ static int tegra_ehci_hub_control(
156 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { 159 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
157 /* Resume completed, re-enable disconnect detection */ 160 /* Resume completed, re-enable disconnect detection */
158 tegra->port_resuming = 0; 161 tegra->port_resuming = 0;
159 tegra_usb_phy_postresume(tegra->phy); 162 tegra_usb_phy_postresume(hcd->phy);
160 } 163 }
161 } 164 }
162 165
@@ -184,7 +187,7 @@ static int tegra_ehci_hub_control(
184 } 187 }
185 188
186 /* For USB1 port we need to issue Port Reset twice internally */ 189 /* For USB1 port we need to issue Port Reset twice internally */
187 if (tegra->phy->instance == 0 && 190 if (tegra->needs_double_reset &&
188 (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { 191 (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) {
189 spin_unlock_irqrestore(&ehci->lock, flags); 192 spin_unlock_irqrestore(&ehci->lock, flags);
190 return tegra_ehci_internal_port_reset(ehci, status_reg); 193 return tegra_ehci_internal_port_reset(ehci, status_reg);
@@ -209,7 +212,7 @@ static int tegra_ehci_hub_control(
209 goto done; 212 goto done;
210 213
211 /* Disable disconnect detection during port resume */ 214 /* Disable disconnect detection during port resume */
212 tegra_usb_phy_preresume(tegra->phy); 215 tegra_usb_phy_preresume(hcd->phy);
213 216
214 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); 217 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);
215 218
@@ -473,7 +476,7 @@ static int controller_resume(struct device *dev)
473 } 476 }
474 477
475 /* Force the phy to keep data lines in suspend state */ 478 /* Force the phy to keep data lines in suspend state */
476 tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); 479 tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed);
477 480
478 /* Enable host mode */ 481 /* Enable host mode */
479 tdi_reset(ehci); 482 tdi_reset(ehci);
@@ -540,17 +543,17 @@ static int controller_resume(struct device *dev)
540 } 543 }
541 } 544 }
542 545
543 tegra_ehci_phy_restore_end(tegra->phy); 546 tegra_ehci_phy_restore_end(hcd->phy);
544 goto done; 547 goto done;
545 548
546 restart: 549 restart:
547 if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) 550 if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH)
548 tegra_ehci_phy_restore_end(tegra->phy); 551 tegra_ehci_phy_restore_end(hcd->phy);
549 552
550 tegra_ehci_restart(hcd); 553 tegra_ehci_restart(hcd);
551 554
552 done: 555 done:
553 tegra_usb_phy_preresume(tegra->phy); 556 tegra_usb_phy_preresume(hcd->phy);
554 tegra->port_resuming = 1; 557 tegra->port_resuming = 1;
555 return 0; 558 return 0;
556} 559}
@@ -604,6 +607,37 @@ static const struct dev_pm_ops tegra_ehci_pm_ops = {
604 607
605#endif 608#endif
606 609
610/* Bits of PORTSC1, which will get cleared by writing 1 into them */
611#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
612
613void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val)
614{
615 unsigned long val;
616 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
617 void __iomem *base = hcd->regs;
618
619 val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
620 val &= ~TEGRA_USB_PORTSC1_PTS(3);
621 val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3);
622 writel(val, base + TEGRA_USB_PORTSC1);
623}
624EXPORT_SYMBOL_GPL(tegra_ehci_set_pts);
625
626void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
627{
628 unsigned long val;
629 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
630 void __iomem *base = hcd->regs;
631
632 val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
633 if (enable)
634 val |= TEGRA_USB_PORTSC1_PHCD;
635 else
636 val &= ~TEGRA_USB_PORTSC1_PHCD;
637 writel(val, base + TEGRA_USB_PORTSC1);
638}
639EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd);
640
607static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); 641static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
608 642
609static int tegra_ehci_probe(struct platform_device *pdev) 643static int tegra_ehci_probe(struct platform_device *pdev)
@@ -615,6 +649,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
615 int err = 0; 649 int err = 0;
616 int irq; 650 int irq;
617 int instance = pdev->id; 651 int instance = pdev->id;
652 struct usb_phy *u_phy;
618 653
619 pdata = pdev->dev.platform_data; 654 pdata = pdev->dev.platform_data;
620 if (!pdata) { 655 if (!pdata) {
@@ -656,15 +691,8 @@ static int tegra_ehci_probe(struct platform_device *pdev)
656 if (err) 691 if (err)
657 goto fail_clk; 692 goto fail_clk;
658 693
659 tegra->emc_clk = devm_clk_get(&pdev->dev, "emc"); 694 tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node,
660 if (IS_ERR(tegra->emc_clk)) { 695 "nvidia,needs-double-reset");
661 dev_err(&pdev->dev, "Can't get emc clock\n");
662 err = PTR_ERR(tegra->emc_clk);
663 goto fail_emc_clk;
664 }
665
666 clk_prepare_enable(tegra->emc_clk);
667 clk_set_rate(tegra->emc_clk, 400000000);
668 696
669 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 697 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
670 if (!res) { 698 if (!res) {
@@ -712,9 +740,19 @@ static int tegra_ehci_probe(struct platform_device *pdev)
712 goto fail_io; 740 goto fail_io;
713 } 741 }
714 742
715 usb_phy_init(&tegra->phy->u_phy); 743 hcd->phy = u_phy = &tegra->phy->u_phy;
744 usb_phy_init(hcd->phy);
745
746 u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
747 GFP_KERNEL);
748 if (!u_phy->otg) {
749 dev_err(&pdev->dev, "Failed to alloc memory for otg\n");
750 err = -ENOMEM;
751 goto fail_io;
752 }
753 u_phy->otg->host = hcd_to_bus(hcd);
716 754
717 err = usb_phy_set_suspend(&tegra->phy->u_phy, 0); 755 err = usb_phy_set_suspend(hcd->phy, 0);
718 if (err) { 756 if (err) {
719 dev_err(&pdev->dev, "Failed to power on the phy\n"); 757 dev_err(&pdev->dev, "Failed to power on the phy\n");
720 goto fail; 758 goto fail;
@@ -760,10 +798,8 @@ fail:
760 if (!IS_ERR_OR_NULL(tegra->transceiver)) 798 if (!IS_ERR_OR_NULL(tegra->transceiver))
761 otg_set_host(tegra->transceiver->otg, NULL); 799 otg_set_host(tegra->transceiver->otg, NULL);
762#endif 800#endif
763 usb_phy_shutdown(&tegra->phy->u_phy); 801 usb_phy_shutdown(hcd->phy);
764fail_io: 802fail_io:
765 clk_disable_unprepare(tegra->emc_clk);
766fail_emc_clk:
767 clk_disable_unprepare(tegra->clk); 803 clk_disable_unprepare(tegra->clk);
768fail_clk: 804fail_clk:
769 usb_put_hcd(hcd); 805 usb_put_hcd(hcd);
@@ -784,15 +820,12 @@ static int tegra_ehci_remove(struct platform_device *pdev)
784 otg_set_host(tegra->transceiver->otg, NULL); 820 otg_set_host(tegra->transceiver->otg, NULL);
785#endif 821#endif
786 822
823 usb_phy_shutdown(hcd->phy);
787 usb_remove_hcd(hcd); 824 usb_remove_hcd(hcd);
788 usb_put_hcd(hcd); 825 usb_put_hcd(hcd);
789 826
790 usb_phy_shutdown(&tegra->phy->u_phy);
791
792 clk_disable_unprepare(tegra->clk); 827 clk_disable_unprepare(tegra->clk);
793 828
794 clk_disable_unprepare(tegra->emc_clk);
795
796 return 0; 829 return 0;
797} 830}
798 831