clk: samsung: Define a common samsung_clk_register_pll()
authorYadwinder Singh Brar <yadi.brar@samsung.com>
Tue, 11 Jun 2013 09:31:07 +0000 (15:01 +0530)
committerMike Turquette <mturquette@linaro.org>
Fri, 2 Aug 2013 20:19:18 +0000 (13:19 -0700)
This patch defines a common samsung_clk_register_pll()
Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same clk ops
implementation, added pll2550 and pll2650 also.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-pll.h
drivers/clk/samsung/clk.h

index f62f854184884ed5b97ea3788ddce98dccf1a382..8e2240a58a07d82424d59711b45438b23d7702d3 100644 (file)
@@ -17,6 +17,7 @@ struct samsung_clk_pll {
        struct clk_hw           hw;
        void __iomem            *lock_reg;
        void __iomem            *con_reg;
+       enum samsung_pll_type   type;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -412,3 +413,72 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 
        return clk;
 }
+
+static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
+                                               void __iomem *base)
+{
+       struct samsung_clk_pll *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+       int ret;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n",
+                       __func__, pll_clk->name);
+               return;
+       }
+
+       init.name = pll_clk->name;
+       init.flags = pll_clk->flags;
+       init.parent_names = &pll_clk->parent_name;
+       init.num_parents = 1;
+
+       switch (pll_clk->type) {
+       /* clk_ops for 35xx and 2550 are similar */
+       case pll_35xx:
+       case pll_2550:
+               init.ops = &samsung_pll35xx_clk_ops;
+               break;
+       /* clk_ops for 36xx and 2650 are similar */
+       case pll_36xx:
+       case pll_2650:
+               init.ops = &samsung_pll36xx_clk_ops;
+               break;
+       default:
+               pr_warn("%s: Unknown pll type for pll clk %s\n",
+                       __func__, pll_clk->name);
+       }
+
+       pll->hw.init = &init;
+       pll->type = pll_clk->type;
+       pll->lock_reg = base + pll_clk->lock_offset;
+       pll->con_reg = base + pll_clk->con_offset;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s : %ld\n",
+                       __func__, pll_clk->name, PTR_ERR(clk));
+               kfree(pll);
+               return;
+       }
+
+       samsung_clk_add_lookup(clk, pll_clk->id);
+
+       if (!pll_clk->alias)
+               return;
+
+       ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
+       if (ret)
+               pr_err("%s: failed to register lookup for %s : %d",
+                       __func__, pll_clk->name, ret);
+}
+
+void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
+                               unsigned int nr_pll, void __iomem *base)
+{
+       int cnt;
+
+       for (cnt = 0; cnt < nr_pll; cnt++)
+               _samsung_clk_register_pll(&pll_list[cnt], base);
+}
index f33786e9a78bea4ba4c247a42edc39ad6fc045b7..0d86bf0de40ca68221a75085fcdaccdfe3592be2 100644 (file)
 #ifndef __SAMSUNG_CLK_PLL_H
 #define __SAMSUNG_CLK_PLL_H
 
+enum samsung_pll_type {
+       pll_35xx,
+       pll_36xx,
+       pll_2550,
+       pll_2650,
+};
+
 enum pll45xx_type {
        pll_4500,
        pll_4502,
index 2f7dba20ced8b9145f261b817be65387f3048662..4e83e521fe7d0370b47f9caf66cc3804d4b93563 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include "clk-pll.h"
 
 /**
  * struct samsung_clock_alias: information about mux clock
@@ -261,6 +262,51 @@ struct samsung_clk_reg_dump {
        u32     value;
 };
 
+/**
+ * struct samsung_pll_clock: information about pll clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this pll clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @con_offset: offset of the register for configuring the PLL.
+ * @lock_offset: offset of the register for locking the PLL.
+ * @type: Type of PLL to be registered.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_pll_clock {
+       unsigned int            id;
+       const char              *dev_name;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       int                     con_offset;
+       int                     lock_offset;
+       enum samsung_pll_type   type;
+       const char              *alias;
+};
+
+#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
+       {                                                               \
+               .id             = _id,                                  \
+               .type           = _typ,                                 \
+               .dev_name       = _dname,                               \
+               .name           = _name,                                \
+               .parent_name    = _pname,                               \
+               .flags          = CLK_GET_RATE_NOCACHE,                 \
+               .con_offset     = _con,                                 \
+               .lock_offset    = _lock,                                \
+               .alias          = _alias,                               \
+       }
+
+#define PLL(_typ, _id, _name, _pname, _lock, _con)                     \
+       __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
+               _lock, _con, NULL)
+
+#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)           \
+       __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
+               _lock, _con, _alias)
+
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
                unsigned long nr_clks, unsigned long *rdump,
                unsigned long nr_rdump, unsigned long *soc_rdump,
@@ -284,6 +330,8 @@ extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
                unsigned int nr_clk);
 extern void __init samsung_clk_register_gate(
                struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
+               unsigned int nr_clk, void __iomem *base);
 
 extern unsigned long _get_rate(const char *clk_name);