Commit aa607ebf authored by Stephen Warren's avatar Stephen Warren

ARM: tegra: add USB ULPI PHY reset GPIO to device tree

ULPI PHYs have a reset signal, and different boards use a different GPIO
for this task. Add a property to device tree to represent this.

I'm not sure if adding this property to the EHCI controller node is
entirely correct; perhaps eventually we should have explicit separate
nodes for the various PHYs. However, we don't have that right now, so this
binding seems like a reasonable choice.

Cc: <devicetree-discuss@lists.ozlabs.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
parent 60d148b9
...@@ -12,6 +12,9 @@ Required properties : ...@@ -12,6 +12,9 @@ Required properties :
- nvidia,vbus-gpio : If present, specifies a gpio that needs to be - nvidia,vbus-gpio : If present, specifies a gpio that needs to be
activated for the bus to be powered. activated for the bus to be powered.
Required properties for phy_type == ulpi:
- nvidia,phy-reset-gpio : The GPIO used to reset the PHY.
Optional properties: Optional properties:
- dr_mode : dual role mode. Indicates the working mode for - dr_mode : dual role mode. Indicates the working mode for
nvidia,tegra20-ehci compatible controllers. Can be "host", "peripheral", nvidia,tegra20-ehci compatible controllers. Can be "host", "peripheral",
......
...@@ -336,4 +336,8 @@ sdhci@c8000600 { ...@@ -336,4 +336,8 @@ sdhci@c8000600 {
power-gpios = <&gpio 70 0>; /* gpio PI6 */ power-gpios = <&gpio 70 0>; /* gpio PI6 */
support-8bit; support-8bit;
}; };
usb@c5004000 {
nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
};
}; };
...@@ -351,4 +351,8 @@ wifi { ...@@ -351,4 +351,8 @@ wifi {
linux,default-trigger = "rfkill0"; linux,default-trigger = "rfkill0";
}; };
}; };
usb@c5004000 {
nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
};
}; };
...@@ -415,4 +415,8 @@ emc-table@380000 { ...@@ -415,4 +415,8 @@ emc-table@380000 {
0x00000000 0x00000000 0x00000000 0x00000000 >; 0x00000000 0x00000000 0x00000000 0x00000000 >;
}; };
}; };
usb@c5004000 {
nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
};
}; };
...@@ -304,4 +304,8 @@ sdhci@c8000600 { ...@@ -304,4 +304,8 @@ sdhci@c8000600 {
cd-gpios = <&gpio 121 0>; cd-gpios = <&gpio 121 0>;
wp-gpios = <&gpio 122 0>; wp-gpios = <&gpio 122 0>;
}; };
usb@c5004000 {
nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
};
}; };
...@@ -335,4 +335,8 @@ sdhci@c8000400 { ...@@ -335,4 +335,8 @@ sdhci@c8000400 {
sdhci@c8000600 { sdhci@c8000600 {
support-8bit; support-8bit;
}; };
usb@c5004000 {
nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
};
}; };
...@@ -61,8 +61,8 @@ struct tegra_usb_phy { ...@@ -61,8 +61,8 @@ struct tegra_usb_phy {
struct usb_phy *ulpi; struct usb_phy *ulpi;
}; };
struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
void *config, enum tegra_usb_phy_mode phy_mode); void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy); int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/usb/ulpi.h> #include <linux/usb/ulpi.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -654,8 +655,8 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy) ...@@ -654,8 +655,8 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
clk_disable(phy->clk); clk_disable(phy->clk);
} }
struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
void *config, enum tegra_usb_phy_mode phy_mode) void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
{ {
struct tegra_usb_phy *phy; struct tegra_usb_phy *phy;
struct tegra_ulpi_config *ulpi_config; struct tegra_ulpi_config *ulpi_config;
...@@ -711,6 +712,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, ...@@ -711,6 +712,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
err = -ENXIO; err = -ENXIO;
goto err1; goto err1;
} }
if (!gpio_is_valid(ulpi_config->reset_gpio))
ulpi_config->reset_gpio =
of_get_named_gpio(dev->of_node,
"nvidia,phy-reset-gpio", 0);
if (!gpio_is_valid(ulpi_config->reset_gpio)) {
pr_err("%s: invalid reset gpio: %d\n", __func__,
ulpi_config->reset_gpio);
err = -EINVAL;
goto err1;
}
gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
gpio_direction_output(ulpi_config->reset_gpio, 0); gpio_direction_output(ulpi_config->reset_gpio, 0);
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
......
...@@ -708,8 +708,9 @@ static int tegra_ehci_probe(struct platform_device *pdev) ...@@ -708,8 +708,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
} }
} }
tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, tegra->phy = tegra_usb_phy_open(&pdev->dev, instance, hcd->regs,
TEGRA_USB_PHY_MODE_HOST); pdata->phy_config,
TEGRA_USB_PHY_MODE_HOST);
if (IS_ERR(tegra->phy)) { if (IS_ERR(tegra->phy)) {
dev_err(&pdev->dev, "Failed to open USB phy\n"); dev_err(&pdev->dev, "Failed to open USB phy\n");
err = -ENXIO; err = -ENXIO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment