diff options
author | Yadwinder Singh Brar <yadi.brar@samsung.com> | 2013-06-11 05:31:07 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-08-02 16:19:18 -0400 |
commit | 07dc76fa61a0e76c759011ae224c882ada18e70c (patch) | |
tree | 07f9ab96a77a739f3ae1081933985d9bbea1f2d4 | |
parent | 079dbead49d6a09e4522ad5cedf1bbebbc5f794b (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.c | 70 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-pll.h | 7 | ||||
-rw-r--r-- | drivers/clk/samsung/clk.h | 48 |
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 | |||
417 | static 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 | |||
477 | void __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 | ||
15 | enum samsung_pll_type { | ||
16 | pll_35xx, | ||
17 | pll_36xx, | ||
18 | pll_2550, | ||
19 | pll_2650, | ||
20 | }; | ||
21 | |||
15 | enum pll45xx_type { | 22 | enum 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 | */ | ||
277 | struct 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 | |||
264 | extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, | 310 | extern 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); |
285 | extern void __init samsung_clk_register_gate( | 331 | extern 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); |
333 | extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, | ||
334 | unsigned int nr_clk, void __iomem *base); | ||
287 | 335 | ||
288 | extern unsigned long _get_rate(const char *clk_name); | 336 | extern unsigned long _get_rate(const char *clk_name); |
289 | 337 | ||