Example #1
0
static int omap_usb_dpll_lock(struct omap_usb *phy)
{
	u32			val;
	unsigned long		rate;
	enum sys_clk_rate	clk_index;

	rate		= clk_get_rate(phy->sys_clk);
	clk_index	= __get_sys_clk_index(rate);

	if (clk_index == CLK_RATE_UNDEFINED) {
		pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate);
		return -EINVAL;
	}

	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
	val &= ~PLL_REGN_MASK;
	val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT;
	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);

	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
	val &= ~PLL_SELFREQDCO_MASK;
	val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT;
	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);

	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
	val &= ~PLL_REGM_MASK;
	val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT;
	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);

	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
	val &= ~PLL_REGM_F_MASK;
	val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT;
	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);

	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
	val &= ~PLL_SD_MASK;
	val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT;
	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);

	omap_usb_dpll_relock(phy);

	return 0;
}
Example #2
0
static int omap_usb3_suspend(struct usb_phy *x, int suspend)
{
	struct omap_usb *phy = phy_to_omapusb(x);
	int	val;
	int timeout = PLL_IDLE_TIME;

	if (suspend && !phy->is_suspended) {
		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
		val |= PLL_IDLE;
		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);

		do {
			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
			if (val & PLL_TICOPWDN)
				break;
			udelay(1);
		} while (--timeout);

		omap_control_usb3_phy_power(phy->control_dev, 0);

		phy->is_suspended	= 1;
	} else if (!suspend && phy->is_suspended) {
		phy->is_suspended	= 0;

		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
		val &= ~PLL_IDLE;
		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);

		do {
			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
			if (!(val & PLL_TICOPWDN))
				break;
			udelay(1);
		} while (--timeout);
	}

	return 0;
}
Example #3
0
static void omap_usb_dpll_relock(struct omap_usb *phy)
{
	u32		val;
	unsigned long	timeout;

	omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);

	timeout = jiffies + msecs_to_jiffies(20);
	do {
		val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
		if (val & PLL_LOCK)
			break;
	} while (!WARN_ON(time_after(jiffies, timeout)));
}
Example #4
0
static int omap_usb_init(struct phy *x)
{
	struct omap_usb *phy = phy_get_drvdata(x);
	u32 val;

	if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
		/*
		 *
		 * Reduce the sensitivity of internal PHY by enabling the
		 * DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This
		 * resolves issues with certain devices which can otherwise
		 * be prone to false disconnects.
		 *
		 */
		val = omap_usb_readl(phy->phy_base, USB2PHY_ANA_CONFIG1);
		val |= USB2PHY_DISCON_BYP_LATCH;
		omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val);
	}

	return 0;
}