aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYadwinder Singh Brar <yadi.brar@samsung.com>2013-06-11 05:31:07 -0400
committerMike Turquette <mturquette@linaro.org>2013-08-02 16:19:18 -0400
commit07dc76fa61a0e76c759011ae224c882ada18e70c (patch)
tree07f9ab96a77a739f3ae1081933985d9bbea1f2d4
parent079dbead49d6a09e4522ad5cedf1bbebbc5f794b (diff)
clk: samsung: Define a common samsung_clk_register_pll()
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>
-rw-r--r--drivers/clk/samsung/clk-pll.c70
-rw-r--r--drivers/clk/samsung/clk-pll.h7
-rw-r--r--drivers/clk/samsung/clk.h48
3 files changed, 125 insertions, 0 deletions
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index f62f85418488..8e2240a58a07 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -17,6 +17,7 @@ struct samsung_clk_pll {
17 struct clk_hw hw; 17 struct clk_hw hw;
18 void __iomem *lock_reg; 18 void __iomem *lock_reg;
19 void __iomem *con_reg; 19 void __iomem *con_reg;
20 enum samsung_pll_type type;
20}; 21};
21 22
22#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw) 23#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,
412 413
413 return clk; 414 return clk;
414} 415}
416
417static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
418 void __iomem *base)
419{
420 struct samsung_clk_pll *pll;
421 struct clk *clk;
422 struct clk_init_data init;
423 int ret;
424
425 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
426 if (!pll) {
427 pr_err("%s: could not allocate pll clk %s\n",
428 __func__, pll_clk->name);
429 return;
430 }
431
432 init.name = pll_clk->name;
433 init.flags = pll_clk->flags;
434 init.parent_names = &pll_clk->parent_name;
435 init.num_parents = 1;
436
437 switch (pll_clk->type) {
438 /* clk_ops for 35xx and 2550 are similar */
439 case pll_35xx:
440 case pll_2550:
441 init.ops = &samsung_pll35xx_clk_ops;
442 break;
443 /* clk_ops for 36xx and 2650 are similar */
444 case pll_36xx:
445 case pll_2650:
446 init.ops = &samsung_pll36xx_clk_ops;
447 break;
448 default:
449 pr_warn("%s: Unknown pll type for pll clk %s\n",
450 __func__, pll_clk->name);
451 }
452
453 pll->hw.init = &init;
454 pll->type = pll_clk->type;
455 pll->lock_reg = base + pll_clk->lock_offset;
456 pll->con_reg = base + pll_clk->con_offset;
457
458 clk = clk_register(NULL, &pll->hw);
459 if (IS_ERR(clk)) {
460 pr_err("%s: failed to register pll clock %s : %ld\n",
461 __func__, pll_clk->name, PTR_ERR(clk));
462 kfree(pll);
463 return;
464 }
465
466 samsung_clk_add_lookup(clk, pll_clk->id);
467
468 if (!pll_clk->alias)
469 return;
470
471 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
472 if (ret)
473 pr_err("%s: failed to register lookup for %s : %d",
474 __func__, pll_clk->name, ret);
475}
476
477void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
478 unsigned int nr_pll, void __iomem *base)
479{
480 int cnt;
481
482 for (cnt = 0; cnt < nr_pll; cnt++)
483 _samsung_clk_register_pll(&pll_list[cnt], base);
484}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index f33786e9a78b..0d86bf0de40c 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -12,6 +12,13 @@
12#ifndef __SAMSUNG_CLK_PLL_H 12#ifndef __SAMSUNG_CLK_PLL_H
13#define __SAMSUNG_CLK_PLL_H 13#define __SAMSUNG_CLK_PLL_H
14 14
15enum samsung_pll_type {
16 pll_35xx,
17 pll_36xx,
18 pll_2550,
19 pll_2650,
20};
21
15enum pll45xx_type { 22enum pll45xx_type {
16 pll_4500, 23 pll_4500,
17 pll_4502, 24 pll_4502,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 2f7dba20ced8..4e83e521fe7d 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -19,6 +19,7 @@
19#include <linux/clk-provider.h> 19#include <linux/clk-provider.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include "clk-pll.h"
22 23
23/** 24/**
24 * struct samsung_clock_alias: information about mux clock 25 * struct samsung_clock_alias: information about mux clock
@@ -261,6 +262,51 @@ struct samsung_clk_reg_dump {
261 u32 value; 262 u32 value;
262}; 263};
263 264
265/**
266 * struct samsung_pll_clock: information about pll clock
267 * @id: platform specific id of the clock.
268 * @dev_name: name of the device to which this clock belongs.
269 * @name: name of this pll clock.
270 * @parent_name: name of the parent clock.
271 * @flags: optional flags for basic clock.
272 * @con_offset: offset of the register for configuring the PLL.
273 * @lock_offset: offset of the register for locking the PLL.
274 * @type: Type of PLL to be registered.
275 * @alias: optional clock alias name to be assigned to this clock.
276 */
277struct samsung_pll_clock {
278 unsigned int id;
279 const char *dev_name;
280 const char *name;
281 const char *parent_name;
282 unsigned long flags;
283 int con_offset;
284 int lock_offset;
285 enum samsung_pll_type type;
286 const char *alias;
287};
288
289#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
290 { \
291 .id = _id, \
292 .type = _typ, \
293 .dev_name = _dname, \
294 .name = _name, \
295 .parent_name = _pname, \
296 .flags = CLK_GET_RATE_NOCACHE, \
297 .con_offset = _con, \
298 .lock_offset = _lock, \
299 .alias = _alias, \
300 }
301
302#define PLL(_typ, _id, _name, _pname, _lock, _con) \
303 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
304 _lock, _con, NULL)
305
306#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias) \
307 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
308 _lock, _con, _alias)
309
264extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, 310extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
265 unsigned long nr_clks, unsigned long *rdump, 311 unsigned long nr_clks, unsigned long *rdump,
266 unsigned long nr_rdump, unsigned long *soc_rdump, 312 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,
284 unsigned int nr_clk); 330 unsigned int nr_clk);
285extern void __init samsung_clk_register_gate( 331extern void __init samsung_clk_register_gate(
286 struct samsung_gate_clock *clk_list, unsigned int nr_clk); 332 struct samsung_gate_clock *clk_list, unsigned int nr_clk);
333extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
334 unsigned int nr_clk, void __iomem *base);
287 335
288extern unsigned long _get_rate(const char *clk_name); 336extern unsigned long _get_rate(const char *clk_name);
289 337