Source
x
static long clk_pllv3_vf610_round_rate(struct clk_hw *hw, unsigned long rate,
/*
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
/**
* struct clk_pllv3 - IMX PLL clock version 3
* @clk_hw: clock source
* @base: base address of PLL registers
* @power_bit: pll power bit mask
* @powerup_set: set power_bit to power up the PLL
* @div_mask: mask of divider bits
* @div_shift: shift of divider bits
*
* IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
* is actually a multiplier, and always sits at bit 0.
*/
struct clk_pllv3 {
struct clk_hw hw;
void __iomem *base;
u32 power_bit;
bool powerup_set;
u32 div_mask;
u32 div_shift;
unsigned long ref_clock;
};
static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
{
unsigned long timeout = jiffies + msecs_to_jiffies(10);
u32 val = readl_relaxed(pll->base) & pll->power_bit;
/* No need to wait for lock when pll is not powered up */
if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
return 0;
/* Wait for PLL to lock */
do {
if (readl_relaxed(pll->base) & BM_PLL_LOCK)
break;
if (time_after(jiffies, timeout))
break;
usleep_range(50, 500);
} while (1);
return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
}
static int clk_pllv3_prepare(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val;
val = readl_relaxed(pll->base);
if (pll->powerup_set)
val |= pll->power_bit;
else
val &= ~pll->power_bit;
writel_relaxed(val, pll->base);
return clk_pllv3_wait_lock(pll);
}
static void clk_pllv3_unprepare(struct clk_hw *hw)