Commit 80525cc2 authored by Thierry Reding's avatar Thierry Reding

Merge branch 'for-5.7/phy' into for-5.7/usb

parents ca9e742b 6835bdc9
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
config PHY_TEGRA_XUSB config PHY_TEGRA_XUSB
tristate "NVIDIA Tegra XUSB pad controller driver" tristate "NVIDIA Tegra XUSB pad controller driver"
depends on ARCH_TEGRA depends on ARCH_TEGRA
select USB_CONN_GPIO
select USB_PHY
help help
Choose this option if you have an NVIDIA Tegra SoC. Choose this option if you have an NVIDIA Tegra SoC.
......
...@@ -6,4 +6,5 @@ phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o ...@@ -6,4 +6,5 @@ phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC) += xusb-tegra186.o phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC) += xusb-tegra186.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_194_SOC) += xusb-tegra186.o
obj-$(CONFIG_PHY_TEGRA194_P2U) += phy-tegra194-p2u.o obj-$(CONFIG_PHY_TEGRA194_P2U) += phy-tegra194-p2u.o
...@@ -1422,6 +1422,8 @@ tegra124_usb2_port_map(struct tegra_xusb_port *port) ...@@ -1422,6 +1422,8 @@ tegra124_usb2_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra124_usb2_port_ops = { static const struct tegra_xusb_port_ops tegra124_usb2_port_ops = {
.release = tegra_xusb_usb2_port_release,
.remove = tegra_xusb_usb2_port_remove,
.enable = tegra124_usb2_port_enable, .enable = tegra124_usb2_port_enable,
.disable = tegra124_usb2_port_disable, .disable = tegra124_usb2_port_disable,
.map = tegra124_usb2_port_map, .map = tegra124_usb2_port_map,
...@@ -1443,6 +1445,7 @@ tegra124_ulpi_port_map(struct tegra_xusb_port *port) ...@@ -1443,6 +1445,7 @@ tegra124_ulpi_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra124_ulpi_port_ops = { static const struct tegra_xusb_port_ops tegra124_ulpi_port_ops = {
.release = tegra_xusb_ulpi_port_release,
.enable = tegra124_ulpi_port_enable, .enable = tegra124_ulpi_port_enable,
.disable = tegra124_ulpi_port_disable, .disable = tegra124_ulpi_port_disable,
.map = tegra124_ulpi_port_map, .map = tegra124_ulpi_port_map,
...@@ -1464,6 +1467,7 @@ tegra124_hsic_port_map(struct tegra_xusb_port *port) ...@@ -1464,6 +1467,7 @@ tegra124_hsic_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra124_hsic_port_ops = { static const struct tegra_xusb_port_ops tegra124_hsic_port_ops = {
.release = tegra_xusb_hsic_port_release,
.enable = tegra124_hsic_port_enable, .enable = tegra124_hsic_port_enable,
.disable = tegra124_hsic_port_disable, .disable = tegra124_hsic_port_disable,
.map = tegra124_hsic_port_map, .map = tegra124_hsic_port_map,
...@@ -1647,6 +1651,8 @@ tegra124_usb3_port_map(struct tegra_xusb_port *port) ...@@ -1647,6 +1651,8 @@ tegra124_usb3_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra124_usb3_port_ops = { static const struct tegra_xusb_port_ops tegra124_usb3_port_ops = {
.release = tegra_xusb_usb3_port_release,
.remove = tegra_xusb_usb3_port_remove,
.enable = tegra124_usb3_port_enable, .enable = tegra124_usb3_port_enable,
.disable = tegra124_usb3_port_disable, .disable = tegra124_usb3_port_disable,
.map = tegra124_usb3_port_map, .map = tegra124_usb3_port_map,
......
This diff is collapsed.
...@@ -236,6 +236,7 @@ ...@@ -236,6 +236,7 @@
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT 18 #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT 18
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK 0xf #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK 0xf
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING 8 #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING 8
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED 0
struct tegra210_xusb_fuse_calibration { struct tegra210_xusb_fuse_calibration {
u32 hs_curr_level[4]; u32 hs_curr_level[4];
...@@ -935,6 +936,103 @@ static int tegra210_usb2_phy_exit(struct phy *phy) ...@@ -935,6 +936,103 @@ static int tegra210_usb2_phy_exit(struct phy *phy)
return tegra210_xusb_padctl_disable(lane->pad->padctl); return tegra210_xusb_padctl_disable(lane->pad->padctl);
} }
static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
bool status)
{
u32 value;
dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
if (status) {
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
} else {
value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
}
padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
return 0;
}
static int tegra210_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
bool status)
{
u32 value;
dev_dbg(padctl->dev, "%s id override\n", status ? "set" : "clear");
value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
if (status) {
if (value & XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON) {
value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
usleep_range(1000, 2000);
value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
}
value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
} else {
value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
}
padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
return 0;
}
static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
struct tegra_xusb_usb2_port *port = tegra_xusb_find_usb2_port(padctl,
lane->index);
int err = 0;
mutex_lock(&padctl->lock);
dev_dbg(&port->base.dev, "%s: mode %d", __func__, mode);
if (mode == PHY_MODE_USB_OTG) {
if (submode == USB_ROLE_HOST) {
tegra210_xusb_padctl_id_override(padctl, true);
err = regulator_enable(port->supply);
} else if (submode == USB_ROLE_DEVICE) {
tegra210_xusb_padctl_vbus_override(padctl, true);
} else if (submode == USB_ROLE_NONE) {
/*
* When port is peripheral only or role transitions to
* USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
* be enabled.
*/
if (regulator_is_enabled(port->supply))
regulator_disable(port->supply);
tegra210_xusb_padctl_id_override(padctl, false);
tegra210_xusb_padctl_vbus_override(padctl, false);
}
}
mutex_unlock(&padctl->lock);
return err;
}
static int tegra210_usb2_phy_power_on(struct phy *phy) static int tegra210_usb2_phy_power_on(struct phy *phy)
{ {
struct tegra_xusb_lane *lane = phy_get_drvdata(phy); struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
...@@ -1048,9 +1146,11 @@ static int tegra210_usb2_phy_power_on(struct phy *phy) ...@@ -1048,9 +1146,11 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
padctl_writel(padctl, value, padctl_writel(padctl, value,
XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
err = regulator_enable(port->supply); if (port->supply && port->mode == USB_DR_MODE_HOST) {
if (err) err = regulator_enable(port->supply);
return err; if (err)
return err;
}
mutex_lock(&padctl->lock); mutex_lock(&padctl->lock);
...@@ -1164,6 +1264,7 @@ static const struct phy_ops tegra210_usb2_phy_ops = { ...@@ -1164,6 +1264,7 @@ static const struct phy_ops tegra210_usb2_phy_ops = {
.exit = tegra210_usb2_phy_exit, .exit = tegra210_usb2_phy_exit,
.power_on = tegra210_usb2_phy_power_on, .power_on = tegra210_usb2_phy_power_on,
.power_off = tegra210_usb2_phy_power_off, .power_off = tegra210_usb2_phy_power_off,
.set_mode = tegra210_usb2_phy_set_mode,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -1852,6 +1953,8 @@ tegra210_usb2_port_map(struct tegra_xusb_port *port) ...@@ -1852,6 +1953,8 @@ tegra210_usb2_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra210_usb2_port_ops = { static const struct tegra_xusb_port_ops tegra210_usb2_port_ops = {
.release = tegra_xusb_usb2_port_release,
.remove = tegra_xusb_usb2_port_remove,
.enable = tegra210_usb2_port_enable, .enable = tegra210_usb2_port_enable,
.disable = tegra210_usb2_port_disable, .disable = tegra210_usb2_port_disable,
.map = tegra210_usb2_port_map, .map = tegra210_usb2_port_map,
...@@ -1873,6 +1976,7 @@ tegra210_hsic_port_map(struct tegra_xusb_port *port) ...@@ -1873,6 +1976,7 @@ tegra210_hsic_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra210_hsic_port_ops = { static const struct tegra_xusb_port_ops tegra210_hsic_port_ops = {
.release = tegra_xusb_hsic_port_release,
.enable = tegra210_hsic_port_enable, .enable = tegra210_hsic_port_enable,
.disable = tegra210_hsic_port_disable, .disable = tegra210_hsic_port_disable,
.map = tegra210_hsic_port_map, .map = tegra210_hsic_port_map,
...@@ -2018,35 +2122,13 @@ tegra210_usb3_port_map(struct tegra_xusb_port *port) ...@@ -2018,35 +2122,13 @@ tegra210_usb3_port_map(struct tegra_xusb_port *port)
} }
static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = { static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = {
.release = tegra_xusb_usb3_port_release,
.remove = tegra_xusb_usb3_port_remove,
.enable = tegra210_usb3_port_enable, .enable = tegra210_usb3_port_enable,
.disable = tegra210_usb3_port_disable, .disable = tegra210_usb3_port_disable,
.map = tegra210_usb3_port_map, .map = tegra210_usb3_port_map,
}; };
static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
bool status)
{
u32 value;
dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
if (status) {
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
} else {
value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
}
padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID);
return 0;
}
static int tegra210_utmi_port_reset(struct phy *phy) static int tegra210_utmi_port_reset(struct phy *phy)
{ {
struct tegra_xusb_padctl *padctl; struct tegra_xusb_padctl *padctl;
......
This diff is collapsed.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/usb/role.h>
/* legacy entry points for backwards-compatibility */ /* legacy entry points for backwards-compatibility */
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev); int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
...@@ -266,9 +267,18 @@ struct tegra_xusb_port { ...@@ -266,9 +267,18 @@ struct tegra_xusb_port {
struct list_head list; struct list_head list;
struct device dev; struct device dev;
struct usb_role_switch *usb_role_sw;
struct work_struct usb_phy_work;
struct usb_phy usb_phy;
const struct tegra_xusb_port_ops *ops; const struct tegra_xusb_port_ops *ops;
}; };
static inline struct tegra_xusb_port *to_tegra_xusb_port(struct device *dev)
{
return container_of(dev, struct tegra_xusb_port, dev);
}
struct tegra_xusb_lane_map { struct tegra_xusb_lane_map {
unsigned int port; unsigned int port;
const char *type; const char *type;
...@@ -303,6 +313,8 @@ to_usb2_port(struct tegra_xusb_port *port) ...@@ -303,6 +313,8 @@ to_usb2_port(struct tegra_xusb_port *port)
struct tegra_xusb_usb2_port * struct tegra_xusb_usb2_port *
tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl, tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl,
unsigned int index); unsigned int index);
void tegra_xusb_usb2_port_release(struct tegra_xusb_port *port);
void tegra_xusb_usb2_port_remove(struct tegra_xusb_port *port);
struct tegra_xusb_ulpi_port { struct tegra_xusb_ulpi_port {
struct tegra_xusb_port base; struct tegra_xusb_port base;
...@@ -317,6 +329,8 @@ to_ulpi_port(struct tegra_xusb_port *port) ...@@ -317,6 +329,8 @@ to_ulpi_port(struct tegra_xusb_port *port)
return container_of(port, struct tegra_xusb_ulpi_port, base); return container_of(port, struct tegra_xusb_ulpi_port, base);
} }
void tegra_xusb_ulpi_port_release(struct tegra_xusb_port *port);
struct tegra_xusb_hsic_port { struct tegra_xusb_hsic_port {
struct tegra_xusb_port base; struct tegra_xusb_port base;
}; };
...@@ -327,12 +341,15 @@ to_hsic_port(struct tegra_xusb_port *port) ...@@ -327,12 +341,15 @@ to_hsic_port(struct tegra_xusb_port *port)
return container_of(port, struct tegra_xusb_hsic_port, base); return container_of(port, struct tegra_xusb_hsic_port, base);
} }
void tegra_xusb_hsic_port_release(struct tegra_xusb_port *port);
struct tegra_xusb_usb3_port { struct tegra_xusb_usb3_port {
struct tegra_xusb_port base; struct tegra_xusb_port base;
struct regulator *supply; struct regulator *supply;
bool context_saved; bool context_saved;
unsigned int port; unsigned int port;
bool internal; bool internal;
bool disable_gen2;
u32 tap1; u32 tap1;
u32 amp; u32 amp;
...@@ -349,8 +366,12 @@ to_usb3_port(struct tegra_xusb_port *port) ...@@ -349,8 +366,12 @@ to_usb3_port(struct tegra_xusb_port *port)
struct tegra_xusb_usb3_port * struct tegra_xusb_usb3_port *
tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl, tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl,
unsigned int index); unsigned int index);
void tegra_xusb_usb3_port_release(struct tegra_xusb_port *port);
void tegra_xusb_usb3_port_remove(struct tegra_xusb_port *port);
struct tegra_xusb_port_ops { struct tegra_xusb_port_ops {
void (*release)(struct tegra_xusb_port *port);
void (*remove)(struct tegra_xusb_port *port);
int (*enable)(struct tegra_xusb_port *port); int (*enable)(struct tegra_xusb_port *port);
void (*disable)(struct tegra_xusb_port *port); void (*disable)(struct tegra_xusb_port *port);
struct tegra_xusb_lane *(*map)(struct tegra_xusb_port *port); struct tegra_xusb_lane *(*map)(struct tegra_xusb_port *port);
...@@ -392,6 +413,7 @@ struct tegra_xusb_padctl_soc { ...@@ -392,6 +413,7 @@ struct tegra_xusb_padctl_soc {
const char * const *supply_names; const char * const *supply_names;
unsigned int num_supplies; unsigned int num_supplies;
bool supports_gen2;
bool need_fake_usb3_port; bool need_fake_usb3_port;
}; };
...@@ -448,5 +470,8 @@ extern const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc; ...@@ -448,5 +470,8 @@ extern const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc;
#if defined(CONFIG_ARCH_TEGRA_186_SOC) #if defined(CONFIG_ARCH_TEGRA_186_SOC)
extern const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc; extern const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc;
#endif #endif
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
extern const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc;
#endif
#endif /* __PHY_TEGRA_XUSB_H */ #endif /* __PHY_TEGRA_XUSB_H */
...@@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, ...@@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl, int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
bool val); bool val);
int tegra_phy_xusb_utmi_port_reset(struct phy *phy); int tegra_phy_xusb_utmi_port_reset(struct phy *phy);
int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
unsigned int port);
#endif /* PHY_TEGRA_XUSB_H */ #endif /* PHY_TEGRA_XUSB_H */
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