Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tegra-for-3.9-soc-usb' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/soc

From Stephen Warren:
ARM: tegra: USB driver cleanup

The Tegra USB driver has a number of issues:

1) The PHY driver isn't a true platform device, and doesn't implement
the standard USB PHY API.

2) struct device instance numbers were used to make decisions in the
driver, rather than being parameterized by DT or platform data.

This pull request solves issue (2), and lays the groundwork for solving
issue (1). The work on issue (1) involved introducing new DT nodes for
the USB PHYs, which in turn interacted with the Tegra common clock
framework changes, due to the move of clock lookups into device tree.
Hence, these USB driver changes are taken through the Tegra tree with
acks from USB maintainers.

This pull request is based on the previous pull request, with tag
tegra-for-3.9-soc-ccf.

* tag 'tegra-for-3.9-soc-usb' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
usb: host: tegra: make use of PHY pointer of HCD
ARM: tegra: Add reset GPIO information to PHY DT node
usb: host: tegra: don't touch EMC clock
usb: add APIs to access host registers from Tegra PHY
USB: PHY: tegra: Get rid of instance number to differentiate PHY type
USB: PHY: tegra: get rid of instance number to differentiate legacy controller
ARM: tegra: add clocks properties to USB PHY nodes
ARM: tegra: add DT nodes for Tegra USB PHY
usb: phy: remove unused APIs from Tegra PHY.
usb: host: tegra: Resetting PORT0 based on information received via DT.
ARM: tegra: Add new DT property to USB node.
usb: phy: use kzalloc to allocate struct tegra_usb_phy
ARM: tegra: remove USB address related macros from iomap.h

