aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenu Byravarasu <vbyravarasu@nvidia.com>2013-05-16 10:13:02 -0400
committerFelipe Balbi <balbi@ti.com>2013-05-29 19:49:11 -0400
commit2d22b42db02fdafeb7b990c2c25caabff4dd46fe (patch)
tree5f80c9594098d7d6339d5bb19004c2be79b10d10
parent6829f92f6e64bfc6a553d7a2203ce1cb2e433c01 (diff)
usb: phy: registering Tegra USB PHY as platform driver
Registered Tegra USB PHY as a separate platform driver. To synchronize host controller and PHY initialization, used deferred probe mechanism. As PHY should be initialized before EHCI starts running, deferred probe of Tegra EHCI driver till PHY probe gets completed. Got rid of instance number based handling in host driver. Made use of DT params to get the PHY Pad registers. Signed-off-by: Venu Byravarasu <vbyravarasu@nvidia.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/host/ehci-tegra.c104
-rw-r--r--drivers/usb/phy/phy-tegra-usb.c325
-rw-r--r--include/linux/usb/tegra_usb_phy.h11
3 files changed, 230 insertions, 210 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index d64199044b4a..8390c870299a 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -611,7 +611,7 @@ static const struct dev_pm_ops tegra_ehci_pm_ops = {
611/* Bits of PORTSC1, which will get cleared by writing 1 into them */ 611/* Bits of PORTSC1, which will get cleared by writing 1 into them */
612#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) 612#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
613 613
614static void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val) 614void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val)
615{ 615{
616 unsigned long val; 616 unsigned long val;
617 struct usb_hcd *hcd = bus_to_hcd(x->otg->host); 617 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
@@ -622,8 +622,9 @@ static void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val)
622 val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3); 622 val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3);
623 writel(val, base + TEGRA_USB_PORTSC1); 623 writel(val, base + TEGRA_USB_PORTSC1);
624} 624}
625EXPORT_SYMBOL_GPL(tegra_ehci_set_pts);
625 626
626static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable) 627void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
627{ 628{
628 unsigned long val; 629 unsigned long val;
629 struct usb_hcd *hcd = bus_to_hcd(x->otg->host); 630 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
@@ -636,6 +637,7 @@ static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
636 val &= ~TEGRA_USB_PORTSC1_PHCD; 637 val &= ~TEGRA_USB_PORTSC1_PHCD;
637 writel(val, base + TEGRA_USB_PORTSC1); 638 writel(val, base + TEGRA_USB_PORTSC1);
638} 639}
640EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd);
639 641
640static int tegra_ehci_probe(struct platform_device *pdev) 642static int tegra_ehci_probe(struct platform_device *pdev)
641{ 643{
@@ -645,7 +647,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
645 struct tegra_ehci_platform_data *pdata; 647 struct tegra_ehci_platform_data *pdata;
646 int err = 0; 648 int err = 0;
647 int irq; 649 int irq;
648 int instance = pdev->id; 650 struct device_node *np_phy;
649 struct usb_phy *u_phy; 651 struct usb_phy *u_phy;
650 652
651 pdata = pdev->dev.platform_data; 653 pdata = pdev->dev.platform_data;
@@ -670,38 +672,49 @@ static int tegra_ehci_probe(struct platform_device *pdev)
670 if (!tegra) 672 if (!tegra)
671 return -ENOMEM; 673 return -ENOMEM;
672 674
673 hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,
674 dev_name(&pdev->dev));
675 if (!hcd) {
676 dev_err(&pdev->dev, "Unable to create HCD\n");
677 return -ENOMEM;
678 }
679
680 platform_set_drvdata(pdev, tegra);
681
682 tegra->clk = devm_clk_get(&pdev->dev, NULL); 675 tegra->clk = devm_clk_get(&pdev->dev, NULL);
683 if (IS_ERR(tegra->clk)) { 676 if (IS_ERR(tegra->clk)) {
684 dev_err(&pdev->dev, "Can't get ehci clock\n"); 677 dev_err(&pdev->dev, "Can't get ehci clock\n");
685 err = PTR_ERR(tegra->clk); 678 return PTR_ERR(tegra->clk);
686 goto fail_clk;
687 } 679 }
688 680
689 err = clk_prepare_enable(tegra->clk); 681 err = clk_prepare_enable(tegra->clk);
690 if (err) 682 if (err)
691 goto fail_clk; 683 return err;
692 684
693 tegra_periph_reset_assert(tegra->clk); 685 tegra_periph_reset_assert(tegra->clk);
694 udelay(1); 686 udelay(1);
695 tegra_periph_reset_deassert(tegra->clk); 687 tegra_periph_reset_deassert(tegra->clk);
696 688
689 np_phy = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0);
690 if (!np_phy) {
691 err = -ENODEV;
692 goto cleanup_clk;
693 }
694
695 u_phy = tegra_usb_get_phy(np_phy);
696 if (IS_ERR(u_phy)) {
697 err = PTR_ERR(u_phy);
698 goto cleanup_clk;
699 }
700
697 tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node, 701 tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node,
698 "nvidia,needs-double-reset"); 702 "nvidia,needs-double-reset");
699 703
704 hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,
705 dev_name(&pdev->dev));
706 if (!hcd) {
707 dev_err(&pdev->dev, "Unable to create HCD\n");
708 err = -ENOMEM;
709 goto cleanup_clk;
710 }
711 hcd->phy = u_phy;
712
700 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 713 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
701 if (!res) { 714 if (!res) {
702 dev_err(&pdev->dev, "Failed to get I/O memory\n"); 715 dev_err(&pdev->dev, "Failed to get I/O memory\n");
703 err = -ENXIO; 716 err = -ENXIO;
704 goto fail_io; 717 goto cleanup_hcd_create;
705 } 718 }
706 hcd->rsrc_start = res->start; 719 hcd->rsrc_start = res->start;
707 hcd->rsrc_len = resource_size(res); 720 hcd->rsrc_len = resource_size(res);
@@ -709,57 +722,28 @@ static int tegra_ehci_probe(struct platform_device *pdev)
709 if (!hcd->regs) { 722 if (!hcd->regs) {
710 dev_err(&pdev->dev, "Failed to remap I/O memory\n"); 723 dev_err(&pdev->dev, "Failed to remap I/O memory\n");
711 err = -ENOMEM; 724 err = -ENOMEM;
712 goto fail_io; 725 goto cleanup_hcd_create;
713 }
714
715 /* This is pretty ugly and needs to be fixed when we do only
716 * device-tree probing. Old code relies on the platform_device
717 * numbering that we lack for device-tree-instantiated devices.
718 */
719 if (instance < 0) {
720 switch (res->start) {
721 case TEGRA_USB_BASE:
722 instance = 0;
723 break;
724 case TEGRA_USB2_BASE:
725 instance = 1;
726 break;
727 case TEGRA_USB3_BASE:
728 instance = 2;
729 break;
730 default:
731 err = -ENODEV;
732 dev_err(&pdev->dev, "unknown usb instance\n");
733 goto fail_io;
734 }
735 } 726 }
736 727
737 tegra->phy = tegra_usb_phy_open(&pdev->dev, instance, hcd->regs, 728 err = usb_phy_init(hcd->phy);
738 pdata->phy_config, 729 if (err) {
739 tegra_ehci_set_pts, 730 dev_err(&pdev->dev, "Failed to initialize phy\n");
740 tegra_ehci_set_phcd); 731 goto cleanup_hcd_create;
741 if (IS_ERR(tegra->phy)) {
742 dev_err(&pdev->dev, "Failed to open USB phy\n");
743 err = -ENXIO;
744 goto fail_io;
745 } 732 }
746 733
747 hcd->phy = u_phy = &tegra->phy->u_phy;
748 usb_phy_init(hcd->phy);
749
750 u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), 734 u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
751 GFP_KERNEL); 735 GFP_KERNEL);
752 if (!u_phy->otg) { 736 if (!u_phy->otg) {
753 dev_err(&pdev->dev, "Failed to alloc memory for otg\n"); 737 dev_err(&pdev->dev, "Failed to alloc memory for otg\n");
754 err = -ENOMEM; 738 err = -ENOMEM;
755 goto fail_io; 739 goto cleanup_phy;
756 } 740 }
757 u_phy->otg->host = hcd_to_bus(hcd); 741 u_phy->otg->host = hcd_to_bus(hcd);
758 742
759 err = usb_phy_set_suspend(hcd->phy, 0); 743 err = usb_phy_set_suspend(hcd->phy, 0);
760 if (err) { 744 if (err) {
761 dev_err(&pdev->dev, "Failed to power on the phy\n"); 745 dev_err(&pdev->dev, "Failed to power on the phy\n");
762 goto fail_phy; 746 goto cleanup_phy;
763 } 747 }
764 748
765 tegra->host_resumed = 1; 749 tegra->host_resumed = 1;
@@ -769,7 +753,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
769 if (!irq) { 753 if (!irq) {
770 dev_err(&pdev->dev, "Failed to get IRQ\n"); 754 dev_err(&pdev->dev, "Failed to get IRQ\n");
771 err = -ENODEV; 755 err = -ENODEV;
772 goto fail_phy; 756 goto cleanup_phy;
773 } 757 }
774 758
775 if (pdata->operating_mode == TEGRA_USB_OTG) { 759 if (pdata->operating_mode == TEGRA_USB_OTG) {
@@ -781,10 +765,12 @@ static int tegra_ehci_probe(struct platform_device *pdev)
781 tegra->transceiver = ERR_PTR(-ENODEV); 765 tegra->transceiver = ERR_PTR(-ENODEV);
782 } 766 }
783 767
768 platform_set_drvdata(pdev, tegra);
769
784 err = usb_add_hcd(hcd, irq, IRQF_SHARED); 770 err = usb_add_hcd(hcd, irq, IRQF_SHARED);
785 if (err) { 771 if (err) {
786 dev_err(&pdev->dev, "Failed to add USB HCD\n"); 772 dev_err(&pdev->dev, "Failed to add USB HCD\n");
787 goto fail; 773 goto cleanup_phy;
788 } 774 }
789 775
790 pm_runtime_set_active(&pdev->dev); 776 pm_runtime_set_active(&pdev->dev);
@@ -797,15 +783,15 @@ static int tegra_ehci_probe(struct platform_device *pdev)
797 pm_runtime_put_sync(&pdev->dev); 783 pm_runtime_put_sync(&pdev->dev);
798 return err; 784 return err;
799 785
800fail: 786cleanup_phy:
801 if (!IS_ERR(tegra->transceiver)) 787 if (!IS_ERR(tegra->transceiver))
802 otg_set_host(tegra->transceiver->otg, NULL); 788 otg_set_host(tegra->transceiver->otg, NULL);
803fail_phy: 789
804 usb_phy_shutdown(hcd->phy); 790 usb_phy_shutdown(hcd->phy);
805fail_io: 791cleanup_hcd_create:
806 clk_disable_unprepare(tegra->clk);
807fail_clk:
808 usb_put_hcd(hcd); 792 usb_put_hcd(hcd);
793cleanup_clk:
794 clk_disable_unprepare(tegra->clk);
809 return err; 795 return err;
810} 796}
811 797
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index f423ae88b741..5d9af11d2731 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -1,9 +1,11 @@
1/* 1/*
2 * Copyright (C) 2010 Google, Inc. 2 * Copyright (C) 2010 Google, Inc.
3 * Copyright (C) 2013 NVIDIA Corporation
3 * 4 *
4 * Author: 5 * Author:
5 * Erik Gilling <konkers@google.com> 6 * Erik Gilling <konkers@google.com>
6 * Benoit Goby <benoit@android.com> 7 * Benoit Goby <benoit@android.com>
8 * Venu Byravarasu <vbyravarasu@nvidia.com>
7 * 9 *
8 * This software is licensed under the terms of the GNU General Public 10 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and 11 * License version 2, as published by the Free Software Foundation, and
@@ -30,9 +32,7 @@
30#include <linux/usb/ulpi.h> 32#include <linux/usb/ulpi.h>
31#include <asm/mach-types.h> 33#include <asm/mach-types.h>
32#include <linux/usb/tegra_usb_phy.h> 34#include <linux/usb/tegra_usb_phy.h>
33 35#include <linux/module.h>
34#define TEGRA_USB_BASE 0xC5000000
35#define TEGRA_USB_SIZE SZ_16K
36 36
37#define ULPI_VIEWPORT 0x170 37#define ULPI_VIEWPORT 0x170
38 38
@@ -198,32 +198,15 @@ static struct tegra_utmip_config utmip_default[] = {
198 198
199static int utmip_pad_open(struct tegra_usb_phy *phy) 199static int utmip_pad_open(struct tegra_usb_phy *phy)
200{ 200{
201 phy->pad_clk = clk_get_sys("utmip-pad", NULL); 201 phy->pad_clk = devm_clk_get(phy->dev, "utmi-pads");
202 if (IS_ERR(phy->pad_clk)) { 202 if (IS_ERR(phy->pad_clk)) {
203 pr_err("%s: can't get utmip pad clock\n", __func__); 203 pr_err("%s: can't get utmip pad clock\n", __func__);
204 return PTR_ERR(phy->pad_clk); 204 return PTR_ERR(phy->pad_clk);
205 } 205 }
206 206
207 if (phy->is_legacy_phy) {
208 phy->pad_regs = phy->regs;
209 } else {
210 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
211 if (!phy->pad_regs) {
212 pr_err("%s: can't remap usb registers\n", __func__);
213 clk_put(phy->pad_clk);
214 return -ENOMEM;
215 }
216 }
217 return 0; 207 return 0;
218} 208}
219 209
220static void utmip_pad_close(struct tegra_usb_phy *phy)
221{
222 if (!phy->is_legacy_phy)
223 iounmap(phy->pad_regs);
224 clk_put(phy->pad_clk);
225}
226
227static void utmip_pad_power_on(struct tegra_usb_phy *phy) 210static void utmip_pad_power_on(struct tegra_usb_phy *phy)
228{ 211{
229 unsigned long val, flags; 212 unsigned long val, flags;
@@ -299,7 +282,7 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
299 val &= ~USB_SUSP_SET; 282 val &= ~USB_SUSP_SET;
300 writel(val, base + USB_SUSP_CTRL); 283 writel(val, base + USB_SUSP_CTRL);
301 } else 284 } else
302 phy->set_phcd(&phy->u_phy, true); 285 tegra_ehci_set_phcd(&phy->u_phy, true);
303 286
304 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) 287 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
305 pr_err("%s: timeout waiting for phy to stabilize\n", __func__); 288 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
@@ -321,7 +304,7 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
321 val &= ~USB_SUSP_CLR; 304 val &= ~USB_SUSP_CLR;
322 writel(val, base + USB_SUSP_CTRL); 305 writel(val, base + USB_SUSP_CTRL);
323 } else 306 } else
324 phy->set_phcd(&phy->u_phy, false); 307 tegra_ehci_set_phcd(&phy->u_phy, false);
325 308
326 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 309 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
327 USB_PHY_CLK_VALID)) 310 USB_PHY_CLK_VALID))
@@ -444,7 +427,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
444 utmi_phy_clk_enable(phy); 427 utmi_phy_clk_enable(phy);
445 428
446 if (!phy->is_legacy_phy) 429 if (!phy->is_legacy_phy)
447 phy->set_pts(&phy->u_phy, 0); 430 tegra_ehci_set_pts(&phy->u_phy, 0);
448 431
449 return 0; 432 return 0;
450} 433}
@@ -614,76 +597,11 @@ static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
614 return gpio_direction_output(phy->reset_gpio, 0); 597 return gpio_direction_output(phy->reset_gpio, 0);
615} 598}
616 599
617static int tegra_phy_init(struct usb_phy *x)
618{
619 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
620 struct tegra_ulpi_config *ulpi_config;
621 int err;
622
623 if (phy->is_ulpi_phy) {
624 ulpi_config = phy->config;
625 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
626 if (IS_ERR(phy->clk)) {
627 pr_err("%s: can't get ulpi clock\n", __func__);
628 return PTR_ERR(phy->clk);
629 }
630
631 phy->reset_gpio =
632 of_get_named_gpio(phy->dev->of_node,
633 "nvidia,phy-reset-gpio", 0);
634 if (!gpio_is_valid(phy->reset_gpio)) {
635 dev_err(phy->dev, "invalid gpio: %d\n",
636 phy->reset_gpio);
637 err = phy->reset_gpio;
638 goto cleanup_clk_get;
639 }
640
641 err = gpio_request(phy->reset_gpio, "ulpi_phy_reset_b");
642 if (err < 0) {
643 dev_err(phy->dev, "request failed for gpio: %d\n",
644 phy->reset_gpio);
645 goto cleanup_clk_get;
646 }
647
648 err = gpio_direction_output(phy->reset_gpio, 0);
649 if (err < 0) {
650 dev_err(phy->dev, "gpio %d direction not set to output\n",
651 phy->reset_gpio);
652 goto cleanup_gpio_req;
653 }
654
655 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
656 if (!phy->ulpi) {
657 dev_err(phy->dev, "otg_ulpi_create returned NULL\n");
658 err = -ENOMEM;
659 goto cleanup_gpio_req;
660 }
661
662 phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT;
663 } else {
664 err = utmip_pad_open(phy);
665 if (err < 0)
666 return err;
667 }
668 return 0;
669cleanup_gpio_req:
670 gpio_free(phy->reset_gpio);
671cleanup_clk_get:
672 clk_put(phy->clk);
673 return err;
674}
675
676static void tegra_usb_phy_close(struct usb_phy *x) 600static void tegra_usb_phy_close(struct usb_phy *x)
677{ 601{
678 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 602 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
679 603
680 if (phy->is_ulpi_phy)
681 clk_put(phy->clk);
682 else
683 utmip_pad_close(phy);
684 clk_disable_unprepare(phy->pll_u); 604 clk_disable_unprepare(phy->pll_u);
685 clk_put(phy->pll_u);
686 kfree(phy);
687} 605}
688 606
689static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) 607static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
@@ -711,63 +629,63 @@ static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend)
711 return tegra_usb_phy_power_on(phy); 629 return tegra_usb_phy_power_on(phy);
712} 630}
713 631
714struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 632static int ulpi_open(struct tegra_usb_phy *phy)
715 void __iomem *regs, void *config,
716 void (*set_pts)(struct usb_phy *x, u8 pts_val),
717 void (*set_phcd)(struct usb_phy *x, bool enable))
718
719{ 633{
720 struct tegra_usb_phy *phy;
721 unsigned long parent_rate;
722 int i;
723 int err; 634 int err;
724 struct device_node *np = dev->of_node;
725 635
726 phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); 636 phy->clk = devm_clk_get(phy->dev, "ulpi-link");
727 if (!phy) 637 if (IS_ERR(phy->clk)) {
728 return ERR_PTR(-ENOMEM); 638 pr_err("%s: can't get ulpi clock\n", __func__);
639 return PTR_ERR(phy->clk);
640 }
729 641
730 phy->instance = instance; 642 err = devm_gpio_request(phy->dev, phy->reset_gpio, "ulpi_phy_reset_b");
731 phy->regs = regs; 643 if (err < 0) {
732 phy->config = config; 644 dev_err(phy->dev, "request failed for gpio: %d\n",
733 phy->dev = dev; 645 phy->reset_gpio);
734 phy->is_legacy_phy = 646 return err;
735 of_property_read_bool(np, "nvidia,has-legacy-mode"); 647 }
736 phy->set_pts = set_pts;
737 phy->set_phcd = set_phcd;
738 err = of_property_match_string(np, "phy_type", "ulpi");
739 if (err < 0)
740 phy->is_ulpi_phy = false;
741 else
742 phy->is_ulpi_phy = true;
743 648
744 err = of_property_match_string(np, "dr_mode", "otg"); 649 err = gpio_direction_output(phy->reset_gpio, 0);
745 if (err < 0) { 650 if (err < 0) {
746 err = of_property_match_string(np, "dr_mode", "peripheral"); 651 dev_err(phy->dev, "gpio %d direction not set to output\n",
747 if (err < 0) 652 phy->reset_gpio);
748 phy->mode = TEGRA_USB_PHY_MODE_HOST; 653 return err;
654 }
655
656 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
657 if (!phy->ulpi) {
658 dev_err(phy->dev, "otg_ulpi_create returned NULL\n");
659 err = -ENOMEM;
660 return err;
661 }
662
663 phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT;
664 return 0;
665}
666
667static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
668{
669 unsigned long parent_rate;
670 int i;
671 int err;
672
673 if (!phy->is_ulpi_phy) {
674 if (phy->is_legacy_phy)
675 phy->config = &utmip_default[0];
749 else 676 else
750 phy->mode = TEGRA_USB_PHY_MODE_DEVICE; 677 phy->config = &utmip_default[2];
751 } else
752 phy->mode = TEGRA_USB_PHY_MODE_OTG;
753
754 if (!phy->config) {
755 if (phy->is_ulpi_phy) {
756 pr_err("%s: ulpi phy configuration missing", __func__);
757 err = -EINVAL;
758 goto err0;
759 } else {
760 phy->config = &utmip_default[instance];
761 }
762 } 678 }
763 679
764 phy->pll_u = clk_get_sys(NULL, "pll_u"); 680 phy->pll_u = devm_clk_get(phy->dev, "pll_u");
765 if (IS_ERR(phy->pll_u)) { 681 if (IS_ERR(phy->pll_u)) {
766 pr_err("Can't get pll_u clock\n"); 682 pr_err("Can't get pll_u clock\n");
767 err = PTR_ERR(phy->pll_u); 683 return PTR_ERR(phy->pll_u);
768 goto err0;
769 } 684 }
770 clk_prepare_enable(phy->pll_u); 685
686 err = clk_prepare_enable(phy->pll_u);
687 if (err)
688 return err;
771 689
772 parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); 690 parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
773 for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { 691 for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) {
@@ -779,23 +697,22 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
779 if (!phy->freq) { 697 if (!phy->freq) {
780 pr_err("invalid pll_u parent rate %ld\n", parent_rate); 698 pr_err("invalid pll_u parent rate %ld\n", parent_rate);
781 err = -EINVAL; 699 err = -EINVAL;
782 goto err1; 700 goto fail;
783 } 701 }
784 702
785 phy->u_phy.init = tegra_phy_init; 703 if (phy->is_ulpi_phy)
786 phy->u_phy.shutdown = tegra_usb_phy_close; 704 err = ulpi_open(phy);
787 phy->u_phy.set_suspend = tegra_usb_phy_suspend; 705 else
706 err = utmip_pad_open(phy);
707 if (err < 0)
708 goto fail;
788 709
789 return phy; 710 return 0;
790 711
791err1: 712fail:
792 clk_disable_unprepare(phy->pll_u); 713 clk_disable_unprepare(phy->pll_u);
793 clk_put(phy->pll_u); 714 return err;
794err0:
795 kfree(phy);
796 return ERR_PTR(err);
797} 715}
798EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
799 716
800void tegra_usb_phy_preresume(struct usb_phy *x) 717void tegra_usb_phy_preresume(struct usb_phy *x)
801{ 718{
@@ -834,3 +751,121 @@ void tegra_ehci_phy_restore_end(struct usb_phy *x)
834} 751}
835EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); 752EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end);
836 753
754static int tegra_usb_phy_probe(struct platform_device *pdev)
755{
756 struct resource *res;
757 struct tegra_usb_phy *tegra_phy = NULL;
758 struct device_node *np = pdev->dev.of_node;
759 int err;
760
761 tegra_phy = devm_kzalloc(&pdev->dev, sizeof(*tegra_phy), GFP_KERNEL);
762 if (!tegra_phy) {
763 dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
764 return -ENOMEM;
765 }
766
767 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
768 if (!res) {
769 dev_err(&pdev->dev, "Failed to get I/O memory\n");
770 return -ENXIO;
771 }
772
773 tegra_phy->regs = devm_ioremap(&pdev->dev, res->start,
774 resource_size(res));
775 if (!tegra_phy->regs) {
776 dev_err(&pdev->dev, "Failed to remap I/O memory\n");
777 return -ENOMEM;
778 }
779
780 tegra_phy->is_legacy_phy =
781 of_property_read_bool(np, "nvidia,has-legacy-mode");
782
783 err = of_property_match_string(np, "phy_type", "ulpi");
784 if (err < 0) {
785 tegra_phy->is_ulpi_phy = false;
786
787 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
788 if (!res) {
789 dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n");
790 return -ENXIO;
791 }
792
793 tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
794 resource_size(res));
795 if (!tegra_phy->regs) {
796 dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
797 return -ENOMEM;
798 }
799 } else {
800 tegra_phy->is_ulpi_phy = true;
801
802 tegra_phy->reset_gpio =
803 of_get_named_gpio(np, "nvidia,phy-reset-gpio", 0);
804 if (!gpio_is_valid(tegra_phy->reset_gpio)) {
805 dev_err(&pdev->dev, "invalid gpio: %d\n",
806 tegra_phy->reset_gpio);
807 return tegra_phy->reset_gpio;
808 }
809 }
810
811 err = of_property_match_string(np, "dr_mode", "otg");
812 if (err < 0) {
813 err = of_property_match_string(np, "dr_mode", "peripheral");
814 if (err < 0)
815 tegra_phy->mode = TEGRA_USB_PHY_MODE_HOST;
816 else
817 tegra_phy->mode = TEGRA_USB_PHY_MODE_DEVICE;
818 } else
819 tegra_phy->mode = TEGRA_USB_PHY_MODE_OTG;
820
821 tegra_phy->dev = &pdev->dev;
822 err = tegra_usb_phy_init(tegra_phy);
823 if (err < 0)
824 return err;
825
826 tegra_phy->u_phy.shutdown = tegra_usb_phy_close;
827 tegra_phy->u_phy.set_suspend = tegra_usb_phy_suspend;
828
829 dev_set_drvdata(&pdev->dev, tegra_phy);
830 return 0;
831}
832
833static struct of_device_id tegra_usb_phy_id_table[] = {
834 { .compatible = "nvidia,tegra20-usb-phy", },
835 { },
836};
837MODULE_DEVICE_TABLE(of, tegra_usb_phy_id_table);
838
839static struct platform_driver tegra_usb_phy_driver = {
840 .probe = tegra_usb_phy_probe,
841 .driver = {
842 .name = "tegra-phy",
843 .owner = THIS_MODULE,
844 .of_match_table = of_match_ptr(tegra_usb_phy_id_table),
845 },
846};
847module_platform_driver(tegra_usb_phy_driver);
848
849static int tegra_usb_phy_match(struct device *dev, void *data)
850{
851 struct tegra_usb_phy *tegra_phy = dev_get_drvdata(dev);
852 struct device_node *dn = data;
853
854 return (tegra_phy->dev->of_node == dn) ? 1 : 0;
855}
856
857struct usb_phy *tegra_usb_get_phy(struct device_node *dn)
858{
859 struct device *dev;
860 struct tegra_usb_phy *tegra_phy;
861
862 dev = driver_find_device(&tegra_usb_phy_driver.driver, NULL, dn,
863 tegra_usb_phy_match);
864 if (!dev)
865 return ERR_PTR(-EPROBE_DEFER);
866
867 tegra_phy = dev_get_drvdata(dev);
868
869 return &tegra_phy->u_phy;
870}
871EXPORT_SYMBOL_GPL(tegra_usb_get_phy);
diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h
index 97d123c4d7cc..0cd15d2df53d 100644
--- a/include/linux/usb/tegra_usb_phy.h
+++ b/include/linux/usb/tegra_usb_phy.h
@@ -63,14 +63,9 @@ struct tegra_usb_phy {
63 bool is_legacy_phy; 63 bool is_legacy_phy;
64 bool is_ulpi_phy; 64 bool is_ulpi_phy;
65 int reset_gpio; 65 int reset_gpio;
66 void (*set_pts)(struct usb_phy *x, u8 pts_val);
67 void (*set_phcd)(struct usb_phy *x, bool enable);
68}; 66};
69 67
70struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 68struct usb_phy *tegra_usb_get_phy(struct device_node *dn);
71 void __iomem *regs, void *config,
72 void (*set_pts)(struct usb_phy *x, u8 pts_val),
73 void (*set_phcd)(struct usb_phy *x, bool enable));
74 69
75void tegra_usb_phy_preresume(struct usb_phy *phy); 70void tegra_usb_phy_preresume(struct usb_phy *phy);
76 71
@@ -81,4 +76,8 @@ void tegra_ehci_phy_restore_start(struct usb_phy *phy,
81 76
82void tegra_ehci_phy_restore_end(struct usb_phy *phy); 77void tegra_ehci_phy_restore_end(struct usb_phy *phy);
83 78
79void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val);
80
81void tegra_ehci_set_phcd(struct usb_phy *x, bool enable);
82
84#endif /* __TEGRA_USB_PHY_H */ 83#endif /* __TEGRA_USB_PHY_H */