diff options
author | Tomasz Figa <t.figa@samsung.com> | 2013-12-24 11:32:53 +0100 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-18 12:00:08 +0900 |
commit | 6d8bf4a1b0c69a68c905bb8617c9b73e0ea49079 (patch) | |
tree | b72ce66936f57e634c473d7e150f5f7463d70181 /drivers/clk | |
parent | b9b83d24d606725c18e60e6186615c1039d309bd (diff) | |
download | linux-3.10-6d8bf4a1b0c69a68c905bb8617c9b73e0ea49079.tar.gz linux-3.10-6d8bf4a1b0c69a68c905bb8617c9b73e0ea49079.tar.bz2 linux-3.10-6d8bf4a1b0c69a68c905bb8617c9b73e0ea49079.zip |
clk: samsung: pll: Add support for PLL4600x used on Exynos3250
This PLL differs from 46xx only by offsets of registers, so operations
are reused, just modified to account for this minor difference.
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/samsung/clk-pll.c | 28 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-pll.h | 1 |
2 files changed, 21 insertions, 8 deletions
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 170d6ca34c5..7989c27cddf 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -580,6 +580,8 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name, #define PLL46XX_PLL_LOCK 0x0 #define PLL46XX_PLL_CON0 0x100 #define PLL46XX_PLL_CON1 0x104 +#define PLL4600X_PLL_CON0 0x4 +#define PLL4600X_PLL_CON1 0x8 #define PLL46XX_PLL_LOCK_CONST 3000 #define PLL46XX_PLL_CON0_LOCKED (1 << 29) @@ -589,6 +591,8 @@ struct samsung_clk_pll46xx { enum pll46xx_type type; void __iomem *base; struct pll_pms *pms; + unsigned int con0_offset; + unsigned int con1_offset; }; #define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw) @@ -596,7 +600,7 @@ struct samsung_clk_pll46xx { static inline unsigned long samsung_pll46xx_calc_f_out(u64 f_in, u32 p, u32 m, u32 s, u32 k, enum pll46xx_type type) { - u8 shift = (type == pll_4600) ? 16 : 10; + u8 shift = (type == pll_4600 || type == pll_4600x) ? 16 : 10; f_in *= (m << shift) + k; do_div(f_in, (p << s)); @@ -610,8 +614,8 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw); u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; - pll_con0 = __raw_readl(pll->base + PLL46XX_PLL_CON0); - pll_con1 = __raw_readl(pll->base + PLL46XX_PLL_CON1); + pll_con0 = __raw_readl(pll->base + pll->con0_offset); + pll_con1 = __raw_readl(pll->base + pll->con1_offset); mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; @@ -663,28 +667,28 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, pll->base + PLL46XX_PLL_LOCK); /* Change PLL divisors */ - tmp = __raw_readl(pll->base + PLL46XX_PLL_CON0); + tmp = __raw_readl(pll->base + pll->con0_offset); tmp &= ~((PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | (PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT)); tmp |= (pms[index].p << PLL46XX_PDIV_SHIFT) | (pms[index].m << PLL46XX_MDIV_SHIFT) | (pms[index].s << PLL46XX_SDIV_SHIFT); - __raw_writel(tmp, pll->base + PLL46XX_PLL_CON0); + __raw_writel(tmp, pll->base + pll->con0_offset); - tmp = __raw_readl(pll->base + PLL46XX_PLL_CON1); + tmp = __raw_readl(pll->base + pll->con1_offset); tmp &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) | (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) | (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT)); tmp |= (pms[index].k << PLL46XX_KDIV_SHIFT) | (pms[index].mrr << PLL46XX_MRR_SHIFT) | (pms[index].mfr << PLL46XX_MFR_SHIFT); - __raw_writel(tmp, pll->base + PLL46XX_PLL_CON1); + __raw_writel(tmp, pll->base + pll->con1_offset); /* Wait for locking */ do { cpu_relax(); - tmp = __raw_readl(pll->base + PLL46XX_PLL_CON0); + tmp = __raw_readl(pll->base + pll->con0_offset); } while (!(tmp & PLL46XX_PLL_CON0_LOCKED)); return 0; @@ -724,6 +728,14 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name, pll->type = type; pll->pms = pms; + if (type == pll_4600x) { + pll->con0_offset = PLL4600X_PLL_CON0; + pll->con1_offset = PLL4600X_PLL_CON1; + } else { + pll->con0_offset = PLL46XX_PLL_CON0; + pll->con1_offset = PLL46XX_PLL_CON1; + } + clk = clk_register(NULL, &pll->hw); if (IS_ERR(clk)) { pr_err("%s: failed to register pll clock %s\n", __func__, diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index c00c2bdb885..5b1bb240893 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -20,6 +20,7 @@ enum pll45xx_type { enum pll46xx_type { pll_4600, + pll_4600x, /* For exynos3250 EPLL */ pll_4650, pll_4650c, }; |