[ARM] tegra: usb_phy: Add tegra_usb_phy_power_off

Change-Id: If4d66b1a0f1810773b9dc9bcec0e252df947e609
Signed-off-by: Benoit Goby <benoit@android.com>
This commit is contained in:
Benoit Goby
2010-07-21 17:44:44 -07:00
committed by Colin Cross
parent 0b00f73157
commit b2d28cdbf3
2 changed files with 60 additions and 3 deletions

View File

@@ -30,6 +30,8 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs);
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
int tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
int tegra_usb_phy_close(struct tegra_usb_phy *phy);
#endif //__MACH_USB_PHY_H

View File

@@ -29,6 +29,7 @@
#define USB_PORTSC1 0x184
#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
#define USB_PORTSC1_PHCD (1 << 23)
#define USB_SUSP_CTRL 0x400
#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
@@ -240,6 +241,52 @@ void utmi_phy_power_on(struct tegra_usb_phy *phy)
}
}
void utmi_phy_power_off(struct tegra_usb_phy *phy)
{
unsigned long val;
void *base = phy->regs;
if (phy->instance == 0) {
val = readl(base + USB_SUSP_CTRL);
val |= USB_SUSP_SET;
writel(val, base + USB_SUSP_CTRL);
udelay(10);
val = readl(base + USB_SUSP_CTRL);
val &= ~USB_SUSP_SET;
writel(val, base + USB_SUSP_CTRL);
}
if (phy->instance == 2) {
val = readl(base + USB_PORTSC1);
val |= USB_PORTSC1_PHCD;
writel(val, base + USB_PORTSC1);
}
val = readl(base + USB_SUSP_CTRL);
val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV;
writel(val, base + USB_SUSP_CTRL);
val = readl(base + USB_SUSP_CTRL);
val |= UTMIP_RESET;
writel(val, base + USB_SUSP_CTRL);
val = readl(base + UTMIP_BAT_CHRG_CFG0);
val |= UTMIP_PD_CHRG;
writel(val, base + UTMIP_BAT_CHRG_CFG0);
val = readl(base + UTMIP_XCVR_CFG0);
val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
UTMIP_FORCE_PDZI_POWERDOWN;
writel(val, base + UTMIP_XCVR_CFG0);
val = readl(base + UTMIP_XCVR_CFG1);
val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
UTMIP_FORCE_PDDR_POWERDOWN;
writel(val, base + UTMIP_XCVR_CFG1);
}
struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs)
{
struct tegra_usb_phy *phy;
@@ -261,8 +308,6 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs)
goto err0;
}
clk_enable(phy->pll_u);
parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
for (freq_sel = 0; freq_sel < ARRAY_SIZE(udc_freq_table); freq_sel++) {
if (udc_freq_table[freq_sel] == parent_rate)
@@ -291,15 +336,25 @@ err0:
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
{
/* TODO usb2 ulpi */
clk_enable(phy->pll_u);
if (phy->instance != 1)
utmi_phy_power_on(phy);
return 0;
}
int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
{
/* TODO usb2 ulpi */
if (phy->instance != 1)
utmi_phy_power_off(phy);
clk_disable(phy->pll_u);
return 0;
}
int tegra_usb_phy_close(struct tegra_usb_phy *phy)
{
clk_disable(phy->pll_u);
clk_put(phy->pll_u);
kfree(phy);
return 0;