xusb: t210: support utmi pad biasing
Based on t186 driver and downstream: https://gitlab.com/nvidia/nv-tegra/linux-4.9/-/commit/8d05313ac9fd54a2fc373a0e789390dfa0607726
This commit is contained in:
1 parent
671b02a011
commit
0184fed5fc
1 file changed
+196
-88
@@ -28,6 +28,8 @@
|
||||
#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK 0x3f
|
||||
#define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT 7
|
||||
#define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK 0xf
|
||||
#define FUSE_SKU_CALIB_HS_SQUELCH_SHIFT 29
|
||||
#define FUSE_SKU_CALIB_HS_SQUELCH_MASK 0x7
|
||||
|
||||
#define FUSE_USB_CALIB_EXT_RPD_CTRL_SHIFT 0
|
||||
#define FUSE_USB_CALIB_EXT_RPD_CTRL_MASK 0x1f
|
||||
@@ -95,6 +97,7 @@
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI (1 << 29)
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 (1 << 27)
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD (1 << 26)
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_TERM_SEL (1 << 25)
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT 0
|
||||
#define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK 0x3f
|
||||
|
||||
@@ -413,6 +416,8 @@
|
||||
#define UHSIC_STROBE_RPD_C BIT(16)
|
||||
#define UHSIC_STROBE_RPD_D BIT(24)
|
||||
|
||||
#define TEGRA_UTMI_PAD_MAX 4
|
||||
|
||||
struct init_data {
|
||||
u8 cfg_addr;
|
||||
u16 cfg_wdata;
|
||||
@@ -428,6 +433,7 @@ static struct init_data tegra210b01_usb3_pll_g1_init_data[] = {
|
||||
struct tegra210_xusb_fuse_calibration {
|
||||
u32 hs_curr_level[4];
|
||||
u32 hs_term_range_adj;
|
||||
u32 hs_squelch;
|
||||
u32 rpd_ctrl;
|
||||
};
|
||||
|
||||
@@ -442,6 +448,8 @@ struct tegra210_xusb_padctl {
|
||||
struct tegra_xusb_padctl base;
|
||||
struct regmap *regmap;
|
||||
|
||||
DECLARE_BITMAP(utmi_pad_enabled, TEGRA_UTMI_PAD_MAX);
|
||||
|
||||
struct tegra210_xusb_fuse_calibration fuse;
|
||||
struct tegra210_xusb_padctl_context context;
|
||||
};
|
||||
@@ -1939,6 +1947,151 @@ static int tegra210_usb2_phy_exit(struct phy *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra210_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl,
|
||||
struct tegra_xusb_usb2_pad *pad)
|
||||
{
|
||||
struct tegra210_xusb_padctl *priv = to_tegra210_xusb_padctl(padctl);
|
||||
struct device *dev = padctl->dev;
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX))
|
||||
return;
|
||||
|
||||
err = clk_prepare_enable(pad->clk);
|
||||
if (err < 0)
|
||||
dev_warn(dev, "failed to enable USB2 trk clock: %d\n", err);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value &= ~(XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT);
|
||||
value |= ((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL &
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK) <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT);
|
||||
value &= ~(XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT);
|
||||
value |= ((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL &
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK) <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT);
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD;
|
||||
value &= ~(XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT);
|
||||
value |= ((priv->fuse.hs_squelch &
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK) <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT);
|
||||
value &= ~(XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT);
|
||||
value |= ((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL &
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK) <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT);
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
|
||||
udelay(1);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
}
|
||||
|
||||
static void tegra210_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl,
|
||||
struct tegra_xusb_usb2_pad *pad)
|
||||
{
|
||||
struct tegra210_xusb_padctl *priv = to_tegra210_xusb_padctl(padctl);
|
||||
u32 value;
|
||||
|
||||
if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX))
|
||||
return;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
}
|
||||
|
||||
static void tegra210_utmi_pad_power_on(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
struct tegra210_xusb_padctl *priv = to_tegra210_xusb_padctl(padctl);
|
||||
struct tegra_xusb_usb2_port *port;
|
||||
struct device *dev = padctl->dev;
|
||||
unsigned int index = lane->index;
|
||||
u32 value;
|
||||
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
if (test_bit(index, priv->utmi_pad_enabled)) {
|
||||
mutex_unlock(&padctl->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
port = tegra_xusb_find_usb2_port(padctl, index);
|
||||
if (!port) {
|
||||
dev_err(dev, "no port found for USB2 lane %u\n", index);
|
||||
mutex_unlock(&padctl->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "power on UTMI pad %u\n", index);
|
||||
|
||||
tegra210_utmi_bias_pad_power_on(padctl, pad);
|
||||
|
||||
udelay(2);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
value &= ~XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
value &= ~XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
|
||||
set_bit(index, priv->utmi_pad_enabled);
|
||||
mutex_unlock(&padctl->lock);
|
||||
}
|
||||
|
||||
static void tegra210_utmi_pad_power_down(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
struct tegra210_xusb_padctl *priv = to_tegra210_xusb_padctl(padctl);
|
||||
unsigned int index = lane->index;
|
||||
u32 value;
|
||||
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
if (!test_bit(index, priv->utmi_pad_enabled)) {
|
||||
mutex_unlock(&padctl->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
value |= XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
|
||||
udelay(2);
|
||||
|
||||
clear_bit(index, priv->utmi_pad_enabled);
|
||||
|
||||
tegra210_utmi_bias_pad_power_off(padctl, pad);
|
||||
|
||||
mutex_unlock(&padctl->lock);
|
||||
}
|
||||
|
||||
static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
|
||||
bool status)
|
||||
{
|
||||
@@ -2040,13 +2193,11 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane);
|
||||
struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
struct tegra210_xusb_padctl *priv;
|
||||
struct tegra_xusb_usb2_port *port;
|
||||
unsigned int index = lane->index;
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
port = tegra_xusb_find_usb2_port(padctl, index);
|
||||
if (!port) {
|
||||
@@ -2086,21 +2237,6 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
|
||||
}
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) |
|
||||
(XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT));
|
||||
value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT);
|
||||
|
||||
if (tegra_sku_info.revision < TEGRA_REVISION_A02)
|
||||
value |=
|
||||
(XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_VAL <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT);
|
||||
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP);
|
||||
value &= ~XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_MASK(index);
|
||||
if (port->mode == USB_DR_MODE_UNKNOWN)
|
||||
@@ -2114,28 +2250,40 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT) |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI);
|
||||
value |= (priv->fuse.hs_curr_level[index] +
|
||||
usb2->hs_curr_level_offset) <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT;
|
||||
value &= ~XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI;
|
||||
value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_TERM_SEL;
|
||||
value &= ~(XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT);
|
||||
if (usb2->hs_curr_level_offset) {
|
||||
int hs_current_level;
|
||||
|
||||
hs_current_level = (int) priv->fuse.hs_curr_level[index] +
|
||||
usb2->hs_curr_level_offset;
|
||||
|
||||
if (hs_current_level < 0)
|
||||
hs_current_level = 0;
|
||||
if (hs_current_level > 0x3f)
|
||||
hs_current_level = 0x3f;
|
||||
|
||||
value |= (hs_current_level &
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK) <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT;
|
||||
} else {
|
||||
value |= (priv->fuse.hs_curr_level[index] &
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK) <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT;
|
||||
}
|
||||
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) |
|
||||
(XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_MASK <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_SHIFT) |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_OVRD |
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_OVRD);
|
||||
value |= (priv->fuse.hs_term_range_adj <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) |
|
||||
(priv->fuse.rpd_ctrl <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_SHIFT);
|
||||
value &= ~(XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT);
|
||||
value |= (priv->fuse.hs_term_range_adj &
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK) <<
|
||||
XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT;
|
||||
value &= ~RPD_CTRL(~0);
|
||||
value |= RPD_CTRL(priv->fuse.rpd_ctrl);
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
|
||||
|
||||
value = padctl_readl(padctl,
|
||||
@@ -2151,55 +2299,14 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
||||
padctl_writel(padctl, value,
|
||||
XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
|
||||
|
||||
if (pad->enable > 0) {
|
||||
pad->enable++;
|
||||
mutex_unlock(&padctl->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(pad->clk);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) |
|
||||
(XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT));
|
||||
value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) |
|
||||
(XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL <<
|
||||
XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT);
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
|
||||
udelay(1);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
|
||||
udelay(50);
|
||||
|
||||
clk_disable_unprepare(pad->clk);
|
||||
|
||||
pad->enable++;
|
||||
mutex_unlock(&padctl->lock);
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
mutex_unlock(&padctl->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tegra210_usb2_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
struct tegra_xusb_usb2_port *port;
|
||||
u32 value;
|
||||
@@ -2239,17 +2346,6 @@ static int tegra210_usb2_phy_power_off(struct phy *phy)
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP);
|
||||
}
|
||||
|
||||
if (WARN_ON(pad->enable == 0))
|
||||
goto out;
|
||||
|
||||
if (--pad->enable > 0)
|
||||
goto out;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
|
||||
out:
|
||||
mutex_unlock(&padctl->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -3239,6 +3335,8 @@ static int tegra210_utmi_port_reset(struct phy *phy)
|
||||
static int
|
||||
tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse)
|
||||
{
|
||||
struct tegra210_xusb_padctl *priv =
|
||||
container_of(fuse, struct tegra210_xusb_padctl, fuse);
|
||||
unsigned int i;
|
||||
u32 value;
|
||||
int err;
|
||||
@@ -3247,12 +3345,18 @@ tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
dev_info(priv->base.dev, "TEGRA_FUSE_SKU_CALIB_0 = 0x%x\n", value);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fuse->hs_curr_level); i++) {
|
||||
fuse->hs_curr_level[i] =
|
||||
(value >> FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(i)) &
|
||||
FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK;
|
||||
}
|
||||
|
||||
fuse->hs_squelch =
|
||||
(value >> FUSE_SKU_CALIB_HS_SQUELCH_SHIFT)
|
||||
& FUSE_SKU_CALIB_HS_SQUELCH_MASK;
|
||||
|
||||
fuse->hs_term_range_adj =
|
||||
(value >> FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT) &
|
||||
FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK;
|
||||
@@ -3261,6 +3365,8 @@ tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
dev_info(priv->base.dev, "TEGRA_FUSE_USB_CALIB_EXT_0 = 0x%x\n", value);
|
||||
|
||||
fuse->rpd_ctrl =
|
||||
(value >> FUSE_USB_CALIB_EXT_RPD_CTRL_SHIFT) &
|
||||
FUSE_USB_CALIB_EXT_RPD_CTRL_MASK;
|
||||
@@ -3392,6 +3498,8 @@ static const struct tegra_xusb_padctl_ops tegra210_xusb_padctl_ops = {
|
||||
.hsic_set_idle = tegra210_hsic_set_idle,
|
||||
.vbus_override = tegra210_xusb_padctl_vbus_override,
|
||||
.utmi_port_reset = tegra210_utmi_port_reset,
|
||||
.utmi_pad_power_on = tegra210_utmi_pad_power_on,
|
||||
.utmi_pad_power_down = tegra210_utmi_pad_power_down,
|
||||
};
|
||||
|
||||
static const char * const tegra210_xusb_padctl_supply_names[] = {
|
||||
|
||||
Reference in new issue
Block a user