[PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553
Mike Turquette
mturquette at linaro.org
Tue Jun 11 22:53:05 EDT 2013
Quoting Tomasz Figa (2013-06-05 16:57:25)
> This patch adds support for PLL6552 and PLL6553 PLLs present on Samsung
> S3C64xx SoCs.
>
> Signed-off-by: Tomasz Figa <tomasz.figa at gmail.com>
Acked-by: Mike Turquette <mturquette at linaro.org>
or I can take it into clk-next.
> ---
> drivers/clk/samsung/clk-pll.c | 160 ++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk-pll.h | 4 ++
> 2 files changed, 164 insertions(+)
>
> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index 89135f6..cef0bb9 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -336,6 +336,166 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
> }
>
> /*
> + * PLL6552 Clock Type
> + */
> +
> +#define PLL6552_LOCK_REG 0x00
> +#define PLL6552_CON_REG 0x0c
> +
> +#define PLL6552_MDIV_MASK 0x3ff
> +#define PLL6552_PDIV_MASK 0x3f
> +#define PLL6552_SDIV_MASK 0x7
> +#define PLL6552_MDIV_SHIFT 16
> +#define PLL6552_PDIV_SHIFT 8
> +#define PLL6552_SDIV_SHIFT 0
> +
> +struct samsung_clk_pll6552 {
> + struct clk_hw hw;
> + void __iomem *reg_base;
> +};
> +
> +#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
> +
> +static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
> + u32 mdiv, pdiv, sdiv, pll_con;
> + u64 fvco = parent_rate;
> +
> + pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
> + mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
> + pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
> + sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
> +
> + fvco *= mdiv;
> + do_div(fvco, (pdiv << sdiv));
> +
> + return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll6552_clk_ops = {
> + .recalc_rate = samsung_pll6552_recalc_rate,
> +};
> +
> +struct clk * __init samsung_clk_register_pll6552(const char *name,
> + const char *pname, void __iomem *base)
> +{
> + struct samsung_clk_pll6552 *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll) {
> + pr_err("%s: could not allocate pll clk %s\n", __func__, name);
> + return NULL;
> + }
> +
> + init.name = name;
> + init.ops = &samsung_pll6552_clk_ops;
> + init.parent_names = &pname;
> + init.num_parents = 1;
> +
> + pll->hw.init = &init;
> + pll->reg_base = base;
> +
> + clk = clk_register(NULL, &pll->hw);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register pll clock %s\n", __func__,
> + name);
> + kfree(pll);
> + }
> +
> + if (clk_register_clkdev(clk, name, NULL))
> + pr_err("%s: failed to register lookup for %s", __func__, name);
> +
> + return clk;
> +}
> +
> +/*
> + * PLL6553 Clock Type
> + */
> +
> +#define PLL6553_LOCK_REG 0x00
> +#define PLL6553_CON0_REG 0x0c
> +#define PLL6553_CON1_REG 0x10
> +
> +#define PLL6553_MDIV_MASK 0xff
> +#define PLL6553_PDIV_MASK 0x3f
> +#define PLL6553_SDIV_MASK 0x7
> +#define PLL6553_KDIV_MASK 0xffff
> +#define PLL6553_MDIV_SHIFT 16
> +#define PLL6553_PDIV_SHIFT 8
> +#define PLL6553_SDIV_SHIFT 0
> +#define PLL6553_KDIV_SHIFT 0
> +
> +struct samsung_clk_pll6553 {
> + struct clk_hw hw;
> + void __iomem *reg_base;
> +};
> +
> +#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
> +
> +static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
> + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
> + u64 fvco = parent_rate;
> +
> + pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
> + pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
> + mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
> + pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
> + sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
> + kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
> +
> + fvco *= (mdiv << 16) + kdiv;
> + do_div(fvco, (pdiv << sdiv));
> + fvco >>= 16;
> +
> + return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll6553_clk_ops = {
> + .recalc_rate = samsung_pll6553_recalc_rate,
> +};
> +
> +struct clk * __init samsung_clk_register_pll6553(const char *name,
> + const char *pname, void __iomem *base)
> +{
> + struct samsung_clk_pll6553 *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll) {
> + pr_err("%s: could not allocate pll clk %s\n", __func__, name);
> + return NULL;
> + }
> +
> + init.name = name;
> + init.ops = &samsung_pll6553_clk_ops;
> + init.parent_names = &pname;
> + init.num_parents = 1;
> +
> + pll->hw.init = &init;
> + pll->reg_base = base;
> +
> + clk = clk_register(NULL, &pll->hw);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register pll clock %s\n", __func__,
> + name);
> + kfree(pll);
> + }
> +
> + if (clk_register_clkdev(clk, name, NULL))
> + pr_err("%s: failed to register lookup for %s", __func__, name);
> +
> + return clk;
> +}
> +
> +/*
> * PLL2550x Clock Type
> */
>
> diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
> index f33786e..1d68a68 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -34,6 +34,10 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
> extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
> const char *pname, const void __iomem *con_reg,
> enum pll46xx_type type);
> +extern struct clk *samsung_clk_register_pll6552(const char *name,
> + const char *pname, void __iomem *base);
> +extern struct clk *samsung_clk_register_pll6553(const char *name,
> + const char *pname, void __iomem *base);
> extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
> const char *pname, const void __iomem *reg_base,
> const unsigned long offset);
> --
> 1.8.2.1
More information about the linux-arm-kernel
mailing list