static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode) { struct tusb1210 *tusb = phy_get_drvdata(phy); int ret; ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL); if (ret < 0) return ret; switch (mode) { case PHY_MODE_USB_HOST: ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT | ULPI_OTG_CTRL_ID_PULLUP | ULPI_OTG_CTRL_DP_PULLDOWN | ULPI_OTG_CTRL_DM_PULLDOWN); ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); ret |= ULPI_OTG_CTRL_DRVVBUS; break; case PHY_MODE_USB_DEVICE: ret &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DP_PULLDOWN | ULPI_OTG_CTRL_DM_PULLDOWN); ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT; break; default: /* nothing */ return 0; } return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); }
static int mv_hsic_phy_init(struct phy *phy) { struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); struct platform_device *pdev = mv_phy->pdev; void __iomem *base = mv_phy->base; clk_prepare_enable(mv_phy->clk); /* Set reference clock */ writel(0x1 << PHY_28NM_HSIC_PLL_SELLPFR_SHIFT | 0xf0 << PHY_28NM_HSIC_PLL_FBDIV_SHIFT | 0xd << PHY_28NM_HSIC_PLL_REFDIV_SHIFT, base + PHY_28NM_HSIC_PLL_CTRL01); /* Turn on PLL */ writel(readl(base + PHY_28NM_HSIC_PLL_CTRL2) | PHY_28NM_HSIC_S2H_PU_PLL, base + PHY_28NM_HSIC_PLL_CTRL2); /* Make sure PHY PLL is locked */ if (!wait_for_reg(base + PHY_28NM_HSIC_PLL_CTRL2, PHY_28NM_HSIC_H2S_PLL_LOCK, HZ / 10)) { dev_err(&pdev->dev, "HSIC PHY PLL not locked after 100mS."); clk_disable_unprepare(mv_phy->clk); return -ETIMEDOUT; } return 0; }
static int ti_pipe3_exit(struct phy *x) { struct ti_pipe3 *phy = phy_get_drvdata(x); u32 val; unsigned long timeout; /* SATA DPLL can't be powered down due to Errata i783 and PCIe * does not have internal DPLL */ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") || of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) return 0; /* Put DPLL in IDLE mode */ val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); val |= PLL_IDLE; ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); /* wait for LDO and Oscillator to power down */ timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME); do { cpu_relax(); val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) break; } while (!time_after(jiffies, timeout)); if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n", val); return -EBUSY; } return 0; }
static int ti_pipe3_init(struct phy *x) { struct ti_pipe3 *phy = phy_get_drvdata(x); u32 val; int ret = 0; /* * Set pcie_pcs register to 0x96 for proper functioning of phy * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table * 18-1804. */ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { omap_control_pcie_pcs(phy->control_dev, 0x96); return 0; } /* Bring it out of IDLE if it is IDLE */ val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); if (val & PLL_IDLE) { val &= ~PLL_IDLE; ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); ret = ti_pipe3_dpll_wait_lock(phy); } /* Program the DPLL only if not locked */ val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); if (!(val & PLL_LOCK)) if (ti_pipe3_dpll_program(phy)) return -EINVAL; return ret; }
static int pcie_phy_power_on(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); int err; u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); err = wait_on_timeout(50 * MSECOND, padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1) & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET); return err; }
static int phy_berlin_usb_power_on(struct phy *phy) { struct phy_berlin_usb_priv *priv = phy_get_drvdata(phy); reset_control_reset(priv->rst_ctrl); writel(priv->pll_divider, priv->base + USB_PHY_PLL); writel(CLK_STABLE | PLL_CTRL_REG | PHASE_OFF_TOL_250 | KVC0_REG_CTRL | CLK_BLK_EN, priv->base + USB_PHY_PLL_CONTROL); writel(V2I_VCO_RATIO(0x5) | R_ROTATE_0 | ANA_TEST_DC_CTRL(0x5), priv->base + USB_PHY_ANALOG); writel(PHASE_FREEZE_DLY_4_CL | ACK_LENGTH_16_CL | SQ_LENGTH_12 | DISCON_THRESHOLD_260 | SQ_THRESHOLD(0xa) | LPF_COEF(0x2) | INTPL_CUR_30, priv->base + USB_PHY_RX_CTRL); writel(TX_VDD12_13 | TX_OUT_AMP(0x3), priv->base + USB_PHY_TX_CTRL1); writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4), priv->base + USB_PHY_TX_CTRL0); writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4) | EXT_FS_RCAL_DIV(0x2), priv->base + USB_PHY_TX_CTRL0); writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4), priv->base + USB_PHY_TX_CTRL0); writel(TX_CHAN_CTRL_REG(0xf) | DRV_SLEWRATE(0x3) | IMP_CAL_FS_HS_DLY_3 | FS_DRV_EN_MASK(0xd), priv->base + USB_PHY_TX_CTRL2); return 0; }
static int sata_phy_power_on(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); int err; u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); err = wait_on_timeout(50 * MSECOND, padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1) & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET); return err; }
static int samsung_usb2_phy_power_on(struct phy *phy) { struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); struct samsung_usb2_phy_driver *drv = inst->drv; int ret; dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", inst->cfg->label); ret = clk_prepare_enable(drv->clk); if (ret) goto err_main_clk; ret = clk_prepare_enable(drv->ref_clk); if (ret) goto err_instance_clk; if (inst->cfg->power_on) { spin_lock(&drv->lock); ret = inst->cfg->power_on(inst); spin_unlock(&drv->lock); } return 0; err_instance_clk: clk_disable_unprepare(drv->clk); err_main_clk: return ret; }
static int exynos_mipi_video_phy_power_on(struct phy *phy) { struct video_phy_desc *phy_desc = phy_get_drvdata(phy); struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc); return __set_phy_state(state, phy_desc->index, 1); }
static int sata_phy_power_off(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); return 0; }
static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy) { struct ufs_qcom_phy_qmp_20nm *phy = phy_get_drvdata(generic_phy); struct ufs_qcom_phy *phy_common = &phy->common_cfg; int err = 0; err = ufs_qcom_phy_init_clks(generic_phy, phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n", __func__, err); goto out; } err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n", __func__, err); goto out; } ufs_qcom_phy_qmp_20nm_advertise_quirks(phy_common); out: return err; }
static int rockchip_set_phy_state(struct phy *phy, bool enable) { struct rockchip_dp_phy *dp = phy_get_drvdata(phy); int ret; if (enable) { ret = regmap_write(dp->grf, GRF_SOC_CON12, GRF_EDP_PHY_SIDDQ_HIWORD_MASK | GRF_EDP_PHY_SIDDQ_ON); if (ret < 0) { dev_err(dp->dev, "Can't enable PHY power %d\n", ret); return ret; } ret = clk_prepare_enable(dp->phy_24m); } else { clk_disable_unprepare(dp->phy_24m); ret = regmap_write(dp->grf, GRF_SOC_CON12, GRF_EDP_PHY_SIDDQ_HIWORD_MASK | GRF_EDP_PHY_SIDDQ_OFF); } return ret; }
static int uniphier_pciephy_init(struct phy *phy) { struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy); int ret; ret = clk_prepare_enable(priv->clk); if (ret) return ret; ret = reset_control_deassert(priv->rst); if (ret) goto out_clk_disable; uniphier_pciephy_set_param(priv, PCL_PHY_R00, RX_EQ_ADJ_EN, RX_EQ_ADJ_EN); uniphier_pciephy_set_param(priv, PCL_PHY_R06, RX_EQ_ADJ, FIELD_PREP(RX_EQ_ADJ, RX_EQ_ADJ_VAL)); uniphier_pciephy_set_param(priv, PCL_PHY_R26, VCO_CTRL, FIELD_PREP(VCO_CTRL, VCO_CTRL_INIT_VAL)); usleep_range(1, 10); uniphier_pciephy_deassert(priv); usleep_range(1, 10); return 0; out_clk_disable: clk_disable_unprepare(priv->clk); return ret; }
int xpsgtr_wait_pll_lock(struct phy *phy) { struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy); struct xpsgtr_dev *gtr_dev = gtr_phy->data; u32 offset, reg; u32 timeout = 1000; int ret = 0; /* Check pll is locked */ offset = gtr_phy->lane * PLL_STATUS_READ_OFFSET + L0_PLL_STATUS_READ_1; dev_dbg(gtr_dev->dev, "Waiting for PLL lock...\n"); do { reg = readl(gtr_dev->serdes + offset); if ((reg & PLL_STATUS_LOCKED) == PLL_STATUS_LOCKED) break; if (!--timeout) { dev_err(gtr_dev->dev, "PLL lock time out\n"); ret = -ETIMEDOUT; break; } udelay(1); } while (1); if (ret == 0) gtr_phy->pll_lock = true; dev_info(gtr_dev->dev, "Lane:%d type:%d protocol:%d pll_locked:%s\n", gtr_phy->lane, gtr_phy->type, gtr_phy->protocol, gtr_phy->pll_lock ? "yes" : "no"); return ret; }
static int exynos5440_pcie_phy_power_off(struct phy *phy) { struct exynos_pcie_phy *ep = phy_get_drvdata(phy); u32 val; if (readl_poll_timeout(ep->phy_base + PCIE_PHY_PLL_LOCKED, val, (val != 0), 1, 500)) { dev_err(&phy->dev, "PLL Locked: 0x%x\n", val); return -ETIMEDOUT; } val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); val |= PCIE_PHY_COMMON_PD_CMN; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); val |= PCIE_PHY_TRSV0_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); val |= PCIE_PHY_TRSV1_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); val |= PCIE_PHY_TRSV2_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); val |= PCIE_PHY_TRSV3_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); return 0; }
static int exynos5440_pcie_phy_power_on(struct phy *phy) { struct exynos_pcie_phy *ep = phy_get_drvdata(phy); u32 val; exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET); exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_CMN_REG); exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSVREG_RESET); exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSV_RESET); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); val &= ~PCIE_PHY_COMMON_PD_CMN; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); val &= ~PCIE_PHY_TRSV0_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); val &= ~PCIE_PHY_TRSV1_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); val &= ~PCIE_PHY_TRSV2_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); val &= ~PCIE_PHY_TRSV3_PD_TSV; exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); return 0; }
static int rcar_gen3_phy_usb2_exit(struct phy *p) { struct rcar_gen3_chan *channel = phy_get_drvdata(p); writel(0, channel->base + USB2_INT_ENABLE); return 0; }
static int lpc18xx_usb_otg_phy_exit(struct phy *phy) { struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy); clk_unprepare(lpc->clk); return 0; }
static int omap_usb_power_on(struct phy *x) { struct omap_usb *phy = phy_get_drvdata(x); omap_control_phy_power(phy->control_dev, 1); return 0; }
static int exynos_dp_video_phy_power_off(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); /* Enable power isolation on DP-PHY */ return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, EXYNOS5_PHY_ENABLE, 0); }
static int exynos_sata_phy_power_off(struct phy *phy) { struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, EXYNOS5_SATAPHY_PMU_ENABLE, false); }
static int bcm_kona_usb_phy_power_off(struct phy *gphy) { struct bcm_kona_usb *phy = phy_get_drvdata(gphy); bcm_kona_usb_phy_power(phy, 0); return 0; }
static int ti_pipe3_power_on(struct phy *x) { struct ti_pipe3 *phy = phy_get_drvdata(x); omap_control_phy_power(phy->control_dev, 1); return 0; }
static int exynos_dp_video_phy_power_off(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); /* Enable power isolation on DP-PHY */ exynos_dp_video_phy_pwr_isol(state, 1); return 0; }
static int stm32_usbphyc_phy_exit(struct phy *phy) { struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy); struct stm32_usbphyc *usbphyc = usbphyc_phy->usbphyc; usbphyc_phy->active = false; return stm32_usbphyc_pll_disable(usbphyc); }
static int tusb1210_power_off(struct phy *phy) { struct tusb1210 *tusb = phy_get_drvdata(phy); gpiod_set_value_cansleep(tusb->gpio_reset, 0); gpiod_set_value_cansleep(tusb->gpio_cs, 0); return 0; }
static int mtk_hdmi_phy_power_off(struct phy *phy) { struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); mtk_hdmi_phy_disable_tmds(hdmi_phy); clk_disable_unprepare(hdmi_phy->pll); return 0; }
static int spear1310_miphy_exit(struct phy *phy) { struct spear1310_miphy_priv *priv = phy_get_drvdata(phy); int ret = 0; if (priv->mode == PCIE) ret = spear1310_miphy_pcie_exit(priv); return ret; }
static int mv_hsic_phy_power_off(struct phy *phy) { struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); void __iomem *base = mv_phy->base; writel(readl(base + PHY_28NM_HSIC_CTRL) & ~PHY_28NM_HSIC_S2H_HSIC_EN, base + PHY_28NM_HSIC_CTRL); return 0; }
static int da8xx_usb11_phy_power_off(struct phy *phy) { struct da8xx_usb_phy *d_phy = phy_get_drvdata(phy); regmap_write_bits(d_phy->regmap, CFGCHIP(2), CFGCHIP2_USB1SUSPENDM, 0); clk_disable_unprepare(d_phy->usb11_clk); return 0; }