#define LINESTATE_DP BIT(0)
#define LINESTATE_DM BIT(1)
+#define QUSB2PHY_PLL_ANALOG_CONTROLS_ONE 0x0
+
unsigned int phy_tune2;
module_param(phy_tune2, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(phy_tune2, "QUSB PHY v2 TUNE2");
struct usb_phy phy;
void __iomem *base;
void __iomem *tune2_efuse_reg;
+ void __iomem *tcsr_clamp_dig_n;
struct clk *ref_clk_src;
struct clk *ref_clk;
/* Bus suspend case */
if (qphy->cable_connected ||
(qphy->phy.flags & PHY_HOST_MODE)) {
+
+ /* enable clock bypass */
+ writel_relaxed(0x90,
+ qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
+
/* Disable all interrupts */
writel_relaxed(0x00,
qphy->base + QUSB2PHY_INTR_CTRL);
wmb();
qusb_phy_enable_clocks(qphy, false);
} else { /* Cable disconnect case */
- /* Disable all interrupts */
- writel_relaxed(0x00,
- qphy->base + QUSB2PHY_INTR_CTRL);
- /* Put PHY into non-driving mode */
- writel_relaxed(0x23,
- qphy->base + QUSB2PHY_PWR_CTRL1);
+ clk_reset(qphy->phy_reset, CLK_RESET_ASSERT);
+ usleep_range(100, 150);
+ clk_reset(qphy->phy_reset, CLK_RESET_DEASSERT);
- /* Makes sure that above write goes through */
+ /* enable clock bypass */
+ writel_relaxed(0x90,
+ qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
+
+ writel_relaxed(0x0, qphy->tcsr_clamp_dig_n);
+ /*
+ * clamp needs asserted before
+ * power/clocks can be turned off
+ */
wmb();
qusb_phy_enable_clocks(qphy, false);
if (qphy->cable_connected ||
(qphy->phy.flags & PHY_HOST_MODE)) {
qusb_phy_enable_clocks(qphy, true);
+
+ /* disable clock bypass */
+ writel_relaxed(0x80,
+ qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_ONE);
+
/* Clear all interrupts on resume */
writel_relaxed(0x00,
qphy->base + QUSB2PHY_INTR_CTRL);
/* Makes sure that above write goes through */
wmb();
} else { /* Cable connect case */
+ writel_relaxed(0x1, qphy->tcsr_clamp_dig_n);
+
+ /*
+ * clamp needs de-asserted before
+ * power/clocks can be turned on
+ */
+ wmb();
+
+ clk_reset(qphy->phy_reset, CLK_RESET_DEASSERT);
+
qusb_phy_enable_power(qphy, true, true);
qusb_phy_enable_clocks(qphy, true);
}
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "tcsr_clamp_dig_n_1p8");
+ if (res) {
+ qphy->tcsr_clamp_dig_n = devm_ioremap_resource(dev, res);
+ if (IS_ERR(qphy->tcsr_clamp_dig_n)) {
+ dev_dbg(dev, "couldn't ioremap tcsr_clamp_dig_n\n");
+ return PTR_ERR(qphy->tcsr_clamp_dig_n);
+ }
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"tune2_efuse_addr");
if (res) {
qphy->tune2_efuse_reg = devm_ioremap_nocache(dev, res->start,