+192 -139
+3
Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
··· 11 11 - phy_type : Should be one of "ulpi" or "utmi". 12 12 - nvidia,vbus-gpio : If present, specifies a gpio that needs to be 13 13 activated for the bus to be powered. 14 + - nvidia,phy : phandle of the PHY instance, the controller is connected to. 14 15 15 16 Required properties for phy_type == ulpi: 16 17 - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. ··· 28 27 registers are accessed through the APB_MISC base address instead of 29 28 the USB controller. Since this is a legacy issue it probably does not 30 29 warrant a compatible string of its own. 30 + - nvidia,needs-double-reset : boolean is to be set for some of the Tegra2 31 + USB ports, which need reset twice due to hardware issues.
+17
Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt
··· 1 + Tegra SOC USB PHY 2 + 3 + The device node for Tegra SOC USB PHY: 4 + 5 + Required properties : 6 + - compatible : Should be "nvidia,tegra20-usb-phy". 7 + - reg : Address and length of the register set for the USB PHY interface. 8 + - phy_type : Should be one of "ulpi" or "utmi". 9 + 10 + Required properties for phy_type == ulpi: 11 + - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. 12 + 13 + Optional properties: 14 + - nvidia,has-legacy-mode : boolean indicates whether this controller can 15 + operate in legacy mode (as APX 2500 / 2600). In legacy mode some 16 + registers are accessed through the APB_MISC base address instead of 17 + the USB controller.
+4
arch/arm/boot/dts/tegra20-harmony.dts
··· 432 432 status = "okay"; 433 433 }; 434 434 435 + usb-phy@c5004400 { 436 + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ 437 + }; 438 + 435 439 sdhci@c8000200 { 436 440 status = "okay"; 437 441 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+4
arch/arm/boot/dts/tegra20-paz00.dts
··· 420 420 status = "okay"; 421 421 }; 422 422 423 + usb-phy@c5004400 { 424 + nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ 425 + }; 426 + 423 427 sdhci@c8000000 { 424 428 status = "okay"; 425 429 cd-gpios = <&gpio 173 0>; /* gpio PV5 */
+4
arch/arm/boot/dts/tegra20-seaboard.dts
··· 561 561 status = "okay"; 562 562 }; 563 563 564 + usb-phy@c5004400 { 565 + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ 566 + }; 567 + 564 568 sdhci@c8000000 { 565 569 status = "okay"; 566 570 power-gpios = <&gpio 86 0>; /* gpio PK6 */
+4
arch/arm/boot/dts/tegra20-trimslice.dts
··· 310 310 status = "okay"; 311 311 }; 312 312 313 + usb-phy@c5004400 { 314 + nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ 315 + }; 316 + 313 317 sdhci@c8000000 { 314 318 status = "okay"; 315 319 bus-width = <4>;
+4
arch/arm/boot/dts/tegra20-ventana.dts
··· 497 497 status = "okay"; 498 498 }; 499 499 500 + usb-phy@c5004400 { 501 + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ 502 + }; 503 + 500 504 sdhci@c8000000 { 501 505 status = "okay"; 502 506 power-gpios = <&gpio 86 0>; /* gpio PK6 */
+29
arch/arm/boot/dts/tegra20.dtsi
··· 400 400 #size-cells = <0>; 401 401 }; 402 402 403 + phy1: usb-phy@c5000400 { 404 + compatible = "nvidia,tegra20-usb-phy"; 405 + reg = <0xc5000400 0x3c00>; 406 + phy_type = "utmi"; 407 + nvidia,has-legacy-mode; 408 + clocks = <&tegra_car 22>, <&tegra_car 127>; 409 + clock-names = "phy", "pll_u"; 410 + }; 411 + 412 + phy2: usb-phy@c5004400 { 413 + compatible = "nvidia,tegra20-usb-phy"; 414 + reg = <0xc5004400 0x3c00>; 415 + phy_type = "ulpi"; 416 + clocks = <&tegra_car 94>, <&tegra_car 127>; 417 + clock-names = "phy", "pll_u"; 418 + }; 419 + 420 + phy3: usb-phy@c5008400 { 421 + compatible = "nvidia,tegra20-usb-phy"; 422 + reg = <0xc5008400 0x3C00>; 423 + phy_type = "utmi"; 424 + clocks = <&tegra_car 22>, <&tegra_car 127>; 425 + clock-names = "phy", "pll_u"; 426 + }; 427 + 403 428 usb@c5000000 { 404 429 compatible = "nvidia,tegra20-ehci", "usb-ehci"; 405 430 reg = <0xc5000000 0x4000>; ··· 432 407 phy_type = "utmi"; 433 408 nvidia,has-legacy-mode; 434 409 clocks = <&tegra_car 22>; 410 + nvidia,needs-double-reset; 411 + nvidia,phy = <&phy1>; 435 412 status = "disabled"; 436 413 }; 437 414 ··· 443 416 interrupts = <0 21 0x04>; 444 417 phy_type = "ulpi"; 445 418 clocks = <&tegra_car 58>; 419 + nvidia,phy = <&phy2>; 446 420 status = "disabled"; 447 421 }; 448 422 ··· 453 425 interrupts = <0 97 0x04>; 454 426 phy_type = "utmi"; 455 427 clocks = <&tegra_car 59>; 428 + nvidia,phy = <&phy3>; 456 429 status = "disabled"; 457 430 }; 458 431
+3 -3
arch/arm/mach-tegra/board-dt-tegra20.c
··· 68 68 }; 69 69 70 70 static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 71 - OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0", 71 + OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0", 72 72 &tegra_ehci1_pdata), 73 - OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", 73 + OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1", 74 74 &tegra_ehci2_pdata), 75 - OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", 75 + OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2", 76 76 &tegra_ehci3_pdata), 77 77 {} 78 78 };
-9
arch/arm/mach-tegra/iomap.h
··· 240 240 #define TEGRA_CSITE_BASE 0x70040000 241 241 #define TEGRA_CSITE_SIZE SZ_256K 242 242 243 - #define TEGRA_USB_BASE 0xC5000000 244 - #define TEGRA_USB_SIZE SZ_16K 245 - 246 - #define TEGRA_USB2_BASE 0xC5004000 247 - #define TEGRA_USB2_SIZE SZ_16K 248 - 249 - #define TEGRA_USB3_BASE 0xC5008000 250 - #define TEGRA_USB3_SIZE SZ_16K 251 - 252 243 #define TEGRA_SDMMC1_BASE 0xC8000000 253 244 #define TEGRA_SDMMC1_SIZE SZ_512 254 245
+65 -32
drivers/usb/host/ehci-tegra.c
··· 2 2 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs 3 3 * 4 4 * Copyright (C) 2010 Google, Inc. 5 - * Copyright (C) 2009 NVIDIA Corporation 5 + * Copyright (C) 2009 - 2013 NVIDIA Corporation 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU General Public License as published by the ··· 26 26 #include <linux/of.h> 27 27 #include <linux/of_gpio.h> 28 28 #include <linux/pm_runtime.h> 29 - 29 + #include <linux/usb/ehci_def.h> 30 30 #include <linux/usb/tegra_usb_phy.h> 31 31 32 32 #define TEGRA_USB_BASE 0xC5000000 33 33 #define TEGRA_USB2_BASE 0xC5004000 34 34 #define TEGRA_USB3_BASE 0xC5008000 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) 35 40 36 41 #define TEGRA_USB_DMA_ALIGN 32 37 42 ··· 44 39 struct ehci_hcd *ehci; 45 40 struct tegra_usb_phy *phy; 46 41 struct clk *clk; 47 - struct clk *emc_clk; 48 42 struct usb_phy *transceiver; 49 43 int host_resumed; 50 44 int port_resuming; 45 + bool needs_double_reset; 51 46 enum tegra_usb_phy_port_speed port_speed; 52 47 }; 53 48 ··· 55 50 { 56 51 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 57 52 58 - clk_prepare_enable(tegra->emc_clk); 59 53 clk_prepare_enable(tegra->clk); 60 - usb_phy_set_suspend(&tegra->phy->u_phy, 0); 54 + usb_phy_set_suspend(hcd->phy, 0); 61 55 tegra->host_resumed = 1; 62 56 } 63 57 ··· 65 61 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 66 62 67 63 tegra->host_resumed = 0; 68 - usb_phy_set_suspend(&tegra->phy->u_phy, 1); 64 + usb_phy_set_suspend(hcd->phy, 1); 69 65 clk_disable_unprepare(tegra->clk); 70 - clk_disable_unprepare(tegra->emc_clk); 71 66 } 72 67 73 68 static int tegra_ehci_internal_port_reset( ··· 159 156 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { 160 157 /* Resume completed, re-enable disconnect detection */ 161 158 tegra->port_resuming = 0; 162 - tegra_usb_phy_postresume(tegra->phy); 159 + tegra_usb_phy_postresume(hcd->phy); 163 160 } 164 161 } 165 162 ··· 187 184 } 188 185 189 186 /* For USB1 port we need to issue Port Reset twice internally */ 190 - if (tegra->phy->instance == 0 && 187 + if (tegra->needs_double_reset && 191 188 (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { 192 189 spin_unlock_irqrestore(&ehci->lock, flags); 193 190 return tegra_ehci_internal_port_reset(ehci, status_reg); ··· 212 209 goto done; 213 210 214 211 /* Disable disconnect detection during port resume */ 215 - tegra_usb_phy_preresume(tegra->phy); 212 + tegra_usb_phy_preresume(hcd->phy); 216 213 217 214 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); 218 215 ··· 476 473 } 477 474 478 475 /* Force the phy to keep data lines in suspend state */ 479 - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); 476 + tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed); 480 477 481 478 /* Enable host mode */ 482 479 tdi_reset(ehci); ··· 543 540 } 544 541 } 545 542 546 - tegra_ehci_phy_restore_end(tegra->phy); 543 + tegra_ehci_phy_restore_end(hcd->phy); 547 544 goto done; 548 545 549 546 restart: 550 547 if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) 551 - tegra_ehci_phy_restore_end(tegra->phy); 548 + tegra_ehci_phy_restore_end(hcd->phy); 552 549 553 550 tegra_ehci_restart(hcd); 554 551 555 552 done: 556 - tegra_usb_phy_preresume(tegra->phy); 553 + tegra_usb_phy_preresume(hcd->phy); 557 554 tegra->port_resuming = 1; 558 555 return 0; 559 556 } ··· 607 604 608 605 #endif 609 606 607 + /* Bits of PORTSC1, which will get cleared by writing 1 into them */ 608 + #define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) 609 + 610 + void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val) 611 + { 612 + unsigned long val; 613 + struct usb_hcd *hcd = bus_to_hcd(x->otg->host); 614 + void __iomem *base = hcd->regs; 615 + 616 + val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS; 617 + val &= ~TEGRA_USB_PORTSC1_PTS(3); 618 + val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3); 619 + writel(val, base + TEGRA_USB_PORTSC1); 620 + } 621 + EXPORT_SYMBOL_GPL(tegra_ehci_set_pts); 622 + 623 + void tegra_ehci_set_phcd(struct usb_phy *x, bool enable) 624 + { 625 + unsigned long val; 626 + struct usb_hcd *hcd = bus_to_hcd(x->otg->host); 627 + void __iomem *base = hcd->regs; 628 + 629 + val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS; 630 + if (enable) 631 + val |= TEGRA_USB_PORTSC1_PHCD; 632 + else 633 + val &= ~TEGRA_USB_PORTSC1_PHCD; 634 + writel(val, base + TEGRA_USB_PORTSC1); 635 + } 636 + EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd); 637 + 610 638 static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); 611 639 612 640 static int tegra_ehci_probe(struct platform_device *pdev) ··· 649 615 int err = 0; 650 616 int irq; 651 617 int instance = pdev->id; 618 + struct usb_phy *u_phy; 652 619 653 620 pdata = pdev->dev.platform_data; 654 621 if (!pdata) { ··· 691 656 if (err) 692 657 goto fail_clk; 693 658 694 - tegra->emc_clk = devm_clk_get(&pdev->dev, "emc"); 695 - if (IS_ERR(tegra->emc_clk)) { 696 - dev_err(&pdev->dev, "Can't get emc clock\n"); 697 - err = PTR_ERR(tegra->emc_clk); 698 - goto fail_emc_clk; 699 - } 700 - 701 - clk_prepare_enable(tegra->emc_clk); 702 - clk_set_rate(tegra->emc_clk, 400000000); 659 + tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node, 660 + "nvidia,needs-double-reset"); 703 661 704 662 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 705 663 if (!res) { ··· 740 712 goto fail_io; 741 713 } 742 714 743 - usb_phy_init(&tegra->phy->u_phy); 715 + hcd->phy = u_phy = &tegra->phy->u_phy; 716 + usb_phy_init(hcd->phy); 744 717 745 - err = usb_phy_set_suspend(&tegra->phy->u_phy, 0); 718 + u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), 719 + GFP_KERNEL); 720 + if (!u_phy->otg) { 721 + dev_err(&pdev->dev, "Failed to alloc memory for otg\n"); 722 + err = -ENOMEM; 723 + goto fail_io; 724 + } 725 + u_phy->otg->host = hcd_to_bus(hcd); 726 + 727 + err = usb_phy_set_suspend(hcd->phy, 0); 746 728 if (err) { 747 729 dev_err(&pdev->dev, "Failed to power on the phy\n"); 748 730 goto fail; ··· 798 760 if (!IS_ERR_OR_NULL(tegra->transceiver)) 799 761 otg_set_host(tegra->transceiver->otg, NULL); 800 762 #endif 801 - usb_phy_shutdown(&tegra->phy->u_phy); 763 + usb_phy_shutdown(hcd->phy); 802 764 fail_io: 803 - clk_disable_unprepare(tegra->emc_clk); 804 - fail_emc_clk: 805 765 clk_disable_unprepare(tegra->clk); 806 766 fail_clk: 807 767 usb_put_hcd(hcd); ··· 820 784 otg_set_host(tegra->transceiver->otg, NULL); 821 785 #endif 822 786 787 + usb_phy_shutdown(hcd->phy); 823 788 usb_remove_hcd(hcd); 824 789 usb_put_hcd(hcd); 825 790 826 - usb_phy_shutdown(&tegra->phy->u_phy); 827 - 828 791 clk_disable_unprepare(tegra->clk); 829 - 830 - clk_disable_unprepare(tegra->emc_clk); 831 792 832 793 return 0; 833 794 }
+45 -87
drivers/usb/phy/tegra_usb_phy.c
··· 24 24 #include <linux/platform_device.h> 25 25 #include <linux/io.h> 26 26 #include <linux/gpio.h> 27 + #include <linux/of.h> 27 28 #include <linux/of_gpio.h> 28 29 #include <linux/usb/otg.h> 29 30 #include <linux/usb/ulpi.h> ··· 35 34 #define TEGRA_USB_SIZE SZ_16K 36 35 37 36 #define ULPI_VIEWPORT 0x170 38 - 39 - #define USB_PORTSC1 0x184 40 - #define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) 41 - #define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26) 42 - #define USB_PORTSC1_PHCD (1 << 23) 43 - #define USB_PORTSC1_WKOC (1 << 22) 44 - #define USB_PORTSC1_WKDS (1 << 21) 45 - #define USB_PORTSC1_WKCN (1 << 20) 46 - #define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16) 47 - #define USB_PORTSC1_PP (1 << 12) 48 - #define USB_PORTSC1_SUSP (1 << 7) 49 - #define USB_PORTSC1_PE (1 << 2) 50 - #define USB_PORTSC1_CCS (1 << 0) 51 37 52 38 #define USB_SUSP_CTRL 0x400 53 39 #define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) ··· 196 208 }, 197 209 }; 198 210 199 - static inline bool phy_is_ulpi(struct tegra_usb_phy *phy) 200 - { 201 - return (phy->instance == 1); 202 - } 203 - 204 211 static int utmip_pad_open(struct tegra_usb_phy *phy) 205 212 { 206 213 phy->pad_clk = clk_get_sys("utmip-pad", NULL); ··· 204 221 return PTR_ERR(phy->pad_clk); 205 222 } 206 223 207 - if (phy->instance == 0) { 224 + if (phy->is_legacy_phy) { 208 225 phy->pad_regs = phy->regs; 209 226 } else { 210 227 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); ··· 219 236 220 237 static void utmip_pad_close(struct tegra_usb_phy *phy) 221 238 { 222 - if (phy->instance != 0) 239 + if (!phy->is_legacy_phy) 223 240 iounmap(phy->pad_regs); 224 241 clk_put(phy->pad_clk); 225 242 } ··· 288 305 unsigned long val; 289 306 void __iomem *base = phy->regs; 290 307 291 - if (phy->instance == 0) { 308 + if (phy->is_legacy_phy) { 292 309 val = readl(base + USB_SUSP_CTRL); 293 310 val |= USB_SUSP_SET; 294 311 writel(val, base + USB_SUSP_CTRL); ··· 298 315 val = readl(base + USB_SUSP_CTRL); 299 316 val &= ~USB_SUSP_SET; 300 317 writel(val, base + USB_SUSP_CTRL); 301 - } 302 - 303 - if (phy->instance == 2) { 304 - val = readl(base + USB_PORTSC1); 305 - val |= USB_PORTSC1_PHCD; 306 - writel(val, base + USB_PORTSC1); 307 - } 318 + } else 319 + tegra_ehci_set_phcd(&phy->u_phy, true); 308 320 309 321 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) 310 322 pr_err("%s: timeout waiting for phy to stabilize\n", __func__); ··· 310 332 unsigned long val; 311 333 void __iomem *base = phy->regs; 312 334 313 - if (phy->instance == 0) { 335 + if (phy->is_legacy_phy) { 314 336 val = readl(base + USB_SUSP_CTRL); 315 337 val |= USB_SUSP_CLR; 316 338 writel(val, base + USB_SUSP_CTRL); ··· 320 342 val = readl(base + USB_SUSP_CTRL); 321 343 val &= ~USB_SUSP_CLR; 322 344 writel(val, base + USB_SUSP_CTRL); 323 - } 324 - 325 - if (phy->instance == 2) { 326 - val = readl(base + USB_PORTSC1); 327 - val &= ~USB_PORTSC1_PHCD; 328 - writel(val, base + USB_PORTSC1); 329 - } 345 + } else 346 + tegra_ehci_set_phcd(&phy->u_phy, false); 330 347 331 348 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 332 349 USB_PHY_CLK_VALID)) ··· 338 365 val |= UTMIP_RESET; 339 366 writel(val, base + USB_SUSP_CTRL); 340 367 341 - if (phy->instance == 0) { 368 + if (phy->is_legacy_phy) { 342 369 val = readl(base + USB1_LEGACY_CTRL); 343 370 val |= USB1_NO_LEGACY_MODE; 344 371 writel(val, base + USB1_LEGACY_CTRL); ··· 413 440 val |= UTMIP_BIAS_PDTRK_COUNT(0x5); 414 441 writel(val, base + UTMIP_BIAS_CFG1); 415 442 416 - if (phy->instance == 0) { 443 + if (phy->is_legacy_phy) { 417 444 val = readl(base + UTMIP_SPARE_CFG0); 418 445 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) 419 446 val &= ~FUSE_SETUP_SEL; 420 447 else 421 448 val |= FUSE_SETUP_SEL; 422 449 writel(val, base + UTMIP_SPARE_CFG0); 423 - } 424 - 425 - if (phy->instance == 2) { 450 + } else { 426 451 val = readl(base + USB_SUSP_CTRL); 427 452 val |= UTMIP_PHY_ENABLE; 428 453 writel(val, base + USB_SUSP_CTRL); ··· 430 459 val &= ~UTMIP_RESET; 431 460 writel(val, base + USB_SUSP_CTRL); 432 461 433 - if (phy->instance == 0) { 462 + if (phy->is_legacy_phy) { 434 463 val = readl(base + USB1_LEGACY_CTRL); 435 464 val &= ~USB1_VBUS_SENSE_CTL_MASK; 436 465 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; ··· 443 472 444 473 utmi_phy_clk_enable(phy); 445 474 446 - if (phy->instance == 2) { 447 - val = readl(base + USB_PORTSC1); 448 - val &= ~USB_PORTSC1_PTS(~0); 449 - writel(val, base + USB_PORTSC1); 450 - } 475 + if (!phy->is_legacy_phy) 476 + tegra_ehci_set_pts(&phy->u_phy, 0); 451 477 452 478 return 0; 453 479 } ··· 589 621 return ret; 590 622 } 591 623 592 - val = readl(base + USB_PORTSC1); 593 - val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN; 594 - writel(val, base + USB_PORTSC1); 595 - 596 624 val = readl(base + USB_SUSP_CTRL); 597 625 val |= USB_SUSP_CLR; 598 626 writel(val, base + USB_SUSP_CTRL); ··· 603 639 604 640 static int ulpi_phy_power_off(struct tegra_usb_phy *phy) 605 641 { 606 - unsigned long val; 607 - void __iomem *base = phy->regs; 608 642 struct tegra_ulpi_config *config = phy->config; 609 - 610 - /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB 611 - * Controller to immediately bring the ULPI PHY out of low power 612 - */ 613 - val = readl(base + USB_PORTSC1); 614 - val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); 615 - writel(val, base + USB_PORTSC1); 616 643 617 644 clk_disable(phy->clk); 618 645 return gpio_direction_output(config->reset_gpio, 0); ··· 615 660 struct tegra_ulpi_config *ulpi_config; 616 661 int err; 617 662 618 - if (phy_is_ulpi(phy)) { 663 + if (phy->is_ulpi_phy) { 619 664 ulpi_config = phy->config; 620 665 phy->clk = clk_get_sys(NULL, ulpi_config->clk); 621 666 if (IS_ERR(phy->clk)) { ··· 653 698 { 654 699 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 655 700 656 - if (phy_is_ulpi(phy)) 701 + if (phy->is_ulpi_phy) 657 702 clk_put(phy->clk); 658 703 else 659 704 utmip_pad_close(phy); ··· 664 709 665 710 static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) 666 711 { 667 - if (phy_is_ulpi(phy)) 712 + if (phy->is_ulpi_phy) 668 713 return ulpi_phy_power_on(phy); 669 714 else 670 715 return utmi_phy_power_on(phy); ··· 672 717 673 718 static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) 674 719 { 675 - if (phy_is_ulpi(phy)) 720 + if (phy->is_ulpi_phy) 676 721 return ulpi_phy_power_off(phy); 677 722 else 678 723 return utmi_phy_power_off(phy); ··· 694 739 unsigned long parent_rate; 695 740 int i; 696 741 int err; 742 + struct device_node *np = dev->of_node; 697 743 698 - phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); 744 + phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); 699 745 if (!phy) 700 746 return ERR_PTR(-ENOMEM); 701 747 ··· 705 749 phy->config = config; 706 750 phy->mode = phy_mode; 707 751 phy->dev = dev; 752 + phy->is_legacy_phy = 753 + of_property_read_bool(np, "nvidia,has-legacy-mode"); 754 + err = of_property_match_string(np, "phy_type", "ulpi"); 755 + if (err < 0) 756 + phy->is_ulpi_phy = false; 757 + else 758 + phy->is_ulpi_phy = true; 708 759 709 760 if (!phy->config) { 710 - if (phy_is_ulpi(phy)) { 761 + if (phy->is_ulpi_phy) { 711 762 pr_err("%s: ulpi phy configuration missing", __func__); 712 763 err = -EINVAL; 713 764 goto err0; ··· 759 796 } 760 797 EXPORT_SYMBOL_GPL(tegra_usb_phy_open); 761 798 762 - void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) 799 + void tegra_usb_phy_preresume(struct usb_phy *x) 763 800 { 764 - if (!phy_is_ulpi(phy)) 801 + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 802 + 803 + if (!phy->is_ulpi_phy) 765 804 utmi_phy_preresume(phy); 766 805 } 767 806 EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); 768 807 769 - void tegra_usb_phy_postresume(struct tegra_usb_phy *phy) 808 + void tegra_usb_phy_postresume(struct usb_phy *x) 770 809 { 771 - if (!phy_is_ulpi(phy)) 810 + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 811 + 812 + if (!phy->is_ulpi_phy) 772 813 utmi_phy_postresume(phy); 773 814 } 774 815 EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); 775 816 776 - void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, 817 + void tegra_ehci_phy_restore_start(struct usb_phy *x, 777 818 enum tegra_usb_phy_port_speed port_speed) 778 819 { 779 - if (!phy_is_ulpi(phy)) 820 + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 821 + 822 + if (!phy->is_ulpi_phy) 780 823 utmi_phy_restore_start(phy, port_speed); 781 824 } 782 825 EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); 783 826 784 - void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) 827 + void tegra_ehci_phy_restore_end(struct usb_phy *x) 785 828 { 786 - if (!phy_is_ulpi(phy)) 829 + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 830 + 831 + if (!phy->is_ulpi_phy) 787 832 utmi_phy_restore_end(phy); 788 833 } 789 834 EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); 790 835 791 - void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) 792 - { 793 - if (!phy_is_ulpi(phy)) 794 - utmi_phy_clk_disable(phy); 795 - } 796 - EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable); 797 - 798 - void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) 799 - { 800 - if (!phy_is_ulpi(phy)) 801 - utmi_phy_clk_enable(phy); 802 - } 803 - EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);
+10 -8
include/linux/usb/tegra_usb_phy.h
··· 59 59 struct usb_phy *ulpi; 60 60 struct usb_phy u_phy; 61 61 struct device *dev; 62 + bool is_legacy_phy; 63 + bool is_ulpi_phy; 62 64 }; 63 65 64 66 struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 65 67 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); 66 68 67 - void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); 69 + void tegra_usb_phy_preresume(struct usb_phy *phy); 68 70 69 - void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); 71 + void tegra_usb_phy_postresume(struct usb_phy *phy); 70 72 71 - void tegra_usb_phy_preresume(struct tegra_usb_phy *phy); 72 - 73 - void tegra_usb_phy_postresume(struct tegra_usb_phy *phy); 74 - 75 - void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, 73 + void tegra_ehci_phy_restore_start(struct usb_phy *phy, 76 74 enum tegra_usb_phy_port_speed port_speed); 77 75 78 - void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); 76 + void tegra_ehci_phy_restore_end(struct usb_phy *phy); 77 + 78 + void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val); 79 + 80 + void tegra_ehci_set_phcd(struct usb_phy *x, bool enable); 79 81 80 82 #endif /* __TEGRA_USB_PHY_H */