aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/at91/clk-programmable.c4
-rw-r--r--drivers/clk/bcm/clk-kona.c4
-rw-r--r--drivers/clk/clk-composite.c9
-rw-r--r--drivers/clk/clk-mux.c2
-rw-r--r--drivers/clk/clk-s2mps11.c2
-rw-r--r--drivers/clk/clk.c42
-rw-r--r--drivers/clk/hisilicon/clk-hi3620.c72
-rw-r--r--drivers/clk/mmp/Makefile7
-rw-r--r--drivers/clk/mmp/clk-frac.c74
-rw-r--r--drivers/clk/mmp/clk-gate.c133
-rw-r--r--drivers/clk/mmp/clk-mix.c513
-rw-r--r--drivers/clk/mmp/clk-mmp2.c6
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c334
-rw-r--r--drivers/clk/mmp/clk-of-pxa168.c279
-rw-r--r--drivers/clk/mmp/clk-of-pxa910.c301
-rw-r--r--drivers/clk/mmp/clk-pxa168.c6
-rw-r--r--drivers/clk/mmp/clk-pxa910.c6
-rw-r--r--drivers/clk/mmp/clk.c192
-rw-r--r--drivers/clk/mmp/clk.h226
-rw-r--r--drivers/clk/mmp/reset.c99
-rw-r--r--drivers/clk/mmp/reset.h31
-rw-r--r--drivers/clk/pxa/Makefile1
-rw-r--r--drivers/clk/pxa/clk-pxa.c45
-rw-r--r--drivers/clk/pxa/clk-pxa.h9
-rw-r--r--drivers/clk/pxa/clk-pxa25x.c273
-rw-r--r--drivers/clk/pxa/clk-pxa27x.c9
-rw-r--r--drivers/clk/qcom/clk-pll.c2
-rw-r--r--drivers/clk/qcom/clk-rcg.c20
-rw-r--r--drivers/clk/qcom/clk-rcg2.c28
-rw-r--r--drivers/clk/rockchip/Makefile1
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c154
-rw-r--r--drivers/clk/rockchip/clk-pll.c81
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c79
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c246
-rw-r--r--drivers/clk/rockchip/clk.c20
-rw-r--r--drivers/clk/rockchip/clk.h45
-rw-r--r--drivers/clk/samsung/Makefile2
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c33
-rw-r--r--drivers/clk/samsung/clk-exynos4.c2
-rw-r--r--drivers/clk/samsung/clk-exynos4415.c1144
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c185
-rw-r--r--drivers/clk/samsung/clk-exynos7.c743
-rw-r--r--drivers/clk/samsung/clk-pll.c25
-rw-r--r--drivers/clk/samsung/clk-pll.h4
-rw-r--r--drivers/clk/samsung/clk.c102
-rw-r--r--drivers/clk/samsung/clk.h43
-rw-r--r--drivers/clk/shmobile/clk-div6.c113
-rw-r--r--drivers/clk/sunxi/Makefile1
-rw-r--r--drivers/clk/sunxi/clk-a20-gmac.c7
-rw-r--r--drivers/clk/sunxi/clk-factors.c6
-rw-r--r--drivers/clk/sunxi/clk-factors.h3
-rw-r--r--drivers/clk/sunxi/clk-mod0.c1
-rw-r--r--drivers/clk/sunxi/clk-sun6i-ar100.c4
-rw-r--r--drivers/clk/sunxi/clk-sun8i-mbus.c1
-rw-r--r--drivers/clk/sunxi/clk-sun9i-core.c271
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c85
56 files changed, 5611 insertions, 519 deletions
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 62e2509f9df1..bbdb1b985c91 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -57,7 +57,7 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
57static long clk_programmable_determine_rate(struct clk_hw *hw, 57static long clk_programmable_determine_rate(struct clk_hw *hw,
58 unsigned long rate, 58 unsigned long rate,
59 unsigned long *best_parent_rate, 59 unsigned long *best_parent_rate,
60 struct clk **best_parent_clk) 60 struct clk_hw **best_parent_hw)
61{ 61{
62 struct clk *parent = NULL; 62 struct clk *parent = NULL;
63 long best_rate = -EINVAL; 63 long best_rate = -EINVAL;
@@ -84,7 +84,7 @@ static long clk_programmable_determine_rate(struct clk_hw *hw,
84 if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) { 84 if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) {
85 best_rate = tmp_rate; 85 best_rate = tmp_rate;
86 *best_parent_rate = parent_rate; 86 *best_parent_rate = parent_rate;
87 *best_parent_clk = parent; 87 *best_parent_hw = __clk_get_hw(parent);
88 } 88 }
89 89
90 if (!best_rate) 90 if (!best_rate)
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
index 95af2e665dd3..1c06f6f3a8c5 100644
--- a/drivers/clk/bcm/clk-kona.c
+++ b/drivers/clk/bcm/clk-kona.c
@@ -1032,7 +1032,7 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1032} 1032}
1033 1033
1034static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate, 1034static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
1035 unsigned long *best_parent_rate, struct clk **best_parent) 1035 unsigned long *best_parent_rate, struct clk_hw **best_parent)
1036{ 1036{
1037 struct kona_clk *bcm_clk = to_kona_clk(hw); 1037 struct kona_clk *bcm_clk = to_kona_clk(hw);
1038 struct clk *clk = hw->clk; 1038 struct clk *clk = hw->clk;
@@ -1075,7 +1075,7 @@ static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
1075 if (delta < best_delta) { 1075 if (delta < best_delta) {
1076 best_delta = delta; 1076 best_delta = delta;
1077 best_rate = other_rate; 1077 best_rate = other_rate;
1078 *best_parent = parent; 1078 *best_parent = __clk_get_hw(parent);
1079 *best_parent_rate = parent_rate; 1079 *best_parent_rate = parent_rate;
1080 } 1080 }
1081 } 1081 }
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index b9355daf8065..4386697236a7 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -57,7 +57,7 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
57 57
58static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, 58static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long *best_parent_rate, 59 unsigned long *best_parent_rate,
60 struct clk **best_parent_p) 60 struct clk_hw **best_parent_p)
61{ 61{
62 struct clk_composite *composite = to_clk_composite(hw); 62 struct clk_composite *composite = to_clk_composite(hw);
63 const struct clk_ops *rate_ops = composite->rate_ops; 63 const struct clk_ops *rate_ops = composite->rate_ops;
@@ -80,8 +80,9 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
80 *best_parent_p = NULL; 80 *best_parent_p = NULL;
81 81
82 if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) { 82 if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
83 *best_parent_p = clk_get_parent(mux_hw->clk); 83 parent = clk_get_parent(mux_hw->clk);
84 *best_parent_rate = __clk_get_rate(*best_parent_p); 84 *best_parent_p = __clk_get_hw(parent);
85 *best_parent_rate = __clk_get_rate(parent);
85 86
86 return rate_ops->round_rate(rate_hw, rate, 87 return rate_ops->round_rate(rate_hw, rate,
87 best_parent_rate); 88 best_parent_rate);
@@ -103,7 +104,7 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
103 104
104 if (!rate_diff || !*best_parent_p 105 if (!rate_diff || !*best_parent_p
105 || best_rate_diff > rate_diff) { 106 || best_rate_diff > rate_diff) {
106 *best_parent_p = parent; 107 *best_parent_p = __clk_get_hw(parent);
107 *best_parent_rate = parent_rate; 108 *best_parent_rate = parent_rate;
108 best_rate_diff = rate_diff; 109 best_rate_diff = rate_diff;
109 best_rate = tmp_rate; 110 best_rate = tmp_rate;
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 4f96ff3ba728..6e1ecf94bf58 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
77 77
78 else { 78 else {
79 if (mux->flags & CLK_MUX_INDEX_BIT) 79 if (mux->flags & CLK_MUX_INDEX_BIT)
80 index = (1 << ffs(index)); 80 index = 1 << index;
81 81
82 if (mux->flags & CLK_MUX_INDEX_ONE) 82 if (mux->flags & CLK_MUX_INDEX_ONE)
83 index++; 83 index++;
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c
index 87a41038237d..bfa1e64e267d 100644
--- a/drivers/clk/clk-s2mps11.c
+++ b/drivers/clk/clk-s2mps11.c
@@ -218,7 +218,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
218 default: 218 default:
219 dev_err(&pdev->dev, "Invalid device type\n"); 219 dev_err(&pdev->dev, "Invalid device type\n");
220 return -EINVAL; 220 return -EINVAL;
221 }; 221 }
222 222
223 /* Store clocks of_node in first element of s2mps11_clks array */ 223 /* Store clocks of_node in first element of s2mps11_clks array */
224 s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); 224 s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 4896ae9e23da..f4963b7d4e17 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -240,7 +240,6 @@ static const struct file_operations clk_dump_fops = {
240 .release = single_release, 240 .release = single_release,
241}; 241};
242 242
243/* caller must hold prepare_lock */
244static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) 243static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
245{ 244{
246 struct dentry *d; 245 struct dentry *d;
@@ -354,13 +353,13 @@ out:
354 mutex_unlock(&clk_debug_lock); 353 mutex_unlock(&clk_debug_lock);
355} 354}
356 355
357struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, 356struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
358 void *data, const struct file_operations *fops) 357 void *data, const struct file_operations *fops)
359{ 358{
360 struct dentry *d = NULL; 359 struct dentry *d = NULL;
361 360
362 if (clk->dentry) 361 if (hw->clk->dentry)
363 d = debugfs_create_file(name, mode, clk->dentry, data, fops); 362 d = debugfs_create_file(name, mode, hw->clk->dentry, data, fops);
364 363
365 return d; 364 return d;
366} 365}
@@ -574,11 +573,6 @@ unsigned int __clk_get_enable_count(struct clk *clk)
574 return !clk ? 0 : clk->enable_count; 573 return !clk ? 0 : clk->enable_count;
575} 574}
576 575
577unsigned int __clk_get_prepare_count(struct clk *clk)
578{
579 return !clk ? 0 : clk->prepare_count;
580}
581
582unsigned long __clk_get_rate(struct clk *clk) 576unsigned long __clk_get_rate(struct clk *clk)
583{ 577{
584 unsigned long ret; 578 unsigned long ret;
@@ -601,7 +595,7 @@ out:
601} 595}
602EXPORT_SYMBOL_GPL(__clk_get_rate); 596EXPORT_SYMBOL_GPL(__clk_get_rate);
603 597
604unsigned long __clk_get_accuracy(struct clk *clk) 598static unsigned long __clk_get_accuracy(struct clk *clk)
605{ 599{
606 if (!clk) 600 if (!clk)
607 return 0; 601 return 0;
@@ -707,7 +701,7 @@ struct clk *__clk_lookup(const char *name)
707 */ 701 */
708long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, 702long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
709 unsigned long *best_parent_rate, 703 unsigned long *best_parent_rate,
710 struct clk **best_parent_p) 704 struct clk_hw **best_parent_p)
711{ 705{
712 struct clk *clk = hw->clk, *parent, *best_parent = NULL; 706 struct clk *clk = hw->clk, *parent, *best_parent = NULL;
713 int i, num_parents; 707 int i, num_parents;
@@ -743,7 +737,7 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
743 737
744out: 738out:
745 if (best_parent) 739 if (best_parent)
746 *best_parent_p = best_parent; 740 *best_parent_p = best_parent->hw;
747 *best_parent_rate = best; 741 *best_parent_rate = best;
748 742
749 return best; 743 return best;
@@ -951,6 +945,7 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
951{ 945{
952 unsigned long parent_rate = 0; 946 unsigned long parent_rate = 0;
953 struct clk *parent; 947 struct clk *parent;
948 struct clk_hw *parent_hw;
954 949
955 if (!clk) 950 if (!clk)
956 return 0; 951 return 0;
@@ -959,10 +954,11 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
959 if (parent) 954 if (parent)
960 parent_rate = parent->rate; 955 parent_rate = parent->rate;
961 956
962 if (clk->ops->determine_rate) 957 if (clk->ops->determine_rate) {
958 parent_hw = parent ? parent->hw : NULL;
963 return clk->ops->determine_rate(clk->hw, rate, &parent_rate, 959 return clk->ops->determine_rate(clk->hw, rate, &parent_rate,
964 &parent); 960 &parent_hw);
965 else if (clk->ops->round_rate) 961 } else if (clk->ops->round_rate)
966 return clk->ops->round_rate(clk->hw, rate, &parent_rate); 962 return clk->ops->round_rate(clk->hw, rate, &parent_rate);
967 else if (clk->flags & CLK_SET_RATE_PARENT) 963 else if (clk->flags & CLK_SET_RATE_PARENT)
968 return __clk_round_rate(clk->parent, rate); 964 return __clk_round_rate(clk->parent, rate);
@@ -1350,6 +1346,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
1350{ 1346{
1351 struct clk *top = clk; 1347 struct clk *top = clk;
1352 struct clk *old_parent, *parent; 1348 struct clk *old_parent, *parent;
1349 struct clk_hw *parent_hw;
1353 unsigned long best_parent_rate = 0; 1350 unsigned long best_parent_rate = 0;
1354 unsigned long new_rate; 1351 unsigned long new_rate;
1355 int p_index = 0; 1352 int p_index = 0;
@@ -1365,9 +1362,11 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
1365 1362
1366 /* find the closest rate and parent clk/rate */ 1363 /* find the closest rate and parent clk/rate */
1367 if (clk->ops->determine_rate) { 1364 if (clk->ops->determine_rate) {
1365 parent_hw = parent ? parent->hw : NULL;
1368 new_rate = clk->ops->determine_rate(clk->hw, rate, 1366 new_rate = clk->ops->determine_rate(clk->hw, rate,
1369 &best_parent_rate, 1367 &best_parent_rate,
1370 &parent); 1368 &parent_hw);
1369 parent = parent_hw->clk;
1371 } else if (clk->ops->round_rate) { 1370 } else if (clk->ops->round_rate) {
1372 new_rate = clk->ops->round_rate(clk->hw, rate, 1371 new_rate = clk->ops->round_rate(clk->hw, rate,
1373 &best_parent_rate); 1372 &best_parent_rate);
@@ -1614,7 +1613,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
1614 1613
1615 if (clk->num_parents == 1) { 1614 if (clk->num_parents == 1) {
1616 if (IS_ERR_OR_NULL(clk->parent)) 1615 if (IS_ERR_OR_NULL(clk->parent))
1617 ret = clk->parent = __clk_lookup(clk->parent_names[0]); 1616 clk->parent = __clk_lookup(clk->parent_names[0]);
1618 ret = clk->parent; 1617 ret = clk->parent;
1619 goto out; 1618 goto out;
1620 } 1619 }
@@ -1944,7 +1943,6 @@ int __clk_init(struct device *dev, struct clk *clk)
1944 else 1943 else
1945 clk->rate = 0; 1944 clk->rate = 0;
1946 1945
1947 clk_debug_register(clk);
1948 /* 1946 /*
1949 * walk the list of orphan clocks and reparent any that are children of 1947 * walk the list of orphan clocks and reparent any that are children of
1950 * this clock 1948 * this clock
@@ -1979,6 +1977,9 @@ int __clk_init(struct device *dev, struct clk *clk)
1979out: 1977out:
1980 clk_prepare_unlock(); 1978 clk_prepare_unlock();
1981 1979
1980 if (!ret)
1981 clk_debug_register(clk);
1982
1982 return ret; 1983 return ret;
1983} 1984}
1984 1985
@@ -2273,14 +2274,17 @@ int __clk_get(struct clk *clk)
2273 2274
2274void __clk_put(struct clk *clk) 2275void __clk_put(struct clk *clk)
2275{ 2276{
2277 struct module *owner;
2278
2276 if (!clk || WARN_ON_ONCE(IS_ERR(clk))) 2279 if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
2277 return; 2280 return;
2278 2281
2279 clk_prepare_lock(); 2282 clk_prepare_lock();
2283 owner = clk->owner;
2280 kref_put(&clk->ref, __clk_release); 2284 kref_put(&clk->ref, __clk_release);
2281 clk_prepare_unlock(); 2285 clk_prepare_unlock();
2282 2286
2283 module_put(clk->owner); 2287 module_put(owner);
2284} 2288}
2285 2289
2286/*** clk rate change notifiers ***/ 2290/*** clk rate change notifiers ***/
diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c
index 339945d2503b..007144f81f50 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -38,44 +38,44 @@
38#include "clk.h" 38#include "clk.h"
39 39
40/* clock parent list */ 40/* clock parent list */
41static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; 41static const char *timer0_mux_p[] __initconst = { "osc32k", "timerclk01", };
42static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; 42static const char *timer1_mux_p[] __initconst = { "osc32k", "timerclk01", };
43static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; 43static const char *timer2_mux_p[] __initconst = { "osc32k", "timerclk23", };
44static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; 44static const char *timer3_mux_p[] __initconst = { "osc32k", "timerclk23", };
45static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; 45static const char *timer4_mux_p[] __initconst = { "osc32k", "timerclk45", };
46static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; 46static const char *timer5_mux_p[] __initconst = { "osc32k", "timerclk45", };
47static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; 47static const char *timer6_mux_p[] __initconst = { "osc32k", "timerclk67", };
48static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; 48static const char *timer7_mux_p[] __initconst = { "osc32k", "timerclk67", };
49static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; 49static const char *timer8_mux_p[] __initconst = { "osc32k", "timerclk89", };
50static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; 50static const char *timer9_mux_p[] __initconst = { "osc32k", "timerclk89", };
51static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; 51static const char *uart0_mux_p[] __initconst = { "osc26m", "pclk", };
52static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; 52static const char *uart1_mux_p[] __initconst = { "osc26m", "pclk", };
53static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; 53static const char *uart2_mux_p[] __initconst = { "osc26m", "pclk", };
54static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; 54static const char *uart3_mux_p[] __initconst = { "osc26m", "pclk", };
55static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; 55static const char *uart4_mux_p[] __initconst = { "osc26m", "pclk", };
56static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 56static const char *spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
57static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 57static const char *spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
58static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 58static const char *spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
59/* share axi parent */ 59/* share axi parent */
60static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; 60static const char *saxi_mux_p[] __initconst = { "armpll3", "armpll2", };
61static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; 61static const char *pwm0_mux_p[] __initconst = { "osc32k", "osc26m", };
62static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; 62static const char *pwm1_mux_p[] __initconst = { "osc32k", "osc26m", };
63static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; 63static const char *sd_mux_p[] __initconst = { "armpll2", "armpll3", };
64static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; 64static const char *mmc1_mux_p[] __initconst = { "armpll2", "armpll3", };
65static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; 65static const char *mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", };
66static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; 66static const char *g2d_mux_p[] __initconst = { "armpll2", "armpll3", };
67static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; 67static const char *venc_mux_p[] __initconst = { "armpll2", "armpll3", };
68static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; 68static const char *vdec_mux_p[] __initconst = { "armpll2", "armpll3", };
69static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; 69static const char *vpp_mux_p[] __initconst = { "armpll2", "armpll3", };
70static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; 70static const char *edc0_mux_p[] __initconst = { "armpll2", "armpll3", };
71static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", 71static const char *ldi0_mux_p[] __initconst = { "armpll2", "armpll4",
72 "armpll3", "armpll5", }; 72 "armpll3", "armpll5", };
73static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; 73static const char *edc1_mux_p[] __initconst = { "armpll2", "armpll3", };
74static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", 74static const char *ldi1_mux_p[] __initconst = { "armpll2", "armpll4",
75 "armpll3", "armpll5", }; 75 "armpll3", "armpll5", };
76static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; 76static const char *rclk_hsic_p[] __initconst = { "armpll3", "armpll2", };
77static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; 77static const char *mmc2_mux_p[] __initconst = { "armpll2", "armpll3", };
78static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; 78static const char *mmc3_mux_p[] __initconst = { "armpll2", "armpll3", };
79 79
80 80
81/* fixed rate clocks */ 81/* fixed rate clocks */
@@ -296,7 +296,7 @@ static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
296 296
297static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, 297static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
298 unsigned long *best_parent_rate, 298 unsigned long *best_parent_rate,
299 struct clk **best_parent_p) 299 struct clk_hw **best_parent_p)
300{ 300{
301 struct clk_mmc *mclk = to_mmc(hw); 301 struct clk_mmc *mclk = to_mmc(hw);
302 unsigned long best = 0; 302 unsigned long best = 0;
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d78044ce3..3caaf7cc169c 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,12 @@
2# Makefile for mmp specific clk 2# Makefile for mmp specific clk
3# 3#
4 4
5obj-y += clk-apbc.o clk-apmu.o clk-frac.o 5obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
6
7obj-$(CONFIG_RESET_CONTROLLER) += reset.o
8
9obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
10obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
6 11
7obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o 12obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
8obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o 13obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 23a56f561812..584a9927993b 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -22,19 +22,12 @@
22 * numerator/denominator = Fin / (Fout * factor) 22 * numerator/denominator = Fin / (Fout * factor)
23 */ 23 */
24 24
25#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw) 25#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
26struct clk_factor {
27 struct clk_hw hw;
28 void __iomem *base;
29 struct clk_factor_masks *masks;
30 struct clk_factor_tbl *ftbl;
31 unsigned int ftbl_cnt;
32};
33 26
34static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, 27static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
35 unsigned long *prate) 28 unsigned long *prate)
36{ 29{
37 struct clk_factor *factor = to_clk_factor(hw); 30 struct mmp_clk_factor *factor = to_clk_factor(hw);
38 unsigned long rate = 0, prev_rate; 31 unsigned long rate = 0, prev_rate;
39 int i; 32 int i;
40 33
@@ -58,8 +51,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
58static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, 51static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
59 unsigned long parent_rate) 52 unsigned long parent_rate)
60{ 53{
61 struct clk_factor *factor = to_clk_factor(hw); 54 struct mmp_clk_factor *factor = to_clk_factor(hw);
62 struct clk_factor_masks *masks = factor->masks; 55 struct mmp_clk_factor_masks *masks = factor->masks;
63 unsigned int val, num, den; 56 unsigned int val, num, den;
64 57
65 val = readl_relaxed(factor->base); 58 val = readl_relaxed(factor->base);
@@ -81,11 +74,12 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
81static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, 74static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
82 unsigned long prate) 75 unsigned long prate)
83{ 76{
84 struct clk_factor *factor = to_clk_factor(hw); 77 struct mmp_clk_factor *factor = to_clk_factor(hw);
85 struct clk_factor_masks *masks = factor->masks; 78 struct mmp_clk_factor_masks *masks = factor->masks;
86 int i; 79 int i;
87 unsigned long val; 80 unsigned long val;
88 unsigned long prev_rate, rate = 0; 81 unsigned long prev_rate, rate = 0;
82 unsigned long flags = 0;
89 83
90 for (i = 0; i < factor->ftbl_cnt; i++) { 84 for (i = 0; i < factor->ftbl_cnt; i++) {
91 prev_rate = rate; 85 prev_rate = rate;
@@ -97,6 +91,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
97 if (i > 0) 91 if (i > 0)
98 i--; 92 i--;
99 93
94 if (factor->lock)
95 spin_lock_irqsave(factor->lock, flags);
96
100 val = readl_relaxed(factor->base); 97 val = readl_relaxed(factor->base);
101 98
102 val &= ~(masks->num_mask << masks->num_shift); 99 val &= ~(masks->num_mask << masks->num_shift);
@@ -107,21 +104,65 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
107 104
108 writel_relaxed(val, factor->base); 105 writel_relaxed(val, factor->base);
109 106
107 if (factor->lock)
108 spin_unlock_irqrestore(factor->lock, flags);
109
110 return 0; 110 return 0;
111} 111}
112 112
113static void clk_factor_init(struct clk_hw *hw)
114{
115 struct mmp_clk_factor *factor = to_clk_factor(hw);
116 struct mmp_clk_factor_masks *masks = factor->masks;
117 u32 val, num, den;
118 int i;
119 unsigned long flags = 0;
120
121 if (factor->lock)
122 spin_lock_irqsave(factor->lock, flags);
123
124 val = readl(factor->base);
125
126 /* calculate numerator */
127 num = (val >> masks->num_shift) & masks->num_mask;
128
129 /* calculate denominator */
130 den = (val >> masks->den_shift) & masks->den_mask;
131
132 for (i = 0; i < factor->ftbl_cnt; i++)
133 if (den == factor->ftbl[i].den && num == factor->ftbl[i].num)
134 break;
135
136 if (i >= factor->ftbl_cnt) {
137 val &= ~(masks->num_mask << masks->num_shift);
138 val |= (factor->ftbl[0].num & masks->num_mask) <<
139 masks->num_shift;
140
141 val &= ~(masks->den_mask << masks->den_shift);
142 val |= (factor->ftbl[0].den & masks->den_mask) <<
143 masks->den_shift;
144
145 writel(val, factor->base);
146 }
147
148 if (factor->lock)
149 spin_unlock_irqrestore(factor->lock, flags);
150}
151
113static struct clk_ops clk_factor_ops = { 152static struct clk_ops clk_factor_ops = {
114 .recalc_rate = clk_factor_recalc_rate, 153 .recalc_rate = clk_factor_recalc_rate,
115 .round_rate = clk_factor_round_rate, 154 .round_rate = clk_factor_round_rate,
116 .set_rate = clk_factor_set_rate, 155 .set_rate = clk_factor_set_rate,
156 .init = clk_factor_init,
117}; 157};
118 158
119struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, 159struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
120 unsigned long flags, void __iomem *base, 160 unsigned long flags, void __iomem *base,
121 struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl, 161 struct mmp_clk_factor_masks *masks,
122 unsigned int ftbl_cnt) 162 struct mmp_clk_factor_tbl *ftbl,
163 unsigned int ftbl_cnt, spinlock_t *lock)
123{ 164{
124 struct clk_factor *factor; 165 struct mmp_clk_factor *factor;
125 struct clk_init_data init; 166 struct clk_init_data init;
126 struct clk *clk; 167 struct clk *clk;
127 168
@@ -142,6 +183,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
142 factor->ftbl = ftbl; 183 factor->ftbl = ftbl;
143 factor->ftbl_cnt = ftbl_cnt; 184 factor->ftbl_cnt = ftbl_cnt;
144 factor->hw.init = &init; 185 factor->hw.init = &init;
186 factor->lock = lock;
145 187
146 init.name = name; 188 init.name = name;
147 init.ops = &clk_factor_ops; 189 init.ops = &clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644
index 000000000000..adbd9d64ded2
--- /dev/null
+++ b/drivers/clk/mmp/clk-gate.c
@@ -0,0 +1,133 @@
1/*
2 * mmp gate clock operation source file
3 *
4 * Copyright (C) 2014 Marvell
5 * Chao Xie <chao.xie@marvell.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/slab.h>
14#include <linux/io.h>
15#include <linux/err.h>
16#include <linux/delay.h>
17
18#include "clk.h"
19
20/*
21 * Some clocks will have mutiple bits to enable the clocks, and
22 * the bits to disable the clock is not same as enabling bits.
23 */
24
25#define to_clk_mmp_gate(hw) container_of(hw, struct mmp_clk_gate, hw)
26
27static int mmp_clk_gate_enable(struct clk_hw *hw)
28{
29 struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
30 struct clk *clk = hw->clk;
31 unsigned long flags = 0;
32 unsigned long rate;
33 u32 tmp;
34
35 if (gate->lock)
36 spin_lock_irqsave(gate->lock, flags);
37
38 tmp = readl(gate->reg);
39 tmp &= ~gate->mask;
40 tmp |= gate->val_enable;
41 writel(tmp, gate->reg);
42
43 if (gate->lock)
44 spin_unlock_irqrestore(gate->lock, flags);
45
46 if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
47 rate = __clk_get_rate(clk);
48 /* Need delay 2 cycles. */
49 udelay(2000000/rate);
50 }
51
52 return 0;
53}
54
55static void mmp_clk_gate_disable(struct clk_hw *hw)
56{
57 struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
58 unsigned long flags = 0;
59 u32 tmp;
60
61 if (gate->lock)
62 spin_lock_irqsave(gate->lock, flags);
63
64 tmp = readl(gate->reg);
65 tmp &= ~gate->mask;
66 tmp |= gate->val_disable;
67 writel(tmp, gate->reg);
68
69 if (gate->lock)
70 spin_unlock_irqrestore(gate->lock, flags);
71}
72
73static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
74{
75 struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
76 unsigned long flags = 0;
77 u32 tmp;
78
79 if (gate->lock)
80 spin_lock_irqsave(gate->lock, flags);
81
82 tmp = readl(gate->reg);
83
84 if (gate->lock)
85 spin_unlock_irqrestore(gate->lock, flags);
86
87 return (tmp & gate->mask) == gate->val_enable;
88}
89
90const struct clk_ops mmp_clk_gate_ops = {
91 .enable = mmp_clk_gate_enable,
92 .disable = mmp_clk_gate_disable,
93 .is_enabled = mmp_clk_gate_is_enabled,
94};
95
96struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
97 const char *parent_name, unsigned long flags,
98 void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
99 unsigned int gate_flags, spinlock_t *lock)
100{
101 struct mmp_clk_gate *gate;
102 struct clk *clk;
103 struct clk_init_data init;
104
105 /* allocate the gate */
106 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
107 if (!gate) {
108 pr_err("%s:%s could not allocate gate clk\n", __func__, name);
109 return ERR_PTR(-ENOMEM);
110 }
111
112 init.name = name;
113 init.ops = &mmp_clk_gate_ops;
114 init.flags = flags | CLK_IS_BASIC;
115 init.parent_names = (parent_name ? &parent_name : NULL);
116 init.num_parents = (parent_name ? 1 : 0);
117
118 /* struct clk_gate assignments */
119 gate->reg = reg;
120 gate->mask = mask;
121 gate->val_enable = val_enable;
122 gate->val_disable = val_disable;
123 gate->flags = gate_flags;
124 gate->lock = lock;
125 gate->hw.init = &init;
126
127 clk = clk_register(dev, &gate->hw);
128
129 if (IS_ERR(clk))
130 kfree(gate);
131
132 return clk;
133}
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644
index 000000000000..48fa53c7ce5e
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix.c
@@ -0,0 +1,513 @@
1/*
2 * mmp mix(div and mux) clock operation source file
3 *
4 * Copyright (C) 2014 Marvell
5 * Chao Xie <chao.xie@marvell.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/slab.h>
14#include <linux/io.h>
15#include <linux/err.h>
16
17#include "clk.h"
18
19/*
20 * The mix clock is a clock combined mux and div type clock.
21 * Because the div field and mux field need to be set at same
22 * time, we can not divide it into 2 types of clock
23 */
24
25#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
26
27static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
28{
29 unsigned int div_mask = (1 << mix->reg_info.width_div) - 1;
30 unsigned int maxdiv = 0;
31 struct clk_div_table *clkt;
32
33 if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
34 return div_mask;
35 if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
36 return 1 << div_mask;
37 if (mix->div_table) {
38 for (clkt = mix->div_table; clkt->div; clkt++)
39 if (clkt->div > maxdiv)
40 maxdiv = clkt->div;
41 return maxdiv;
42 }
43 return div_mask + 1;
44}
45
46static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
47{
48 struct clk_div_table *clkt;
49
50 if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
51 return val;
52 if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
53 return 1 << val;
54 if (mix->div_table) {
55 for (clkt = mix->div_table; clkt->div; clkt++)
56 if (clkt->val == val)
57 return clkt->div;
58 if (clkt->div == 0)
59 return 0;
60 }
61 return val + 1;
62}
63
64static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
65{
66 int num_parents = __clk_get_num_parents(mix->hw.clk);
67 int i;
68
69 if (mix->mux_flags & CLK_MUX_INDEX_BIT)
70 return ffs(val) - 1;
71 if (mix->mux_flags & CLK_MUX_INDEX_ONE)
72 return val - 1;
73 if (mix->mux_table) {
74 for (i = 0; i < num_parents; i++)
75 if (mix->mux_table[i] == val)
76 return i;
77 if (i == num_parents)
78 return 0;
79 }
80
81 return val;
82}
83static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
84{
85 struct clk_div_table *clkt;
86
87 if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
88 return div;
89 if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
90 return __ffs(div);
91 if (mix->div_table) {
92 for (clkt = mix->div_table; clkt->div; clkt++)
93 if (clkt->div == div)
94 return clkt->val;
95 if (clkt->div == 0)
96 return 0;
97 }
98
99 return div - 1;
100}
101
102static unsigned int _get_mux_val(struct mmp_clk_mix *mix, unsigned int mux)
103{
104 if (mix->mux_table)
105 return mix->mux_table[mux];
106
107 return mux;
108}
109
110static void _filter_clk_table(struct mmp_clk_mix *mix,
111 struct mmp_clk_mix_clk_table *table,
112 unsigned int table_size)
113{
114 int i;
115 struct mmp_clk_mix_clk_table *item;
116 struct clk *parent, *clk;
117 unsigned long parent_rate;
118
119 clk = mix->hw.clk;
120
121 for (i = 0; i < table_size; i++) {
122 item = &table[i];
123 parent = clk_get_parent_by_index(clk, item->parent_index);
124 parent_rate = __clk_get_rate(parent);
125 if (parent_rate % item->rate) {
126 item->valid = 0;
127 } else {
128 item->divisor = parent_rate / item->rate;
129 item->valid = 1;
130 }
131 }
132}
133
134static int _set_rate(struct mmp_clk_mix *mix, u32 mux_val, u32 div_val,
135 unsigned int change_mux, unsigned int change_div)
136{
137 struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
138 u8 width, shift;
139 u32 mux_div, fc_req;
140 int ret, timeout = 50;
141 unsigned long flags = 0;
142
143 if (!change_mux && !change_div)
144 return -EINVAL;
145
146 if (mix->lock)
147 spin_lock_irqsave(mix->lock, flags);
148
149 if (mix->type == MMP_CLK_MIX_TYPE_V1
150 || mix->type == MMP_CLK_MIX_TYPE_V2)
151 mux_div = readl(ri->reg_clk_ctrl);
152 else
153 mux_div = readl(ri->reg_clk_sel);
154
155 if (change_div) {
156 width = ri->width_div;
157 shift = ri->shift_div;
158 mux_div &= ~MMP_CLK_BITS_MASK(width, shift);
159 mux_div |= MMP_CLK_BITS_SET_VAL(div_val, width, shift);
160 }
161
162 if (change_mux) {
163 width = ri->width_mux;
164 shift = ri->shift_mux;
165 mux_div &= ~MMP_CLK_BITS_MASK(width, shift);
166 mux_div |= MMP_CLK_BITS_SET_VAL(mux_val, width, shift);
167 }
168
169 if (mix->type == MMP_CLK_MIX_TYPE_V1) {
170 writel(mux_div, ri->reg_clk_ctrl);
171 } else if (mix->type == MMP_CLK_MIX_TYPE_V2) {
172 mux_div |= (1 << ri->bit_fc);
173 writel(mux_div, ri->reg_clk_ctrl);
174
175 do {
176 fc_req = readl(ri->reg_clk_ctrl);
177 timeout--;
178 if (!(fc_req & (1 << ri->bit_fc)))
179 break;
180 } while (timeout);
181
182 if (timeout == 0) {
183 pr_err("%s:%s cannot do frequency change\n",
184 __func__, __clk_get_name(mix->hw.clk));
185 ret = -EBUSY;
186 goto error;
187 }
188 } else {
189 fc_req = readl(ri->reg_clk_ctrl);
190 fc_req |= 1 << ri->bit_fc;
191 writel(fc_req, ri->reg_clk_ctrl);
192 writel(mux_div, ri->reg_clk_sel);
193 fc_req &= ~(1 << ri->bit_fc);
194 }
195
196 ret = 0;
197error:
198 if (mix->lock)
199 spin_unlock_irqrestore(mix->lock, flags);
200
201 return ret;
202}
203
204static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate,
205 unsigned long *best_parent_rate,
206 struct clk_hw **best_parent_clk)
207{
208 struct mmp_clk_mix *mix = to_clk_mix(hw);
209 struct mmp_clk_mix_clk_table *item;
210 struct clk *parent, *parent_best, *mix_clk;
211 unsigned long parent_rate, mix_rate, mix_rate_best, parent_rate_best;
212 unsigned long gap, gap_best;
213 u32 div_val_max;
214 unsigned int div;
215 int i, j;
216
217 mix_clk = hw->clk;
218
219 parent = NULL;
220 mix_rate_best = 0;
221 parent_rate_best = 0;
222 gap_best = rate;
223 parent_best = NULL;
224
225 if (mix->table) {
226 for (i = 0; i < mix->table_size; i++) {
227 item = &mix->table[i];
228 if (item->valid == 0)
229 continue;
230 parent = clk_get_parent_by_index(mix_clk,
231 item->parent_index);
232 parent_rate = __clk_get_rate(parent);
233 mix_rate = parent_rate / item->divisor;
234 gap = abs(mix_rate - rate);
235 if (parent_best == NULL || gap < gap_best) {
236 parent_best = parent;
237 parent_rate_best = parent_rate;
238 mix_rate_best = mix_rate;
239 gap_best = gap;
240 if (gap_best == 0)
241 goto found;
242 }
243 }
244 } else {
245 for (i = 0; i < __clk_get_num_parents(mix_clk); i++) {
246 parent = clk_get_parent_by_index(mix_clk, i);
247 parent_rate = __clk_get_rate(parent);
248 div_val_max = _get_maxdiv(mix);
249 for (j = 0; j < div_val_max; j++) {
250 div = _get_div(mix, j);
251 mix_rate = parent_rate / div;
252 gap = abs(mix_rate - rate);
253 if (parent_best == NULL || gap < gap_best) {
254 parent_best = parent;
255 parent_rate_best = parent_rate;
256 mix_rate_best = mix_rate;
257 gap_best = gap;
258 if (gap_best == 0)
259 goto found;
260 }
261 }
262 }
263 }
264
265found:
266 *best_parent_rate = parent_rate_best;
267 *best_parent_clk = __clk_get_hw(parent_best);
268
269 return mix_rate_best;
270}
271
272static int mmp_clk_mix_set_rate_and_parent(struct clk_hw *hw,
273 unsigned long rate,
274 unsigned long parent_rate,
275 u8 index)
276{
277 struct mmp_clk_mix *mix = to_clk_mix(hw);
278 unsigned int div;
279 u32 div_val, mux_val;
280
281 div = parent_rate / rate;
282 div_val = _get_div_val(mix, div);
283 mux_val = _get_mux_val(mix, index);
284
285 return _set_rate(mix, mux_val, div_val, 1, 1);
286}
287
288static u8 mmp_clk_mix_get_parent(struct clk_hw *hw)
289{
290 struct mmp_clk_mix *mix = to_clk_mix(hw);
291 struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
292 unsigned long flags = 0;
293 u32 mux_div = 0;
294 u8 width, shift;
295 u32 mux_val;
296
297 if (mix->lock)
298 spin_lock_irqsave(mix->lock, flags);
299
300 if (mix->type == MMP_CLK_MIX_TYPE_V1
301 || mix->type == MMP_CLK_MIX_TYPE_V2)
302 mux_div = readl(ri->reg_clk_ctrl);
303 else
304 mux_div = readl(ri->reg_clk_sel);
305
306 if (mix->lock)
307 spin_unlock_irqrestore(mix->lock, flags);
308
309 width = mix->reg_info.width_mux;
310 shift = mix->reg_info.shift_mux;
311
312 mux_val = MMP_CLK_BITS_GET_VAL(mux_div, width, shift);
313
314 return _get_mux(mix, mux_val);
315}
316
317static unsigned long mmp_clk_mix_recalc_rate(struct clk_hw *hw,
318 unsigned long parent_rate)
319{
320 struct mmp_clk_mix *mix = to_clk_mix(hw);
321 struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
322 unsigned long flags = 0;
323 u32 mux_div = 0;
324 u8 width, shift;
325 unsigned int div;
326
327 if (mix->lock)
328 spin_lock_irqsave(mix->lock, flags);
329
330 if (mix->type == MMP_CLK_MIX_TYPE_V1
331 || mix->type == MMP_CLK_MIX_TYPE_V2)
332 mux_div = readl(ri->reg_clk_ctrl);
333 else
334 mux_div = readl(ri->reg_clk_sel);
335
336 if (mix->lock)
337 spin_unlock_irqrestore(mix->lock, flags);
338
339 width = mix->reg_info.width_div;
340 shift = mix->reg_info.shift_div;
341
342 div = _get_div(mix, MMP_CLK_BITS_GET_VAL(mux_div, width, shift));
343
344 return parent_rate / div;
345}
346
347static int mmp_clk_set_parent(struct clk_hw *hw, u8 index)
348{
349 struct mmp_clk_mix *mix = to_clk_mix(hw);
350 struct mmp_clk_mix_clk_table *item;
351 int i;
352 u32 div_val, mux_val;
353
354 if (mix->table) {
355 for (i = 0; i < mix->table_size; i++) {
356 item = &mix->table[i];
357 if (item->valid == 0)
358 continue;
359 if (item->parent_index == index)
360 break;
361 }
362 if (i < mix->table_size) {
363 div_val = _get_div_val(mix, item->divisor);
364 mux_val = _get_mux_val(mix, item->parent_index);
365 } else
366 return -EINVAL;
367 } else {
368 mux_val = _get_mux_val(mix, index);
369 div_val = 0;
370 }
371
372 return _set_rate(mix, mux_val, div_val, 1, div_val ? 1 : 0);
373}
374
375static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
376 unsigned long best_parent_rate)
377{
378 struct mmp_clk_mix *mix = to_clk_mix(hw);
379 struct mmp_clk_mix_clk_table *item;
380 unsigned long parent_rate;
381 unsigned int best_divisor;
382 struct clk *mix_clk, *parent;
383 int i;
384
385 best_divisor = best_parent_rate / rate;
386
387 mix_clk = hw->clk;
388 if (mix->table) {
389 for (i = 0; i < mix->table_size; i++) {
390 item = &mix->table[i];
391 if (item->valid == 0)
392 continue;
393 parent = clk_get_parent_by_index(mix_clk,
394 item->parent_index);
395 parent_rate = __clk_get_rate(parent);
396 if (parent_rate == best_parent_rate
397 && item->divisor == best_divisor)
398 break;
399 }
400 if (i < mix->table_size)
401 return _set_rate(mix,
402 _get_mux_val(mix, item->parent_index),
403 _get_div_val(mix, item->divisor),
404 1, 1);
405 else
406 return -EINVAL;
407 } else {
408 for (i = 0; i < __clk_get_num_parents(mix_clk); i++) {
409 parent = clk_get_parent_by_index(mix_clk, i);
410 parent_rate = __clk_get_rate(parent);
411 if (parent_rate == best_parent_rate)
412 break;
413 }
414 if (i < __clk_get_num_parents(mix_clk))
415 return _set_rate(mix, _get_mux_val(mix, i),
416 _get_div_val(mix, best_divisor), 1, 1);
417 else
418 return -EINVAL;
419 }
420}
421
422static void mmp_clk_mix_init(struct clk_hw *hw)
423{
424 struct mmp_clk_mix *mix = to_clk_mix(hw);
425
426 if (mix->table)
427 _filter_clk_table(mix, mix->table, mix->table_size);
428}
429
430const struct clk_ops mmp_clk_mix_ops = {
431 .determine_rate = mmp_clk_mix_determine_rate,
432 .set_rate_and_parent = mmp_clk_mix_set_rate_and_parent,
433 .set_rate = mmp_clk_set_rate,
434 .set_parent = mmp_clk_set_parent,
435 .get_parent = mmp_clk_mix_get_parent,
436 .recalc_rate = mmp_clk_mix_recalc_rate,
437 .init = mmp_clk_mix_init,
438};
439
440struct clk *mmp_clk_register_mix(struct device *dev,
441 const char *name,
442 const char **parent_names,
443 u8 num_parents,
444 unsigned long flags,
445 struct mmp_clk_mix_config *config,
446 spinlock_t *lock)
447{
448 struct mmp_clk_mix *mix;
449 struct clk *clk;
450 struct clk_init_data init;
451 size_t table_bytes;
452
453 mix = kzalloc(sizeof(*mix), GFP_KERNEL);
454 if (!mix) {
455 pr_err("%s:%s: could not allocate mmp mix clk\n",
456 __func__, name);
457 return ERR_PTR(-ENOMEM);
458 }
459
460 init.name = name;
461 init.flags = flags | CLK_GET_RATE_NOCACHE;
462 init.parent_names = parent_names;
463 init.num_parents = num_parents;
464 init.ops = &mmp_clk_mix_ops;
465
466 memcpy(&mix->reg_info, &config->reg_info, sizeof(config->reg_info));
467 if (config->table) {
468 table_bytes = sizeof(*config->table) * config->table_size;
469 mix->table = kzalloc(table_bytes, GFP_KERNEL);
470 if (!mix->table) {
471 pr_err("%s:%s: could not allocate mmp mix table\n",
472 __func__, name);
473 kfree(mix);
474 return ERR_PTR(-ENOMEM);
475 }
476 memcpy(mix->table, config->table, table_bytes);
477 mix->table_size = config->table_size;
478 }
479
480 if (config->mux_table) {
481 table_bytes = sizeof(u32) * num_parents;
482 mix->mux_table = kzalloc(table_bytes, GFP_KERNEL);
483 if (!mix->mux_table) {
484 pr_err("%s:%s: could not allocate mmp mix mux-table\n",
485 __func__, name);
486 kfree(mix->table);
487 kfree(mix);
488 return ERR_PTR(-ENOMEM);
489 }
490 memcpy(mix->mux_table, config->mux_table, table_bytes);
491 }
492
493 mix->div_flags = config->div_flags;
494 mix->mux_flags = config->mux_flags;
495 mix->lock = lock;
496 mix->hw.init = &init;
497
498 if (config->reg_info.bit_fc >= 32)
499 mix->type = MMP_CLK_MIX_TYPE_V1;
500 else if (config->reg_info.reg_clk_sel)
501 mix->type = MMP_CLK_MIX_TYPE_V3;
502 else
503 mix->type = MMP_CLK_MIX_TYPE_V2;
504 clk = clk_register(dev, &mix->hw);
505
506 if (IS_ERR(clk)) {
507 kfree(mix->mux_table);
508 kfree(mix->table);
509 kfree(mix);
510 }
511
512 return clk;
513}
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index b2721cae257a..5c90a4230fa3 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -54,7 +54,7 @@
54 54
55static DEFINE_SPINLOCK(clk_lock); 55static DEFINE_SPINLOCK(clk_lock);
56 56
57static struct clk_factor_masks uart_factor_masks = { 57static struct mmp_clk_factor_masks uart_factor_masks = {
58 .factor = 2, 58 .factor = 2,
59 .num_mask = 0x1fff, 59 .num_mask = 0x1fff,
60 .den_mask = 0x1fff, 60 .den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
62 .den_shift = 0, 62 .den_shift = 0,
63}; 63};
64 64
65static struct clk_factor_tbl uart_factor_tbl[] = { 65static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
66 {.num = 14634, .den = 2165}, /*14.745MHZ */ 66 {.num = 14634, .den = 2165}, /*14.745MHZ */
67 {.num = 3521, .den = 689}, /*19.23MHZ */ 67 {.num = 3521, .den = 689}, /*19.23MHZ */
68 {.num = 9679, .den = 5728}, /*58.9824MHZ */ 68 {.num = 9679, .den = 5728}, /*58.9824MHZ */
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
191 clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, 191 clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
192 mpmu_base + MPMU_UART_PLL, 192 mpmu_base + MPMU_UART_PLL,
193 &uart_factor_masks, uart_factor_tbl, 193 &uart_factor_masks, uart_factor_tbl,
194 ARRAY_SIZE(uart_factor_tbl)); 194 ARRAY_SIZE(uart_factor_tbl), &clk_lock);
195 clk_set_rate(clk, 14745600); 195 clk_set_rate(clk, 14745600);
196 clk_register_clkdev(clk, "uart_pll", NULL); 196 clk_register_clkdev(clk, "uart_pll", NULL);
197 197
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644
index 000000000000..2cbc2b43ae52
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -0,0 +1,334 @@
1/*
2 * mmp2 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/of_address.h>
19
20#include <dt-bindings/clock/marvell,mmp2.h>
21
22#include "clk.h"
23#include "reset.h"
24
25#define APBC_RTC 0x0
26#define APBC_TWSI0 0x4
27#define APBC_TWSI1 0x8
28#define APBC_TWSI2 0xc
29#define APBC_TWSI3 0x10
30#define APBC_TWSI4 0x7c
31#define APBC_TWSI5 0x80
32#define APBC_KPC 0x18
33#define APBC_UART0 0x2c
34#define APBC_UART1 0x30
35#define APBC_UART2 0x34
36#define APBC_UART3 0x88
37#define APBC_GPIO 0x38
38#define APBC_PWM0 0x3c
39#define APBC_PWM1 0x40
40#define APBC_PWM2 0x44
41#define APBC_PWM3 0x48
42#define APBC_SSP0 0x50
43#define APBC_SSP1 0x54
44#define APBC_SSP2 0x58
45#define APBC_SSP3 0x5c
46#define APMU_SDH0 0x54
47#define APMU_SDH1 0x58
48#define APMU_SDH2 0xe8
49#define APMU_SDH3 0xec
50#define APMU_USB 0x5c
51#define APMU_DISP0 0x4c
52#define APMU_DISP1 0x110
53#define APMU_CCIC0 0x50
54#define APMU_CCIC1 0xf4
55#define MPMU_UART_PLL 0x14
56
57struct mmp2_clk_unit {
58 struct mmp_clk_unit unit;
59 void __iomem *mpmu_base;
60 void __iomem *apmu_base;
61 void __iomem *apbc_base;
62};
63
64static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
65 {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
66 {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
67 {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000},
68 {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000},
69 {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
70};
71
72static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
73 {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
74 {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
75 {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
76 {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
77 {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0},
78 {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0},
79 {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0},
80 {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
81 {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0},
82 {MMP2_CLK_PLL2_4, "pll2_4", "pll2_2", 1, 2, 0},
83 {MMP2_CLK_PLL2_8, "pll2_8", "pll2_4", 1, 2, 0},
84 {MMP2_CLK_PLL2_16, "pll2_16", "pll2_8", 1, 2, 0},
85 {MMP2_CLK_PLL2_3, "pll2_3", "pll2", 1, 3, 0},
86 {MMP2_CLK_PLL2_6, "pll2_6", "pll2_3", 1, 2, 0},
87 {MMP2_CLK_PLL2_12, "pll2_12", "pll2_6", 1, 2, 0},
88 {MMP2_CLK_VCTCXO_2, "vctcxo_2", "vctcxo", 1, 2, 0},
89 {MMP2_CLK_VCTCXO_4, "vctcxo_4", "vctcxo_2", 1, 2, 0},
90};
91
92static struct mmp_clk_factor_masks uart_factor_masks = {
93 .factor = 2,
94 .num_mask = 0x1fff,
95 .den_mask = 0x1fff,
96 .num_shift = 16,
97 .den_shift = 0,
98};
99
100static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
101 {.num = 14634, .den = 2165}, /*14.745MHZ */
102 {.num = 3521, .den = 689}, /*19.23MHZ */
103 {.num = 9679, .den = 5728}, /*58.9824MHZ */
104 {.num = 15850, .den = 9451}, /*59.429MHZ */
105};
106
107static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
108{
109 struct clk *clk;
110 struct mmp_clk_unit *unit = &pxa_unit->unit;
111
112 mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
113 ARRAY_SIZE(fixed_rate_clks));
114
115 mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
116 ARRAY_SIZE(fixed_factor_clks));
117
118 clk = mmp_clk_register_factor("uart_pll", "pll1_4",
119 CLK_SET_RATE_PARENT,
120 pxa_unit->mpmu_base + MPMU_UART_PLL,
121 &uart_factor_masks, uart_factor_tbl,
122 ARRAY_SIZE(uart_factor_tbl), NULL);
123 mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
124}
125
126static DEFINE_SPINLOCK(uart0_lock);
127static DEFINE_SPINLOCK(uart1_lock);
128static DEFINE_SPINLOCK(uart2_lock);
129static const char *uart_parent_names[] = {"uart_pll", "vctcxo"};
130
131static DEFINE_SPINLOCK(ssp0_lock);
132static DEFINE_SPINLOCK(ssp1_lock);
133static DEFINE_SPINLOCK(ssp2_lock);
134static DEFINE_SPINLOCK(ssp3_lock);
135static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"};
136
137static DEFINE_SPINLOCK(reset_lock);
138
139static struct mmp_param_mux_clk apbc_mux_clks[] = {
140 {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
141 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
142 {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock},
143 {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART3, 4, 3, 0, &uart2_lock},
144 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
145 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
146 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
147 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
148};
149
150static struct mmp_param_gate_clk apbc_gate_clks[] = {
151 {MMP2_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x7, 0x3, 0x0, 0, &reset_lock},
152 {MMP2_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x7, 0x3, 0x0, 0, &reset_lock},
153 {MMP2_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI2, 0x7, 0x3, 0x0, 0, &reset_lock},
154 {MMP2_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x7, 0x3, 0x0, 0, &reset_lock},
155 {MMP2_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI4, 0x7, 0x3, 0x0, 0, &reset_lock},
156 {MMP2_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI5, 0x7, 0x3, 0x0, 0, &reset_lock},
157 {MMP2_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x7, 0x3, 0x0, 0, &reset_lock},
158 {MMP2_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock},
159 {MMP2_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x87, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock},
160 {MMP2_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x7, 0x3, 0x0, 0, &reset_lock},
161 {MMP2_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x7, 0x3, 0x0, 0, &reset_lock},
162 {MMP2_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x7, 0x3, 0x0, 0, &reset_lock},
163 {MMP2_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x7, 0x3, 0x0, 0, &reset_lock},
164 /* The gate clocks has mux parent. */
165 {MMP2_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x7, 0x3, 0x0, 0, &uart0_lock},
166 {MMP2_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x7, 0x3, 0x0, 0, &uart1_lock},
167 {MMP2_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock},
168 {MMP2_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, APBC_UART3, 0x7, 0x3, 0x0, 0, &uart2_lock},
169 {MMP2_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x7, 0x3, 0x0, 0, &ssp0_lock},
170 {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock},
171 {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock},
172 {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock},
173};
174
175static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
176{
177 struct mmp_clk_unit *unit = &pxa_unit->unit;
178
179 mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
180 ARRAY_SIZE(apbc_mux_clks));
181
182 mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
183 ARRAY_SIZE(apbc_gate_clks));
184}
185
186static DEFINE_SPINLOCK(sdh_lock);
187static const char *sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"};
188static struct mmp_clk_mix_config sdh_mix_config = {
189 .reg_info = DEFINE_MIX_REG_INFO(4, 10, 2, 8, 32),
190};
191
192static DEFINE_SPINLOCK(usb_lock);
193
194static DEFINE_SPINLOCK(disp0_lock);
195static DEFINE_SPINLOCK(disp1_lock);
196static const char *disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"};
197
198static DEFINE_SPINLOCK(ccic0_lock);
199static DEFINE_SPINLOCK(ccic1_lock);
200static const char *ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"};
201static struct mmp_clk_mix_config ccic0_mix_config = {
202 .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
203};
204static struct mmp_clk_mix_config ccic1_mix_config = {
205 .reg_info = DEFINE_MIX_REG_INFO(4, 16, 2, 6, 32),
206};
207
208static struct mmp_param_mux_clk apmu_mux_clks[] = {
209 {MMP2_CLK_DISP0_MUX, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 2, 0, &disp0_lock},
210 {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock},
211};
212
213static struct mmp_param_div_clk apmu_div_clks[] = {
214 {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock},
215 {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock},
216 {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock},
217 {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
218 {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock},
219};
220
221static struct mmp_param_gate_clk apmu_gate_clks[] = {
222 {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
223 /* The gate clocks has mux parent. */
224 {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
225 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
226 {MMP2_CLK_SDH1, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
227 {MMP2_CLK_SDH1, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
228 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
229 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
230 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock},
231 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock},
232 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
233 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
234 {MMP2_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
235 {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock},
236 {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
237 {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
238};
239
240static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
241{
242 struct clk *clk;
243 struct mmp_clk_unit *unit = &pxa_unit->unit;
244
245 sdh_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_SDH0;
246 clk = mmp_clk_register_mix(NULL, "sdh_mix_clk", sdh_parent_names,
247 ARRAY_SIZE(sdh_parent_names),
248 CLK_SET_RATE_PARENT,
249 &sdh_mix_config, &sdh_lock);
250
251 ccic0_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC0;
252 clk = mmp_clk_register_mix(NULL, "ccic0_mix_clk", ccic_parent_names,
253 ARRAY_SIZE(ccic_parent_names),
254 CLK_SET_RATE_PARENT,
255 &ccic0_mix_config, &ccic0_lock);
256 mmp_clk_add(unit, MMP2_CLK_CCIC0_MIX, clk);
257
258 ccic1_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC1;
259 clk = mmp_clk_register_mix(NULL, "ccic1_mix_clk", ccic_parent_names,
260 ARRAY_SIZE(ccic_parent_names),
261 CLK_SET_RATE_PARENT,
262 &ccic1_mix_config, &ccic1_lock);
263 mmp_clk_add(unit, MMP2_CLK_CCIC1_MIX, clk);
264
265 mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
266 ARRAY_SIZE(apmu_mux_clks));
267
268 mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
269 ARRAY_SIZE(apmu_div_clks));
270
271 mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
272 ARRAY_SIZE(apmu_gate_clks));
273}
274
275static void mmp2_clk_reset_init(struct device_node *np,
276 struct mmp2_clk_unit *pxa_unit)
277{
278 struct mmp_clk_reset_cell *cells;
279 int i, nr_resets;
280
281 nr_resets = ARRAY_SIZE(apbc_gate_clks);
282 cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
283 if (!cells)
284 return;
285
286 for (i = 0; i < nr_resets; i++) {
287 cells[i].clk_id = apbc_gate_clks[i].id;
288 cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset;
289 cells[i].flags = 0;
290 cells[i].lock = apbc_gate_clks[i].lock;
291 cells[i].bits = 0x4;
292 }
293
294 mmp_clk_reset_register(np, cells, nr_resets);
295}
296
297static void __init mmp2_clk_init(struct device_node *np)
298{
299 struct mmp2_clk_unit *pxa_unit;
300
301 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
302 if (!pxa_unit)
303 return;
304
305 pxa_unit->mpmu_base = of_iomap(np, 0);
306 if (!pxa_unit->mpmu_base) {
307 pr_err("failed to map mpmu registers\n");
308 return;
309 }
310
311 pxa_unit->apmu_base = of_iomap(np, 1);
312 if (!pxa_unit->mpmu_base) {
313 pr_err("failed to map apmu registers\n");
314 return;
315 }
316
317 pxa_unit->apbc_base = of_iomap(np, 2);
318 if (!pxa_unit->apbc_base) {
319 pr_err("failed to map apbc registers\n");
320 return;
321 }
322
323 mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
324
325 mmp2_pll_init(pxa_unit);
326
327 mmp2_apb_periph_clk_init(pxa_unit);
328
329 mmp2_axi_periph_clk_init(pxa_unit);
330
331 mmp2_clk_reset_init(np, pxa_unit);
332}
333
334CLK_OF_DECLARE(mmp2_clk, "marvell,mmp2-clock", mmp2_clk_init);
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644
index 000000000000..5b1810dc4bd2
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -0,0 +1,279 @@
1/*
2 * pxa168 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/of_address.h>
19
20#include <dt-bindings/clock/marvell,pxa168.h>
21
22#include "clk.h"
23#include "reset.h"
24
25#define APBC_RTC 0x28
26#define APBC_TWSI0 0x2c
27#define APBC_KPC 0x30
28#define APBC_UART0 0x0
29#define APBC_UART1 0x4
30#define APBC_GPIO 0x8
31#define APBC_PWM0 0xc
32#define APBC_PWM1 0x10
33#define APBC_PWM2 0x14
34#define APBC_PWM3 0x18
35#define APBC_SSP0 0x81c
36#define APBC_SSP1 0x820
37#define APBC_SSP2 0x84c
38#define APBC_SSP3 0x858
39#define APBC_SSP4 0x85c
40#define APBC_TWSI1 0x6c
41#define APBC_UART2 0x70
42#define APMU_SDH0 0x54
43#define APMU_SDH1 0x58
44#define APMU_USB 0x5c
45#define APMU_DISP0 0x4c
46#define APMU_CCIC0 0x50
47#define APMU_DFC 0x60
48#define MPMU_UART_PLL 0x14
49
50struct pxa168_clk_unit {
51 struct mmp_clk_unit unit;
52 void __iomem *mpmu_base;
53 void __iomem *apmu_base;
54 void __iomem *apbc_base;
55};
56
57static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
58 {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
59 {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
60 {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
61};
62
63static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
64 {PXA168_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
65 {PXA168_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
66 {PXA168_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
67 {PXA168_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
68 {PXA168_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
69 {PXA168_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
70 {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
71 {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
72 {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
73 {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
74 {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
75 {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
76 {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
77};
78
79static struct mmp_clk_factor_masks uart_factor_masks = {
80 .factor = 2,
81 .num_mask = 0x1fff,
82 .den_mask = 0x1fff,
83 .num_shift = 16,
84 .den_shift = 0,
85};
86
87static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
88 {.num = 8125, .den = 1536}, /*14.745MHZ */
89};
90
91static void pxa168_pll_init(struct pxa168_clk_unit *pxa_unit)
92{
93 struct clk *clk;
94 struct mmp_clk_unit *unit = &pxa_unit->unit;
95
96 mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
97 ARRAY_SIZE(fixed_rate_clks));
98
99 mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
100 ARRAY_SIZE(fixed_factor_clks));
101
102 clk = mmp_clk_register_factor("uart_pll", "pll1_4",
103 CLK_SET_RATE_PARENT,
104 pxa_unit->mpmu_base + MPMU_UART_PLL,
105 &uart_factor_masks, uart_factor_tbl,
106 ARRAY_SIZE(uart_factor_tbl), NULL);
107 mmp_clk_add(unit, PXA168_CLK_UART_PLL, clk);
108}
109
110static DEFINE_SPINLOCK(uart0_lock);
111static DEFINE_SPINLOCK(uart1_lock);
112static DEFINE_SPINLOCK(uart2_lock);
113static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"};
114
115static DEFINE_SPINLOCK(ssp0_lock);
116static DEFINE_SPINLOCK(ssp1_lock);
117static DEFINE_SPINLOCK(ssp2_lock);
118static DEFINE_SPINLOCK(ssp3_lock);
119static DEFINE_SPINLOCK(ssp4_lock);
120static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
121
122static DEFINE_SPINLOCK(reset_lock);
123
124static struct mmp_param_mux_clk apbc_mux_clks[] = {
125 {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
126 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
127 {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock},
128 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
129 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
130 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
131 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
132 {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock},
133};
134
135static struct mmp_param_gate_clk apbc_gate_clks[] = {
136 {PXA168_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock},
137 {PXA168_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock},
138 {PXA168_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock},
139 {PXA168_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
140 {PXA168_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
141 {PXA168_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock},
142 {PXA168_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock},
143 {PXA168_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock},
144 {PXA168_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock},
145 /* The gate clocks has mux parent. */
146 {PXA168_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock},
147 {PXA168_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
148 {PXA168_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock},
149 {PXA168_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock},
150 {PXA168_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock},
151 {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock},
152 {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock},
153 {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock},
154};
155
156static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
157{
158 struct mmp_clk_unit *unit = &pxa_unit->unit;
159
160 mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
161 ARRAY_SIZE(apbc_mux_clks));
162
163 mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
164 ARRAY_SIZE(apbc_gate_clks));
165
166}
167
168static DEFINE_SPINLOCK(sdh0_lock);
169static DEFINE_SPINLOCK(sdh1_lock);
170static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"};
171
172static DEFINE_SPINLOCK(usb_lock);
173
174static DEFINE_SPINLOCK(disp0_lock);
175static const char *disp_parent_names[] = {"pll1_2", "pll1_12"};
176
177static DEFINE_SPINLOCK(ccic0_lock);
178static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"};
179static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
180
181static struct mmp_param_mux_clk apmu_mux_clks[] = {
182 {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock},
183 {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock},
184 {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock},
185 {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock},
186 {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock},
187};
188
189static struct mmp_param_div_clk apmu_div_clks[] = {
190 {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
191};
192
193static struct mmp_param_gate_clk apmu_gate_clks[] = {
194 {PXA168_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL},
195 {PXA168_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
196 {PXA168_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock},
197 /* The gate clocks has mux parent. */
198 {PXA168_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
199 {PXA168_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
200 {PXA168_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
201 {PXA168_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
202 {PXA168_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
203 {PXA168_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
204};
205
206static void pxa168_axi_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
207{
208 struct mmp_clk_unit *unit = &pxa_unit->unit;
209
210 mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
211 ARRAY_SIZE(apmu_mux_clks));
212
213 mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
214 ARRAY_SIZE(apmu_div_clks));
215
216 mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
217 ARRAY_SIZE(apmu_gate_clks));
218}
219
220static void pxa168_clk_reset_init(struct device_node *np,
221 struct pxa168_clk_unit *pxa_unit)
222{
223 struct mmp_clk_reset_cell *cells;
224 int i, nr_resets;
225
226 nr_resets = ARRAY_SIZE(apbc_gate_clks);
227 cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
228 if (!cells)
229 return;
230
231 for (i = 0; i < nr_resets; i++) {
232 cells[i].clk_id = apbc_gate_clks[i].id;
233 cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset;
234 cells[i].flags = 0;
235 cells[i].lock = apbc_gate_clks[i].lock;
236 cells[i].bits = 0x4;
237 }
238
239 mmp_clk_reset_register(np, cells, nr_resets);
240}
241
242static void __init pxa168_clk_init(struct device_node *np)
243{
244 struct pxa168_clk_unit *pxa_unit;
245
246 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
247 if (!pxa_unit)
248 return;
249
250 pxa_unit->mpmu_base = of_iomap(np, 0);
251 if (!pxa_unit->mpmu_base) {
252 pr_err("failed to map mpmu registers\n");
253 return;
254 }
255
256 pxa_unit->apmu_base = of_iomap(np, 1);
257 if (!pxa_unit->mpmu_base) {
258 pr_err("failed to map apmu registers\n");
259 return;
260 }
261
262 pxa_unit->apbc_base = of_iomap(np, 2);
263 if (!pxa_unit->apbc_base) {
264 pr_err("failed to map apbc registers\n");
265 return;
266 }
267
268 mmp_clk_init(np, &pxa_unit->unit, PXA168_NR_CLKS);
269
270 pxa168_pll_init(pxa_unit);
271
272 pxa168_apb_periph_clk_init(pxa_unit);
273
274 pxa168_axi_periph_clk_init(pxa_unit);
275
276 pxa168_clk_reset_init(np, pxa_unit);
277}
278
279CLK_OF_DECLARE(pxa168_clk, "marvell,pxa168-clock", pxa168_clk_init);
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644
index 000000000000..5e3c80dad336
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -0,0 +1,301 @@
1/*
2 * pxa910 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/of_address.h>
19
20#include <dt-bindings/clock/marvell,pxa910.h>
21
22#include "clk.h"
23#include "reset.h"
24
25#define APBC_RTC 0x28
26#define APBC_TWSI0 0x2c
27#define APBC_KPC 0x18
28#define APBC_UART0 0x0
29#define APBC_UART1 0x4
30#define APBC_GPIO 0x8
31#define APBC_PWM0 0xc
32#define APBC_PWM1 0x10
33#define APBC_PWM2 0x14
34#define APBC_PWM3 0x18
35#define APBC_SSP0 0x1c
36#define APBC_SSP1 0x20
37#define APBC_SSP2 0x4c
38#define APBCP_TWSI1 0x28
39#define APBCP_UART2 0x1c
40#define APMU_SDH0 0x54
41#define APMU_SDH1 0x58
42#define APMU_USB 0x5c
43#define APMU_DISP0 0x4c
44#define APMU_CCIC0 0x50
45#define APMU_DFC 0x60
46#define MPMU_UART_PLL 0x14
47
48struct pxa910_clk_unit {
49 struct mmp_clk_unit unit;
50 void __iomem *mpmu_base;
51 void __iomem *apmu_base;
52 void __iomem *apbc_base;
53 void __iomem *apbcp_base;
54};
55
56static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
57 {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
58 {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
59 {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
60};
61
62static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
63 {PXA910_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
64 {PXA910_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
65 {PXA910_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
66 {PXA910_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
67 {PXA910_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
68 {PXA910_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
69 {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
70 {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
71 {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
72 {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
73 {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
74 {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
75 {PXA910_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
76};
77
78static struct mmp_clk_factor_masks uart_factor_masks = {
79 .factor = 2,
80 .num_mask = 0x1fff,
81 .den_mask = 0x1fff,
82 .num_shift = 16,
83 .den_shift = 0,
84};
85
86static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
87 {.num = 8125, .den = 1536}, /*14.745MHZ */
88};
89
90static void pxa910_pll_init(struct pxa910_clk_unit *pxa_unit)
91{
92 struct clk *clk;
93 struct mmp_clk_unit *unit = &pxa_unit->unit;
94
95 mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
96 ARRAY_SIZE(fixed_rate_clks));
97
98 mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
99 ARRAY_SIZE(fixed_factor_clks));
100
101 clk = mmp_clk_register_factor("uart_pll", "pll1_4",
102 CLK_SET_RATE_PARENT,
103 pxa_unit->mpmu_base + MPMU_UART_PLL,
104 &uart_factor_masks, uart_factor_tbl,
105 ARRAY_SIZE(uart_factor_tbl), NULL);
106 mmp_clk_add(unit, PXA910_CLK_UART_PLL, clk);
107}
108
109static DEFINE_SPINLOCK(uart0_lock);
110static DEFINE_SPINLOCK(uart1_lock);
111static DEFINE_SPINLOCK(uart2_lock);
112static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"};
113
114static DEFINE_SPINLOCK(ssp0_lock);
115static DEFINE_SPINLOCK(ssp1_lock);
116static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
117
118static DEFINE_SPINLOCK(reset_lock);
119
120static struct mmp_param_mux_clk apbc_mux_clks[] = {
121 {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
122 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
123 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
124 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
125};
126
127static struct mmp_param_mux_clk apbcp_mux_clks[] = {
128 {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBCP_UART2, 4, 3, 0, &uart2_lock},
129};
130
131static struct mmp_param_gate_clk apbc_gate_clks[] = {
132 {PXA910_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock},
133 {PXA910_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock},
134 {PXA910_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
135 {PXA910_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
136 {PXA910_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock},
137 {PXA910_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock},
138 {PXA910_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock},
139 {PXA910_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock},
140 /* The gate clocks has mux parent. */
141 {PXA910_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock},
142 {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
143 {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock},
144 {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock},
145};
146
147static struct mmp_param_gate_clk apbcp_gate_clks[] = {
148 {PXA910_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBCP_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock},
149 /* The gate clocks has mux parent. */
150 {PXA910_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock},
151};
152
153static void pxa910_apb_periph_clk_init(struct pxa910_clk_unit *pxa_unit)
154{
155 struct mmp_clk_unit *unit = &pxa_unit->unit;
156
157 mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
158 ARRAY_SIZE(apbc_mux_clks));
159
160 mmp_register_mux_clks(unit, apbcp_mux_clks, pxa_unit->apbcp_base,
161 ARRAY_SIZE(apbcp_mux_clks));
162
163 mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
164 ARRAY_SIZE(apbc_gate_clks));
165
166 mmp_register_gate_clks(unit, apbcp_gate_clks, pxa_unit->apbcp_base,
167 ARRAY_SIZE(apbcp_gate_clks));
168}
169
170static DEFINE_SPINLOCK(sdh0_lock);
171static DEFINE_SPINLOCK(sdh1_lock);
172static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"};
173
174static DEFINE_SPINLOCK(usb_lock);
175
176static DEFINE_SPINLOCK(disp0_lock);
177static const char *disp_parent_names[] = {"pll1_2", "pll1_12"};
178
179static DEFINE_SPINLOCK(ccic0_lock);
180static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"};
181static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
182
183static struct mmp_param_mux_clk apmu_mux_clks[] = {
184 {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock},
185 {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock},
186 {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock},
187 {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock},
188 {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock},
189};
190
191static struct mmp_param_div_clk apmu_div_clks[] = {
192 {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
193};
194
195static struct mmp_param_gate_clk apmu_gate_clks[] = {
196 {PXA910_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL},
197 {PXA910_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
198 {PXA910_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock},
199 /* The gate clocks has mux parent. */
200 {PXA910_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
201 {PXA910_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
202 {PXA910_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
203 {PXA910_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
204 {PXA910_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
205 {PXA910_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
206};
207
208static void pxa910_axi_periph_clk_init(struct pxa910_clk_unit *pxa_unit)
209{
210 struct mmp_clk_unit *unit = &pxa_unit->unit;
211
212 mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
213 ARRAY_SIZE(apmu_mux_clks));
214
215 mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
216 ARRAY_SIZE(apmu_div_clks));
217
218 mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
219 ARRAY_SIZE(apmu_gate_clks));
220}
221
222static void pxa910_clk_reset_init(struct device_node *np,
223 struct pxa910_clk_unit *pxa_unit)
224{
225 struct mmp_clk_reset_cell *cells;
226 int i, base, nr_resets_apbc, nr_resets_apbcp, nr_resets;
227
228 nr_resets_apbc = ARRAY_SIZE(apbc_gate_clks);
229 nr_resets_apbcp = ARRAY_SIZE(apbcp_gate_clks);
230 nr_resets = nr_resets_apbc + nr_resets_apbcp;
231 cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
232 if (!cells)
233 return;
234
235 base = 0;
236 for (i = 0; i < nr_resets_apbc; i++) {
237 cells[base + i].clk_id = apbc_gate_clks[i].id;
238 cells[base + i].reg =
239 pxa_unit->apbc_base + apbc_gate_clks[i].offset;
240 cells[base + i].flags = 0;
241 cells[base + i].lock = apbc_gate_clks[i].lock;
242 cells[base + i].bits = 0x4;
243 }
244
245 base = nr_resets_apbc;
246 for (i = 0; i < nr_resets_apbcp; i++) {
247 cells[base + i].clk_id = apbcp_gate_clks[i].id;
248 cells[base + i].reg =
249 pxa_unit->apbc_base + apbc_gate_clks[i].offset;
250 cells[base + i].flags = 0;
251 cells[base + i].lock = apbc_gate_clks[i].lock;
252 cells[base + i].bits = 0x4;
253 }
254
255 mmp_clk_reset_register(np, cells, nr_resets);
256}
257
258static void __init pxa910_clk_init(struct device_node *np)
259{
260 struct pxa910_clk_unit *pxa_unit;
261
262 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
263 if (!pxa_unit)
264 return;
265
266 pxa_unit->mpmu_base = of_iomap(np, 0);
267 if (!pxa_unit->mpmu_base) {
268 pr_err("failed to map mpmu registers\n");
269 return;
270 }
271
272 pxa_unit->apmu_base = of_iomap(np, 1);
273 if (!pxa_unit->mpmu_base) {
274 pr_err("failed to map apmu registers\n");
275 return;
276 }
277
278 pxa_unit->apbc_base = of_iomap(np, 2);
279 if (!pxa_unit->apbc_base) {
280 pr_err("failed to map apbc registers\n");
281 return;
282 }
283
284 pxa_unit->apbcp_base = of_iomap(np, 3);
285 if (!pxa_unit->mpmu_base) {
286 pr_err("failed to map apbcp registers\n");
287 return;
288 }
289
290 mmp_clk_init(np, &pxa_unit->unit, PXA910_NR_CLKS);
291
292 pxa910_pll_init(pxa_unit);
293
294 pxa910_apb_periph_clk_init(pxa_unit);
295
296 pxa910_axi_periph_clk_init(pxa_unit);
297
298 pxa910_clk_reset_init(np, pxa_unit);
299}
300
301CLK_OF_DECLARE(pxa910_clk, "marvell,pxa910-clock", pxa910_clk_init);
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 014396b028a2..93e967c0f972 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -47,7 +47,7 @@
47 47
48static DEFINE_SPINLOCK(clk_lock); 48static DEFINE_SPINLOCK(clk_lock);
49 49
50static struct clk_factor_masks uart_factor_masks = { 50static struct mmp_clk_factor_masks uart_factor_masks = {
51 .factor = 2, 51 .factor = 2,
52 .num_mask = 0x1fff, 52 .num_mask = 0x1fff,
53 .den_mask = 0x1fff, 53 .den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
55 .den_shift = 0, 55 .den_shift = 0,
56}; 56};
57 57
58static struct clk_factor_tbl uart_factor_tbl[] = { 58static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
59 {.num = 8125, .den = 1536}, /*14.745MHZ */ 59 {.num = 8125, .den = 1536}, /*14.745MHZ */
60}; 60};
61 61
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
158 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, 158 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
159 mpmu_base + MPMU_UART_PLL, 159 mpmu_base + MPMU_UART_PLL,
160 &uart_factor_masks, uart_factor_tbl, 160 &uart_factor_masks, uart_factor_tbl,
161 ARRAY_SIZE(uart_factor_tbl)); 161 ARRAY_SIZE(uart_factor_tbl), &clk_lock);
162 clk_set_rate(uart_pll, 14745600); 162 clk_set_rate(uart_pll, 14745600);
163 clk_register_clkdev(uart_pll, "uart_pll", NULL); 163 clk_register_clkdev(uart_pll, "uart_pll", NULL);
164 164
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index 9efc6a47535d..993abcdb32cc 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -45,7 +45,7 @@
45 45
46static DEFINE_SPINLOCK(clk_lock); 46static DEFINE_SPINLOCK(clk_lock);
47 47
48static struct clk_factor_masks uart_factor_masks = { 48static struct mmp_clk_factor_masks uart_factor_masks = {
49 .factor = 2, 49 .factor = 2,
50 .num_mask = 0x1fff, 50 .num_mask = 0x1fff,
51 .den_mask = 0x1fff, 51 .den_mask = 0x1fff,
@@ -53,7 +53,7 @@ static struct clk_factor_masks uart_factor_masks = {
53 .den_shift = 0, 53 .den_shift = 0,
54}; 54};
55 55
56static struct clk_factor_tbl uart_factor_tbl[] = { 56static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
57 {.num = 8125, .den = 1536}, /*14.745MHZ */ 57 {.num = 8125, .den = 1536}, /*14.745MHZ */
58}; 58};
59 59
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
163 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, 163 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
164 mpmu_base + MPMU_UART_PLL, 164 mpmu_base + MPMU_UART_PLL,
165 &uart_factor_masks, uart_factor_tbl, 165 &uart_factor_masks, uart_factor_tbl,
166 ARRAY_SIZE(uart_factor_tbl)); 166 ARRAY_SIZE(uart_factor_tbl), &clk_lock);
167 clk_set_rate(uart_pll, 14745600); 167 clk_set_rate(uart_pll, 14745600);
168 clk_register_clkdev(uart_pll, "uart_pll", NULL); 168 clk_register_clkdev(uart_pll, "uart_pll", NULL);
169 169
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644
index 000000000000..cf038ef54c59
--- /dev/null
+++ b/drivers/clk/mmp/clk.c
@@ -0,0 +1,192 @@
1#include <linux/io.h>
2#include <linux/clk.h>
3#include <linux/clk-provider.h>
4#include <linux/clkdev.h>
5#include <linux/of.h>
6#include <linux/of_address.h>
7
8#include "clk.h"
9
10void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
11 int nr_clks)
12{
13 static struct clk **clk_table;
14
15 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
16 if (!clk_table)
17 return;
18
19 unit->clk_table = clk_table;
20 unit->nr_clks = nr_clks;
21 unit->clk_data.clks = clk_table;
22 unit->clk_data.clk_num = nr_clks;
23 of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data);
24}
25
26void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
27 struct mmp_param_fixed_rate_clk *clks,
28 int size)
29{
30 int i;
31 struct clk *clk;
32
33 for (i = 0; i < size; i++) {
34 clk = clk_register_fixed_rate(NULL, clks[i].name,
35 clks[i].parent_name,
36 clks[i].flags,
37 clks[i].fixed_rate);
38 if (IS_ERR(clk)) {
39 pr_err("%s: failed to register clock %s\n",
40 __func__, clks[i].name);
41 continue;
42 }
43 if (clks[i].id)
44 unit->clk_table[clks[i].id] = clk;
45 }
46}
47
48void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
49 struct mmp_param_fixed_factor_clk *clks,
50 int size)
51{
52 struct clk *clk;
53 int i;
54
55 for (i = 0; i < size; i++) {
56 clk = clk_register_fixed_factor(NULL, clks[i].name,
57 clks[i].parent_name,
58 clks[i].flags, clks[i].mult,
59 clks[i].div);
60 if (IS_ERR(clk)) {
61 pr_err("%s: failed to register clock %s\n",
62 __func__, clks[i].name);
63 continue;
64 }
65 if (clks[i].id)
66 unit->clk_table[clks[i].id] = clk;
67 }
68}
69
70void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
71 struct mmp_param_general_gate_clk *clks,
72 void __iomem *base, int size)
73{
74 struct clk *clk;
75 int i;
76
77 for (i = 0; i < size; i++) {
78 clk = clk_register_gate(NULL, clks[i].name,
79 clks[i].parent_name,
80 clks[i].flags,
81 base + clks[i].offset,
82 clks[i].bit_idx,
83 clks[i].gate_flags,
84 clks[i].lock);
85
86 if (IS_ERR(clk)) {
87 pr_err("%s: failed to register clock %s\n",
88 __func__, clks[i].name);
89 continue;
90 }
91 if (clks[i].id)
92 unit->clk_table[clks[i].id] = clk;
93 }
94}
95
96void mmp_register_gate_clks(struct mmp_clk_unit *unit,
97 struct mmp_param_gate_clk *clks,
98 void __iomem *base, int size)
99{
100 struct clk *clk;
101 int i;
102
103 for (i = 0; i < size; i++) {
104 clk = mmp_clk_register_gate(NULL, clks[i].name,
105 clks[i].parent_name,
106 clks[i].flags,
107 base + clks[i].offset,
108 clks[i].mask,
109 clks[i].val_enable,
110 clks[i].val_disable,
111 clks[i].gate_flags,
112 clks[i].lock);
113
114 if (IS_ERR(clk)) {
115 pr_err("%s: failed to register clock %s\n",
116 __func__, clks[i].name);
117 continue;
118 }
119 if (clks[i].id)
120 unit->clk_table[clks[i].id] = clk;
121 }
122}
123
124void mmp_register_mux_clks(struct mmp_clk_unit *unit,
125 struct mmp_param_mux_clk *clks,
126 void __iomem *base, int size)
127{
128 struct clk *clk;
129 int i;
130
131 for (i = 0; i < size; i++) {
132 clk = clk_register_mux(NULL, clks[i].name,
133 clks[i].parent_name,
134 clks[i].num_parents,
135 clks[i].flags,
136 base + clks[i].offset,
137 clks[i].shift,
138 clks[i].width,
139 clks[i].mux_flags,
140 clks[i].lock);
141
142 if (IS_ERR(clk)) {
143 pr_err("%s: failed to register clock %s\n",
144 __func__, clks[i].name);
145 continue;
146 }
147 if (clks[i].id)
148 unit->clk_table[clks[i].id] = clk;
149 }
150}
151
152void mmp_register_div_clks(struct mmp_clk_unit *unit,
153 struct mmp_param_div_clk *clks,
154 void __iomem *base, int size)
155{
156 struct clk *clk;
157 int i;
158
159 for (i = 0; i < size; i++) {
160 clk = clk_register_divider(NULL, clks[i].name,
161 clks[i].parent_name,
162 clks[i].flags,
163 base + clks[i].offset,
164 clks[i].shift,
165 clks[i].width,
166 clks[i].div_flags,
167 clks[i].lock);
168
169 if (IS_ERR(clk)) {
170 pr_err("%s: failed to register clock %s\n",
171 __func__, clks[i].name);
172 continue;
173 }
174 if (clks[i].id)
175 unit->clk_table[clks[i].id] = clk;
176 }
177}
178
179void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
180 struct clk *clk)
181{
182 if (IS_ERR_OR_NULL(clk)) {
183 pr_err("CLK %d has invalid pointer %p\n", id, clk);
184 return;
185 }
186 if (id > unit->nr_clks) {
187 pr_err("CLK %d is invalid\n", id);
188 return;
189 }
190
191 unit->clk_table[id] = clk;
192}
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index ab86dd4a416a..adf9b711b037 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -7,19 +7,123 @@
7#define APBC_NO_BUS_CTRL BIT(0) 7#define APBC_NO_BUS_CTRL BIT(0)
8#define APBC_POWER_CTRL BIT(1) 8#define APBC_POWER_CTRL BIT(1)
9 9
10struct clk_factor_masks { 10
11 unsigned int factor; 11/* Clock type "factor" */
12 unsigned int num_mask; 12struct mmp_clk_factor_masks {
13 unsigned int den_mask; 13 unsigned int factor;
14 unsigned int num_shift; 14 unsigned int num_mask;
15 unsigned int den_shift; 15 unsigned int den_mask;
16 unsigned int num_shift;
17 unsigned int den_shift;
16}; 18};
17 19
18struct clk_factor_tbl { 20struct mmp_clk_factor_tbl {
19 unsigned int num; 21 unsigned int num;
20 unsigned int den; 22 unsigned int den;
21}; 23};
22 24
25struct mmp_clk_factor {
26 struct clk_hw hw;
27 void __iomem *base;
28 struct mmp_clk_factor_masks *masks;
29 struct mmp_clk_factor_tbl *ftbl;
30 unsigned int ftbl_cnt;
31 spinlock_t *lock;
32};
33
34extern struct clk *mmp_clk_register_factor(const char *name,
35 const char *parent_name, unsigned long flags,
36 void __iomem *base, struct mmp_clk_factor_masks *masks,
37 struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
38 spinlock_t *lock);
39
40/* Clock type "mix" */
41#define MMP_CLK_BITS_MASK(width, shift) \
42 (((1 << (width)) - 1) << (shift))
43#define MMP_CLK_BITS_GET_VAL(data, width, shift) \
44 ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
45#define MMP_CLK_BITS_SET_VAL(val, width, shift) \
46 (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
47
48enum {
49 MMP_CLK_MIX_TYPE_V1,
50 MMP_CLK_MIX_TYPE_V2,
51 MMP_CLK_MIX_TYPE_V3,
52};
53
54/* The register layout */
55struct mmp_clk_mix_reg_info {
56 void __iomem *reg_clk_ctrl;
57 void __iomem *reg_clk_sel;
58 u8 width_div;
59 u8 shift_div;
60 u8 width_mux;
61 u8 shift_mux;
62 u8 bit_fc;
63};
64
65/* The suggested clock table from user. */
66struct mmp_clk_mix_clk_table {
67 unsigned long rate;
68 u8 parent_index;
69 unsigned int divisor;
70 unsigned int valid;
71};
72
73struct mmp_clk_mix_config {
74 struct mmp_clk_mix_reg_info reg_info;
75 struct mmp_clk_mix_clk_table *table;
76 unsigned int table_size;
77 u32 *mux_table;
78 struct clk_div_table *div_table;
79 u8 div_flags;
80 u8 mux_flags;
81};
82
83struct mmp_clk_mix {
84 struct clk_hw hw;
85 struct mmp_clk_mix_reg_info reg_info;
86 struct mmp_clk_mix_clk_table *table;
87 u32 *mux_table;
88 struct clk_div_table *div_table;
89 unsigned int table_size;
90 u8 div_flags;
91 u8 mux_flags;
92 unsigned int type;
93 spinlock_t *lock;
94};
95
96extern const struct clk_ops mmp_clk_mix_ops;
97extern struct clk *mmp_clk_register_mix(struct device *dev,
98 const char *name,
99 const char **parent_names,
100 u8 num_parents,
101 unsigned long flags,
102 struct mmp_clk_mix_config *config,
103 spinlock_t *lock);
104
105
106/* Clock type "gate". MMP private gate */
107#define MMP_CLK_GATE_NEED_DELAY BIT(0)
108
109struct mmp_clk_gate {
110 struct clk_hw hw;
111 void __iomem *reg;
112 u32 mask;
113 u32 val_enable;
114 u32 val_disable;
115 unsigned int flags;
116 spinlock_t *lock;
117};
118
119extern const struct clk_ops mmp_clk_gate_ops;
120extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
121 const char *parent_name, unsigned long flags,
122 void __iomem *reg, u32 mask, u32 val_enable,
123 u32 val_disable, unsigned int gate_flags,
124 spinlock_t *lock);
125
126
23extern struct clk *mmp_clk_register_pll2(const char *name, 127extern struct clk *mmp_clk_register_pll2(const char *name,
24 const char *parent_name, unsigned long flags); 128 const char *parent_name, unsigned long flags);
25extern struct clk *mmp_clk_register_apbc(const char *name, 129extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,8 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
28extern struct clk *mmp_clk_register_apmu(const char *name, 132extern struct clk *mmp_clk_register_apmu(const char *name,
29 const char *parent_name, void __iomem *base, u32 enable_mask, 133 const char *parent_name, void __iomem *base, u32 enable_mask,
30 spinlock_t *lock); 134 spinlock_t *lock);
31extern struct clk *mmp_clk_register_factor(const char *name, 135
32 const char *parent_name, unsigned long flags, 136struct mmp_clk_unit {
33 void __iomem *base, struct clk_factor_masks *masks, 137 unsigned int nr_clks;
34 struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt); 138 struct clk **clk_table;
139 struct clk_onecell_data clk_data;
140};
141
142struct mmp_param_fixed_rate_clk {
143 unsigned int id;
144 char *name;
145 const char *parent_name;
146 unsigned long flags;
147 unsigned long fixed_rate;
148};
149void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
150 struct mmp_param_fixed_rate_clk *clks,
151 int size);
152
153struct mmp_param_fixed_factor_clk {
154 unsigned int id;
155 char *name;
156 const char *parent_name;
157 unsigned long mult;
158 unsigned long div;
159 unsigned long flags;
160};
161void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
162 struct mmp_param_fixed_factor_clk *clks,
163 int size);
164
165struct mmp_param_general_gate_clk {
166 unsigned int id;
167 const char *name;
168 const char *parent_name;
169 unsigned long flags;
170 unsigned long offset;
171 u8 bit_idx;
172 u8 gate_flags;
173 spinlock_t *lock;
174};
175void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
176 struct mmp_param_general_gate_clk *clks,
177 void __iomem *base, int size);
178
179struct mmp_param_gate_clk {
180 unsigned int id;
181 char *name;
182 const char *parent_name;
183 unsigned long flags;
184 unsigned long offset;
185 u32 mask;
186 u32 val_enable;
187 u32 val_disable;
188 unsigned int gate_flags;
189 spinlock_t *lock;
190};
191void mmp_register_gate_clks(struct mmp_clk_unit *unit,
192 struct mmp_param_gate_clk *clks,
193 void __iomem *base, int size);
194
195struct mmp_param_mux_clk {
196 unsigned int id;
197 char *name;
198 const char **parent_name;
199 u8 num_parents;
200 unsigned long flags;
201 unsigned long offset;
202 u8 shift;
203 u8 width;
204 u8 mux_flags;
205 spinlock_t *lock;
206};
207void mmp_register_mux_clks(struct mmp_clk_unit *unit,
208 struct mmp_param_mux_clk *clks,
209 void __iomem *base, int size);
210
211struct mmp_param_div_clk {
212 unsigned int id;
213 char *name;
214 const char *parent_name;
215 unsigned long flags;
216 unsigned long offset;
217 u8 shift;
218 u8 width;
219 u8 div_flags;
220 spinlock_t *lock;
221};
222void mmp_register_div_clks(struct mmp_clk_unit *unit,
223 struct mmp_param_div_clk *clks,
224 void __iomem *base, int size);
225
226#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
227{ \
228 .width_div = (w_d), \
229 .shift_div = (s_d), \
230 .width_mux = (w_m), \
231 .shift_mux = (s_m), \
232 .bit_fc = (fc), \
233}
234
235void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
236 int nr_clks);
237void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
238 struct clk *clk);
35#endif 239#endif
diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c
new file mode 100644
index 000000000000..b54da1fe73f0
--- /dev/null
+++ b/drivers/clk/mmp/reset.c
@@ -0,0 +1,99 @@
1#include <linux/slab.h>
2#include <linux/io.h>
3#include <linux/of.h>
4#include <linux/of_address.h>
5#include <linux/reset-controller.h>
6
7#include "reset.h"
8
9#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)
10
11static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,
12 const struct of_phandle_args *reset_spec)
13{
14 struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
15 struct mmp_clk_reset_cell *cell;
16 int i;
17
18 if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
19 return -EINVAL;
20
21 for (i = 0; i < rcdev->nr_resets; i++) {
22 cell = &unit->cells[i];
23 if (cell->clk_id == reset_spec->args[0])
24 break;
25 }
26
27 if (i == rcdev->nr_resets)
28 return -EINVAL;
29
30 return i;
31}
32
33static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,
34 unsigned long id)
35{
36 struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
37 struct mmp_clk_reset_cell *cell;
38 unsigned long flags = 0;
39 u32 val;
40
41 cell = &unit->cells[id];
42 if (cell->lock)
43 spin_lock_irqsave(cell->lock, flags);
44
45 val = readl(cell->reg);
46 val |= cell->bits;
47 writel(val, cell->reg);
48
49 if (cell->lock)
50 spin_unlock_irqrestore(cell->lock, flags);
51
52 return 0;
53}
54
55static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
56 unsigned long id)
57{
58 struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
59 struct mmp_clk_reset_cell *cell;
60 unsigned long flags = 0;
61 u32 val;
62
63 cell = &unit->cells[id];
64 if (cell->lock)
65 spin_lock_irqsave(cell->lock, flags);
66
67 val = readl(cell->reg);
68 val &= ~cell->bits;
69 writel(val, cell->reg);
70
71 if (cell->lock)
72 spin_unlock_irqrestore(cell->lock, flags);
73
74 return 0;
75}
76
77static struct reset_control_ops mmp_clk_reset_ops = {
78 .assert = mmp_clk_reset_assert,
79 .deassert = mmp_clk_reset_deassert,
80};
81
82void mmp_clk_reset_register(struct device_node *np,
83 struct mmp_clk_reset_cell *cells, int nr_resets)
84{
85 struct mmp_clk_reset_unit *unit;
86
87 unit = kzalloc(sizeof(*unit), GFP_KERNEL);
88 if (!unit)
89 return;
90
91 unit->cells = cells;
92 unit->rcdev.of_reset_n_cells = 1;
93 unit->rcdev.nr_resets = nr_resets;
94 unit->rcdev.ops = &mmp_clk_reset_ops;
95 unit->rcdev.of_node = np;
96 unit->rcdev.of_xlate = mmp_of_reset_xlate;
97
98 reset_controller_register(&unit->rcdev);
99}
diff --git a/drivers/clk/mmp/reset.h b/drivers/clk/mmp/reset.h
new file mode 100644
index 000000000000..be8b1a7000f7
--- /dev/null
+++ b/drivers/clk/mmp/reset.h
@@ -0,0 +1,31 @@
1#ifndef __MACH_MMP_CLK_RESET_H
2#define __MACH_MMP_CLK_RESET_H
3
4#include <linux/reset-controller.h>
5
6#define MMP_RESET_INVERT 1
7
8struct mmp_clk_reset_cell {
9 unsigned int clk_id;
10 void __iomem *reg;
11 u32 bits;
12 unsigned int flags;
13 spinlock_t *lock;
14};
15
16struct mmp_clk_reset_unit {
17 struct reset_controller_dev rcdev;
18 struct mmp_clk_reset_cell *cells;
19};
20
21#ifdef CONFIG_RESET_CONTROLLER
22void mmp_clk_reset_register(struct device_node *np,
23 struct mmp_clk_reset_cell *cells, int nr_resets);
24#else
25static inline void mmp_clk_reset_register(struct device_node *np,
26 struct mmp_clk_reset_cell *cells, int nr_resets)
27{
28}
29#endif
30
31#endif
diff --git a/drivers/clk/pxa/Makefile b/drivers/clk/pxa/Makefile
index 4ff2abcd500b..38e915344605 100644
--- a/drivers/clk/pxa/Makefile
+++ b/drivers/clk/pxa/Makefile
@@ -1,2 +1,3 @@
1obj-y += clk-pxa.o 1obj-y += clk-pxa.o
2obj-$(CONFIG_PXA25x) += clk-pxa25x.o
2obj-$(CONFIG_PXA27x) += clk-pxa27x.o 3obj-$(CONFIG_PXA27x) += clk-pxa27x.o
diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c
index ef3c05389c0a..4e834753ab09 100644
--- a/drivers/clk/pxa/clk-pxa.c
+++ b/drivers/clk/pxa/clk-pxa.c
@@ -26,12 +26,20 @@ static struct clk_onecell_data onecell_data = {
26 .clk_num = CLK_MAX, 26 .clk_num = CLK_MAX,
27}; 27};
28 28
29#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw) 29struct pxa_clk {
30 struct clk_hw hw;
31 struct clk_fixed_factor lp;
32 struct clk_fixed_factor hp;
33 struct clk_gate gate;
34 bool (*is_in_low_power)(void);
35};
36
37#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk, hw)
30 38
31static unsigned long cken_recalc_rate(struct clk_hw *hw, 39static unsigned long cken_recalc_rate(struct clk_hw *hw,
32 unsigned long parent_rate) 40 unsigned long parent_rate)
33{ 41{
34 struct pxa_clk_cken *pclk = to_pxa_clk(hw); 42 struct pxa_clk *pclk = to_pxa_clk(hw);
35 struct clk_fixed_factor *fix; 43 struct clk_fixed_factor *fix;
36 44
37 if (!pclk->is_in_low_power || pclk->is_in_low_power()) 45 if (!pclk->is_in_low_power || pclk->is_in_low_power())
@@ -48,7 +56,7 @@ static struct clk_ops cken_rate_ops = {
48 56
49static u8 cken_get_parent(struct clk_hw *hw) 57static u8 cken_get_parent(struct clk_hw *hw)
50{ 58{
51 struct pxa_clk_cken *pclk = to_pxa_clk(hw); 59 struct pxa_clk *pclk = to_pxa_clk(hw);
52 60
53 if (!pclk->is_in_low_power) 61 if (!pclk->is_in_low_power)
54 return 0; 62 return 0;
@@ -69,29 +77,32 @@ void __init clkdev_pxa_register(int ckid, const char *con_id,
69 clk_register_clkdev(clk, con_id, dev_id); 77 clk_register_clkdev(clk, con_id, dev_id);
70} 78}
71 79
72int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks) 80int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks)
73{ 81{
74 int i; 82 int i;
75 struct pxa_clk_cken *pclk; 83 struct pxa_clk *pxa_clk;
76 struct clk *clk; 84 struct clk *clk;
77 85
78 for (i = 0; i < nb_clks; i++) { 86 for (i = 0; i < nb_clks; i++) {
79 pclk = clks + i; 87 pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL);
80 pclk->gate.lock = &lock; 88 pxa_clk->is_in_low_power = clks[i].is_in_low_power;
81 clk = clk_register_composite(NULL, pclk->name, 89 pxa_clk->lp = clks[i].lp;
82 pclk->parent_names, 2, 90 pxa_clk->hp = clks[i].hp;
83 &pclk->hw, &cken_mux_ops, 91 pxa_clk->gate = clks[i].gate;
84 &pclk->hw, &cken_rate_ops, 92 pxa_clk->gate.lock = &lock;
85 &pclk->gate.hw, &clk_gate_ops, 93 clk = clk_register_composite(NULL, clks[i].name,
86 pclk->flags); 94 clks[i].parent_names, 2,
87 clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id, 95 &pxa_clk->hw, &cken_mux_ops,
88 clk); 96 &pxa_clk->hw, &cken_rate_ops,
97 &pxa_clk->gate.hw, &clk_gate_ops,
98 clks[i].flags);
99 clkdev_pxa_register(clks[i].ckid, clks[i].con_id,
100 clks[i].dev_id, clk);
89 } 101 }
90 return 0; 102 return 0;
91} 103}
92 104
93static void __init pxa_dt_clocks_init(struct device_node *np) 105void __init clk_pxa_dt_common_init(struct device_node *np)
94{ 106{
95 of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data); 107 of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data);
96} 108}
97CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init);
diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h
index 5fe219d06b49..323965430111 100644
--- a/drivers/clk/pxa/clk-pxa.h
+++ b/drivers/clk/pxa/clk-pxa.h
@@ -25,7 +25,7 @@
25 static struct clk_ops name ## _rate_ops = { \ 25 static struct clk_ops name ## _rate_ops = { \
26 .recalc_rate = name ## _get_rate, \ 26 .recalc_rate = name ## _get_rate, \
27 }; \ 27 }; \
28 static struct clk *clk_register_ ## name(void) \ 28 static struct clk * __init clk_register_ ## name(void) \
29 { \ 29 { \
30 return clk_register_composite(NULL, clk_name, \ 30 return clk_register_composite(NULL, clk_name, \
31 name ## _parents, \ 31 name ## _parents, \
@@ -40,7 +40,7 @@
40 static struct clk_ops name ## _rate_ops = { \ 40 static struct clk_ops name ## _rate_ops = { \
41 .recalc_rate = name ## _get_rate, \ 41 .recalc_rate = name ## _get_rate, \
42 }; \ 42 }; \
43 static struct clk *clk_register_ ## name(void) \ 43 static struct clk * __init clk_register_ ## name(void) \
44 { \ 44 { \
45 return clk_register_composite(NULL, clk_name, \ 45 return clk_register_composite(NULL, clk_name, \
46 name ## _parents, \ 46 name ## _parents, \
@@ -66,7 +66,7 @@
66 * | Clock | --- | / div_hp | 66 * | Clock | --- | / div_hp |
67 * +------------+ +-----------+ 67 * +------------+ +-----------+
68 */ 68 */
69struct pxa_clk_cken { 69struct desc_clk_cken {
70 struct clk_hw hw; 70 struct clk_hw hw;
71 int ckid; 71 int ckid;
72 const char *name; 72 const char *name;
@@ -102,6 +102,7 @@ static int dummy_clk_set_parent(struct clk_hw *hw, u8 index)
102 102
103extern void clkdev_pxa_register(int ckid, const char *con_id, 103extern void clkdev_pxa_register(int ckid, const char *con_id,
104 const char *dev_id, struct clk *clk); 104 const char *dev_id, struct clk *clk);
105extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks); 105extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks);
106void clk_pxa_dt_common_init(struct device_node *np);
106 107
107#endif 108#endif
diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c
new file mode 100644
index 000000000000..6cd88d963a7f
--- /dev/null
+++ b/drivers/clk/pxa/clk-pxa25x.c
@@ -0,0 +1,273 @@
1/*
2 * Marvell PXA25x family clocks
3 *
4 * Copyright (C) 2014 Robert Jarzmik
5 *
6 * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
13 * should go away.
14 */
15#include <linux/clk-provider.h>
16#include <linux/clk.h>
17#include <linux/clkdev.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <mach/pxa25x.h>
21#include <mach/pxa2xx-regs.h>
22
23#include <dt-bindings/clock/pxa-clock.h>
24#include "clk-pxa.h"
25
26#define KHz 1000
27#define MHz (1000 * 1000)
28
29enum {
30 PXA_CORE_RUN = 0,
31 PXA_CORE_TURBO,
32};
33
34/*
35 * Various clock factors driven by the CCCR register.
36 */
37
38/* Crystal Frequency to Memory Frequency Multiplier (L) */
39static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
40
41/* Memory Frequency to Run Mode Frequency Multiplier (M) */
42static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
43
44/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
45/* Note: we store the value N * 2 here. */
46static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
47
48static const char * const get_freq_khz[] = {
49 "core", "run", "cpll", "memory"
50};
51
52/*
53 * Get the clock frequency as reflected by CCCR and the turbo flag.
54 * We assume these values have been applied via a fcs.
55 * If info is not 0 we also display the current settings.
56 */
57unsigned int pxa25x_get_clk_frequency_khz(int info)
58{
59 struct clk *clk;
60 unsigned long clks[5];
61 int i;
62
63 for (i = 0; i < ARRAY_SIZE(get_freq_khz); i++) {
64 clk = clk_get(NULL, get_freq_khz[i]);
65 if (IS_ERR(clk)) {
66 clks[i] = 0;
67 } else {
68 clks[i] = clk_get_rate(clk);
69 clk_put(clk);
70 }
71 }
72
73 if (info) {
74 pr_info("Run Mode clock: %ld.%02ldMHz\n",
75 clks[1] / 1000000, (clks[1] % 1000000) / 10000);
76 pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
77 clks[2] / 1000000, (clks[2] % 1000000) / 10000);
78 pr_info("Memory clock: %ld.%02ldMHz\n",
79 clks[3] / 1000000, (clks[3] % 1000000) / 10000);
80 }
81
82 return (unsigned int)clks[0];
83}
84
85static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw,
86 unsigned long parent_rate)
87{
88 unsigned long cccr = CCCR;
89 unsigned int m = M_clk_mult[(cccr >> 5) & 0x03];
90
91 return parent_rate / m;
92}
93PARENTS(clk_pxa25x_memory) = { "run" };
94RATE_RO_OPS(clk_pxa25x_memory, "memory");
95
96PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" };
97PARENTS(pxa25x_pbus147) = { "ppll_147_46mhz", "ppll_147_46mhz" };
98PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" };
99
100#define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \
101 bit, is_lp, flags) \
102 PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \
103 is_lp, &CKEN, CKEN_ ## bit, flags)
104#define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
105 PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \
106 div_hp, bit, NULL, 0)
107#define PXA25X_PBUS147_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)\
108 PXA25X_CKEN(dev_id, con_id, pxa25x_pbus147_parents, mult_hp, \
109 div_hp, bit, NULL, 0)
110#define PXA25X_OSC3_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
111 PXA25X_CKEN(dev_id, con_id, pxa25x_osc3_parents, mult_hp, \
112 div_hp, bit, NULL, 0)
113
114#define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \
115 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
116 &CKEN, CKEN_ ## bit, 0)
117#define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \
118 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
119 &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
120
121static struct desc_clk_cken pxa25x_clocks[] __initdata = {
122 PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0),
123 PXA25X_PBUS95_CKEN("pxa2xx-i2c.0", NULL, I2C, 1, 3, 0),
124 PXA25X_PBUS95_CKEN("pxa2xx-ir", "FICPCLK", FICP, 1, 2, 0),
125 PXA25X_PBUS95_CKEN("pxa25x-udc", NULL, USB, 1, 2, 5),
126 PXA25X_PBUS147_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 10, 1),
127 PXA25X_PBUS147_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 10, 1),
128 PXA25X_PBUS147_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 10, 1),
129 PXA25X_PBUS147_CKEN("pxa2xx-uart.3", NULL, HWUART, 1, 10, 1),
130 PXA25X_PBUS147_CKEN("pxa2xx-i2s", NULL, I2S, 1, 10, 0),
131 PXA25X_PBUS147_CKEN(NULL, "AC97CLK", AC97, 1, 12, 0),
132 PXA25X_OSC3_CKEN("pxa25x-ssp.0", NULL, SSP, 1, 1, 0),
133 PXA25X_OSC3_CKEN("pxa25x-nssp.1", NULL, NSSP, 1, 1, 0),
134 PXA25X_OSC3_CKEN("pxa25x-nssp.2", NULL, ASSP, 1, 1, 0),
135 PXA25X_OSC3_CKEN("pxa25x-pwm.0", NULL, PWM0, 1, 1, 0),
136 PXA25X_OSC3_CKEN("pxa25x-pwm.1", NULL, PWM1, 1, 1, 0),
137
138 PXA25X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, clk_pxa25x_memory_parents, 0),
139 PXA25X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC,
140 clk_pxa25x_memory_parents, 0),
141};
142
143static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw)
144{
145 unsigned long clkcfg;
146 unsigned int t;
147
148 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
149 t = clkcfg & (1 << 0);
150 if (t)
151 return PXA_CORE_TURBO;
152 return PXA_CORE_RUN;
153}
154
155static unsigned long clk_pxa25x_core_get_rate(struct clk_hw *hw,
156 unsigned long parent_rate)
157{
158 return parent_rate;
159}
160PARENTS(clk_pxa25x_core) = { "run", "cpll" };
161MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core");
162
163static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw,
164 unsigned long parent_rate)
165{
166 unsigned long cccr = CCCR;
167 unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07];
168
169 return (parent_rate / n2) * 2;
170}
171PARENTS(clk_pxa25x_run) = { "cpll" };
172RATE_RO_OPS(clk_pxa25x_run, "run");
173
174static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw,
175 unsigned long parent_rate)
176{
177 unsigned long clkcfg, cccr = CCCR;
178 unsigned int l, m, n2, t;
179
180 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
181 t = clkcfg & (1 << 0);
182 l = L_clk_mult[(cccr >> 0) & 0x1f];
183 m = M_clk_mult[(cccr >> 5) & 0x03];
184 n2 = N2_clk_mult[(cccr >> 7) & 0x07];
185
186 if (t)
187 return m * l * n2 * parent_rate / 2;
188 return m * l * parent_rate;
189}
190PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" };
191RATE_RO_OPS(clk_pxa25x_cpll, "cpll");
192
193static void __init pxa25x_register_core(void)
194{
195 clk_register_clk_pxa25x_cpll();
196 clk_register_clk_pxa25x_run();
197 clkdev_pxa_register(CLK_CORE, "core", NULL,
198 clk_register_clk_pxa25x_core());
199}
200
201static void __init pxa25x_register_plls(void)
202{
203 clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL,
204 CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
205 3686400);
206 clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
207 CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
208 32768);
209 clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
210 clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz",
211 0, 26, 1);
212 clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz",
213 0, 40, 1);
214}
215
216static void __init pxa25x_base_clocks_init(void)
217{
218 pxa25x_register_plls();
219 pxa25x_register_core();
220 clk_register_clk_pxa25x_memory();
221}
222
223#define DUMMY_CLK(_con_id, _dev_id, _parent) \
224 { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
225struct dummy_clk {
226 const char *con_id;
227 const char *dev_id;
228 const char *parent;
229};
230static struct dummy_clk dummy_clks[] __initdata = {
231 DUMMY_CLK(NULL, "pxa25x-gpio", "osc_32_768khz"),
232 DUMMY_CLK(NULL, "pxa26x-gpio", "osc_32_768khz"),
233 DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"),
234 DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"),
235 DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
236 DUMMY_CLK("OSTIMER0", NULL, "osc_32_768khz"),
237 DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
238};
239
240static void __init pxa25x_dummy_clocks_init(void)
241{
242 struct clk *clk;
243 struct dummy_clk *d;
244 const char *name;
245 int i;
246
247 /*
248 * All pinctrl logic has been wiped out of the clock driver, especially
249 * for gpio11 and gpio12 outputs. Machine code should ensure proper pin
250 * control (ie. pxa2xx_mfp_config() invocation).
251 */
252 for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
253 d = &dummy_clks[i];
254 name = d->dev_id ? d->dev_id : d->con_id;
255 clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
256 clk_register_clkdev(clk, d->con_id, d->dev_id);
257 }
258}
259
260int __init pxa25x_clocks_init(void)
261{
262 pxa25x_base_clocks_init();
263 pxa25x_dummy_clocks_init();
264 return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks));
265}
266
267static void __init pxa25x_dt_clocks_init(struct device_node *np)
268{
269 pxa25x_clocks_init();
270 clk_pxa_dt_common_init(np);
271}
272CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks",
273 pxa25x_dt_clocks_init);
diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c
index 88b9fe13fa44..5f9b54b024b9 100644
--- a/drivers/clk/pxa/clk-pxa27x.c
+++ b/drivers/clk/pxa/clk-pxa27x.c
@@ -111,7 +111,7 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" };
111 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ 111 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
112 &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) 112 &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
113 113
114static struct pxa_clk_cken pxa27x_clocks[] = { 114static struct desc_clk_cken pxa27x_clocks[] __initdata = {
115 PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), 115 PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1),
116 PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1), 116 PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1),
117 PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1), 117 PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1),
@@ -368,3 +368,10 @@ static int __init pxa27x_clocks_init(void)
368 return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); 368 return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks));
369} 369}
370postcore_initcall(pxa27x_clocks_init); 370postcore_initcall(pxa27x_clocks_init);
371
372static void __init pxa27x_dt_clocks_init(struct device_node *np)
373{
374 pxa27x_clocks_init();
375 clk_pxa_dt_common_init(np);
376}
377CLK_OF_DECLARE(pxa_clks, "marvell,pxa270-clocks", pxa27x_dt_clocks_init);
diff --git a/drivers/clk/qcom/clk-pll.c b/drivers/clk/qcom/clk-pll.c
index b823bc3b6250..60873a7f45d9 100644
--- a/drivers/clk/qcom/clk-pll.c
+++ b/drivers/clk/qcom/clk-pll.c
@@ -141,7 +141,7 @@ struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
141 141
142static long 142static long
143clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate, 143clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
144 unsigned long *p_rate, struct clk **p) 144 unsigned long *p_rate, struct clk_hw **p)
145{ 145{
146 struct clk_pll *pll = to_clk_pll(hw); 146 struct clk_pll *pll = to_clk_pll(hw);
147 const struct pll_freq_tbl *f; 147 const struct pll_freq_tbl *f;
diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
index b6e6959e89aa..0b93972c8807 100644
--- a/drivers/clk/qcom/clk-rcg.c
+++ b/drivers/clk/qcom/clk-rcg.c
@@ -368,16 +368,17 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
368 368
369static long _freq_tbl_determine_rate(struct clk_hw *hw, 369static long _freq_tbl_determine_rate(struct clk_hw *hw,
370 const struct freq_tbl *f, unsigned long rate, 370 const struct freq_tbl *f, unsigned long rate,
371 unsigned long *p_rate, struct clk **p) 371 unsigned long *p_rate, struct clk_hw **p_hw)
372{ 372{
373 unsigned long clk_flags; 373 unsigned long clk_flags;
374 struct clk *p;
374 375
375 f = qcom_find_freq(f, rate); 376 f = qcom_find_freq(f, rate);
376 if (!f) 377 if (!f)
377 return -EINVAL; 378 return -EINVAL;
378 379
379 clk_flags = __clk_get_flags(hw->clk); 380 clk_flags = __clk_get_flags(hw->clk);
380 *p = clk_get_parent_by_index(hw->clk, f->src); 381 p = clk_get_parent_by_index(hw->clk, f->src);
381 if (clk_flags & CLK_SET_RATE_PARENT) { 382 if (clk_flags & CLK_SET_RATE_PARENT) {
382 rate = rate * f->pre_div; 383 rate = rate * f->pre_div;
383 if (f->n) { 384 if (f->n) {
@@ -387,15 +388,16 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
387 rate = tmp; 388 rate = tmp;
388 } 389 }
389 } else { 390 } else {
390 rate = __clk_get_rate(*p); 391 rate = __clk_get_rate(p);
391 } 392 }
393 *p_hw = __clk_get_hw(p);
392 *p_rate = rate; 394 *p_rate = rate;
393 395
394 return f->freq; 396 return f->freq;
395} 397}
396 398
397static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, 399static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
398 unsigned long *p_rate, struct clk **p) 400 unsigned long *p_rate, struct clk_hw **p)
399{ 401{
400 struct clk_rcg *rcg = to_clk_rcg(hw); 402 struct clk_rcg *rcg = to_clk_rcg(hw);
401 403
@@ -403,7 +405,7 @@ static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
403} 405}
404 406
405static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, 407static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
406 unsigned long *p_rate, struct clk **p) 408 unsigned long *p_rate, struct clk_hw **p)
407{ 409{
408 struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); 410 struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
409 411
@@ -411,13 +413,15 @@ static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
411} 413}
412 414
413static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate, 415static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
414 unsigned long *p_rate, struct clk **p) 416 unsigned long *p_rate, struct clk_hw **p_hw)
415{ 417{
416 struct clk_rcg *rcg = to_clk_rcg(hw); 418 struct clk_rcg *rcg = to_clk_rcg(hw);
417 const struct freq_tbl *f = rcg->freq_tbl; 419 const struct freq_tbl *f = rcg->freq_tbl;
420 struct clk *p;
418 421
419 *p = clk_get_parent_by_index(hw->clk, f->src); 422 p = clk_get_parent_by_index(hw->clk, f->src);
420 *p_rate = __clk_round_rate(*p, rate); 423 *p_hw = __clk_get_hw(p);
424 *p_rate = __clk_round_rate(p, rate);
421 425
422 return *p_rate; 426 return *p_rate;
423} 427}
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index cfa9eb4fe9ca..08b8b3729f53 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -175,16 +175,17 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
175 175
176static long _freq_tbl_determine_rate(struct clk_hw *hw, 176static long _freq_tbl_determine_rate(struct clk_hw *hw,
177 const struct freq_tbl *f, unsigned long rate, 177 const struct freq_tbl *f, unsigned long rate,
178 unsigned long *p_rate, struct clk **p) 178 unsigned long *p_rate, struct clk_hw **p_hw)
179{ 179{
180 unsigned long clk_flags; 180 unsigned long clk_flags;
181 struct clk *p;
181 182
182 f = qcom_find_freq(f, rate); 183 f = qcom_find_freq(f, rate);
183 if (!f) 184 if (!f)
184 return -EINVAL; 185 return -EINVAL;
185 186
186 clk_flags = __clk_get_flags(hw->clk); 187 clk_flags = __clk_get_flags(hw->clk);
187 *p = clk_get_parent_by_index(hw->clk, f->src); 188 p = clk_get_parent_by_index(hw->clk, f->src);
188 if (clk_flags & CLK_SET_RATE_PARENT) { 189 if (clk_flags & CLK_SET_RATE_PARENT) {
189 if (f->pre_div) { 190 if (f->pre_div) {
190 rate /= 2; 191 rate /= 2;
@@ -198,15 +199,16 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
198 rate = tmp; 199 rate = tmp;
199 } 200 }
200 } else { 201 } else {
201 rate = __clk_get_rate(*p); 202 rate = __clk_get_rate(p);
202 } 203 }
204 *p_hw = __clk_get_hw(p);
203 *p_rate = rate; 205 *p_rate = rate;
204 206
205 return f->freq; 207 return f->freq;
206} 208}
207 209
208static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate, 210static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
209 unsigned long *p_rate, struct clk **p) 211 unsigned long *p_rate, struct clk_hw **p)
210{ 212{
211 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 213 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
212 214
@@ -359,7 +361,7 @@ static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
359} 361}
360 362
361static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, 363static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
362 unsigned long *p_rate, struct clk **p) 364 unsigned long *p_rate, struct clk_hw **p)
363{ 365{
364 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 366 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
365 const struct freq_tbl *f = rcg->freq_tbl; 367 const struct freq_tbl *f = rcg->freq_tbl;
@@ -371,7 +373,7 @@ static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
371 u32 hid_div; 373 u32 hid_div;
372 374
373 /* Force the correct parent */ 375 /* Force the correct parent */
374 *p = clk_get_parent_by_index(hw->clk, f->src); 376 *p = __clk_get_hw(clk_get_parent_by_index(hw->clk, f->src));
375 377
376 if (src_rate == 810000000) 378 if (src_rate == 810000000)
377 frac = frac_table_810m; 379 frac = frac_table_810m;
@@ -410,18 +412,20 @@ const struct clk_ops clk_edp_pixel_ops = {
410EXPORT_SYMBOL_GPL(clk_edp_pixel_ops); 412EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
411 413
412static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate, 414static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
413 unsigned long *p_rate, struct clk **p) 415 unsigned long *p_rate, struct clk_hw **p_hw)
414{ 416{
415 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 417 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
416 const struct freq_tbl *f = rcg->freq_tbl; 418 const struct freq_tbl *f = rcg->freq_tbl;
417 unsigned long parent_rate, div; 419 unsigned long parent_rate, div;
418 u32 mask = BIT(rcg->hid_width) - 1; 420 u32 mask = BIT(rcg->hid_width) - 1;
421 struct clk *p;
419 422
420 if (rate == 0) 423 if (rate == 0)
421 return -EINVAL; 424 return -EINVAL;
422 425
423 *p = clk_get_parent_by_index(hw->clk, f->src); 426 p = clk_get_parent_by_index(hw->clk, f->src);
424 *p_rate = parent_rate = __clk_round_rate(*p, rate); 427 *p_hw = __clk_get_hw(p);
428 *p_rate = parent_rate = __clk_round_rate(p, rate);
425 429
426 div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; 430 div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
427 div = min_t(u32, div, mask); 431 div = min_t(u32, div, mask);
@@ -472,14 +476,16 @@ static const struct frac_entry frac_table_pixel[] = {
472}; 476};
473 477
474static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, 478static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
475 unsigned long *p_rate, struct clk **p) 479 unsigned long *p_rate, struct clk_hw **p)
476{ 480{
477 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 481 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
478 unsigned long request, src_rate; 482 unsigned long request, src_rate;
479 int delta = 100000; 483 int delta = 100000;
480 const struct freq_tbl *f = rcg->freq_tbl; 484 const struct freq_tbl *f = rcg->freq_tbl;
481 const struct frac_entry *frac = frac_table_pixel; 485 const struct frac_entry *frac = frac_table_pixel;
482 struct clk *parent = *p = clk_get_parent_by_index(hw->clk, f->src); 486 struct clk *parent = clk_get_parent_by_index(hw->clk, f->src);
487
488 *p = __clk_get_hw(parent);
483 489
484 for (; frac->num; frac++) { 490 for (; frac->num; frac++) {
485 request = (rate * frac->den) / frac->num; 491 request = (rate * frac->den) / frac->num;
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index bd8514d63634..2714097f90db 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -6,6 +6,7 @@ obj-y += clk-rockchip.o
6obj-y += clk.o 6obj-y += clk.o
7obj-y += clk-pll.o 7obj-y += clk-pll.o
8obj-y += clk-cpu.o 8obj-y += clk-cpu.o
9obj-y += clk-mmc-phase.o
9obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 10obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
10 11
11obj-y += clk-rk3188.o 12obj-y += clk-rk3188.o
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
new file mode 100644
index 000000000000..c842e3b60f21
--- /dev/null
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright 2014 Google, Inc
3 * Author: Alexandru M Stan <amstan@chromium.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/slab.h>
17#include <linux/clk-provider.h>
18#include "clk.h"
19
20struct rockchip_mmc_clock {
21 struct clk_hw hw;
22 void __iomem *reg;
23 int id;
24 int shift;
25};
26
27#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw)
28
29#define RK3288_MMC_CLKGEN_DIV 2
30
31static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
32 unsigned long parent_rate)
33{
34 return parent_rate / RK3288_MMC_CLKGEN_DIV;
35}
36
37#define ROCKCHIP_MMC_DELAY_SEL BIT(10)
38#define ROCKCHIP_MMC_DEGREE_MASK 0x3
39#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
40#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
41
42#define PSECS_PER_SEC 1000000000000LL
43
44/*
45 * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to
46 * simplify calculations. So 45degs could be anywhere between 33deg and 66deg.
47 */
48#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
49
50static int rockchip_mmc_get_phase(struct clk_hw *hw)
51{
52 struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
53 unsigned long rate = clk_get_rate(hw->clk);
54 u32 raw_value;
55 u16 degrees;
56 u32 delay_num = 0;
57
58 raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
59
60 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
61
62 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
63 /* degrees/delaynum * 10000 */
64 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
65 36 * (rate / 1000000);
66
67 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
68 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
69 degrees += delay_num * factor / 10000;
70 }
71
72 return degrees % 360;
73}
74
75static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
76{
77 struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
78 unsigned long rate = clk_get_rate(hw->clk);
79 u8 nineties, remainder;
80 u8 delay_num;
81 u32 raw_value;
82 u64 delay;
83
84 /* allow 22 to be 22.5 */
85 degrees++;
86 /* floor to 22.5 increment */
87 degrees -= ((degrees) * 10 % 225) / 10;
88
89 nineties = degrees / 90;
90 /* 22.5 multiples */
91 remainder = (degrees % 90) / 22;
92
93 delay = PSECS_PER_SEC;
94 do_div(delay, rate);
95 /* / 360 / 22.5 */
96 do_div(delay, 16);
97 do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
98
99 delay *= remainder;
100 delay_num = (u8) min(delay, 255ULL);
101
102 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
103 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
104 raw_value |= nineties;
105 writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg);
106
107 pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
108 __clk_get_name(hw->clk), degrees, delay_num,
109 mmc_clock->reg, raw_value>>(mmc_clock->shift),
110 rockchip_mmc_get_phase(hw)
111 );
112
113 return 0;
114}
115
116static const struct clk_ops rockchip_mmc_clk_ops = {
117 .recalc_rate = rockchip_mmc_recalc,
118 .get_phase = rockchip_mmc_get_phase,
119 .set_phase = rockchip_mmc_set_phase,
120};
121
122struct clk *rockchip_clk_register_mmc(const char *name,
123 const char **parent_names, u8 num_parents,
124 void __iomem *reg, int shift)
125{
126 struct clk_init_data init;
127 struct rockchip_mmc_clock *mmc_clock;
128 struct clk *clk;
129
130 mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL);
131 if (!mmc_clock)
132 return NULL;
133
134 init.num_parents = num_parents;
135 init.parent_names = parent_names;
136 init.ops = &rockchip_mmc_clk_ops;
137
138 mmc_clock->hw.init = &init;
139 mmc_clock->reg = reg;
140 mmc_clock->shift = shift;
141
142 if (name)
143 init.name = name;
144
145 clk = clk_register(NULL, &mmc_clock->hw);
146 if (IS_ERR(clk))
147 goto err_free;
148
149 return clk;
150
151err_free:
152 kfree(mmc_clock);
153 return NULL;
154}
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index a3e886a38480..f8d3baf275b2 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -39,6 +39,7 @@ struct rockchip_clk_pll {
39 int lock_offset; 39 int lock_offset;
40 unsigned int lock_shift; 40 unsigned int lock_shift;
41 enum rockchip_pll_type type; 41 enum rockchip_pll_type type;
42 u8 flags;
42 const struct rockchip_pll_rate_table *rate_table; 43 const struct rockchip_pll_rate_table *rate_table;
43 unsigned int rate_count; 44 unsigned int rate_count;
44 spinlock_t *lock; 45 spinlock_t *lock;
@@ -257,6 +258,55 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
257 return !(pllcon & RK3066_PLLCON3_PWRDOWN); 258 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
258} 259}
259 260
261static void rockchip_rk3066_pll_init(struct clk_hw *hw)
262{
263 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
264 const struct rockchip_pll_rate_table *rate;
265 unsigned int nf, nr, no, bwadj;
266 unsigned long drate;
267 u32 pllcon;
268
269 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
270 return;
271
272 drate = __clk_get_rate(hw->clk);
273 rate = rockchip_get_pll_settings(pll, drate);
274
275 /* when no rate setting for the current rate, rely on clk_set_rate */
276 if (!rate)
277 return;
278
279 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
280 nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
281 no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
282
283 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
284 nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
285
286 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
287 bwadj = (pllcon >> RK3066_PLLCON2_BWADJ_SHIFT) & RK3066_PLLCON2_BWADJ_MASK;
288
289 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), bwadj(%d:%d)\n",
290 __func__, __clk_get_name(hw->clk), drate, rate->nr, nr,
291 rate->no, no, rate->nf, nf, rate->bwadj, bwadj);
292 if (rate->nr != nr || rate->no != no || rate->nf != nf
293 || rate->bwadj != bwadj) {
294 struct clk *parent = __clk_get_parent(hw->clk);
295 unsigned long prate;
296
297 if (!parent) {
298 pr_warn("%s: parent of %s not available\n",
299 __func__, __clk_get_name(hw->clk));
300 return;
301 }
302
303 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
304 __func__, __clk_get_name(hw->clk));
305 prate = __clk_get_rate(parent);
306 rockchip_rk3066_pll_set_rate(hw, drate, prate);
307 }
308}
309
260static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { 310static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
261 .recalc_rate = rockchip_rk3066_pll_recalc_rate, 311 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
262 .enable = rockchip_rk3066_pll_enable, 312 .enable = rockchip_rk3066_pll_enable,
@@ -271,6 +321,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
271 .enable = rockchip_rk3066_pll_enable, 321 .enable = rockchip_rk3066_pll_enable,
272 .disable = rockchip_rk3066_pll_disable, 322 .disable = rockchip_rk3066_pll_disable,
273 .is_enabled = rockchip_rk3066_pll_is_enabled, 323 .is_enabled = rockchip_rk3066_pll_is_enabled,
324 .init = rockchip_rk3066_pll_init,
274}; 325};
275 326
276/* 327/*
@@ -282,7 +333,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
282 void __iomem *base, int con_offset, int grf_lock_offset, 333 void __iomem *base, int con_offset, int grf_lock_offset,
283 int lock_shift, int mode_offset, int mode_shift, 334 int lock_shift, int mode_offset, int mode_shift,
284 struct rockchip_pll_rate_table *rate_table, 335 struct rockchip_pll_rate_table *rate_table,
285 spinlock_t *lock) 336 u8 clk_pll_flags, spinlock_t *lock)
286{ 337{
287 const char *pll_parents[3]; 338 const char *pll_parents[3];
288 struct clk_init_data init; 339 struct clk_init_data init;
@@ -345,8 +396,22 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
345 pll->reg_base = base + con_offset; 396 pll->reg_base = base + con_offset;
346 pll->lock_offset = grf_lock_offset; 397 pll->lock_offset = grf_lock_offset;
347 pll->lock_shift = lock_shift; 398 pll->lock_shift = lock_shift;
399 pll->flags = clk_pll_flags;
348 pll->lock = lock; 400 pll->lock = lock;
349 401
402 /* create the mux on top of the real pll */
403 pll->pll_mux_ops = &clk_mux_ops;
404 pll_mux = &pll->pll_mux;
405 pll_mux->reg = base + mode_offset;
406 pll_mux->shift = mode_shift;
407 pll_mux->mask = PLL_MODE_MASK;
408 pll_mux->flags = 0;
409 pll_mux->lock = lock;
410 pll_mux->hw.init = &init;
411
412 if (pll_type == pll_rk3066)
413 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
414
350 pll_clk = clk_register(NULL, &pll->hw); 415 pll_clk = clk_register(NULL, &pll->hw);
351 if (IS_ERR(pll_clk)) { 416 if (IS_ERR(pll_clk)) {
352 pr_err("%s: failed to register pll clock %s : %ld\n", 417 pr_err("%s: failed to register pll clock %s : %ld\n",
@@ -355,10 +420,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
355 goto err_pll; 420 goto err_pll;
356 } 421 }
357 422
358 /* create the mux on top of the real pll */
359 pll->pll_mux_ops = &clk_mux_ops;
360 pll_mux = &pll->pll_mux;
361
362 /* the actual muxing is xin24m, pll-output, xin32k */ 423 /* the actual muxing is xin24m, pll-output, xin32k */
363 pll_parents[0] = parent_names[0]; 424 pll_parents[0] = parent_names[0];
364 pll_parents[1] = pll_name; 425 pll_parents[1] = pll_name;
@@ -370,16 +431,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
370 init.parent_names = pll_parents; 431 init.parent_names = pll_parents;
371 init.num_parents = ARRAY_SIZE(pll_parents); 432 init.num_parents = ARRAY_SIZE(pll_parents);
372 433
373 pll_mux->reg = base + mode_offset;
374 pll_mux->shift = mode_shift;
375 pll_mux->mask = PLL_MODE_MASK;
376 pll_mux->flags = 0;
377 pll_mux->lock = lock;
378 pll_mux->hw.init = &init;
379
380 if (pll_type == pll_rk3066)
381 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
382
383 mux_clk = clk_register(NULL, &pll_mux->hw); 434 mux_clk = clk_register(NULL, &pll_mux->hw);
384 if (IS_ERR(mux_clk)) 435 if (IS_ERR(mux_clk))
385 goto err_mux; 436 goto err_mux;
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index beed49c79126..c54078960847 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -212,13 +212,13 @@ PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" };
212 212
213static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { 213static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
214 [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), 214 [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
215 RK2928_MODE_CON, 0, 6, rk3188_pll_rates), 215 RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates),
216 [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), 216 [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
217 RK2928_MODE_CON, 4, 5, NULL), 217 RK2928_MODE_CON, 4, 5, 0, NULL),
218 [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), 218 [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8),
219 RK2928_MODE_CON, 8, 7, rk3188_pll_rates), 219 RK2928_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
220 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), 220 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
221 RK2928_MODE_CON, 12, 8, rk3188_pll_rates), 221 RK2928_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
222}; 222};
223 223
224#define MFLAGS CLK_MUX_HIWORD_MASK 224#define MFLAGS CLK_MUX_HIWORD_MASK
@@ -257,9 +257,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
257 GATE(0, "hclk_vdpu", "aclk_vdpu", 0, 257 GATE(0, "hclk_vdpu", "aclk_vdpu", 0,
258 RK2928_CLKGATE_CON(3), 12, GFLAGS), 258 RK2928_CLKGATE_CON(3), 12, GFLAGS),
259 259
260 GATE(0, "gpll_ddr", "gpll", 0, 260 GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
261 RK2928_CLKGATE_CON(1), 7, GFLAGS), 261 RK2928_CLKGATE_CON(1), 7, GFLAGS),
262 COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0, 262 COMPOSITE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED,
263 RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 263 RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
264 RK2928_CLKGATE_CON(0), 2, GFLAGS), 264 RK2928_CLKGATE_CON(0), 2, GFLAGS),
265 265
@@ -270,10 +270,10 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
270 RK2928_CLKGATE_CON(0), 6, GFLAGS), 270 RK2928_CLKGATE_CON(0), 6, GFLAGS),
271 GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, 271 GATE(0, "pclk_cpu", "pclk_cpu_pre", 0,
272 RK2928_CLKGATE_CON(0), 5, GFLAGS), 272 RK2928_CLKGATE_CON(0), 5, GFLAGS),
273 GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, 273 GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED,
274 RK2928_CLKGATE_CON(0), 4, GFLAGS), 274 RK2928_CLKGATE_CON(0), 4, GFLAGS),
275 275
276 COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0, 276 COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
277 RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS, 277 RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS,
278 RK2928_CLKGATE_CON(3), 0, GFLAGS), 278 RK2928_CLKGATE_CON(3), 0, GFLAGS),
279 COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0, 279 COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0,
@@ -304,9 +304,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
304 * the 480m are generated inside the usb block from these clocks, 304 * the 480m are generated inside the usb block from these clocks,
305 * but they are also a source for the hsicphy clock. 305 * but they are also a source for the hsicphy clock.
306 */ 306 */
307 GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, 307 GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
308 RK2928_CLKGATE_CON(1), 5, GFLAGS), 308 RK2928_CLKGATE_CON(1), 5, GFLAGS),
309 GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, 309 GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
310 RK2928_CLKGATE_CON(1), 6, GFLAGS), 310 RK2928_CLKGATE_CON(1), 6, GFLAGS),
311 311
312 COMPOSITE(0, "mac_src", mux_mac_p, 0, 312 COMPOSITE(0, "mac_src", mux_mac_p, 0,
@@ -320,9 +320,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
320 COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, 320 COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0,
321 RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, 321 RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
322 RK2928_CLKGATE_CON(2), 6, GFLAGS), 322 RK2928_CLKGATE_CON(2), 6, GFLAGS),
323 COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 323 COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0,
324 RK2928_CLKSEL_CON(23), 0, 324 RK2928_CLKSEL_CON(23), 0,
325 RK2928_CLKGATE_CON(2), 7, 0, GFLAGS), 325 RK2928_CLKGATE_CON(2), 7, GFLAGS),
326 MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0, 326 MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0,
327 RK2928_CLKSEL_CON(22), 4, 2, MFLAGS), 327 RK2928_CLKSEL_CON(22), 4, 2, MFLAGS),
328 328
@@ -330,6 +330,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
330 RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, 330 RK2928_CLKSEL_CON(24), 8, 8, DFLAGS,
331 RK2928_CLKGATE_CON(2), 8, GFLAGS), 331 RK2928_CLKGATE_CON(2), 8, GFLAGS),
332 332
333 COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
334 RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
335 RK2928_CLKGATE_CON(0), 13, GFLAGS),
336 COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
337 RK2928_CLKSEL_CON(9), 0,
338 RK2928_CLKGATE_CON(0), 14, GFLAGS),
339 MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
340 RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
341
333 /* 342 /*
334 * Clock-Architecture Diagram 4 343 * Clock-Architecture Diagram 4
335 */ 344 */
@@ -399,8 +408,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
399 408
400 /* aclk_cpu gates */ 409 /* aclk_cpu gates */
401 GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), 410 GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS),
402 GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS), 411 GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
403 GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS), 412 GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
404 413
405 /* hclk_cpu gates */ 414 /* hclk_cpu gates */
406 GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), 415 GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS),
@@ -410,14 +419,14 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
410 /* hclk_ahb2apb is part of a clk branch */ 419 /* hclk_ahb2apb is part of a clk branch */
411 GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), 420 GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS),
412 GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), 421 GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS),
413 GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), 422 GATE(HCLK_LCDC1, "hclk_lcdc1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS),
414 GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), 423 GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS),
415 GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS), 424 GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS),
416 GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), 425 GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS),
417 426
418 /* hclk_peri gates */ 427 /* hclk_peri gates */
419 GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS), 428 GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
420 GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS), 429 GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS),
421 GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), 430 GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS),
422 GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), 431 GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
423 GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), 432 GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
@@ -457,18 +466,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
457 GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), 466 GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
458 GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), 467 GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
459 GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), 468 GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
460 GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS), 469 GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
461 GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS), 470 GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS),
462 471
463 /* aclk_peri */ 472 /* aclk_peri */
464 GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), 473 GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
465 GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS), 474 GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS),
466 GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS), 475 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 4, GFLAGS),
467 GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS), 476 GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
468 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS), 477 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
469 478
470 /* pclk_peri gates */ 479 /* pclk_peri gates */
471 GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS), 480 GATE(0, "pclk_peri_axi_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
472 GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS), 481 GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS),
473 GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), 482 GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
474 GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), 483 GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
@@ -511,7 +520,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
511 | CLK_DIVIDER_READ_ONLY, 520 | CLK_DIVIDER_READ_ONLY,
512 RK2928_CLKGATE_CON(4), 9, GFLAGS), 521 RK2928_CLKGATE_CON(4), 9, GFLAGS),
513 522
514 GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, 523 GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED,
515 RK2928_CLKGATE_CON(9), 4, GFLAGS), 524 RK2928_CLKGATE_CON(9), 4, GFLAGS),
516 525
517 COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, 526 COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0,
@@ -577,14 +586,6 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
577 RK2928_CLKGATE_CON(0), 12, GFLAGS), 586 RK2928_CLKGATE_CON(0), 12, GFLAGS),
578 MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, 587 MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0,
579 RK2928_CLKSEL_CON(4), 8, 2, MFLAGS), 588 RK2928_CLKSEL_CON(4), 8, 2, MFLAGS),
580 COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
581 RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
582 RK2928_CLKGATE_CON(0), 13, GFLAGS),
583 COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
584 RK2928_CLKSEL_CON(9), 0,
585 RK2928_CLKGATE_CON(0), 14, GFLAGS),
586 MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
587 RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
588 589
589 GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), 590 GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
590 GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 591 GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
@@ -618,7 +619,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1",
618 "gpll", "cpll" }; 619 "gpll", "cpll" };
619 620
620static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { 621static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
621 COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, 622 COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
622 RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 623 RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
623 div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), 624 div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS),
624 625
@@ -633,7 +634,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
633 RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 634 RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
634 RK2928_CLKGATE_CON(4), 9, GFLAGS), 635 RK2928_CLKGATE_CON(4), 9, GFLAGS),
635 636
636 GATE(CORE_L2C, "core_l2c", "armclk", 0, 637 GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED,
637 RK2928_CLKGATE_CON(9), 4, GFLAGS), 638 RK2928_CLKGATE_CON(9), 4, GFLAGS),
638 639
639 COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, 640 COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0,
@@ -663,7 +664,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
663 RK2928_CLKSEL_CON(30), 0, 2, DFLAGS, 664 RK2928_CLKSEL_CON(30), 0, 2, DFLAGS,
664 RK2928_CLKGATE_CON(3), 6, GFLAGS), 665 RK2928_CLKGATE_CON(3), 6, GFLAGS),
665 DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0, 666 DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0,
666 RK2928_CLKGATE_CON(11), 8, 6, DFLAGS), 667 RK2928_CLKSEL_CON(11), 8, 6, DFLAGS),
667 668
668 MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, 669 MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0,
669 RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), 670 RK2928_CLKSEL_CON(2), 15, 1, MFLAGS),
@@ -675,14 +676,6 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
675 RK2928_CLKGATE_CON(0), 10, GFLAGS), 676 RK2928_CLKGATE_CON(0), 10, GFLAGS),
676 MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, 677 MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
677 RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), 678 RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
678 COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
679 RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
680 RK2928_CLKGATE_CON(13), 13, GFLAGS),
681 COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
682 RK2928_CLKSEL_CON(9), 0,
683 RK2928_CLKGATE_CON(0), 14, GFLAGS),
684 MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
685 RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
686 679
687 GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), 680 GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
688 GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), 681 GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 23278291da44..ac6be7c0132d 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -16,6 +16,7 @@
16#include <linux/clk-provider.h> 16#include <linux/clk-provider.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/syscore_ops.h>
19#include <dt-bindings/clock/rk3288-cru.h> 20#include <dt-bindings/clock/rk3288-cru.h>
20#include "clk.h" 21#include "clk.h"
21 22
@@ -83,11 +84,13 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = {
83 RK3066_PLL_RATE( 742500000, 8, 495, 2), 84 RK3066_PLL_RATE( 742500000, 8, 495, 2),
84 RK3066_PLL_RATE( 696000000, 1, 58, 2), 85 RK3066_PLL_RATE( 696000000, 1, 58, 2),
85 RK3066_PLL_RATE( 600000000, 1, 50, 2), 86 RK3066_PLL_RATE( 600000000, 1, 50, 2),
86 RK3066_PLL_RATE( 594000000, 2, 198, 4), 87 RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1),
87 RK3066_PLL_RATE( 552000000, 1, 46, 2), 88 RK3066_PLL_RATE( 552000000, 1, 46, 2),
88 RK3066_PLL_RATE( 504000000, 1, 84, 4), 89 RK3066_PLL_RATE( 504000000, 1, 84, 4),
90 RK3066_PLL_RATE( 500000000, 3, 125, 2),
89 RK3066_PLL_RATE( 456000000, 1, 76, 4), 91 RK3066_PLL_RATE( 456000000, 1, 76, 4),
90 RK3066_PLL_RATE( 408000000, 1, 68, 4), 92 RK3066_PLL_RATE( 408000000, 1, 68, 4),
93 RK3066_PLL_RATE( 400000000, 3, 100, 2),
91 RK3066_PLL_RATE( 384000000, 2, 128, 4), 94 RK3066_PLL_RATE( 384000000, 2, 128, 4),
92 RK3066_PLL_RATE( 360000000, 1, 60, 4), 95 RK3066_PLL_RATE( 360000000, 1, 60, 4),
93 RK3066_PLL_RATE( 312000000, 1, 52, 4), 96 RK3066_PLL_RATE( 312000000, 1, 52, 4),
@@ -173,14 +176,14 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
173PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 176PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
174PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; 177PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
175PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; 178PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
176PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" }; 179PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" };
180PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" };
177 181
178PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; 182PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
179PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; 183PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
180PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; 184PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
181PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; 185PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" };
182PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; 186PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" };
183PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" };
184PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; 187PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
185PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; 188PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
186PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; 189PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
@@ -192,22 +195,22 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
192PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; 195PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
193PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; 196PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
194 197
195PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1", 198PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2",
196 "sclk_otgphy2" }; 199 "sclk_otgphy0" };
197PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 200PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
198PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; 201PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" };
199 202
200static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { 203static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = {
201 [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), 204 [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0),
202 RK3288_MODE_CON, 0, 6, rk3288_pll_rates), 205 RK3288_MODE_CON, 0, 6, 0, rk3288_pll_rates),
203 [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), 206 [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4),
204 RK3288_MODE_CON, 4, 5, NULL), 207 RK3288_MODE_CON, 4, 5, 0, NULL),
205 [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), 208 [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8),
206 RK3288_MODE_CON, 8, 7, rk3288_pll_rates), 209 RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
207 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), 210 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12),
208 RK3288_MODE_CON, 12, 8, rk3288_pll_rates), 211 RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
209 [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), 212 [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16),
210 RK3288_MODE_CON, 14, 9, rk3288_pll_rates), 213 RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
211}; 214};
212 215
213static struct clk_div_table div_hclk_cpu_t[] = { 216static struct clk_div_table div_hclk_cpu_t[] = {
@@ -226,67 +229,67 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
226 * Clock-Architecture Diagram 1 229 * Clock-Architecture Diagram 1
227 */ 230 */
228 231
229 GATE(0, "apll_core", "apll", 0, 232 GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
230 RK3288_CLKGATE_CON(0), 1, GFLAGS), 233 RK3288_CLKGATE_CON(0), 1, GFLAGS),
231 GATE(0, "gpll_core", "gpll", 0, 234 GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
232 RK3288_CLKGATE_CON(0), 2, GFLAGS), 235 RK3288_CLKGATE_CON(0), 2, GFLAGS),
233 236
234 COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, 237 COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED,
235 RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 238 RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
236 RK3288_CLKGATE_CON(12), 0, GFLAGS), 239 RK3288_CLKGATE_CON(12), 0, GFLAGS),
237 COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, 240 COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED,
238 RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 241 RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
239 RK3288_CLKGATE_CON(12), 1, GFLAGS), 242 RK3288_CLKGATE_CON(12), 1, GFLAGS),
240 COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, 243 COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED,
241 RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 244 RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
242 RK3288_CLKGATE_CON(12), 2, GFLAGS), 245 RK3288_CLKGATE_CON(12), 2, GFLAGS),
243 COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, 246 COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED,
244 RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 247 RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
245 RK3288_CLKGATE_CON(12), 3, GFLAGS), 248 RK3288_CLKGATE_CON(12), 3, GFLAGS),
246 COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, 249 COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED,
247 RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 250 RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
248 RK3288_CLKGATE_CON(12), 4, GFLAGS), 251 RK3288_CLKGATE_CON(12), 4, GFLAGS),
249 COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, 252 COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED,
250 RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 253 RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
251 RK3288_CLKGATE_CON(12), 5, GFLAGS), 254 RK3288_CLKGATE_CON(12), 5, GFLAGS),
252 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, 255 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
253 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 256 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
254 RK3288_CLKGATE_CON(12), 6, GFLAGS), 257 RK3288_CLKGATE_CON(12), 6, GFLAGS),
255 COMPOSITE_NOMUX(0, "atclk", "armclk", 0, 258 COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
256 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 259 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
257 RK3288_CLKGATE_CON(12), 7, GFLAGS), 260 RK3288_CLKGATE_CON(12), 7, GFLAGS),
258 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, 261 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
259 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 262 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
260 RK3288_CLKGATE_CON(12), 8, GFLAGS), 263 RK3288_CLKGATE_CON(12), 8, GFLAGS),
261 GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, 264 GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
262 RK3288_CLKGATE_CON(12), 9, GFLAGS), 265 RK3288_CLKGATE_CON(12), 9, GFLAGS),
263 GATE(0, "cs_dbg", "pclk_dbg_pre", 0, 266 GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
264 RK3288_CLKGATE_CON(12), 10, GFLAGS), 267 RK3288_CLKGATE_CON(12), 10, GFLAGS),
265 GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, 268 GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0,
266 RK3288_CLKGATE_CON(12), 11, GFLAGS), 269 RK3288_CLKGATE_CON(12), 11, GFLAGS),
267 270
268 GATE(0, "dpll_ddr", "dpll", 0, 271 GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
269 RK3288_CLKGATE_CON(0), 8, GFLAGS), 272 RK3288_CLKGATE_CON(0), 8, GFLAGS),
270 GATE(0, "gpll_ddr", "gpll", 0, 273 GATE(0, "gpll_ddr", "gpll", 0,
271 RK3288_CLKGATE_CON(0), 9, GFLAGS), 274 RK3288_CLKGATE_CON(0), 9, GFLAGS),
272 COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0, 275 COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED,
273 RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, 276 RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2,
274 DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 277 DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
275 278
276 GATE(0, "gpll_aclk_cpu", "gpll", 0, 279 GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED,
277 RK3288_CLKGATE_CON(0), 10, GFLAGS), 280 RK3288_CLKGATE_CON(0), 10, GFLAGS),
278 GATE(0, "cpll_aclk_cpu", "cpll", 0, 281 GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED,
279 RK3288_CLKGATE_CON(0), 11, GFLAGS), 282 RK3288_CLKGATE_CON(0), 11, GFLAGS),
280 COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, 283 COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED,
281 RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), 284 RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS),
282 DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, 285 DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT,
283 RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), 286 RK3288_CLKSEL_CON(1), 0, 3, DFLAGS),
284 GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, 287 GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
285 RK3288_CLKGATE_CON(0), 3, GFLAGS), 288 RK3288_CLKGATE_CON(0), 3, GFLAGS),
286 COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0, 289 COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
287 RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, 290 RK3288_CLKSEL_CON(1), 12, 3, DFLAGS,
288 RK3288_CLKGATE_CON(0), 5, GFLAGS), 291 RK3288_CLKGATE_CON(0), 5, GFLAGS),
289 COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0, 292 COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
290 RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, 293 RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t,
291 RK3288_CLKGATE_CON(0), 4, GFLAGS), 294 RK3288_CLKGATE_CON(0), 4, GFLAGS),
292 GATE(0, "c2c_host", "aclk_cpu_src", 0, 295 GATE(0, "c2c_host", "aclk_cpu_src", 0,
@@ -294,7 +297,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
294 COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, 297 COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0,
295 RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, 298 RK3288_CLKSEL_CON(26), 6, 2, DFLAGS,
296 RK3288_CLKGATE_CON(5), 4, GFLAGS), 299 RK3288_CLKGATE_CON(5), 4, GFLAGS),
297 GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0, 300 GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
298 RK3288_CLKGATE_CON(0), 7, GFLAGS), 301 RK3288_CLKGATE_CON(0), 7, GFLAGS),
299 302
300 COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, 303 COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0,
@@ -305,7 +308,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
305 RK3288_CLKGATE_CON(4), 2, GFLAGS), 308 RK3288_CLKGATE_CON(4), 2, GFLAGS),
306 MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, 309 MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
307 RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), 310 RK3288_CLKSEL_CON(4), 8, 2, MFLAGS),
308 COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT, 311 COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0,
309 RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, 312 RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
310 RK3288_CLKGATE_CON(4), 0, GFLAGS), 313 RK3288_CLKGATE_CON(4), 0, GFLAGS),
311 GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, 314 GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT,
@@ -325,7 +328,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
325 COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, 328 COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0,
326 RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, 329 RK3288_CLKSEL_CON(40), 0, 7, DFLAGS,
327 RK3288_CLKGATE_CON(4), 7, GFLAGS), 330 RK3288_CLKGATE_CON(4), 7, GFLAGS),
328 COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0, 331 COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0,
329 RK3288_CLKSEL_CON(41), 0, 332 RK3288_CLKSEL_CON(41), 0,
330 RK3288_CLKGATE_CON(4), 8, GFLAGS), 333 RK3288_CLKGATE_CON(4), 8, GFLAGS),
331 COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, 334 COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0,
@@ -373,12 +376,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
373 GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, 376 GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
374 RK3288_CLKGATE_CON(9), 1, GFLAGS), 377 RK3288_CLKGATE_CON(9), 1, GFLAGS),
375 378
376 COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, 379 COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
377 RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, 380 RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
378 RK3288_CLKGATE_CON(3), 0, GFLAGS), 381 RK3288_CLKGATE_CON(3), 0, GFLAGS),
379 DIV(0, "hclk_vio", "aclk_vio0", 0, 382 DIV(0, "hclk_vio", "aclk_vio0", 0,
380 RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), 383 RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
381 COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0, 384 COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
382 RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, 385 RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
383 RK3288_CLKGATE_CON(3), 2, GFLAGS), 386 RK3288_CLKGATE_CON(3), 2, GFLAGS),
384 387
@@ -436,24 +439,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
436 439
437 DIV(0, "pclk_pd_alive", "gpll", 0, 440 DIV(0, "pclk_pd_alive", "gpll", 0,
438 RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), 441 RK3288_CLKSEL_CON(33), 8, 5, DFLAGS),
439 COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0, 442 COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED,
440 RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, 443 RK3288_CLKSEL_CON(33), 0, 5, DFLAGS,
441 RK3288_CLKGATE_CON(5), 8, GFLAGS), 444 RK3288_CLKGATE_CON(5), 8, GFLAGS),
442 445
443 COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 446 COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0,
444 RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, 447 RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS,
445 RK3288_CLKGATE_CON(5), 7, GFLAGS), 448 RK3288_CLKGATE_CON(5), 7, GFLAGS),
446 449
447 COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, 450 COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
448 RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, 451 RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
449 RK3288_CLKGATE_CON(2), 0, GFLAGS), 452 RK3288_CLKGATE_CON(2), 0, GFLAGS),
450 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, 453 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
451 RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 454 RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
452 RK3288_CLKGATE_CON(2), 3, GFLAGS), 455 RK3288_CLKGATE_CON(2), 3, GFLAGS),
453 COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, 456 COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
454 RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 457 RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
455 RK3288_CLKGATE_CON(2), 2, GFLAGS), 458 RK3288_CLKGATE_CON(2), 2, GFLAGS),
456 GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, 459 GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
457 RK3288_CLKGATE_CON(2), 1, GFLAGS), 460 RK3288_CLKGATE_CON(2), 1, GFLAGS),
458 461
459 /* 462 /*
@@ -483,6 +486,18 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
483 RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, 486 RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS,
484 RK3288_CLKGATE_CON(13), 3, GFLAGS), 487 RK3288_CLKGATE_CON(13), 3, GFLAGS),
485 488
489 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3288_SDMMC_CON0, 1),
490 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3288_SDMMC_CON1, 0),
491
492 MMC(SCLK_SDIO0_DRV, "sdio0_drv", "sclk_sdio0", RK3288_SDIO0_CON0, 1),
493 MMC(SCLK_SDIO0_SAMPLE, "sdio0_sample", "sclk_sdio0", RK3288_SDIO0_CON1, 0),
494
495 MMC(SCLK_SDIO1_DRV, "sdio1_drv", "sclk_sdio1", RK3288_SDIO1_CON0, 1),
496 MMC(SCLK_SDIO1_SAMPLE, "sdio1_sample", "sclk_sdio1", RK3288_SDIO1_CON1, 0),
497
498 MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3288_EMMC_CON0, 1),
499 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3288_EMMC_CON1, 0),
500
486 COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0, 501 COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0,
487 RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, 502 RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS,
488 RK3288_CLKGATE_CON(4), 11, GFLAGS), 503 RK3288_CLKGATE_CON(4), 11, GFLAGS),
@@ -490,13 +505,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
490 RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, 505 RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
491 RK3288_CLKGATE_CON(4), 10, GFLAGS), 506 RK3288_CLKGATE_CON(4), 10, GFLAGS),
492 507
493 GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, 508 GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
494 RK3288_CLKGATE_CON(13), 4, GFLAGS), 509 RK3288_CLKGATE_CON(13), 4, GFLAGS),
495 GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, 510 GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
496 RK3288_CLKGATE_CON(13), 5, GFLAGS), 511 RK3288_CLKGATE_CON(13), 5, GFLAGS),
497 GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0, 512 GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED,
498 RK3288_CLKGATE_CON(13), 6, GFLAGS), 513 RK3288_CLKGATE_CON(13), 6, GFLAGS),
499 GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0, 514 GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED,
500 RK3288_CLKGATE_CON(13), 7, GFLAGS), 515 RK3288_CLKGATE_CON(13), 7, GFLAGS),
501 516
502 COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, 517 COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0,
@@ -517,7 +532,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
517 RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, 532 RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS,
518 RK3288_CLKGATE_CON(5), 6, GFLAGS), 533 RK3288_CLKGATE_CON(5), 6, GFLAGS),
519 534
520 COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0, 535 COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
521 RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, 536 RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
522 RK3288_CLKGATE_CON(1), 8, GFLAGS), 537 RK3288_CLKGATE_CON(1), 8, GFLAGS),
523 COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0, 538 COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
@@ -585,7 +600,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
585 600
586 COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0, 601 COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
587 RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, 602 RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
588 RK3288_CLKGATE_CON(5), 15, GFLAGS), 603 RK3288_CLKGATE_CON(5), 14, GFLAGS),
589 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, 604 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
590 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, 605 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
591 RK3288_CLKGATE_CON(3), 6, GFLAGS), 606 RK3288_CLKGATE_CON(3), 6, GFLAGS),
@@ -601,19 +616,19 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
601 */ 616 */
602 617
603 /* aclk_cpu gates */ 618 /* aclk_cpu gates */
604 GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS), 619 GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS),
605 GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS), 620 GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS),
606 GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS), 621 GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS),
607 GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), 622 GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS),
608 GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS), 623 GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS),
609 GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS), 624 GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS),
610 GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), 625 GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS),
611 GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), 626 GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS),
612 627
613 /* hclk_cpu gates */ 628 /* hclk_cpu gates */
614 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), 629 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS),
615 GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), 630 GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS),
616 GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS), 631 GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS),
617 GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), 632 GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS),
618 GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), 633 GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS),
619 634
@@ -622,42 +637,42 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
622 GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), 637 GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS),
623 GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), 638 GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS),
624 GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), 639 GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS),
625 GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), 640 GATE(PCLK_DDRUPCTL0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS),
626 GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), 641 GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS),
627 GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), 642 GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS),
628 GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), 643 GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS),
629 GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), 644 GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
630 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), 645 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
631 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), 646 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
632 GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), 647 GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
633 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS), 648 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS),
634 649
635 /* ddrctrl [DDR Controller PHY clock] gates */ 650 /* ddrctrl [DDR Controller PHY clock] gates */
636 GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS), 651 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
637 GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS), 652 GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS),
638 653
639 /* ddrphy gates */ 654 /* ddrphy gates */
640 GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS), 655 GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS),
641 GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS), 656 GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS),
642 657
643 /* aclk_peri gates */ 658 /* aclk_peri gates */
644 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS), 659 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS),
645 GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), 660 GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
646 GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS), 661 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS),
647 GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS), 662 GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS),
648 GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), 663 GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
649 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), 664 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
650 665
651 /* hclk_peri gates */ 666 /* hclk_peri gates */
652 GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS), 667 GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS),
653 GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS), 668 GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS),
654 GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), 669 GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS),
655 GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS), 670 GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS),
656 GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), 671 GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS),
657 GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS), 672 GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS),
658 GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS), 673 GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS),
659 GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS), 674 GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS),
660 GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS), 675 GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS),
661 GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), 676 GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS),
662 GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), 677 GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS),
663 GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), 678 GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS),
@@ -669,7 +684,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
669 GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), 684 GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS),
670 685
671 /* pclk_peri gates */ 686 /* pclk_peri gates */
672 GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS), 687 GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS),
673 GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), 688 GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS),
674 GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), 689 GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS),
675 GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), 690 GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS),
@@ -705,48 +720,48 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
705 GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), 720 GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS),
706 GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), 721 GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
707 GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), 722 GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
708 GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS), 723 GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS),
709 GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), 724 GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS),
710 725
711 /* pclk_pd_pmu gates */ 726 /* pclk_pd_pmu gates */
712 GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS), 727 GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS),
713 GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS), 728 GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS),
714 GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS), 729 GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS),
715 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS), 730 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS),
716 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), 731 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
717 732
718 /* hclk_vio gates */ 733 /* hclk_vio gates */
719 GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), 734 GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS),
720 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), 735 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
721 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), 736 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
722 GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), 737 GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS),
723 GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), 738 GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS),
724 GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), 739 GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
725 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), 740 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
726 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), 741 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
727 GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), 742 GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 10, GFLAGS),
728 GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), 743 GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS),
729 GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), 744 GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS),
730 GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), 745 GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS),
731 GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), 746 GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS),
732 GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), 747 GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS),
733 GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), 748 GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS),
734 GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), 749 GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 11, GFLAGS),
735 750
736 /* aclk_vio0 gates */ 751 /* aclk_vio0 gates */
737 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), 752 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
738 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), 753 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
739 GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), 754 GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS),
740 GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), 755 GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
741 756
742 /* aclk_vio1 gates */ 757 /* aclk_vio1 gates */
743 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), 758 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
744 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), 759 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
745 GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), 760 GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS),
746 761
747 /* aclk_rga_pre gates */ 762 /* aclk_rga_pre gates */
748 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), 763 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
749 GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), 764 GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS),
750 765
751 /* 766 /*
752 * Other ungrouped clocks. 767 * Other ungrouped clocks.
@@ -762,6 +777,64 @@ static const char *rk3288_critical_clocks[] __initconst = {
762 "hclk_peri", 777 "hclk_peri",
763}; 778};
764 779
780#ifdef CONFIG_PM_SLEEP
781static void __iomem *rk3288_cru_base;
782
783/* Some CRU registers will be reset in maskrom when the system
784 * wakes up from fastboot.
785 * So save them before suspend, restore them after resume.
786 */
787static const int rk3288_saved_cru_reg_ids[] = {
788 RK3288_MODE_CON,
789 RK3288_CLKSEL_CON(0),
790 RK3288_CLKSEL_CON(1),
791 RK3288_CLKSEL_CON(10),
792 RK3288_CLKSEL_CON(33),
793 RK3288_CLKSEL_CON(37),
794};
795
796static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
797
798static int rk3288_clk_suspend(void)
799{
800 int i, reg_id;
801
802 for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) {
803 reg_id = rk3288_saved_cru_reg_ids[i];
804
805 rk3288_saved_cru_regs[i] =
806 readl_relaxed(rk3288_cru_base + reg_id);
807 }
808 return 0;
809}
810
811static void rk3288_clk_resume(void)
812{
813 int i, reg_id;
814
815 for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) {
816 reg_id = rk3288_saved_cru_reg_ids[i];
817
818 writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000,
819 rk3288_cru_base + reg_id);
820 }
821}
822
823static struct syscore_ops rk3288_clk_syscore_ops = {
824 .suspend = rk3288_clk_suspend,
825 .resume = rk3288_clk_resume,
826};
827
828static void rk3288_clk_sleep_init(void __iomem *reg_base)
829{
830 rk3288_cru_base = reg_base;
831 register_syscore_ops(&rk3288_clk_syscore_ops);
832}
833
834#else /* CONFIG_PM_SLEEP */
835static void rk3288_clk_sleep_init(void __iomem *reg_base) {}
836#endif
837
765static void __init rk3288_clk_init(struct device_node *np) 838static void __init rk3288_clk_init(struct device_node *np)
766{ 839{
767 void __iomem *reg_base; 840 void __iomem *reg_base;
@@ -810,5 +883,6 @@ static void __init rk3288_clk_init(struct device_node *np)
810 ROCKCHIP_SOFTRST_HIWORD_MASK); 883 ROCKCHIP_SOFTRST_HIWORD_MASK);
811 884
812 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); 885 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
886 rk3288_clk_sleep_init(reg_base);
813} 887}
814CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 888CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 880a266f0143..20e05bbb3a67 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -197,7 +197,8 @@ void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
197 list->parent_names, list->num_parents, 197 list->parent_names, list->num_parents,
198 reg_base, list->con_offset, grf_lock_offset, 198 reg_base, list->con_offset, grf_lock_offset,
199 list->lock_shift, list->mode_offset, 199 list->lock_shift, list->mode_offset,
200 list->mode_shift, list->rate_table, &clk_lock); 200 list->mode_shift, list->rate_table,
201 list->pll_flags, &clk_lock);
201 if (IS_ERR(clk)) { 202 if (IS_ERR(clk)) {
202 pr_err("%s: failed to register clock %s\n", __func__, 203 pr_err("%s: failed to register clock %s\n", __func__,
203 list->name); 204 list->name);
@@ -244,9 +245,6 @@ void __init rockchip_clk_register_branches(
244 list->div_flags, &clk_lock); 245 list->div_flags, &clk_lock);
245 break; 246 break;
246 case branch_fraction_divider: 247 case branch_fraction_divider:
247 /* keep all gates untouched for now */
248 flags |= CLK_IGNORE_UNUSED;
249
250 clk = rockchip_clk_register_frac_branch(list->name, 248 clk = rockchip_clk_register_frac_branch(list->name,
251 list->parent_names, list->num_parents, 249 list->parent_names, list->num_parents,
252 reg_base, list->muxdiv_offset, list->div_flags, 250 reg_base, list->muxdiv_offset, list->div_flags,
@@ -256,18 +254,12 @@ void __init rockchip_clk_register_branches(
256 case branch_gate: 254 case branch_gate:
257 flags |= CLK_SET_RATE_PARENT; 255 flags |= CLK_SET_RATE_PARENT;
258 256
259 /* keep all gates untouched for now */
260 flags |= CLK_IGNORE_UNUSED;
261
262 clk = clk_register_gate(NULL, list->name, 257 clk = clk_register_gate(NULL, list->name,
263 list->parent_names[0], flags, 258 list->parent_names[0], flags,
264 reg_base + list->gate_offset, 259 reg_base + list->gate_offset,
265 list->gate_shift, list->gate_flags, &clk_lock); 260 list->gate_shift, list->gate_flags, &clk_lock);
266 break; 261 break;
267 case branch_composite: 262 case branch_composite:
268 /* keep all gates untouched for now */
269 flags |= CLK_IGNORE_UNUSED;
270
271 clk = rockchip_clk_register_branch(list->name, 263 clk = rockchip_clk_register_branch(list->name,
272 list->parent_names, list->num_parents, 264 list->parent_names, list->num_parents,
273 reg_base, list->muxdiv_offset, list->mux_shift, 265 reg_base, list->muxdiv_offset, list->mux_shift,
@@ -277,6 +269,14 @@ void __init rockchip_clk_register_branches(
277 list->gate_offset, list->gate_shift, 269 list->gate_offset, list->gate_shift,
278 list->gate_flags, flags, &clk_lock); 270 list->gate_flags, flags, &clk_lock);
279 break; 271 break;
272 case branch_mmc:
273 clk = rockchip_clk_register_mmc(
274 list->name,
275 list->parent_names, list->num_parents,
276 reg_base + list->muxdiv_offset,
277 list->div_shift
278 );
279 break;
280 } 280 }
281 281
282 /* none of the cases above matched */ 282 /* none of the cases above matched */
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index ca009ab0a33a..58d2e3bdf22f 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -48,6 +48,14 @@
48#define RK3288_GLB_SRST_SND 0x1b4 48#define RK3288_GLB_SRST_SND 0x1b4
49#define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8) 49#define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8)
50#define RK3288_MISC_CON 0x1e8 50#define RK3288_MISC_CON 0x1e8
51#define RK3288_SDMMC_CON0 0x200
52#define RK3288_SDMMC_CON1 0x204
53#define RK3288_SDIO0_CON0 0x208
54#define RK3288_SDIO0_CON1 0x20c
55#define RK3288_SDIO1_CON0 0x210
56#define RK3288_SDIO1_CON1 0x214
57#define RK3288_EMMC_CON0 0x218
58#define RK3288_EMMC_CON1 0x21c
51 59
52enum rockchip_pll_type { 60enum rockchip_pll_type {
53 pll_rk3066, 61 pll_rk3066,
@@ -62,6 +70,15 @@ enum rockchip_pll_type {
62 .bwadj = (_nf >> 1), \ 70 .bwadj = (_nf >> 1), \
63} 71}
64 72
73#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw) \
74{ \
75 .rate = _rate##U, \
76 .nr = _nr, \
77 .nf = _nf, \
78 .no = _no, \
79 .bwadj = _bw, \
80}
81
65struct rockchip_pll_rate_table { 82struct rockchip_pll_rate_table {
66 unsigned long rate; 83 unsigned long rate;
67 unsigned int nr; 84 unsigned int nr;
@@ -81,7 +98,12 @@ struct rockchip_pll_rate_table {
81 * @mode_shift: offset inside the mode-register for the mode of this pll. 98 * @mode_shift: offset inside the mode-register for the mode of this pll.
82 * @lock_shift: offset inside the lock register for the lock status. 99 * @lock_shift: offset inside the lock register for the lock status.
83 * @type: Type of PLL to be registered. 100 * @type: Type of PLL to be registered.
101 * @pll_flags: hardware-specific flags
84 * @rate_table: Table of usable pll rates 102 * @rate_table: Table of usable pll rates
103 *
104 * Flags:
105 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
106 * rate_table parameters and ajust them if necessary.
85 */ 107 */
86struct rockchip_pll_clock { 108struct rockchip_pll_clock {
87 unsigned int id; 109 unsigned int id;
@@ -94,11 +116,14 @@ struct rockchip_pll_clock {
94 int mode_shift; 116 int mode_shift;
95 int lock_shift; 117 int lock_shift;
96 enum rockchip_pll_type type; 118 enum rockchip_pll_type type;
119 u8 pll_flags;
97 struct rockchip_pll_rate_table *rate_table; 120 struct rockchip_pll_rate_table *rate_table;
98}; 121};
99 122
123#define ROCKCHIP_PLL_SYNC_RATE BIT(0)
124
100#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 125#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \
101 _lshift, _rtable) \ 126 _lshift, _pflags, _rtable) \
102 { \ 127 { \
103 .id = _id, \ 128 .id = _id, \
104 .type = _type, \ 129 .type = _type, \
@@ -110,6 +135,7 @@ struct rockchip_pll_clock {
110 .mode_offset = _mode, \ 135 .mode_offset = _mode, \
111 .mode_shift = _mshift, \ 136 .mode_shift = _mshift, \
112 .lock_shift = _lshift, \ 137 .lock_shift = _lshift, \
138 .pll_flags = _pflags, \
113 .rate_table = _rtable, \ 139 .rate_table = _rtable, \
114 } 140 }
115 141
@@ -118,7 +144,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
118 void __iomem *base, int con_offset, int grf_lock_offset, 144 void __iomem *base, int con_offset, int grf_lock_offset,
119 int lock_shift, int reg_mode, int mode_shift, 145 int lock_shift, int reg_mode, int mode_shift,
120 struct rockchip_pll_rate_table *rate_table, 146 struct rockchip_pll_rate_table *rate_table,
121 spinlock_t *lock); 147 u8 clk_pll_flags, spinlock_t *lock);
122 148
123struct rockchip_cpuclk_clksel { 149struct rockchip_cpuclk_clksel {
124 int reg; 150 int reg;
@@ -152,6 +178,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
152 const struct rockchip_cpuclk_rate_table *rates, 178 const struct rockchip_cpuclk_rate_table *rates,
153 int nrates, void __iomem *reg_base, spinlock_t *lock); 179 int nrates, void __iomem *reg_base, spinlock_t *lock);
154 180
181struct clk *rockchip_clk_register_mmc(const char *name,
182 const char **parent_names, u8 num_parents,
183 void __iomem *reg, int shift);
184
155#define PNAME(x) static const char *x[] __initconst 185#define PNAME(x) static const char *x[] __initconst
156 186
157enum rockchip_clk_branch_type { 187enum rockchip_clk_branch_type {
@@ -160,6 +190,7 @@ enum rockchip_clk_branch_type {
160 branch_divider, 190 branch_divider,
161 branch_fraction_divider, 191 branch_fraction_divider,
162 branch_gate, 192 branch_gate,
193 branch_mmc,
163}; 194};
164 195
165struct rockchip_clk_branch { 196struct rockchip_clk_branch {
@@ -352,6 +383,16 @@ struct rockchip_clk_branch {
352 .gate_flags = gf, \ 383 .gate_flags = gf, \
353 } 384 }
354 385
386#define MMC(_id, cname, pname, offset, shift) \
387 { \
388 .id = _id, \
389 .branch_type = branch_mmc, \
390 .name = cname, \
391 .parent_names = (const char *[]){ pname }, \
392 .num_parents = 1, \
393 .muxdiv_offset = offset, \
394 .div_shift = shift, \
395 }
355 396
356void rockchip_clk_init(struct device_node *np, void __iomem *base, 397void rockchip_clk_init(struct device_node *np, void __iomem *base,
357 unsigned long nr_clks); 398 unsigned long nr_clks);
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 6fb4bc602e8a..006c6f294310 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -5,6 +5,7 @@
5obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o 5obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
6obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o 6obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
7obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o 7obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
8obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o
8obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o 9obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
9obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o 10obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
10obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o 11obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
12obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 13obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
13obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o 14obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
14obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o 15obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
16obj-$(CONFIG_ARCH_EXYNOS7) += clk-exynos7.o
15obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o 17obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
16obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o 18obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
17obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o 19obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index acce708ace18..f2c2ccce49bb 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -29,6 +29,13 @@ static DEFINE_SPINLOCK(lock);
29static struct clk **clk_table; 29static struct clk **clk_table;
30static void __iomem *reg_base; 30static void __iomem *reg_base;
31static struct clk_onecell_data clk_data; 31static struct clk_onecell_data clk_data;
32/*
33 * On Exynos5420 this will be a clock which has to be enabled before any
34 * access to audss registers. Typically a child of EPLL.
35 *
36 * On other platforms this will be -ENODEV.
37 */
38static struct clk *epll;
32 39
33#define ASS_CLK_SRC 0x0 40#define ASS_CLK_SRC 0x0
34#define ASS_CLK_DIV 0x4 41#define ASS_CLK_DIV 0x4
@@ -98,6 +105,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
98 dev_err(&pdev->dev, "failed to map audss registers\n"); 105 dev_err(&pdev->dev, "failed to map audss registers\n");
99 return PTR_ERR(reg_base); 106 return PTR_ERR(reg_base);
100 } 107 }
108 /* EPLL don't have to be enabled for boards other than Exynos5420 */
109 epll = ERR_PTR(-ENODEV);
101 110
102 clk_table = devm_kzalloc(&pdev->dev, 111 clk_table = devm_kzalloc(&pdev->dev,
103 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, 112 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
@@ -115,8 +124,20 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
115 pll_in = devm_clk_get(&pdev->dev, "pll_in"); 124 pll_in = devm_clk_get(&pdev->dev, "pll_in");
116 if (!IS_ERR(pll_ref)) 125 if (!IS_ERR(pll_ref))
117 mout_audss_p[0] = __clk_get_name(pll_ref); 126 mout_audss_p[0] = __clk_get_name(pll_ref);
118 if (!IS_ERR(pll_in)) 127 if (!IS_ERR(pll_in)) {
119 mout_audss_p[1] = __clk_get_name(pll_in); 128 mout_audss_p[1] = __clk_get_name(pll_in);
129
130 if (variant == TYPE_EXYNOS5420) {
131 epll = pll_in;
132
133 ret = clk_prepare_enable(epll);
134 if (ret) {
135 dev_err(&pdev->dev,
136 "failed to prepare the epll clock\n");
137 return ret;
138 }
139 }
140 }
120 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", 141 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
121 mout_audss_p, ARRAY_SIZE(mout_audss_p), 142 mout_audss_p, ARRAY_SIZE(mout_audss_p),
122 CLK_SET_RATE_NO_REPARENT, 143 CLK_SET_RATE_NO_REPARENT,
@@ -203,6 +224,9 @@ unregister:
203 clk_unregister(clk_table[i]); 224 clk_unregister(clk_table[i]);
204 } 225 }
205 226
227 if (!IS_ERR(epll))
228 clk_disable_unprepare(epll);
229
206 return ret; 230 return ret;
207} 231}
208 232
@@ -210,6 +234,10 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
210{ 234{
211 int i; 235 int i;
212 236
237#ifdef CONFIG_PM_SLEEP
238 unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
239#endif
240
213 of_clk_del_provider(pdev->dev.of_node); 241 of_clk_del_provider(pdev->dev.of_node);
214 242
215 for (i = 0; i < clk_data.clk_num; i++) { 243 for (i = 0; i < clk_data.clk_num; i++) {
@@ -217,6 +245,9 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
217 clk_unregister(clk_table[i]); 245 clk_unregister(clk_table[i]);
218 } 246 }
219 247
248 if (!IS_ERR(epll))
249 clk_disable_unprepare(epll);
250
220 return 0; 251 return 0;
221} 252}
222 253
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 940f02837b82..88e8c6bbd77f 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -505,7 +505,7 @@ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata
505/* fixed rate clocks generated inside the soc */ 505/* fixed rate clocks generated inside the soc */
506static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { 506static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
507 FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), 507 FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
508 FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), 508 FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", "hdmi", 0, 27000000),
509 FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), 509 FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
510}; 510};
511 511
diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c
new file mode 100644
index 000000000000..2123fc251e0f
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4415.c
@@ -0,0 +1,1144 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * Author: Chanwoo Choi <cw00.choi@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Common Clock Framework support for Exynos4415 SoC.
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/syscore_ops.h>
19
20#include <dt-bindings/clock/exynos4415.h>
21
22#include "clk.h"
23#include "clk-pll.h"
24
25#define SRC_LEFTBUS 0x4200
26#define DIV_LEFTBUS 0x4500
27#define GATE_IP_LEFTBUS 0x4800
28#define GATE_IP_IMAGE 0x4930
29#define SRC_RIGHTBUS 0x8200
30#define DIV_RIGHTBUS 0x8500
31#define GATE_IP_RIGHTBUS 0x8800
32#define GATE_IP_PERIR 0x8960
33#define EPLL_LOCK 0xc010
34#define G3D_PLL_LOCK 0xc020
35#define DISP_PLL_LOCK 0xc030
36#define ISP_PLL_LOCK 0xc040
37#define EPLL_CON0 0xc110
38#define EPLL_CON1 0xc114
39#define EPLL_CON2 0xc118
40#define G3D_PLL_CON0 0xc120
41#define G3D_PLL_CON1 0xc124
42#define G3D_PLL_CON2 0xc128
43#define ISP_PLL_CON0 0xc130
44#define ISP_PLL_CON1 0xc134
45#define ISP_PLL_CON2 0xc138
46#define DISP_PLL_CON0 0xc140
47#define DISP_PLL_CON1 0xc144
48#define DISP_PLL_CON2 0xc148
49#define SRC_TOP0 0xc210
50#define SRC_TOP1 0xc214
51#define SRC_CAM 0xc220
52#define SRC_TV 0xc224
53#define SRC_MFC 0xc228
54#define SRC_G3D 0xc22c
55#define SRC_LCD 0xc234
56#define SRC_ISP 0xc238
57#define SRC_MAUDIO 0xc23c
58#define SRC_FSYS 0xc240
59#define SRC_PERIL0 0xc250
60#define SRC_PERIL1 0xc254
61#define SRC_CAM1 0xc258
62#define SRC_TOP_ISP0 0xc25c
63#define SRC_TOP_ISP1 0xc260
64#define SRC_MASK_TOP 0xc310
65#define SRC_MASK_CAM 0xc320
66#define SRC_MASK_TV 0xc324
67#define SRC_MASK_LCD 0xc334
68#define SRC_MASK_ISP 0xc338
69#define SRC_MASK_MAUDIO 0xc33c
70#define SRC_MASK_FSYS 0xc340
71#define SRC_MASK_PERIL0 0xc350
72#define SRC_MASK_PERIL1 0xc354
73#define DIV_TOP 0xc510
74#define DIV_CAM 0xc520
75#define DIV_TV 0xc524
76#define DIV_MFC 0xc528
77#define DIV_G3D 0xc52c
78#define DIV_LCD 0xc534
79#define DIV_ISP 0xc538
80#define DIV_MAUDIO 0xc53c
81#define DIV_FSYS0 0xc540
82#define DIV_FSYS1 0xc544
83#define DIV_FSYS2 0xc548
84#define DIV_PERIL0 0xc550
85#define DIV_PERIL1 0xc554
86#define DIV_PERIL2 0xc558
87#define DIV_PERIL3 0xc55c
88#define DIV_PERIL4 0xc560
89#define DIV_PERIL5 0xc564
90#define DIV_CAM1 0xc568
91#define DIV_TOP_ISP1 0xc56c
92#define DIV_TOP_ISP0 0xc570
93#define CLKDIV2_RATIO 0xc580
94#define GATE_SCLK_CAM 0xc820
95#define GATE_SCLK_TV 0xc824
96#define GATE_SCLK_MFC 0xc828
97#define GATE_SCLK_G3D 0xc82c
98#define GATE_SCLK_LCD 0xc834
99#define GATE_SCLK_MAUDIO 0xc83c
100#define GATE_SCLK_FSYS 0xc840
101#define GATE_SCLK_PERIL 0xc850
102#define GATE_IP_CAM 0xc920
103#define GATE_IP_TV 0xc924
104#define GATE_IP_MFC 0xc928
105#define GATE_IP_G3D 0xc92c
106#define GATE_IP_LCD 0xc934
107#define GATE_IP_FSYS 0xc940
108#define GATE_IP_PERIL 0xc950
109#define GATE_BLOCK 0xc970
110#define APLL_LOCK 0x14000
111#define APLL_CON0 0x14100
112#define SRC_CPU 0x14200
113#define DIV_CPU0 0x14500
114#define DIV_CPU1 0x14504
115
116enum exynos4415_plls {
117 apll, epll, g3d_pll, isp_pll, disp_pll,
118 nr_plls,
119};
120
121static struct samsung_clk_provider *exynos4415_ctx;
122
123/*
124 * Support for CMU save/restore across system suspends
125 */
126#ifdef CONFIG_PM_SLEEP
127static struct samsung_clk_reg_dump *exynos4415_clk_regs;
128
129static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
130 SRC_LEFTBUS,
131 DIV_LEFTBUS,
132 GATE_IP_LEFTBUS,
133 GATE_IP_IMAGE,
134 SRC_RIGHTBUS,
135 DIV_RIGHTBUS,
136 GATE_IP_RIGHTBUS,
137 GATE_IP_PERIR,
138 EPLL_LOCK,
139 G3D_PLL_LOCK,
140 DISP_PLL_LOCK,
141 ISP_PLL_LOCK,
142 EPLL_CON0,
143 EPLL_CON1,
144 EPLL_CON2,
145 G3D_PLL_CON0,
146 G3D_PLL_CON1,
147 G3D_PLL_CON2,
148 ISP_PLL_CON0,
149 ISP_PLL_CON1,
150 ISP_PLL_CON2,
151 DISP_PLL_CON0,
152 DISP_PLL_CON1,
153 DISP_PLL_CON2,
154 SRC_TOP0,
155 SRC_TOP1,
156 SRC_CAM,
157 SRC_TV,
158 SRC_MFC,
159 SRC_G3D,
160 SRC_LCD,
161 SRC_ISP,
162 SRC_MAUDIO,
163 SRC_FSYS,
164 SRC_PERIL0,
165 SRC_PERIL1,
166 SRC_CAM1,
167 SRC_TOP_ISP0,
168 SRC_TOP_ISP1,
169 SRC_MASK_TOP,
170 SRC_MASK_CAM,
171 SRC_MASK_TV,
172 SRC_MASK_LCD,
173 SRC_MASK_ISP,
174 SRC_MASK_MAUDIO,
175 SRC_MASK_FSYS,
176 SRC_MASK_PERIL0,
177 SRC_MASK_PERIL1,
178 DIV_TOP,
179 DIV_CAM,
180 DIV_TV,
181 DIV_MFC,
182 DIV_G3D,
183 DIV_LCD,
184 DIV_ISP,
185 DIV_MAUDIO,
186 DIV_FSYS0,
187 DIV_FSYS1,
188 DIV_FSYS2,
189 DIV_PERIL0,
190 DIV_PERIL1,
191 DIV_PERIL2,
192 DIV_PERIL3,
193 DIV_PERIL4,
194 DIV_PERIL5,
195 DIV_CAM1,
196 DIV_TOP_ISP1,
197 DIV_TOP_ISP0,
198 CLKDIV2_RATIO,
199 GATE_SCLK_CAM,
200 GATE_SCLK_TV,
201 GATE_SCLK_MFC,
202 GATE_SCLK_G3D,
203 GATE_SCLK_LCD,
204 GATE_SCLK_MAUDIO,
205 GATE_SCLK_FSYS,
206 GATE_SCLK_PERIL,
207 GATE_IP_CAM,
208 GATE_IP_TV,
209 GATE_IP_MFC,
210 GATE_IP_G3D,
211 GATE_IP_LCD,
212 GATE_IP_FSYS,
213 GATE_IP_PERIL,
214 GATE_BLOCK,
215 APLL_LOCK,
216 APLL_CON0,
217 SRC_CPU,
218 DIV_CPU0,
219 DIV_CPU1,
220};
221
222static int exynos4415_clk_suspend(void)
223{
224 samsung_clk_save(exynos4415_ctx->reg_base, exynos4415_clk_regs,
225 ARRAY_SIZE(exynos4415_cmu_clk_regs));
226
227 return 0;
228}
229
230static void exynos4415_clk_resume(void)
231{
232 samsung_clk_restore(exynos4415_ctx->reg_base, exynos4415_clk_regs,
233 ARRAY_SIZE(exynos4415_cmu_clk_regs));
234}
235
236static struct syscore_ops exynos4415_clk_syscore_ops = {
237 .suspend = exynos4415_clk_suspend,
238 .resume = exynos4415_clk_resume,
239};
240
241static void exynos4415_clk_sleep_init(void)
242{
243 exynos4415_clk_regs =
244 samsung_clk_alloc_reg_dump(exynos4415_cmu_clk_regs,
245 ARRAY_SIZE(exynos4415_cmu_clk_regs));
246 if (!exynos4415_clk_regs) {
247 pr_warn("%s: Failed to allocate sleep save data\n", __func__);
248 return;
249 }
250
251 register_syscore_ops(&exynos4415_clk_syscore_ops);
252}
253#else
254static inline void exynos4415_clk_sleep_init(void) { }
255#endif
256
257/* list of all parent clock list */
258PNAME(mout_g3d_pllsrc_p) = { "fin_pll", };
259
260PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
261PNAME(mout_g3d_pll_p) = { "fin_pll", "fout_g3d_pll", };
262PNAME(mout_isp_pll_p) = { "fin_pll", "fout_isp_pll", };
263PNAME(mout_disp_pll_p) = { "fin_pll", "fout_disp_pll", };
264
265PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", };
266PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
267PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", };
268PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", };
269
270PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", };
271PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_g3d_pll", };
272
273PNAME(mout_gdl_p) = { "mout_mpll_user_l", };
274PNAME(mout_gdr_p) = { "mout_mpll_user_r", };
275
276PNAME(mout_aclk_266_p) = { "mout_mpll_user_t", "mout_g3d_pll", };
277
278PNAME(group_epll_g3dpll_p) = { "mout_epll", "mout_g3d_pll" };
279PNAME(group_sclk_p) = { "xxti", "xusbxti",
280 "none", "mout_isp_pll",
281 "none", "none", "div_mpll_pre",
282 "mout_epll", "mout_g3d_pll", };
283PNAME(group_spdif_p) = { "mout_audio0", "mout_audio1",
284 "mout_audio2", "spdif_extclk", };
285PNAME(group_sclk_audio2_p) = { "audiocdclk2", "none",
286 "none", "mout_isp_pll",
287 "mout_disp_pll", "xusbxti",
288 "div_mpll_pre", "mout_epll",
289 "mout_g3d_pll", };
290PNAME(group_sclk_audio1_p) = { "audiocdclk1", "none",
291 "none", "mout_isp_pll",
292 "mout_disp_pll", "xusbxti",
293 "div_mpll_pre", "mout_epll",
294 "mout_g3d_pll", };
295PNAME(group_sclk_audio0_p) = { "audiocdclk0", "none",
296 "none", "mout_isp_pll",
297 "mout_disp_pll", "xusbxti",
298 "div_mpll_pre", "mout_epll",
299 "mout_g3d_pll", };
300PNAME(group_fimc_lclk_p) = { "xxti", "xusbxti",
301 "none", "mout_isp_pll",
302 "none", "mout_disp_pll",
303 "mout_mpll_user_t", "mout_epll",
304 "mout_g3d_pll", };
305PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti",
306 "m_bitclkhsdiv4_4l", "mout_isp_pll",
307 "mout_disp_pll", "sclk_hdmiphy",
308 "div_mpll_pre", "mout_epll",
309 "mout_g3d_pll", };
310PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy" };
311PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" };
312PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" };
313PNAME(mout_jpeg_p) = { "mout_jpeg_0", "mout_jpeg_1" };
314PNAME(mout_jpeg1_p) = { "mout_epll", "mout_g3d_pll" };
315PNAME(group_aclk_isp0_300_p) = { "mout_isp_pll", "div_mpll_pre" };
316PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" };
317PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" };
318PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" };
319PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" };
320
321static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initdata = {
322 /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */
323 FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
324};
325
326static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = {
327 FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
328};
329
330static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = {
331 /*
332 * NOTE: Following table is sorted by register address in ascending
333 * order and then bitfield shift in descending order, as it is done
334 * in the User's Manual. When adding new entries, please make sure
335 * that the order is preserved, to avoid merge conflicts and make
336 * further work with defined data easier.
337 */
338
339 /* SRC_LEFTBUS */
340 MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p,
341 SRC_LEFTBUS, 4, 1),
342 MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1),
343
344 /* SRC_RIGHTBUS */
345 MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p,
346 SRC_RIGHTBUS, 4, 1),
347 MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1),
348
349 /* SRC_TOP0 */
350 MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1),
351 MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p,
352 SRC_TOP0, 24, 1),
353 MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p,
354 SRC_TOP0, 20, 1),
355 MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p,
356 SRC_TOP0, 16, 1),
357 MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p,
358 SRC_TOP0, 12, 1),
359 MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
360 SRC_TOP0, 8, 1),
361 MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1),
362 MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1),
363
364 /* SRC_TOP1 */
365 MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p,
366 SRC_TOP1, 28, 1),
367 MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p,
368 SRC_TOP1, 16, 1),
369 MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p,
370 SRC_TOP1, 12, 1),
371 MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp",
372 group_mout_mpll_user_t_p, SRC_TOP1, 8, 1),
373 MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p,
374 SRC_TOP1, 0, 1),
375
376 /* SRC_CAM */
377 MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4),
378 MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4),
379 MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4),
380 MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM,
381 12, 4),
382 MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM,
383 8, 4),
384 MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM,
385 4, 4),
386 MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM,
387 0, 4),
388
389 /* SRC_TV */
390 MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
391
392 /* SRC_MFC */
393 MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
394 MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1),
395 MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0,
396 1),
397
398 /* SRC_G3D */
399 MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1),
400 MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1),
401 MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0,
402 1),
403
404 /* SRC_LCD */
405 MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4),
406 MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4),
407
408 /* SRC_ISP */
409 MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP,
410 16, 4),
411 MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP,
412 12, 4),
413 MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP,
414 8, 4),
415 MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP,
416 4, 4),
417 MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP,
418 0, 4),
419
420 /* SRC_MAUDIO */
421 MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO,
422 0, 4),
423
424 /* SRC_FSYS */
425 MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
426 MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
427 MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
428 MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
429
430 /* SRC_PERIL0 */
431 MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4),
432 MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
433 MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
434 MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
435
436 /* SRC_PERIL1 */
437 MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4),
438 MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4),
439 MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4),
440 MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4),
441 MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1,
442 4, 4),
443 MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1,
444 0, 4),
445
446 /* SRC_CPU */
447 MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p,
448 SRC_CPU, 24, 1),
449 MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1),
450 MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0,
451 CLK_MUX_READ_ONLY),
452 MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
453 CLK_SET_RATE_PARENT, 0),
454
455 /* SRC_CAM1 */
456 MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1",
457 group_fimc_lclk_p, SRC_CAM1, 20, 1),
458 MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0",
459 group_fimc_lclk_p, SRC_CAM1, 16, 1),
460 MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1),
461 MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1),
462 MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1,
463 0, 1),
464
465 /* SRC_TOP_ISP0 */
466 MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300",
467 group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1),
468 MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user",
469 group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1),
470 MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user",
471 group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1),
472
473 /* SRC_TOP_ISP1 */
474 MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300",
475 group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1),
476 MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user",
477 group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1),
478};
479
480static struct samsung_div_clock exynos4415_div_clks[] __initdata = {
481 /*
482 * NOTE: Following table is sorted by register address in ascending
483 * order and then bitfield shift in descending order, as it is done
484 * in the User's Manual. When adding new entries, please make sure
485 * that the order is preserved, to avoid merge conflicts and make
486 * further work with defined data easier.
487 */
488
489 /* DIV_LEFTBUS */
490 DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
491 DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4),
492
493 /* DIV_RIGHTBUS */
494 DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
495 DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4),
496
497 /* DIV_TOP */
498 DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp",
499 "mout_aclk_400_mcuisp", DIV_TOP, 24, 3),
500 DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3),
501 DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3),
502 DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3),
503 DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4),
504 DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3),
505
506 /* DIV_CAM */
507 DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4),
508 DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4),
509 DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4),
510 DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM,
511 12, 4),
512 DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM,
513 8, 4),
514 DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM,
515 4, 4),
516 DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM,
517 0, 4),
518
519 /* DIV_TV */
520 DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4),
521
522 /* DIV_MFC */
523 DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4),
524
525 /* DIV_G3D */
526 DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4),
527
528 /* DIV_LCD */
529 DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4,
530 CLK_SET_RATE_PARENT, 0),
531 DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4),
532 DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4),
533
534 /* DIV_ISP */
535 DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4),
536 DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp",
537 DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0),
538 DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4),
539 DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp",
540 DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0),
541 DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4),
542 DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4),
543
544 /* DIV_MAUDIO */
545 DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8),
546 DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4),
547
548 /* DIV_FSYS0 */
549 DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8,
550 CLK_SET_RATE_PARENT, 0),
551 DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4),
552
553 /* DIV_FSYS1 */
554 DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8,
555 CLK_SET_RATE_PARENT, 0),
556 DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
557 DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8,
558 CLK_SET_RATE_PARENT, 0),
559 DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
560
561 /* DIV_FSYS2 */
562 DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
563 CLK_SET_RATE_PARENT, 0),
564 DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4,
565 CLK_SET_RATE_PARENT, 0),
566
567 /* DIV_PERIL0 */
568 DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
569 DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
570 DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
571 DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
572
573 /* DIV_PERIL1 */
574 DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8,
575 CLK_SET_RATE_PARENT, 0),
576 DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
577 DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8,
578 CLK_SET_RATE_PARENT, 0),
579 DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
580
581 /* DIV_PERIL2 */
582 DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8,
583 CLK_SET_RATE_PARENT, 0),
584 DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
585
586 /* DIV_PERIL4 */
587 DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8),
588 DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
589 DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8),
590 DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
591
592 /* DIV_PERIL5 */
593 DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6),
594
595 /* DIV_CAM1 */
596 DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc",
597 "mout_pxlasync_csis1", DIV_CAM1, 24, 4),
598 DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc",
599 "mout_pxlasync_csis0", DIV_CAM1, 20, 4),
600 DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4),
601
602 /* DIV_CPU0 */
603 DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3),
604 DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3,
605 CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
606 DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3),
607 DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3),
608 DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3),
609 DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
610 DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
611 DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3,
612 CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
613
614 /* DIV_CPU1 */
615 DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
616 DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
617};
618
619static struct samsung_gate_clock exynos4415_gate_clks[] __initdata = {
620 /*
621 * NOTE: Following table is sorted by register address in ascending
622 * order and then bitfield shift in descending order, as it is done
623 * in the User's Manual. When adding new entries, please make sure
624 * that the order is preserved, to avoid merge conflicts and make
625 * further work with defined data easier.
626 */
627
628 /* GATE_IP_LEFTBUS */
629 GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6,
630 CLK_IGNORE_UNUSED, 0),
631 GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4,
632 CLK_IGNORE_UNUSED, 0),
633 GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3,
634 CLK_IGNORE_UNUSED, 0),
635 GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1,
636 CLK_IGNORE_UNUSED, 0),
637 GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0,
638 CLK_IGNORE_UNUSED, 0),
639
640 /* GATE_IP_IMAGE */
641 GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE,
642 9, 0, 0),
643 GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE,
644 8, 0, 0),
645 GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE,
646 7, 0, 0),
647 GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE,
648 5, 0, 0),
649 GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE,
650 4, 0, 0),
651 GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0),
652 GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0),
653
654 /* GATE_IP_RIGHTBUS */
655 GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100",
656 GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0),
657 GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100",
658 GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0),
659 GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100",
660 GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0),
661 GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100",
662 GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0),
663 GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100",
664 GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0),
665 GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100",
666 GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0),
667 GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100",
668 GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0),
669 GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100",
670 GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0),
671
672 /* GATE_IP_PERIR */
673 GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100",
674 GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0),
675 GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100",
676 GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0),
677 GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22,
678 CLK_IGNORE_UNUSED, 0),
679 GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21,
680 CLK_IGNORE_UNUSED, 0),
681 GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100",
682 GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0),
683 GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100",
684 GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0),
685 GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18,
686 CLK_IGNORE_UNUSED, 0),
687 GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100",
688 GATE_IP_PERIR, 17, 0, 0),
689 GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0),
690 GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0),
691 GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0),
692 GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0),
693 GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12,
694 CLK_IGNORE_UNUSED, 0),
695 GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11,
696 CLK_IGNORE_UNUSED, 0),
697 GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10,
698 CLK_IGNORE_UNUSED, 0),
699 GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9,
700 CLK_IGNORE_UNUSED, 0),
701 GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8,
702 CLK_IGNORE_UNUSED, 0),
703 GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7,
704 CLK_IGNORE_UNUSED, 0),
705 GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6,
706 CLK_IGNORE_UNUSED, 0),
707 GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5,
708 CLK_IGNORE_UNUSED, 0),
709 GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4,
710 CLK_IGNORE_UNUSED, 0),
711 GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3,
712 CLK_IGNORE_UNUSED, 0),
713 GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2,
714 CLK_IGNORE_UNUSED, 0),
715 GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1,
716 CLK_IGNORE_UNUSED, 0),
717 GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0,
718 CLK_IGNORE_UNUSED, 0),
719
720 /* GATE_SCLK_CAM - non-completed */
721 GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc",
722 "div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11,
723 CLK_SET_RATE_PARENT, 0),
724 GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc",
725 "div_pxlasync_csis0_fimc", GATE_SCLK_CAM,
726 10, CLK_SET_RATE_PARENT, 0),
727 GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg",
728 GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0),
729 GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1",
730 GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0),
731 GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0",
732 GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0),
733 GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1",
734 GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0),
735 GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk",
736 GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0),
737 GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk",
738 GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0),
739 GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk",
740 GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0),
741 GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk",
742 GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0),
743
744 /* GATE_SCLK_TV */
745 GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk",
746 GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0),
747 GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
748 GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0),
749 GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk",
750 GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0),
751
752 /* GATE_SCLK_MFC */
753 GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc",
754 GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0),
755
756 /* GATE_SCLK_G3D */
757 GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d",
758 GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0),
759
760 /* GATE_SCLK_LCD */
761 GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0",
762 GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0),
763 GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre",
764 GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0),
765 GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0",
766 GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0),
767 GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0",
768 GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0),
769
770 /* GATE_SCLK_MAUDIO */
771 GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0",
772 GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0),
773 GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0",
774 GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0),
775
776 /* GATE_SCLK_FSYS */
777 GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre",
778 GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
779 GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
780 GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
781 GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
782 GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
783 GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
784 GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
785 GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
786 GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
787
788 /* GATE_SCLK_PERIL */
789 GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1",
790 GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0),
791 GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2",
792 GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0),
793 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1",
794 GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0),
795 GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2",
796 GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0),
797 GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1",
798 GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0),
799 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
800 GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0),
801 GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre",
802 GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0),
803 GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre",
804 GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
805 GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
806 GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
807 GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
808 GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0),
809 GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
810 GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
811 GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
812 GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
813 GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
814 GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0),
815
816 /* GATE_IP_CAM */
817 GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM,
818 22, CLK_IGNORE_UNUSED, 0),
819 GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM,
820 20, CLK_IGNORE_UNUSED, 0),
821 GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM,
822 18, CLK_IGNORE_UNUSED, 0),
823 GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM,
824 17, CLK_IGNORE_UNUSED, 0),
825 GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM,
826 16, CLK_IGNORE_UNUSED, 0),
827 GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0),
828 GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0),
829 GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0),
830 GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0),
831 GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0),
832 GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0),
833 GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0),
834 GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0),
835 GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0),
836 GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0),
837 GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0),
838 GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0),
839
840 /* GATE_IP_TV */
841 GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0),
842 GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0),
843 GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0),
844 GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0),
845 GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0),
846
847 /* GATE_IP_MFC */
848 GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4,
849 CLK_IGNORE_UNUSED, 0),
850 GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3,
851 CLK_IGNORE_UNUSED, 0),
852 GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0),
853 GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0),
854 GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0),
855
856 /* GATE_IP_G3D */
857 GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1,
858 CLK_IGNORE_UNUSED, 0),
859 GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0),
860
861 /* GATE_IP_LCD */
862 GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5,
863 CLK_IGNORE_UNUSED, 0),
864 GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0),
865 GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0),
866 GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0),
867 GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0),
868 GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0),
869
870 /* GATE_IP_FSYS */
871 GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0),
872 GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17,
873 CLK_IGNORE_UNUSED, 0),
874 GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0),
875 GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13,
876 0, 0),
877 GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
878 GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
879 GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
880 GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
881 GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
882 GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
883 GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0),
884
885 /* GATE_IP_PERIL */
886 GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0),
887 GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0),
888 GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0),
889 GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0),
890 GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0),
891 GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0),
892 GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0),
893 GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0),
894 GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0),
895 GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0),
896 GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0),
897 GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0),
898 GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0),
899 GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0),
900 GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
901 GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
902 GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
903 GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0),
904 GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
905 GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
906 GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
907};
908
909/*
910 * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL
911 */
912static struct samsung_pll_rate_table exynos4415_pll_rates[] = {
913 PLL_35XX_RATE(1600000000, 400, 3, 1),
914 PLL_35XX_RATE(1500000000, 250, 2, 1),
915 PLL_35XX_RATE(1400000000, 175, 3, 0),
916 PLL_35XX_RATE(1300000000, 325, 3, 1),
917 PLL_35XX_RATE(1200000000, 400, 4, 1),
918 PLL_35XX_RATE(1100000000, 275, 3, 1),
919 PLL_35XX_RATE(1066000000, 533, 6, 1),
920 PLL_35XX_RATE(1000000000, 250, 3, 1),
921 PLL_35XX_RATE(960000000, 320, 4, 1),
922 PLL_35XX_RATE(900000000, 300, 4, 1),
923 PLL_35XX_RATE(850000000, 425, 6, 1),
924 PLL_35XX_RATE(800000000, 200, 3, 1),
925 PLL_35XX_RATE(700000000, 175, 3, 1),
926 PLL_35XX_RATE(667000000, 667, 12, 1),
927 PLL_35XX_RATE(600000000, 400, 4, 2),
928 PLL_35XX_RATE(550000000, 275, 3, 2),
929 PLL_35XX_RATE(533000000, 533, 6, 2),
930 PLL_35XX_RATE(520000000, 260, 3, 2),
931 PLL_35XX_RATE(500000000, 250, 3, 2),
932 PLL_35XX_RATE(440000000, 220, 3, 2),
933 PLL_35XX_RATE(400000000, 200, 3, 2),
934 PLL_35XX_RATE(350000000, 175, 3, 2),
935 PLL_35XX_RATE(300000000, 300, 3, 3),
936 PLL_35XX_RATE(266000000, 266, 3, 3),
937 PLL_35XX_RATE(200000000, 200, 3, 3),
938 PLL_35XX_RATE(160000000, 160, 3, 3),
939 PLL_35XX_RATE(100000000, 200, 3, 4),
940 { /* sentinel */ }
941};
942
943/* EPLL */
944static struct samsung_pll_rate_table exynos4415_epll_rates[] = {
945 PLL_36XX_RATE(800000000, 200, 3, 1, 0),
946 PLL_36XX_RATE(288000000, 96, 2, 2, 0),
947 PLL_36XX_RATE(192000000, 128, 2, 3, 0),
948 PLL_36XX_RATE(144000000, 96, 2, 3, 0),
949 PLL_36XX_RATE(96000000, 128, 2, 4, 0),
950 PLL_36XX_RATE(84000000, 112, 2, 4, 0),
951 PLL_36XX_RATE(80750011, 107, 2, 4, 43691),
952 PLL_36XX_RATE(73728004, 98, 2, 4, 19923),
953 PLL_36XX_RATE(67987602, 271, 3, 5, 62285),
954 PLL_36XX_RATE(65911004, 175, 2, 5, 49982),
955 PLL_36XX_RATE(50000000, 200, 3, 5, 0),
956 PLL_36XX_RATE(49152003, 131, 2, 5, 4719),
957 PLL_36XX_RATE(48000000, 128, 2, 5, 0),
958 PLL_36XX_RATE(45250000, 181, 3, 5, 0),
959 { /* sentinel */ }
960};
961
962static struct samsung_pll_clock exynos4415_plls[nr_plls] __initdata = {
963 [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
964 APLL_LOCK, APLL_CON0, NULL),
965 [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
966 EPLL_LOCK, EPLL_CON0, NULL),
967 [g3d_pll] = PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll",
968 "mout_g3d_pllsrc", G3D_PLL_LOCK, G3D_PLL_CON0, NULL),
969 [isp_pll] = PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
970 ISP_PLL_LOCK, ISP_PLL_CON0, NULL),
971 [disp_pll] = PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
972 "fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, NULL),
973};
974
975static void __init exynos4415_cmu_init(struct device_node *np)
976{
977 void __iomem *reg_base;
978
979 reg_base = of_iomap(np, 0);
980 if (!reg_base)
981 panic("%s: failed to map registers\n", __func__);
982
983 exynos4415_ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
984 if (!exynos4415_ctx)
985 panic("%s: unable to allocate context.\n", __func__);
986
987 exynos4415_plls[apll].rate_table = exynos4415_pll_rates;
988 exynos4415_plls[epll].rate_table = exynos4415_epll_rates;
989 exynos4415_plls[g3d_pll].rate_table = exynos4415_pll_rates;
990 exynos4415_plls[isp_pll].rate_table = exynos4415_pll_rates;
991 exynos4415_plls[disp_pll].rate_table = exynos4415_pll_rates;
992
993 samsung_clk_register_fixed_factor(exynos4415_ctx,
994 exynos4415_fixed_factor_clks,
995 ARRAY_SIZE(exynos4415_fixed_factor_clks));
996 samsung_clk_register_fixed_rate(exynos4415_ctx,
997 exynos4415_fixed_rate_clks,
998 ARRAY_SIZE(exynos4415_fixed_rate_clks));
999
1000 samsung_clk_register_pll(exynos4415_ctx, exynos4415_plls,
1001 ARRAY_SIZE(exynos4415_plls), reg_base);
1002 samsung_clk_register_mux(exynos4415_ctx, exynos4415_mux_clks,
1003 ARRAY_SIZE(exynos4415_mux_clks));
1004 samsung_clk_register_div(exynos4415_ctx, exynos4415_div_clks,
1005 ARRAY_SIZE(exynos4415_div_clks));
1006 samsung_clk_register_gate(exynos4415_ctx, exynos4415_gate_clks,
1007 ARRAY_SIZE(exynos4415_gate_clks));
1008
1009 exynos4415_clk_sleep_init();
1010
1011 samsung_clk_of_add_provider(np, exynos4415_ctx);
1012}
1013CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
1014
1015/*
1016 * CMU DMC
1017 */
1018
1019#define MPLL_LOCK 0x008
1020#define MPLL_CON0 0x108
1021#define MPLL_CON1 0x10c
1022#define MPLL_CON2 0x110
1023#define BPLL_LOCK 0x118
1024#define BPLL_CON0 0x218
1025#define BPLL_CON1 0x21c
1026#define BPLL_CON2 0x220
1027#define SRC_DMC 0x300
1028#define DIV_DMC1 0x504
1029
1030enum exynos4415_dmc_plls {
1031 mpll, bpll,
1032 nr_dmc_plls,
1033};
1034
1035static struct samsung_clk_provider *exynos4415_dmc_ctx;
1036
1037#ifdef CONFIG_PM_SLEEP
1038static struct samsung_clk_reg_dump *exynos4415_dmc_clk_regs;
1039
1040static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
1041 MPLL_LOCK,
1042 MPLL_CON0,
1043 MPLL_CON1,
1044 MPLL_CON2,
1045 BPLL_LOCK,
1046 BPLL_CON0,
1047 BPLL_CON1,
1048 BPLL_CON2,
1049 SRC_DMC,
1050 DIV_DMC1,
1051};
1052
1053static int exynos4415_dmc_clk_suspend(void)
1054{
1055 samsung_clk_save(exynos4415_dmc_ctx->reg_base,
1056 exynos4415_dmc_clk_regs,
1057 ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
1058 return 0;
1059}
1060
1061static void exynos4415_dmc_clk_resume(void)
1062{
1063 samsung_clk_restore(exynos4415_dmc_ctx->reg_base,
1064 exynos4415_dmc_clk_regs,
1065 ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
1066}
1067
1068static struct syscore_ops exynos4415_dmc_clk_syscore_ops = {
1069 .suspend = exynos4415_dmc_clk_suspend,
1070 .resume = exynos4415_dmc_clk_resume,
1071};
1072
1073static void exynos4415_dmc_clk_sleep_init(void)
1074{
1075 exynos4415_dmc_clk_regs =
1076 samsung_clk_alloc_reg_dump(exynos4415_cmu_dmc_clk_regs,
1077 ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
1078 if (!exynos4415_dmc_clk_regs) {
1079 pr_warn("%s: Failed to allocate sleep save data\n", __func__);
1080 return;
1081 }
1082
1083 register_syscore_ops(&exynos4415_dmc_clk_syscore_ops);
1084}
1085#else
1086static inline void exynos4415_dmc_clk_sleep_init(void) { }
1087#endif /* CONFIG_PM_SLEEP */
1088
1089PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
1090PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", };
1091PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", };
1092
1093static struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initdata = {
1094 MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1),
1095 MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1),
1096 MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1),
1097 MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1),
1098};
1099
1100static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = {
1101 DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3),
1102 DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3),
1103 DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus",
1104 DIV_DMC1, 19, 2),
1105 DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3),
1106 DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
1107 DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
1108};
1109
1110static struct samsung_pll_clock exynos4415_dmc_plls[nr_dmc_plls] __initdata = {
1111 [mpll] = PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
1112 MPLL_LOCK, MPLL_CON0, NULL),
1113 [bpll] = PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
1114 BPLL_LOCK, BPLL_CON0, NULL),
1115};
1116
1117static void __init exynos4415_cmu_dmc_init(struct device_node *np)
1118{
1119 void __iomem *reg_base;
1120
1121 reg_base = of_iomap(np, 0);
1122 if (!reg_base)
1123 panic("%s: failed to map registers\n", __func__);
1124
1125 exynos4415_dmc_ctx = samsung_clk_init(np, reg_base, NR_CLKS_DMC);
1126 if (!exynos4415_dmc_ctx)
1127 panic("%s: unable to allocate context.\n", __func__);
1128
1129 exynos4415_dmc_plls[mpll].rate_table = exynos4415_pll_rates;
1130 exynos4415_dmc_plls[bpll].rate_table = exynos4415_pll_rates;
1131
1132 samsung_clk_register_pll(exynos4415_dmc_ctx, exynos4415_dmc_plls,
1133 ARRAY_SIZE(exynos4415_dmc_plls), reg_base);
1134 samsung_clk_register_mux(exynos4415_dmc_ctx, exynos4415_dmc_mux_clks,
1135 ARRAY_SIZE(exynos4415_dmc_mux_clks));
1136 samsung_clk_register_div(exynos4415_dmc_ctx, exynos4415_dmc_div_clks,
1137 ARRAY_SIZE(exynos4415_dmc_div_clks));
1138
1139 exynos4415_dmc_clk_sleep_init();
1140
1141 samsung_clk_of_add_provider(np, exynos4415_dmc_ctx);
1142}
1143CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
1144 exynos4415_cmu_dmc_init);
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 2527e39aadcf..e2e5193d1049 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -11,10 +11,8 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clkdev.h> 13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/of.h> 14#include <linux/of.h>
16#include <linux/of_address.h> 15#include <linux/of_address.h>
17#include <linux/syscore_ops.h>
18 16
19#include "clk-exynos5260.h" 17#include "clk-exynos5260.h"
20#include "clk.h" 18#include "clk.h"
@@ -22,39 +20,6 @@
22 20
23#include <dt-bindings/clock/exynos5260-clk.h> 21#include <dt-bindings/clock/exynos5260-clk.h>
24 22
25static LIST_HEAD(clock_reg_cache_list);
26
27struct exynos5260_clock_reg_cache {
28 struct list_head node;
29 void __iomem *reg_base;
30 struct samsung_clk_reg_dump *rdump;
31 unsigned int rd_num;
32};
33
34struct exynos5260_cmu_info {
35 /* list of pll clocks and respective count */
36 struct samsung_pll_clock *pll_clks;
37 unsigned int nr_pll_clks;
38 /* list of mux clocks and respective count */
39 struct samsung_mux_clock *mux_clks;
40 unsigned int nr_mux_clks;
41 /* list of div clocks and respective count */
42 struct samsung_div_clock *div_clks;
43 unsigned int nr_div_clks;
44 /* list of gate clocks and respective count */
45 struct samsung_gate_clock *gate_clks;
46 unsigned int nr_gate_clks;
47 /* list of fixed clocks and respective count */
48 struct samsung_fixed_rate_clock *fixed_clks;
49 unsigned int nr_fixed_clks;
50 /* total number of clocks with IDs assigned*/
51 unsigned int nr_clk_ids;
52
53 /* list and number of clocks registers */
54 unsigned long *clk_regs;
55 unsigned int nr_clk_regs;
56};
57
58/* 23/*
59 * Applicable for all 2550 Type PLLS for Exynos5260, listed below 24 * Applicable for all 2550 Type PLLS for Exynos5260, listed below
60 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. 25 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
@@ -113,104 +78,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
113 PLL_36XX_RATE(66000000, 176, 2, 5, 0), 78 PLL_36XX_RATE(66000000, 176, 2, 5, 0),
114}; 79};
115 80
116#ifdef CONFIG_PM_SLEEP
117
118static int exynos5260_clk_suspend(void)
119{
120 struct exynos5260_clock_reg_cache *cache;
121
122 list_for_each_entry(cache, &clock_reg_cache_list, node)
123 samsung_clk_save(cache->reg_base, cache->rdump,
124 cache->rd_num);
125
126 return 0;
127}
128
129static void exynos5260_clk_resume(void)
130{
131 struct exynos5260_clock_reg_cache *cache;
132
133 list_for_each_entry(cache, &clock_reg_cache_list, node)
134 samsung_clk_restore(cache->reg_base, cache->rdump,
135 cache->rd_num);
136}
137
138static struct syscore_ops exynos5260_clk_syscore_ops = {
139 .suspend = exynos5260_clk_suspend,
140 .resume = exynos5260_clk_resume,
141};
142
143static void exynos5260_clk_sleep_init(void __iomem *reg_base,
144 unsigned long *rdump,
145 unsigned long nr_rdump)
146{
147 struct exynos5260_clock_reg_cache *reg_cache;
148
149 reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache),
150 GFP_KERNEL);
151 if (!reg_cache)
152 panic("could not allocate register cache.\n");
153
154 reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
155
156 if (!reg_cache->rdump)
157 panic("could not allocate register dump storage.\n");
158
159 if (list_empty(&clock_reg_cache_list))
160 register_syscore_ops(&exynos5260_clk_syscore_ops);
161
162 reg_cache->rd_num = nr_rdump;
163 reg_cache->reg_base = reg_base;
164 list_add_tail(&reg_cache->node, &clock_reg_cache_list);
165}
166
167#else
168static void exynos5260_clk_sleep_init(void __iomem *reg_base,
169 unsigned long *rdump,
170 unsigned long nr_rdump){}
171#endif
172
173/*
174 * Common function which registers plls, muxes, dividers and gates
175 * for each CMU. It also add CMU register list to register cache.
176 */
177
178void __init exynos5260_cmu_register_one(struct device_node *np,
179 struct exynos5260_cmu_info *cmu)
180{
181 void __iomem *reg_base;
182 struct samsung_clk_provider *ctx;
183
184 reg_base = of_iomap(np, 0);
185 if (!reg_base)
186 panic("%s: failed to map registers\n", __func__);
187
188 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
189 if (!ctx)
190 panic("%s: unable to alllocate ctx\n", __func__);
191
192 if (cmu->pll_clks)
193 samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
194 reg_base);
195 if (cmu->mux_clks)
196 samsung_clk_register_mux(ctx, cmu->mux_clks,
197 cmu->nr_mux_clks);
198 if (cmu->div_clks)
199 samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
200 if (cmu->gate_clks)
201 samsung_clk_register_gate(ctx, cmu->gate_clks,
202 cmu->nr_gate_clks);
203 if (cmu->fixed_clks)
204 samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
205 cmu->nr_fixed_clks);
206 if (cmu->clk_regs)
207 exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
208 cmu->nr_clk_regs);
209
210 samsung_clk_of_add_provider(np, ctx);
211}
212
213
214/* CMU_AUD */ 81/* CMU_AUD */
215 82
216static unsigned long aud_clk_regs[] __initdata = { 83static unsigned long aud_clk_regs[] __initdata = {
@@ -268,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {
268 135
269static void __init exynos5260_clk_aud_init(struct device_node *np) 136static void __init exynos5260_clk_aud_init(struct device_node *np)
270{ 137{
271 struct exynos5260_cmu_info cmu = {0}; 138 struct samsung_cmu_info cmu = {0};
272 139
273 cmu.mux_clks = aud_mux_clks; 140 cmu.mux_clks = aud_mux_clks;
274 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); 141 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -280,7 +147,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np)
280 cmu.clk_regs = aud_clk_regs; 147 cmu.clk_regs = aud_clk_regs;
281 cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); 148 cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);
282 149
283 exynos5260_cmu_register_one(np, &cmu); 150 samsung_cmu_register_one(np, &cmu);
284} 151}
285 152
286CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", 153CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -458,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {
458 325
459static void __init exynos5260_clk_disp_init(struct device_node *np) 326static void __init exynos5260_clk_disp_init(struct device_node *np)
460{ 327{
461 struct exynos5260_cmu_info cmu = {0}; 328 struct samsung_cmu_info cmu = {0};
462 329
463 cmu.mux_clks = disp_mux_clks; 330 cmu.mux_clks = disp_mux_clks;
464 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); 331 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -470,7 +337,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np)
470 cmu.clk_regs = disp_clk_regs; 337 cmu.clk_regs = disp_clk_regs;
471 cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); 338 cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);
472 339
473 exynos5260_cmu_register_one(np, &cmu); 340 samsung_cmu_register_one(np, &cmu);
474} 341}
475 342
476CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", 343CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -522,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {
522 389
523static void __init exynos5260_clk_egl_init(struct device_node *np) 390static void __init exynos5260_clk_egl_init(struct device_node *np)
524{ 391{
525 struct exynos5260_cmu_info cmu = {0}; 392 struct samsung_cmu_info cmu = {0};
526 393
527 cmu.pll_clks = egl_pll_clks; 394 cmu.pll_clks = egl_pll_clks;
528 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); 395 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks);
@@ -534,7 +401,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np)
534 cmu.clk_regs = egl_clk_regs; 401 cmu.clk_regs = egl_clk_regs;
535 cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); 402 cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);
536 403
537 exynos5260_cmu_register_one(np, &cmu); 404 samsung_cmu_register_one(np, &cmu);
538} 405}
539 406
540CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", 407CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -624,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {
624 491
625static void __init exynos5260_clk_fsys_init(struct device_node *np) 492static void __init exynos5260_clk_fsys_init(struct device_node *np)
626{ 493{
627 struct exynos5260_cmu_info cmu = {0}; 494 struct samsung_cmu_info cmu = {0};
628 495
629 cmu.mux_clks = fsys_mux_clks; 496 cmu.mux_clks = fsys_mux_clks;
630 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); 497 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -634,7 +501,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np)
634 cmu.clk_regs = fsys_clk_regs; 501 cmu.clk_regs = fsys_clk_regs;
635 cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); 502 cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);
636 503
637 exynos5260_cmu_register_one(np, &cmu); 504 samsung_cmu_register_one(np, &cmu);
638} 505}
639 506
640CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", 507CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -713,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {
713 580
714static void __init exynos5260_clk_g2d_init(struct device_node *np) 581static void __init exynos5260_clk_g2d_init(struct device_node *np)
715{ 582{
716 struct exynos5260_cmu_info cmu = {0}; 583 struct samsung_cmu_info cmu = {0};
717 584
718 cmu.mux_clks = g2d_mux_clks; 585 cmu.mux_clks = g2d_mux_clks;
719 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); 586 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -725,7 +592,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np)
725 cmu.clk_regs = g2d_clk_regs; 592 cmu.clk_regs = g2d_clk_regs;
726 cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); 593 cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);
727 594
728 exynos5260_cmu_register_one(np, &cmu); 595 samsung_cmu_register_one(np, &cmu);
729} 596}
730 597
731CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", 598CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -774,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
774 641
775static void __init exynos5260_clk_g3d_init(struct device_node *np) 642static void __init exynos5260_clk_g3d_init(struct device_node *np)
776{ 643{
777 struct exynos5260_cmu_info cmu = {0}; 644 struct samsung_cmu_info cmu = {0};
778 645
779 cmu.pll_clks = g3d_pll_clks; 646 cmu.pll_clks = g3d_pll_clks;
780 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); 647 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks);
@@ -788,7 +655,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np)
788 cmu.clk_regs = g3d_clk_regs; 655 cmu.clk_regs = g3d_clk_regs;
789 cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); 656 cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);
790 657
791 exynos5260_cmu_register_one(np, &cmu); 658 samsung_cmu_register_one(np, &cmu);
792} 659}
793 660
794CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", 661CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -909,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {
909 776
910static void __init exynos5260_clk_gscl_init(struct device_node *np) 777static void __init exynos5260_clk_gscl_init(struct device_node *np)
911{ 778{
912 struct exynos5260_cmu_info cmu = {0}; 779 struct samsung_cmu_info cmu = {0};
913 780
914 cmu.mux_clks = gscl_mux_clks; 781 cmu.mux_clks = gscl_mux_clks;
915 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); 782 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -921,7 +788,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np)
921 cmu.clk_regs = gscl_clk_regs; 788 cmu.clk_regs = gscl_clk_regs;
922 cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); 789 cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);
923 790
924 exynos5260_cmu_register_one(np, &cmu); 791 samsung_cmu_register_one(np, &cmu);
925} 792}
926 793
927CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", 794CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -1028,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {
1028 895
1029static void __init exynos5260_clk_isp_init(struct device_node *np) 896static void __init exynos5260_clk_isp_init(struct device_node *np)
1030{ 897{
1031 struct exynos5260_cmu_info cmu = {0}; 898 struct samsung_cmu_info cmu = {0};
1032 899
1033 cmu.mux_clks = isp_mux_clks; 900 cmu.mux_clks = isp_mux_clks;
1034 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); 901 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -1040,7 +907,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np)
1040 cmu.clk_regs = isp_clk_regs; 907 cmu.clk_regs = isp_clk_regs;
1041 cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); 908 cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);
1042 909
1043 exynos5260_cmu_register_one(np, &cmu); 910 samsung_cmu_register_one(np, &cmu);
1044} 911}
1045 912
1046CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", 913CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -1092,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
1092 959
1093static void __init exynos5260_clk_kfc_init(struct device_node *np) 960static void __init exynos5260_clk_kfc_init(struct device_node *np)
1094{ 961{
1095 struct exynos5260_cmu_info cmu = {0}; 962 struct samsung_cmu_info cmu = {0};
1096 963
1097 cmu.pll_clks = kfc_pll_clks; 964 cmu.pll_clks = kfc_pll_clks;
1098 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); 965 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks);
@@ -1104,7 +971,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np)
1104 cmu.clk_regs = kfc_clk_regs; 971 cmu.clk_regs = kfc_clk_regs;
1105 cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); 972 cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);
1106 973
1107 exynos5260_cmu_register_one(np, &cmu); 974 samsung_cmu_register_one(np, &cmu);
1108} 975}
1109 976
1110CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", 977CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1148,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {
1148 1015
1149static void __init exynos5260_clk_mfc_init(struct device_node *np) 1016static void __init exynos5260_clk_mfc_init(struct device_node *np)
1150{ 1017{
1151 struct exynos5260_cmu_info cmu = {0}; 1018 struct samsung_cmu_info cmu = {0};
1152 1019
1153 cmu.mux_clks = mfc_mux_clks; 1020 cmu.mux_clks = mfc_mux_clks;
1154 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); 1021 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1160,7 +1027,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np)
1160 cmu.clk_regs = mfc_clk_regs; 1027 cmu.clk_regs = mfc_clk_regs;
1161 cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); 1028 cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);
1162 1029
1163 exynos5260_cmu_register_one(np, &cmu); 1030 samsung_cmu_register_one(np, &cmu);
1164} 1031}
1165 1032
1166CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", 1033CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1295,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {
1295 1162
1296static void __init exynos5260_clk_mif_init(struct device_node *np) 1163static void __init exynos5260_clk_mif_init(struct device_node *np)
1297{ 1164{
1298 struct exynos5260_cmu_info cmu = {0}; 1165 struct samsung_cmu_info cmu = {0};
1299 1166
1300 cmu.pll_clks = mif_pll_clks; 1167 cmu.pll_clks = mif_pll_clks;
1301 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); 1168 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks);
@@ -1309,7 +1176,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np)
1309 cmu.clk_regs = mif_clk_regs; 1176 cmu.clk_regs = mif_clk_regs;
1310 cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); 1177 cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);
1311 1178
1312 exynos5260_cmu_register_one(np, &cmu); 1179 samsung_cmu_register_one(np, &cmu);
1313} 1180}
1314 1181
1315CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", 1182CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1503,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {
1503 1370
1504static void __init exynos5260_clk_peri_init(struct device_node *np) 1371static void __init exynos5260_clk_peri_init(struct device_node *np)
1505{ 1372{
1506 struct exynos5260_cmu_info cmu = {0}; 1373 struct samsung_cmu_info cmu = {0};
1507 1374
1508 cmu.mux_clks = peri_mux_clks; 1375 cmu.mux_clks = peri_mux_clks;
1509 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); 1376 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1515,7 +1382,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np)
1515 cmu.clk_regs = peri_clk_regs; 1382 cmu.clk_regs = peri_clk_regs;
1516 cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); 1383 cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);
1517 1384
1518 exynos5260_cmu_register_one(np, &cmu); 1385 samsung_cmu_register_one(np, &cmu);
1519} 1386}
1520 1387
1521CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", 1388CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1959,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {
1959 1826
1960static void __init exynos5260_clk_top_init(struct device_node *np) 1827static void __init exynos5260_clk_top_init(struct device_node *np)
1961{ 1828{
1962 struct exynos5260_cmu_info cmu = {0}; 1829 struct samsung_cmu_info cmu = {0};
1963 1830
1964 cmu.pll_clks = top_pll_clks; 1831 cmu.pll_clks = top_pll_clks;
1965 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); 1832 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks);
@@ -1975,7 +1842,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np)
1975 cmu.clk_regs = top_clk_regs; 1842 cmu.clk_regs = top_clk_regs;
1976 cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); 1843 cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);
1977 1844
1978 exynos5260_cmu_register_one(np, &cmu); 1845 samsung_cmu_register_one(np, &cmu);
1979} 1846}
1980 1847
1981CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", 1848CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c
new file mode 100644
index 000000000000..ea4483b8d62e
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos7.c
@@ -0,0 +1,743 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * Author: Naveen Krishna Ch <naveenkrishna.ch@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9*/
10
11#include <linux/clk.h>
12#include <linux/clkdev.h>
13#include <linux/clk-provider.h>
14#include <linux/of.h>
15
16#include "clk.h"
17#include <dt-bindings/clock/exynos7-clk.h>
18
19/* Register Offset definitions for CMU_TOPC (0x10570000) */
20#define CC_PLL_LOCK 0x0000
21#define BUS0_PLL_LOCK 0x0004
22#define BUS1_DPLL_LOCK 0x0008
23#define MFC_PLL_LOCK 0x000C
24#define AUD_PLL_LOCK 0x0010
25#define CC_PLL_CON0 0x0100
26#define BUS0_PLL_CON0 0x0110
27#define BUS1_DPLL_CON0 0x0120
28#define MFC_PLL_CON0 0x0130
29#define AUD_PLL_CON0 0x0140
30#define MUX_SEL_TOPC0 0x0200
31#define MUX_SEL_TOPC1 0x0204
32#define MUX_SEL_TOPC2 0x0208
33#define MUX_SEL_TOPC3 0x020C
34#define DIV_TOPC0 0x0600
35#define DIV_TOPC1 0x0604
36#define DIV_TOPC3 0x060C
37
38static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
39 FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0),
40 FFACTOR(0, "ffac_topc_bus0_pll_div4",
41 "ffac_topc_bus0_pll_div2", 1, 2, 0),
42 FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0),
43 FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0),
44 FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0),
45};
46
47/* List of parent clocks for Muxes in CMU_TOPC */
48PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" };
49PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" };
50PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
51PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" };
52
53PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc",
54 "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc",
55 "mout_sclk_mfc_pll_cmuc" };
56
57PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl",
58 "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"};
59PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl",
60 "ffac_topc_bus1_pll_div2"};
61PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl",
62 "ffac_topc_cc_pll_div2"};
63PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl",
64 "ffac_topc_mfc_pll_div2"};
65
66
67PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl",
68 "ffac_topc_bus0_pll_div2"};
69
70static unsigned long topc_clk_regs[] __initdata = {
71 CC_PLL_LOCK,
72 BUS0_PLL_LOCK,
73 BUS1_DPLL_LOCK,
74 MFC_PLL_LOCK,
75 AUD_PLL_LOCK,
76 CC_PLL_CON0,
77 BUS0_PLL_CON0,
78 BUS1_DPLL_CON0,
79 MFC_PLL_CON0,
80 AUD_PLL_CON0,
81 MUX_SEL_TOPC0,
82 MUX_SEL_TOPC1,
83 MUX_SEL_TOPC2,
84 MUX_SEL_TOPC3,
85 DIV_TOPC0,
86 DIV_TOPC1,
87 DIV_TOPC3,
88};
89
90static struct samsung_mux_clock topc_mux_clks[] __initdata = {
91 MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1),
92 MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1),
93 MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1),
94 MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1),
95
96 MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p,
97 MUX_SEL_TOPC0, 16, 2),
98 MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p,
99 MUX_SEL_TOPC0, 20, 1),
100 MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p,
101 MUX_SEL_TOPC0, 24, 1),
102 MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p,
103 MUX_SEL_TOPC0, 28, 1),
104
105 MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p,
106 MUX_SEL_TOPC1, 16, 1),
107
108 MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2),
109
110 MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2),
111};
112
113static struct samsung_div_clock topc_div_clks[] __initdata = {
114 DIV(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133",
115 DIV_TOPC0, 4, 4),
116
117 DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
118 DIV_TOPC1, 24, 4),
119
120 DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out",
121 DIV_TOPC3, 0, 3),
122 DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl",
123 DIV_TOPC3, 8, 3),
124 DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl",
125 DIV_TOPC3, 12, 3),
126 DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
127 DIV_TOPC3, 16, 3),
128};
129
130static struct samsung_pll_clock topc_pll_clks[] __initdata = {
131 PLL(pll_1451x, 0, "fout_bus0_pll", "fin_pll", BUS0_PLL_LOCK,
132 BUS0_PLL_CON0, NULL),
133 PLL(pll_1452x, 0, "fout_cc_pll", "fin_pll", CC_PLL_LOCK,
134 CC_PLL_CON0, NULL),
135 PLL(pll_1452x, 0, "fout_bus1_pll", "fin_pll", BUS1_DPLL_LOCK,
136 BUS1_DPLL_CON0, NULL),
137 PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK,
138 MFC_PLL_CON0, NULL),
139 PLL(pll_1460x, 0, "fout_aud_pll", "fin_pll", AUD_PLL_LOCK,
140 AUD_PLL_CON0, NULL),
141};
142
143static struct samsung_cmu_info topc_cmu_info __initdata = {
144 .pll_clks = topc_pll_clks,
145 .nr_pll_clks = ARRAY_SIZE(topc_pll_clks),
146 .mux_clks = topc_mux_clks,
147 .nr_mux_clks = ARRAY_SIZE(topc_mux_clks),
148 .div_clks = topc_div_clks,
149 .nr_div_clks = ARRAY_SIZE(topc_div_clks),
150 .fixed_factor_clks = topc_fixed_factor_clks,
151 .nr_fixed_factor_clks = ARRAY_SIZE(topc_fixed_factor_clks),
152 .nr_clk_ids = TOPC_NR_CLK,
153 .clk_regs = topc_clk_regs,
154 .nr_clk_regs = ARRAY_SIZE(topc_clk_regs),
155};
156
157static void __init exynos7_clk_topc_init(struct device_node *np)
158{
159 samsung_cmu_register_one(np, &topc_cmu_info);
160}
161
162CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc",
163 exynos7_clk_topc_init);
164
165/* Register Offset definitions for CMU_TOP0 (0x105D0000) */
166#define MUX_SEL_TOP00 0x0200
167#define MUX_SEL_TOP01 0x0204
168#define MUX_SEL_TOP03 0x020C
169#define MUX_SEL_TOP0_PERIC3 0x023C
170#define DIV_TOP03 0x060C
171#define DIV_TOP0_PERIC3 0x063C
172#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C
173
174/* List of parent clocks for Muxes in CMU_TOP0 */
175PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" };
176PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" };
177PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" };
178PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" };
179
180PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll",
181 "ffac_top0_bus0_pll_div2"};
182PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll",
183 "ffac_top0_bus1_pll_div2"};
184PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll",
185 "ffac_top0_cc_pll_div2"};
186PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll",
187 "ffac_top0_mfc_pll_div2"};
188
189PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll",
190 "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
191 "mout_top0_half_mfc_pll"};
192
193static unsigned long top0_clk_regs[] __initdata = {
194 MUX_SEL_TOP00,
195 MUX_SEL_TOP01,
196 MUX_SEL_TOP03,
197 MUX_SEL_TOP0_PERIC3,
198 DIV_TOP03,
199 DIV_TOP0_PERIC3,
200 ENABLE_SCLK_TOP0_PERIC3,
201};
202
203static struct samsung_mux_clock top0_mux_clks[] __initdata = {
204 MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1),
205 MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1),
206 MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1),
207 MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1),
208
209 MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p,
210 MUX_SEL_TOP01, 4, 1),
211 MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p,
212 MUX_SEL_TOP01, 8, 1),
213 MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p,
214 MUX_SEL_TOP01, 12, 1),
215 MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p,
216 MUX_SEL_TOP01, 16, 1),
217
218 MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2),
219 MUX(0, "mout_aclk_peric0_66", mout_top0_group1, MUX_SEL_TOP03, 20, 2),
220
221 MUX(0, "mout_sclk_uart3", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 4, 2),
222 MUX(0, "mout_sclk_uart2", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 8, 2),
223 MUX(0, "mout_sclk_uart1", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 12, 2),
224 MUX(0, "mout_sclk_uart0", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 16, 2),
225};
226
227static struct samsung_div_clock top0_div_clks[] __initdata = {
228 DIV(DOUT_ACLK_PERIC1, "dout_aclk_peric1_66", "mout_aclk_peric1_66",
229 DIV_TOP03, 12, 6),
230 DIV(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66",
231 DIV_TOP03, 20, 6),
232
233 DIV(0, "dout_sclk_uart3", "mout_sclk_uart3", DIV_TOP0_PERIC3, 4, 4),
234 DIV(0, "dout_sclk_uart2", "mout_sclk_uart2", DIV_TOP0_PERIC3, 8, 4),
235 DIV(0, "dout_sclk_uart1", "mout_sclk_uart1", DIV_TOP0_PERIC3, 12, 4),
236 DIV(0, "dout_sclk_uart0", "mout_sclk_uart0", DIV_TOP0_PERIC3, 16, 4),
237};
238
239static struct samsung_gate_clock top0_gate_clks[] __initdata = {
240 GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_sclk_uart3",
241 ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0),
242 GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_sclk_uart2",
243 ENABLE_SCLK_TOP0_PERIC3, 8, 0, 0),
244 GATE(CLK_SCLK_UART1, "sclk_uart1", "dout_sclk_uart1",
245 ENABLE_SCLK_TOP0_PERIC3, 12, 0, 0),
246 GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0",
247 ENABLE_SCLK_TOP0_PERIC3, 16, 0, 0),
248};
249
250static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
251 FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0),
252 FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0),
253 FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0),
254 FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0),
255};
256
257static struct samsung_cmu_info top0_cmu_info __initdata = {
258 .mux_clks = top0_mux_clks,
259 .nr_mux_clks = ARRAY_SIZE(top0_mux_clks),
260 .div_clks = top0_div_clks,
261 .nr_div_clks = ARRAY_SIZE(top0_div_clks),
262 .gate_clks = top0_gate_clks,
263 .nr_gate_clks = ARRAY_SIZE(top0_gate_clks),
264 .fixed_factor_clks = top0_fixed_factor_clks,
265 .nr_fixed_factor_clks = ARRAY_SIZE(top0_fixed_factor_clks),
266 .nr_clk_ids = TOP0_NR_CLK,
267 .clk_regs = top0_clk_regs,
268 .nr_clk_regs = ARRAY_SIZE(top0_clk_regs),
269};
270
271static void __init exynos7_clk_top0_init(struct device_node *np)
272{
273 samsung_cmu_register_one(np, &top0_cmu_info);
274}
275
276CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0",
277 exynos7_clk_top0_init);
278
279/* Register Offset definitions for CMU_TOP1 (0x105E0000) */
280#define MUX_SEL_TOP10 0x0200
281#define MUX_SEL_TOP11 0x0204
282#define MUX_SEL_TOP13 0x020C
283#define MUX_SEL_TOP1_FSYS0 0x0224
284#define MUX_SEL_TOP1_FSYS1 0x0228
285#define DIV_TOP13 0x060C
286#define DIV_TOP1_FSYS0 0x0624
287#define DIV_TOP1_FSYS1 0x0628
288#define ENABLE_ACLK_TOP13 0x080C
289#define ENABLE_SCLK_TOP1_FSYS0 0x0A24
290#define ENABLE_SCLK_TOP1_FSYS1 0x0A28
291
292/* List of parent clocks for Muxes in CMU_TOP1 */
293PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" };
294PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" };
295PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" };
296PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" };
297
298PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll",
299 "ffac_top1_bus0_pll_div2"};
300PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll",
301 "ffac_top1_bus1_pll_div2"};
302PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll",
303 "ffac_top1_cc_pll_div2"};
304PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll",
305 "ffac_top1_mfc_pll_div2"};
306
307PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll",
308 "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll",
309 "mout_top1_half_mfc_pll"};
310
311static unsigned long top1_clk_regs[] __initdata = {
312 MUX_SEL_TOP10,
313 MUX_SEL_TOP11,
314 MUX_SEL_TOP13,
315 MUX_SEL_TOP1_FSYS0,
316 MUX_SEL_TOP1_FSYS1,
317 DIV_TOP13,
318 DIV_TOP1_FSYS0,
319 DIV_TOP1_FSYS1,
320 ENABLE_ACLK_TOP13,
321 ENABLE_SCLK_TOP1_FSYS0,
322 ENABLE_SCLK_TOP1_FSYS1,
323};
324
325static struct samsung_mux_clock top1_mux_clks[] __initdata = {
326 MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1),
327 MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1),
328 MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p,
329 MUX_SEL_TOP10, 12, 1),
330 MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p,
331 MUX_SEL_TOP10, 16, 1),
332
333 MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p,
334 MUX_SEL_TOP11, 4, 1),
335 MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p,
336 MUX_SEL_TOP11, 8, 1),
337 MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p,
338 MUX_SEL_TOP11, 12, 1),
339 MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p,
340 MUX_SEL_TOP11, 16, 1),
341
342 MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2),
343 MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2),
344
345 MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2),
346
347 MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2),
348 MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2),
349};
350
351static struct samsung_div_clock top1_div_clks[] __initdata = {
352 DIV(DOUT_ACLK_FSYS1_200, "dout_aclk_fsys1_200", "mout_aclk_fsys1_200",
353 DIV_TOP13, 24, 4),
354 DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200",
355 DIV_TOP13, 28, 4),
356
357 DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
358 DIV_TOP1_FSYS0, 24, 4),
359
360 DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
361 DIV_TOP1_FSYS1, 24, 4),
362 DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0",
363 DIV_TOP1_FSYS1, 28, 4),
364};
365
366static struct samsung_gate_clock top1_gate_clks[] __initdata = {
367 GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
368 ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0),
369
370 GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
371 ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0),
372 GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0",
373 ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0),
374};
375
376static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
377 FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0),
378 FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0),
379 FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0),
380 FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0),
381};
382
383static struct samsung_cmu_info top1_cmu_info __initdata = {
384 .mux_clks = top1_mux_clks,
385 .nr_mux_clks = ARRAY_SIZE(top1_mux_clks),
386 .div_clks = top1_div_clks,
387 .nr_div_clks = ARRAY_SIZE(top1_div_clks),
388 .gate_clks = top1_gate_clks,
389 .nr_gate_clks = ARRAY_SIZE(top1_gate_clks),
390 .fixed_factor_clks = top1_fixed_factor_clks,
391 .nr_fixed_factor_clks = ARRAY_SIZE(top1_fixed_factor_clks),
392 .nr_clk_ids = TOP1_NR_CLK,
393 .clk_regs = top1_clk_regs,
394 .nr_clk_regs = ARRAY_SIZE(top1_clk_regs),
395};
396
397static void __init exynos7_clk_top1_init(struct device_node *np)
398{
399 samsung_cmu_register_one(np, &top1_cmu_info);
400}
401
402CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1",
403 exynos7_clk_top1_init);
404
405/* Register Offset definitions for CMU_CCORE (0x105B0000) */
406#define MUX_SEL_CCORE 0x0200
407#define DIV_CCORE 0x0600
408#define ENABLE_ACLK_CCORE0 0x0800
409#define ENABLE_ACLK_CCORE1 0x0804
410#define ENABLE_PCLK_CCORE 0x0900
411
412/*
413 * List of parent clocks for Muxes in CMU_CCORE
414 */
415PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" };
416
417static unsigned long ccore_clk_regs[] __initdata = {
418 MUX_SEL_CCORE,
419 ENABLE_PCLK_CCORE,
420};
421
422static struct samsung_mux_clock ccore_mux_clks[] __initdata = {
423 MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p,
424 MUX_SEL_CCORE, 1, 1),
425};
426
427static struct samsung_gate_clock ccore_gate_clks[] __initdata = {
428 GATE(PCLK_RTC, "pclk_rtc", "mout_aclk_ccore_133_user",
429 ENABLE_PCLK_CCORE, 8, 0, 0),
430};
431
432static struct samsung_cmu_info ccore_cmu_info __initdata = {
433 .mux_clks = ccore_mux_clks,
434 .nr_mux_clks = ARRAY_SIZE(ccore_mux_clks),
435 .gate_clks = ccore_gate_clks,
436 .nr_gate_clks = ARRAY_SIZE(ccore_gate_clks),
437 .nr_clk_ids = CCORE_NR_CLK,
438 .clk_regs = ccore_clk_regs,
439 .nr_clk_regs = ARRAY_SIZE(ccore_clk_regs),
440};
441
442static void __init exynos7_clk_ccore_init(struct device_node *np)
443{
444 samsung_cmu_register_one(np, &ccore_cmu_info);
445}
446
447CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore",
448 exynos7_clk_ccore_init);
449
450/* Register Offset definitions for CMU_PERIC0 (0x13610000) */
451#define MUX_SEL_PERIC0 0x0200
452#define ENABLE_PCLK_PERIC0 0x0900
453#define ENABLE_SCLK_PERIC0 0x0A00
454
455/* List of parent clocks for Muxes in CMU_PERIC0 */
456PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" };
457PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" };
458
459static unsigned long peric0_clk_regs[] __initdata = {
460 MUX_SEL_PERIC0,
461 ENABLE_PCLK_PERIC0,
462 ENABLE_SCLK_PERIC0,
463};
464
465static struct samsung_mux_clock peric0_mux_clks[] __initdata = {
466 MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p,
467 MUX_SEL_PERIC0, 0, 1),
468 MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p,
469 MUX_SEL_PERIC0, 16, 1),
470};
471
472static struct samsung_gate_clock peric0_gate_clks[] __initdata = {
473 GATE(PCLK_HSI2C0, "pclk_hsi2c0", "mout_aclk_peric0_66_user",
474 ENABLE_PCLK_PERIC0, 8, 0, 0),
475 GATE(PCLK_HSI2C1, "pclk_hsi2c1", "mout_aclk_peric0_66_user",
476 ENABLE_PCLK_PERIC0, 9, 0, 0),
477 GATE(PCLK_HSI2C4, "pclk_hsi2c4", "mout_aclk_peric0_66_user",
478 ENABLE_PCLK_PERIC0, 10, 0, 0),
479 GATE(PCLK_HSI2C5, "pclk_hsi2c5", "mout_aclk_peric0_66_user",
480 ENABLE_PCLK_PERIC0, 11, 0, 0),
481 GATE(PCLK_HSI2C9, "pclk_hsi2c9", "mout_aclk_peric0_66_user",
482 ENABLE_PCLK_PERIC0, 12, 0, 0),
483 GATE(PCLK_HSI2C10, "pclk_hsi2c10", "mout_aclk_peric0_66_user",
484 ENABLE_PCLK_PERIC0, 13, 0, 0),
485 GATE(PCLK_HSI2C11, "pclk_hsi2c11", "mout_aclk_peric0_66_user",
486 ENABLE_PCLK_PERIC0, 14, 0, 0),
487 GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user",
488 ENABLE_PCLK_PERIC0, 16, 0, 0),
489 GATE(PCLK_ADCIF, "pclk_adcif", "mout_aclk_peric0_66_user",
490 ENABLE_PCLK_PERIC0, 20, 0, 0),
491 GATE(PCLK_PWM, "pclk_pwm", "mout_aclk_peric0_66_user",
492 ENABLE_PCLK_PERIC0, 21, 0, 0),
493
494 GATE(SCLK_UART0, "sclk_uart0_user", "mout_sclk_uart0_user",
495 ENABLE_SCLK_PERIC0, 16, 0, 0),
496 GATE(SCLK_PWM, "sclk_pwm", "fin_pll", ENABLE_SCLK_PERIC0, 21, 0, 0),
497};
498
499static struct samsung_cmu_info peric0_cmu_info __initdata = {
500 .mux_clks = peric0_mux_clks,
501 .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks),
502 .gate_clks = peric0_gate_clks,
503 .nr_gate_clks = ARRAY_SIZE(peric0_gate_clks),
504 .nr_clk_ids = PERIC0_NR_CLK,
505 .clk_regs = peric0_clk_regs,
506 .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs),
507};
508
509static void __init exynos7_clk_peric0_init(struct device_node *np)
510{
511 samsung_cmu_register_one(np, &peric0_cmu_info);
512}
513
514/* Register Offset definitions for CMU_PERIC1 (0x14C80000) */
515#define MUX_SEL_PERIC10 0x0200
516#define MUX_SEL_PERIC11 0x0204
517#define ENABLE_PCLK_PERIC1 0x0900
518#define ENABLE_SCLK_PERIC10 0x0A00
519
520CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0",
521 exynos7_clk_peric0_init);
522
523/* List of parent clocks for Muxes in CMU_PERIC1 */
524PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" };
525PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" };
526PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" };
527PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" };
528
529static unsigned long peric1_clk_regs[] __initdata = {
530 MUX_SEL_PERIC10,
531 MUX_SEL_PERIC11,
532 ENABLE_PCLK_PERIC1,
533 ENABLE_SCLK_PERIC10,
534};
535
536static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
537 MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p,
538 MUX_SEL_PERIC10, 0, 1),
539
540 MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p,
541 MUX_SEL_PERIC11, 20, 1),
542 MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p,
543 MUX_SEL_PERIC11, 24, 1),
544 MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p,
545 MUX_SEL_PERIC11, 28, 1),
546};
547
548static struct samsung_gate_clock peric1_gate_clks[] __initdata = {
549 GATE(PCLK_HSI2C2, "pclk_hsi2c2", "mout_aclk_peric1_66_user",
550 ENABLE_PCLK_PERIC1, 4, 0, 0),
551 GATE(PCLK_HSI2C3, "pclk_hsi2c3", "mout_aclk_peric1_66_user",
552 ENABLE_PCLK_PERIC1, 5, 0, 0),
553 GATE(PCLK_HSI2C6, "pclk_hsi2c6", "mout_aclk_peric1_66_user",
554 ENABLE_PCLK_PERIC1, 6, 0, 0),
555 GATE(PCLK_HSI2C7, "pclk_hsi2c7", "mout_aclk_peric1_66_user",
556 ENABLE_PCLK_PERIC1, 7, 0, 0),
557 GATE(PCLK_HSI2C8, "pclk_hsi2c8", "mout_aclk_peric1_66_user",
558 ENABLE_PCLK_PERIC1, 8, 0, 0),
559 GATE(PCLK_UART1, "pclk_uart1", "mout_aclk_peric1_66_user",
560 ENABLE_PCLK_PERIC1, 9, 0, 0),
561 GATE(PCLK_UART2, "pclk_uart2", "mout_aclk_peric1_66_user",
562 ENABLE_PCLK_PERIC1, 10, 0, 0),
563 GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user",
564 ENABLE_PCLK_PERIC1, 11, 0, 0),
565
566 GATE(SCLK_UART1, "sclk_uart1_user", "mout_sclk_uart1_user",
567 ENABLE_SCLK_PERIC10, 9, 0, 0),
568 GATE(SCLK_UART2, "sclk_uart2_user", "mout_sclk_uart2_user",
569 ENABLE_SCLK_PERIC10, 10, 0, 0),
570 GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user",
571 ENABLE_SCLK_PERIC10, 11, 0, 0),
572};
573
574static struct samsung_cmu_info peric1_cmu_info __initdata = {
575 .mux_clks = peric1_mux_clks,
576 .nr_mux_clks = ARRAY_SIZE(peric1_mux_clks),
577 .gate_clks = peric1_gate_clks,
578 .nr_gate_clks = ARRAY_SIZE(peric1_gate_clks),
579 .nr_clk_ids = PERIC1_NR_CLK,
580 .clk_regs = peric1_clk_regs,
581 .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs),
582};
583
584static void __init exynos7_clk_peric1_init(struct device_node *np)
585{
586 samsung_cmu_register_one(np, &peric1_cmu_info);
587}
588
589CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1",
590 exynos7_clk_peric1_init);
591
592/* Register Offset definitions for CMU_PERIS (0x10040000) */
593#define MUX_SEL_PERIS 0x0200
594#define ENABLE_PCLK_PERIS 0x0900
595#define ENABLE_PCLK_PERIS_SECURE_CHIPID 0x0910
596#define ENABLE_SCLK_PERIS 0x0A00
597#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10
598
599/* List of parent clocks for Muxes in CMU_PERIS */
600PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" };
601
602static unsigned long peris_clk_regs[] __initdata = {
603 MUX_SEL_PERIS,
604 ENABLE_PCLK_PERIS,
605 ENABLE_PCLK_PERIS_SECURE_CHIPID,
606 ENABLE_SCLK_PERIS,
607 ENABLE_SCLK_PERIS_SECURE_CHIPID,
608};
609
610static struct samsung_mux_clock peris_mux_clks[] __initdata = {
611 MUX(0, "mout_aclk_peris_66_user",
612 mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1),
613};
614
615static struct samsung_gate_clock peris_gate_clks[] __initdata = {
616 GATE(PCLK_WDT, "pclk_wdt", "mout_aclk_peris_66_user",
617 ENABLE_PCLK_PERIS, 6, 0, 0),
618 GATE(PCLK_TMU, "pclk_tmu_apbif", "mout_aclk_peris_66_user",
619 ENABLE_PCLK_PERIS, 10, 0, 0),
620
621 GATE(PCLK_CHIPID, "pclk_chipid", "mout_aclk_peris_66_user",
622 ENABLE_PCLK_PERIS_SECURE_CHIPID, 0, 0, 0),
623 GATE(SCLK_CHIPID, "sclk_chipid", "fin_pll",
624 ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0),
625
626 GATE(SCLK_TMU, "sclk_tmu", "fin_pll", ENABLE_SCLK_PERIS, 10, 0, 0),
627};
628
629static struct samsung_cmu_info peris_cmu_info __initdata = {
630 .mux_clks = peris_mux_clks,
631 .nr_mux_clks = ARRAY_SIZE(peris_mux_clks),
632 .gate_clks = peris_gate_clks,
633 .nr_gate_clks = ARRAY_SIZE(peris_gate_clks),
634 .nr_clk_ids = PERIS_NR_CLK,
635 .clk_regs = peris_clk_regs,
636 .nr_clk_regs = ARRAY_SIZE(peris_clk_regs),
637};
638
639static void __init exynos7_clk_peris_init(struct device_node *np)
640{
641 samsung_cmu_register_one(np, &peris_cmu_info);
642}
643
644CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris",
645 exynos7_clk_peris_init);
646
647/* Register Offset definitions for CMU_FSYS0 (0x10E90000) */
648#define MUX_SEL_FSYS00 0x0200
649#define MUX_SEL_FSYS01 0x0204
650#define ENABLE_ACLK_FSYS01 0x0804
651
652/*
653 * List of parent clocks for Muxes in CMU_FSYS0
654 */
655PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" };
656PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" };
657
658static unsigned long fsys0_clk_regs[] __initdata = {
659 MUX_SEL_FSYS00,
660 MUX_SEL_FSYS01,
661 ENABLE_ACLK_FSYS01,
662};
663
664static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
665 MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p,
666 MUX_SEL_FSYS00, 24, 1),
667
668 MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1),
669};
670
671static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
672 GATE(ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys0_200_user",
673 ENABLE_ACLK_FSYS01, 31, 0, 0),
674};
675
676static struct samsung_cmu_info fsys0_cmu_info __initdata = {
677 .mux_clks = fsys0_mux_clks,
678 .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks),
679 .gate_clks = fsys0_gate_clks,
680 .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks),
681 .nr_clk_ids = TOP1_NR_CLK,
682 .clk_regs = fsys0_clk_regs,
683 .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs),
684};
685
686static void __init exynos7_clk_fsys0_init(struct device_node *np)
687{
688 samsung_cmu_register_one(np, &fsys0_cmu_info);
689}
690
691CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0",
692 exynos7_clk_fsys0_init);
693
694/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */
695#define MUX_SEL_FSYS10 0x0200
696#define MUX_SEL_FSYS11 0x0204
697#define ENABLE_ACLK_FSYS1 0x0800
698
699/*
700 * List of parent clocks for Muxes in CMU_FSYS1
701 */
702PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" };
703PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" };
704PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" };
705
706static unsigned long fsys1_clk_regs[] __initdata = {
707 MUX_SEL_FSYS10,
708 MUX_SEL_FSYS11,
709 ENABLE_ACLK_FSYS1,
710};
711
712static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
713 MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p,
714 MUX_SEL_FSYS10, 28, 1),
715
716 MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1),
717 MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1),
718};
719
720static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
721 GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user",
722 ENABLE_ACLK_FSYS1, 29, 0, 0),
723 GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user",
724 ENABLE_ACLK_FSYS1, 30, 0, 0),
725};
726
727static struct samsung_cmu_info fsys1_cmu_info __initdata = {
728 .mux_clks = fsys1_mux_clks,
729 .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks),
730 .gate_clks = fsys1_gate_clks,
731 .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks),
732 .nr_clk_ids = TOP1_NR_CLK,
733 .clk_regs = fsys1_clk_regs,
734 .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs),
735};
736
737static void __init exynos7_clk_fsys1_init(struct device_node *np)
738{
739 samsung_cmu_register_one(np, &fsys1_cmu_info);
740}
741
742CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1",
743 exynos7_clk_fsys1_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index b07fad2a9167..9d70e5c03804 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -482,6 +482,8 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = {
482 482
483#define PLL46XX_VSEL_MASK (1) 483#define PLL46XX_VSEL_MASK (1)
484#define PLL46XX_MDIV_MASK (0x1FF) 484#define PLL46XX_MDIV_MASK (0x1FF)
485#define PLL1460X_MDIV_MASK (0x3FF)
486
485#define PLL46XX_PDIV_MASK (0x3F) 487#define PLL46XX_PDIV_MASK (0x3F)
486#define PLL46XX_SDIV_MASK (0x7) 488#define PLL46XX_SDIV_MASK (0x7)
487#define PLL46XX_VSEL_SHIFT (27) 489#define PLL46XX_VSEL_SHIFT (27)
@@ -511,13 +513,15 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
511 513
512 pll_con0 = __raw_readl(pll->con_reg); 514 pll_con0 = __raw_readl(pll->con_reg);
513 pll_con1 = __raw_readl(pll->con_reg + 4); 515 pll_con1 = __raw_readl(pll->con_reg + 4);
514 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 516 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
517 PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
515 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 518 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
516 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; 519 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
517 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : 520 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
518 pll_con1 & PLL46XX_KDIV_MASK; 521 pll_con1 & PLL46XX_KDIV_MASK;
519 522
520 shift = pll->type == pll_4600 ? 16 : 10; 523 shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
524
521 fvco *= (mdiv << shift) + kdiv; 525 fvco *= (mdiv << shift) + kdiv;
522 do_div(fvco, (pdiv << sdiv)); 526 do_div(fvco, (pdiv << sdiv));
523 fvco >>= shift; 527 fvco >>= shift;
@@ -573,14 +577,21 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
573 lock = 0xffff; 577 lock = 0xffff;
574 578
575 /* Set PLL PMS and VSEL values. */ 579 /* Set PLL PMS and VSEL values. */
576 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | 580 if (pll->type == pll_1460x) {
581 con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
582 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
583 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
584 } else {
585 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
577 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | 586 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
578 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) | 587 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
579 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT)); 588 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
589 con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
590 }
591
580 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) | 592 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
581 (rate->pdiv << PLL46XX_PDIV_SHIFT) | 593 (rate->pdiv << PLL46XX_PDIV_SHIFT) |
582 (rate->sdiv << PLL46XX_SDIV_SHIFT) | 594 (rate->sdiv << PLL46XX_SDIV_SHIFT);
583 (rate->vsel << PLL46XX_VSEL_SHIFT);
584 595
585 /* Set PLL K, MFR and MRR values. */ 596 /* Set PLL K, MFR and MRR values. */
586 con1 = __raw_readl(pll->con_reg + 0x4); 597 con1 = __raw_readl(pll->con_reg + 0x4);
@@ -1190,6 +1201,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1190 /* clk_ops for 35xx and 2550 are similar */ 1201 /* clk_ops for 35xx and 2550 are similar */
1191 case pll_35xx: 1202 case pll_35xx:
1192 case pll_2550: 1203 case pll_2550:
1204 case pll_1450x:
1205 case pll_1451x:
1206 case pll_1452x:
1193 if (!pll->rate_table) 1207 if (!pll->rate_table)
1194 init.ops = &samsung_pll35xx_clk_min_ops; 1208 init.ops = &samsung_pll35xx_clk_min_ops;
1195 else 1209 else
@@ -1223,6 +1237,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1223 case pll_4600: 1237 case pll_4600:
1224 case pll_4650: 1238 case pll_4650:
1225 case pll_4650c: 1239 case pll_4650c:
1240 case pll_1460x:
1226 if (!pll->rate_table) 1241 if (!pll->rate_table)
1227 init.ops = &samsung_pll46xx_clk_min_ops; 1242 init.ops = &samsung_pll46xx_clk_min_ops;
1228 else 1243 else
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c0ed4d41fd90..213de9af8b4f 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -33,6 +33,10 @@ enum samsung_pll_type {
33 pll_s3c2440_mpll, 33 pll_s3c2440_mpll,
34 pll_2550xx, 34 pll_2550xx,
35 pll_2650xx, 35 pll_2650xx,
36 pll_1450x,
37 pll_1451x,
38 pll_1452x,
39 pll_1460x,
36}; 40};
37 41
38#define PLL_35XX_RATE(_rate, _m, _p, _s) \ 42#define PLL_35XX_RATE(_rate, _m, _p, _s) \
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index deab84d9f37d..4bda54095a16 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -11,9 +11,13 @@
11 * clock framework for Samsung platforms. 11 * clock framework for Samsung platforms.
12*/ 12*/
13 13
14#include <linux/of_address.h>
14#include <linux/syscore_ops.h> 15#include <linux/syscore_ops.h>
16
15#include "clk.h" 17#include "clk.h"
16 18
19static LIST_HEAD(clock_reg_cache_list);
20
17void samsung_clk_save(void __iomem *base, 21void samsung_clk_save(void __iomem *base,
18 struct samsung_clk_reg_dump *rd, 22 struct samsung_clk_reg_dump *rd,
19 unsigned int num_regs) 23 unsigned int num_regs)
@@ -281,7 +285,6 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
281 * obtain the clock speed of all external fixed clock sources from device 285 * obtain the clock speed of all external fixed clock sources from device
282 * tree and register it 286 * tree and register it
283 */ 287 */
284#ifdef CONFIG_OF
285void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, 288void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx,
286 struct samsung_fixed_rate_clock *fixed_rate_clk, 289 struct samsung_fixed_rate_clock *fixed_rate_clk,
287 unsigned int nr_fixed_rate_clk, 290 unsigned int nr_fixed_rate_clk,
@@ -298,7 +301,6 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx,
298 } 301 }
299 samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); 302 samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk);
300} 303}
301#endif
302 304
303/* utility function to get the rate of a specified clock */ 305/* utility function to get the rate of a specified clock */
304unsigned long _get_rate(const char *clk_name) 306unsigned long _get_rate(const char *clk_name)
@@ -313,3 +315,99 @@ unsigned long _get_rate(const char *clk_name)
313 315
314 return clk_get_rate(clk); 316 return clk_get_rate(clk);
315} 317}
318
319#ifdef CONFIG_PM_SLEEP
320static int samsung_clk_suspend(void)
321{
322 struct samsung_clock_reg_cache *reg_cache;
323
324 list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
325 samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
326 reg_cache->rd_num);
327 return 0;
328}
329
330static void samsung_clk_resume(void)
331{
332 struct samsung_clock_reg_cache *reg_cache;
333
334 list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
335 samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump,
336 reg_cache->rd_num);
337}
338
339static struct syscore_ops samsung_clk_syscore_ops = {
340 .suspend = samsung_clk_suspend,
341 .resume = samsung_clk_resume,
342};
343
344static void samsung_clk_sleep_init(void __iomem *reg_base,
345 const unsigned long *rdump,
346 unsigned long nr_rdump)
347{
348 struct samsung_clock_reg_cache *reg_cache;
349
350 reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache),
351 GFP_KERNEL);
352 if (!reg_cache)
353 panic("could not allocate register reg_cache.\n");
354 reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
355
356 if (!reg_cache->rdump)
357 panic("could not allocate register dump storage.\n");
358
359 if (list_empty(&clock_reg_cache_list))
360 register_syscore_ops(&samsung_clk_syscore_ops);
361
362 reg_cache->reg_base = reg_base;
363 reg_cache->rd_num = nr_rdump;
364 list_add_tail(&reg_cache->node, &clock_reg_cache_list);
365}
366
367#else
368static void samsung_clk_sleep_init(void __iomem *reg_base,
369 const unsigned long *rdump,
370 unsigned long nr_rdump) {}
371#endif
372
373/*
374 * Common function which registers plls, muxes, dividers and gates
375 * for each CMU. It also add CMU register list to register cache.
376 */
377void __init samsung_cmu_register_one(struct device_node *np,
378 struct samsung_cmu_info *cmu)
379{
380 void __iomem *reg_base;
381 struct samsung_clk_provider *ctx;
382
383 reg_base = of_iomap(np, 0);
384 if (!reg_base)
385 panic("%s: failed to map registers\n", __func__);
386
387 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
388 if (!ctx)
389 panic("%s: unable to alllocate ctx\n", __func__);
390
391 if (cmu->pll_clks)
392 samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
393 reg_base);
394 if (cmu->mux_clks)
395 samsung_clk_register_mux(ctx, cmu->mux_clks,
396 cmu->nr_mux_clks);
397 if (cmu->div_clks)
398 samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
399 if (cmu->gate_clks)
400 samsung_clk_register_gate(ctx, cmu->gate_clks,
401 cmu->nr_gate_clks);
402 if (cmu->fixed_clks)
403 samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
404 cmu->nr_fixed_clks);
405 if (cmu->fixed_factor_clks)
406 samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
407 cmu->nr_fixed_factor_clks);
408 if (cmu->clk_regs)
409 samsung_clk_sleep_init(reg_base, cmu->clk_regs,
410 cmu->nr_clk_regs);
411
412 samsung_clk_of_add_provider(np, ctx);
413}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 66ab36b5cef1..8acabe1f32c4 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -13,19 +13,15 @@
13#ifndef __SAMSUNG_CLK_H 13#ifndef __SAMSUNG_CLK_H
14#define __SAMSUNG_CLK_H 14#define __SAMSUNG_CLK_H
15 15
16#include <linux/clk.h>
17#include <linux/clkdev.h> 16#include <linux/clkdev.h>
18#include <linux/io.h>
19#include <linux/clk-provider.h> 17#include <linux/clk-provider.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include "clk-pll.h" 18#include "clk-pll.h"
23 19
24/** 20/**
25 * struct samsung_clk_provider: information about clock provider 21 * struct samsung_clk_provider: information about clock provider
26 * @reg_base: virtual address for the register base. 22 * @reg_base: virtual address for the register base.
27 * @clk_data: holds clock related data like clk* and number of clocks. 23 * @clk_data: holds clock related data like clk* and number of clocks.
28 * @lock: maintains exclusion bwtween callbacks for a given clock-provider. 24 * @lock: maintains exclusion between callbacks for a given clock-provider.
29 */ 25 */
30struct samsung_clk_provider { 26struct samsung_clk_provider {
31 void __iomem *reg_base; 27 void __iomem *reg_base;
@@ -324,6 +320,40 @@ struct samsung_pll_clock {
324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ 320 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
325 _lock, _con, _rtable, _alias) 321 _lock, _con, _rtable, _alias)
326 322
323struct samsung_clock_reg_cache {
324 struct list_head node;
325 void __iomem *reg_base;
326 struct samsung_clk_reg_dump *rdump;
327 unsigned int rd_num;
328};
329
330struct samsung_cmu_info {
331 /* list of pll clocks and respective count */
332 struct samsung_pll_clock *pll_clks;
333 unsigned int nr_pll_clks;
334 /* list of mux clocks and respective count */
335 struct samsung_mux_clock *mux_clks;
336 unsigned int nr_mux_clks;
337 /* list of div clocks and respective count */
338 struct samsung_div_clock *div_clks;
339 unsigned int nr_div_clks;
340 /* list of gate clocks and respective count */
341 struct samsung_gate_clock *gate_clks;
342 unsigned int nr_gate_clks;
343 /* list of fixed clocks and respective count */
344 struct samsung_fixed_rate_clock *fixed_clks;
345 unsigned int nr_fixed_clks;
346 /* list of fixed factor clocks and respective count */
347 struct samsung_fixed_factor_clock *fixed_factor_clks;
348 unsigned int nr_fixed_factor_clks;
349 /* total number of clocks with IDs assigned*/
350 unsigned int nr_clk_ids;
351
352 /* list and number of clocks registers */
353 unsigned long *clk_regs;
354 unsigned int nr_clk_regs;
355};
356
327extern struct samsung_clk_provider *__init samsung_clk_init( 357extern struct samsung_clk_provider *__init samsung_clk_init(
328 struct device_node *np, void __iomem *base, 358 struct device_node *np, void __iomem *base,
329 unsigned long nr_clks); 359 unsigned long nr_clks);
@@ -362,6 +392,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
362 struct samsung_pll_clock *pll_list, 392 struct samsung_pll_clock *pll_list,
363 unsigned int nr_clk, void __iomem *base); 393 unsigned int nr_clk, void __iomem *base);
364 394
395extern void __init samsung_cmu_register_one(struct device_node *,
396 struct samsung_cmu_info *);
397
365extern unsigned long _get_rate(const char *clk_name); 398extern unsigned long _get_rate(const char *clk_name);
366 399
367extern void samsung_clk_save(void __iomem *base, 400extern void samsung_clk_save(void __iomem *base,
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
index f065f694cb65..639241e31e03 100644
--- a/drivers/clk/shmobile/clk-div6.c
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -32,6 +32,9 @@ struct div6_clock {
32 struct clk_hw hw; 32 struct clk_hw hw;
33 void __iomem *reg; 33 void __iomem *reg;
34 unsigned int div; 34 unsigned int div;
35 u32 src_shift;
36 u32 src_width;
37 u8 *parents;
35}; 38};
36 39
37#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) 40#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
@@ -39,8 +42,11 @@ struct div6_clock {
39static int cpg_div6_clock_enable(struct clk_hw *hw) 42static int cpg_div6_clock_enable(struct clk_hw *hw)
40{ 43{
41 struct div6_clock *clock = to_div6_clock(hw); 44 struct div6_clock *clock = to_div6_clock(hw);
45 u32 val;
42 46
43 clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); 47 val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP))
48 | CPG_DIV6_DIV(clock->div - 1);
49 clk_writel(val, clock->reg);
44 50
45 return 0; 51 return 0;
46} 52}
@@ -52,7 +58,7 @@ static void cpg_div6_clock_disable(struct clk_hw *hw)
52 /* DIV6 clocks require the divisor field to be non-zero when stopping 58 /* DIV6 clocks require the divisor field to be non-zero when stopping
53 * the clock. 59 * the clock.
54 */ 60 */
55 clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK), 61 clk_writel(clk_readl(clock->reg) | CPG_DIV6_CKSTP | CPG_DIV6_DIV_MASK,
56 clock->reg); 62 clock->reg);
57} 63}
58 64
@@ -94,12 +100,53 @@ static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
94{ 100{
95 struct div6_clock *clock = to_div6_clock(hw); 101 struct div6_clock *clock = to_div6_clock(hw);
96 unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); 102 unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate);
103 u32 val;
97 104
98 clock->div = div; 105 clock->div = div;
99 106
107 val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK;
100 /* Only program the new divisor if the clock isn't stopped. */ 108 /* Only program the new divisor if the clock isn't stopped. */
101 if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP)) 109 if (!(val & CPG_DIV6_CKSTP))
102 clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); 110 clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg);
111
112 return 0;
113}
114
115static u8 cpg_div6_clock_get_parent(struct clk_hw *hw)
116{
117 struct div6_clock *clock = to_div6_clock(hw);
118 unsigned int i;
119 u8 hw_index;
120
121 if (clock->src_width == 0)
122 return 0;
123
124 hw_index = (clk_readl(clock->reg) >> clock->src_shift) &
125 (BIT(clock->src_width) - 1);
126 for (i = 0; i < __clk_get_num_parents(hw->clk); i++) {
127 if (clock->parents[i] == hw_index)
128 return i;
129 }
130
131 pr_err("%s: %s DIV6 clock set to invalid parent %u\n",
132 __func__, __clk_get_name(hw->clk), hw_index);
133 return 0;
134}
135
136static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index)
137{
138 struct div6_clock *clock = to_div6_clock(hw);
139 u8 hw_index;
140 u32 mask;
141
142 if (index >= __clk_get_num_parents(hw->clk))
143 return -EINVAL;
144
145 mask = ~((BIT(clock->src_width) - 1) << clock->src_shift);
146 hw_index = clock->parents[index];
147
148 clk_writel((clk_readl(clock->reg) & mask) |
149 (hw_index << clock->src_shift), clock->reg);
103 150
104 return 0; 151 return 0;
105} 152}
@@ -108,6 +155,8 @@ static const struct clk_ops cpg_div6_clock_ops = {
108 .enable = cpg_div6_clock_enable, 155 .enable = cpg_div6_clock_enable,
109 .disable = cpg_div6_clock_disable, 156 .disable = cpg_div6_clock_disable,
110 .is_enabled = cpg_div6_clock_is_enabled, 157 .is_enabled = cpg_div6_clock_is_enabled,
158 .get_parent = cpg_div6_clock_get_parent,
159 .set_parent = cpg_div6_clock_set_parent,
111 .recalc_rate = cpg_div6_clock_recalc_rate, 160 .recalc_rate = cpg_div6_clock_recalc_rate,
112 .round_rate = cpg_div6_clock_round_rate, 161 .round_rate = cpg_div6_clock_round_rate,
113 .set_rate = cpg_div6_clock_set_rate, 162 .set_rate = cpg_div6_clock_set_rate,
@@ -115,20 +164,33 @@ static const struct clk_ops cpg_div6_clock_ops = {
115 164
116static void __init cpg_div6_clock_init(struct device_node *np) 165static void __init cpg_div6_clock_init(struct device_node *np)
117{ 166{
167 unsigned int num_parents, valid_parents;
168 const char **parent_names;
118 struct clk_init_data init; 169 struct clk_init_data init;
119 struct div6_clock *clock; 170 struct div6_clock *clock;
120 const char *parent_name;
121 const char *name; 171 const char *name;
122 struct clk *clk; 172 struct clk *clk;
173 unsigned int i;
123 int ret; 174 int ret;
124 175
125 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 176 clock = kzalloc(sizeof(*clock), GFP_KERNEL);
126 if (!clock) { 177 if (!clock)
127 pr_err("%s: failed to allocate %s DIV6 clock\n", 178 return;
179
180 num_parents = of_clk_get_parent_count(np);
181 if (num_parents < 1) {
182 pr_err("%s: no parent found for %s DIV6 clock\n",
128 __func__, np->name); 183 __func__, np->name);
129 return; 184 return;
130 } 185 }
131 186
187 clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents),
188 GFP_KERNEL);
189 parent_names = kmalloc_array(num_parents, sizeof(*parent_names),
190 GFP_KERNEL);
191 if (!parent_names)
192 return;
193
132 /* Remap the clock register and read the divisor. Disabling the 194 /* Remap the clock register and read the divisor. Disabling the
133 * clock overwrites the divisor, so we need to cache its value for the 195 * clock overwrites the divisor, so we need to cache its value for the
134 * enable operation. 196 * enable operation.
@@ -150,9 +212,34 @@ static void __init cpg_div6_clock_init(struct device_node *np)
150 goto error; 212 goto error;
151 } 213 }
152 214
153 parent_name = of_clk_get_parent_name(np, 0); 215
154 if (parent_name == NULL) { 216 for (i = 0, valid_parents = 0; i < num_parents; i++) {
155 pr_err("%s: failed to get %s DIV6 clock parent name\n", 217 const char *name = of_clk_get_parent_name(np, i);
218
219 if (name) {
220 parent_names[valid_parents] = name;
221 clock->parents[valid_parents] = i;
222 valid_parents++;
223 }
224 }
225
226 switch (num_parents) {
227 case 1:
228 /* fixed parent clock */
229 clock->src_shift = clock->src_width = 0;
230 break;
231 case 4:
232 /* clock with EXSRC bits 6-7 */
233 clock->src_shift = 6;
234 clock->src_width = 2;
235 break;
236 case 8:
237 /* VCLK with EXSRC bits 12-14 */
238 clock->src_shift = 12;
239 clock->src_width = 3;
240 break;
241 default:
242 pr_err("%s: invalid number of parents for DIV6 clock %s\n",
156 __func__, np->name); 243 __func__, np->name);
157 goto error; 244 goto error;
158 } 245 }
@@ -161,8 +248,8 @@ static void __init cpg_div6_clock_init(struct device_node *np)
161 init.name = name; 248 init.name = name;
162 init.ops = &cpg_div6_clock_ops; 249 init.ops = &cpg_div6_clock_ops;
163 init.flags = CLK_IS_BASIC; 250 init.flags = CLK_IS_BASIC;
164 init.parent_names = &parent_name; 251 init.parent_names = parent_names;
165 init.num_parents = 1; 252 init.num_parents = valid_parents;
166 253
167 clock->hw.init = &init; 254 clock->hw.init = &init;
168 255
@@ -175,11 +262,13 @@ static void __init cpg_div6_clock_init(struct device_node *np)
175 262
176 of_clk_add_provider(np, of_clk_src_simple_get, clk); 263 of_clk_add_provider(np, of_clk_src_simple_get, clk);
177 264
265 kfree(parent_names);
178 return; 266 return;
179 267
180error: 268error:
181 if (clock->reg) 269 if (clock->reg)
182 iounmap(clock->reg); 270 iounmap(clock->reg);
271 kfree(parent_names);
183 kfree(clock); 272 kfree(clock);
184} 273}
185CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); 274CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 7ddc2b553846..a66953c0f430 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -7,6 +7,7 @@ obj-y += clk-a10-hosc.o
7obj-y += clk-a20-gmac.o 7obj-y += clk-a20-gmac.o
8obj-y += clk-mod0.o 8obj-y += clk-mod0.o
9obj-y += clk-sun8i-mbus.o 9obj-y += clk-sun8i-mbus.o
10obj-y += clk-sun9i-core.o
10 11
11obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 12obj-$(CONFIG_MFD_SUN6I_PRCM) += \
12 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ 13 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c
index 5296fd6dd7b3..0dcf4f205fb8 100644
--- a/drivers/clk/sunxi/clk-a20-gmac.c
+++ b/drivers/clk/sunxi/clk-a20-gmac.c
@@ -53,6 +53,11 @@ static DEFINE_SPINLOCK(gmac_lock);
53#define SUN7I_A20_GMAC_MASK 0x3 53#define SUN7I_A20_GMAC_MASK 0x3
54#define SUN7I_A20_GMAC_PARENTS 2 54#define SUN7I_A20_GMAC_PARENTS 2
55 55
56static u32 sun7i_a20_gmac_mux_table[SUN7I_A20_GMAC_PARENTS] = {
57 0x00, /* Select mii_phy_tx_clk */
58 0x02, /* Select gmac_int_tx_clk */
59};
60
56static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) 61static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
57{ 62{
58 struct clk *clk; 63 struct clk *clk;
@@ -90,7 +95,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
90 gate->lock = &gmac_lock; 95 gate->lock = &gmac_lock;
91 mux->reg = reg; 96 mux->reg = reg;
92 mux->mask = SUN7I_A20_GMAC_MASK; 97 mux->mask = SUN7I_A20_GMAC_MASK;
93 mux->flags = CLK_MUX_INDEX_BIT; 98 mux->table = sun7i_a20_gmac_mux_table;
94 mux->lock = &gmac_lock; 99 mux->lock = &gmac_lock;
95 100
96 clk = clk_register_composite(NULL, clk_name, 101 clk = clk_register_composite(NULL, clk_name,
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index f83ba097126c..62e08fb58554 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -81,7 +81,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
81 81
82static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate, 82static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
83 unsigned long *best_parent_rate, 83 unsigned long *best_parent_rate,
84 struct clk **best_parent_p) 84 struct clk_hw **best_parent_p)
85{ 85{
86 struct clk *clk = hw->clk, *parent, *best_parent = NULL; 86 struct clk *clk = hw->clk, *parent, *best_parent = NULL;
87 int i, num_parents; 87 int i, num_parents;
@@ -108,7 +108,7 @@ static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
108 } 108 }
109 109
110 if (best_parent) 110 if (best_parent)
111 *best_parent_p = best_parent; 111 *best_parent_p = __clk_get_hw(best_parent);
112 *best_parent_rate = best; 112 *best_parent_rate = best;
113 113
114 return best_child_rate; 114 return best_child_rate;
@@ -224,7 +224,7 @@ struct clk * __init sunxi_factors_register(struct device_node *node,
224 /* set up gate properties */ 224 /* set up gate properties */
225 mux->reg = reg; 225 mux->reg = reg;
226 mux->shift = data->mux; 226 mux->shift = data->mux;
227 mux->mask = SUNXI_FACTORS_MUX_MASK; 227 mux->mask = data->muxmask;
228 mux->lock = factors->lock; 228 mux->lock = factors->lock;
229 mux_hw = &mux->hw; 229 mux_hw = &mux->hw;
230 } 230 }
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 9913840018d3..912238fde132 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -7,8 +7,6 @@
7 7
8#define SUNXI_FACTORS_NOT_APPLICABLE (0) 8#define SUNXI_FACTORS_NOT_APPLICABLE (0)
9 9
10#define SUNXI_FACTORS_MUX_MASK 0x3
11
12struct clk_factors_config { 10struct clk_factors_config {
13 u8 nshift; 11 u8 nshift;
14 u8 nwidth; 12 u8 nwidth;
@@ -24,6 +22,7 @@ struct clk_factors_config {
24struct factors_data { 22struct factors_data {
25 int enable; 23 int enable;
26 int mux; 24 int mux;
25 int muxmask;
27 struct clk_factors_config *table; 26 struct clk_factors_config *table;
28 void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); 27 void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
29 const char *name; 28 const char *name;
diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
index 4a563850ee6e..da0524eaee94 100644
--- a/drivers/clk/sunxi/clk-mod0.c
+++ b/drivers/clk/sunxi/clk-mod0.c
@@ -70,6 +70,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = {
70static const struct factors_data sun4i_a10_mod0_data __initconst = { 70static const struct factors_data sun4i_a10_mod0_data __initconst = {
71 .enable = 31, 71 .enable = 31,
72 .mux = 24, 72 .mux = 24,
73 .muxmask = BIT(1) | BIT(0),
73 .table = &sun4i_a10_mod0_config, 74 .table = &sun4i_a10_mod0_config,
74 .getter = sun4i_a10_get_mod0_factors, 75 .getter = sun4i_a10_get_mod0_factors,
75}; 76};
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index acca53290be2..3d282fb8f85c 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -46,7 +46,7 @@ static unsigned long ar100_recalc_rate(struct clk_hw *hw,
46 46
47static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate, 47static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate,
48 unsigned long *best_parent_rate, 48 unsigned long *best_parent_rate,
49 struct clk **best_parent_clk) 49 struct clk_hw **best_parent_clk)
50{ 50{
51 int nparents = __clk_get_num_parents(hw->clk); 51 int nparents = __clk_get_num_parents(hw->clk);
52 long best_rate = -EINVAL; 52 long best_rate = -EINVAL;
@@ -100,7 +100,7 @@ static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate,
100 100
101 tmp_rate = (parent_rate >> shift) / div; 101 tmp_rate = (parent_rate >> shift) / div;
102 if (!*best_parent_clk || tmp_rate > best_rate) { 102 if (!*best_parent_clk || tmp_rate > best_rate) {
103 *best_parent_clk = parent; 103 *best_parent_clk = __clk_get_hw(parent);
104 *best_parent_rate = parent_rate; 104 *best_parent_rate = parent_rate;
105 best_rate = tmp_rate; 105 best_rate = tmp_rate;
106 } 106 }
diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c
index 8e49b44cee41..ef49786eefd3 100644
--- a/drivers/clk/sunxi/clk-sun8i-mbus.c
+++ b/drivers/clk/sunxi/clk-sun8i-mbus.c
@@ -60,6 +60,7 @@ static struct clk_factors_config sun8i_a23_mbus_config = {
60static const struct factors_data sun8i_a23_mbus_data __initconst = { 60static const struct factors_data sun8i_a23_mbus_data __initconst = {
61 .enable = 31, 61 .enable = 31,
62 .mux = 24, 62 .mux = 24,
63 .muxmask = BIT(1) | BIT(0),
63 .table = &sun8i_a23_mbus_config, 64 .table = &sun8i_a23_mbus_config,
64 .getter = sun8i_a23_get_mbus_factors, 65 .getter = sun8i_a23_get_mbus_factors,
65}; 66};
diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c
new file mode 100644
index 000000000000..3cb9036d91bb
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun9i-core.c
@@ -0,0 +1,271 @@
1/*
2 * Copyright 2014 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/clkdev.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/log2.h>
22
23#include "clk-factors.h"
24
25
26/**
27 * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1
28 * PLL4 rate is calculated as follows
29 * rate = (parent_rate * n >> p) / (m + 1);
30 * parent_rate is always 24Mhz
31 *
32 * p and m are named div1 and div2 in Allwinner's SDK
33 */
34
35static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
36 u8 *n, u8 *k, u8 *m, u8 *p)
37{
38 int div;
39
40 /* Normalize value to a 6M multiple */
41 div = DIV_ROUND_UP(*freq, 6000000);
42
43 /* divs above 256 cannot be odd */
44 if (div > 256)
45 div = round_up(div, 2);
46
47 /* divs above 512 must be a multiple of 4 */
48 if (div > 512)
49 div = round_up(div, 4);
50
51 *freq = 6000000 * div;
52
53 /* we were called to round the frequency, we can now return */
54 if (n == NULL)
55 return;
56
57 /* p will be 1 for divs under 512 */
58 if (div < 512)
59 *p = 1;
60 else
61 *p = 0;
62
63 /* m will be 1 if div is odd */
64 if (div & 1)
65 *m = 1;
66 else
67 *m = 0;
68
69 /* calculate a suitable n based on m and p */
70 *n = div / (*p + 1) / (*m + 1);
71}
72
73static struct clk_factors_config sun9i_a80_pll4_config = {
74 .mshift = 18,
75 .mwidth = 1,
76 .nshift = 8,
77 .nwidth = 8,
78 .pshift = 16,
79 .pwidth = 1,
80};
81
82static const struct factors_data sun9i_a80_pll4_data __initconst = {
83 .enable = 31,
84 .table = &sun9i_a80_pll4_config,
85 .getter = sun9i_a80_get_pll4_factors,
86};
87
88static DEFINE_SPINLOCK(sun9i_a80_pll4_lock);
89
90static void __init sun9i_a80_pll4_setup(struct device_node *node)
91{
92 sunxi_factors_register(node, &sun9i_a80_pll4_data, &sun9i_a80_pll4_lock);
93}
94CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_setup);
95
96
97/**
98 * sun9i_a80_get_gt_factors() - calculates m factor for GT
99 * GT rate is calculated as follows
100 * rate = parent_rate / (m + 1);
101 */
102
103static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate,
104 u8 *n, u8 *k, u8 *m, u8 *p)
105{
106 u32 div;
107
108 if (parent_rate < *freq)
109 *freq = parent_rate;
110
111 div = DIV_ROUND_UP(parent_rate, *freq);
112
113 /* maximum divider is 4 */
114 if (div > 4)
115 div = 4;
116
117 *freq = parent_rate / div;
118
119 /* we were called to round the frequency, we can now return */
120 if (!m)
121 return;
122
123 *m = div;
124}
125
126static struct clk_factors_config sun9i_a80_gt_config = {
127 .mshift = 0,
128 .mwidth = 2,
129};
130
131static const struct factors_data sun9i_a80_gt_data __initconst = {
132 .mux = 24,
133 .muxmask = BIT(1) | BIT(0),
134 .table = &sun9i_a80_gt_config,
135 .getter = sun9i_a80_get_gt_factors,
136};
137
138static DEFINE_SPINLOCK(sun9i_a80_gt_lock);
139
140static void __init sun9i_a80_gt_setup(struct device_node *node)
141{
142 struct clk *gt = sunxi_factors_register(node, &sun9i_a80_gt_data,
143 &sun9i_a80_gt_lock);
144
145 /* The GT bus clock needs to be always enabled */
146 __clk_get(gt);
147 clk_prepare_enable(gt);
148}
149CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup);
150
151
152/**
153 * sun9i_a80_get_ahb_factors() - calculates p factor for AHB0/1/2
154 * AHB rate is calculated as follows
155 * rate = parent_rate >> p;
156 */
157
158static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate,
159 u8 *n, u8 *k, u8 *m, u8 *p)
160{
161 u32 _p;
162
163 if (parent_rate < *freq)
164 *freq = parent_rate;
165
166 _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq));
167
168 /* maximum p is 3 */
169 if (_p > 3)
170 _p = 3;
171
172 *freq = parent_rate >> _p;
173
174 /* we were called to round the frequency, we can now return */
175 if (!p)
176 return;
177
178 *p = _p;
179}
180
181static struct clk_factors_config sun9i_a80_ahb_config = {
182 .pshift = 0,
183 .pwidth = 2,
184};
185
186static const struct factors_data sun9i_a80_ahb_data __initconst = {
187 .mux = 24,
188 .muxmask = BIT(1) | BIT(0),
189 .table = &sun9i_a80_ahb_config,
190 .getter = sun9i_a80_get_ahb_factors,
191};
192
193static DEFINE_SPINLOCK(sun9i_a80_ahb_lock);
194
195static void __init sun9i_a80_ahb_setup(struct device_node *node)
196{
197 sunxi_factors_register(node, &sun9i_a80_ahb_data, &sun9i_a80_ahb_lock);
198}
199CLK_OF_DECLARE(sun9i_a80_ahb, "allwinner,sun9i-a80-ahb-clk", sun9i_a80_ahb_setup);
200
201
202static const struct factors_data sun9i_a80_apb0_data __initconst = {
203 .mux = 24,
204 .muxmask = BIT(0),
205 .table = &sun9i_a80_ahb_config,
206 .getter = sun9i_a80_get_ahb_factors,
207};
208
209static DEFINE_SPINLOCK(sun9i_a80_apb0_lock);
210
211static void __init sun9i_a80_apb0_setup(struct device_node *node)
212{
213 sunxi_factors_register(node, &sun9i_a80_apb0_data, &sun9i_a80_apb0_lock);
214}
215CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_setup);
216
217
218/**
219 * sun9i_a80_get_apb1_factors() - calculates m, p factors for APB1
220 * APB1 rate is calculated as follows
221 * rate = (parent_rate >> p) / (m + 1);
222 */
223
224static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate,
225 u8 *n, u8 *k, u8 *m, u8 *p)
226{
227 u32 div;
228 u8 calcm, calcp;
229
230 if (parent_rate < *freq)
231 *freq = parent_rate;
232
233 div = DIV_ROUND_UP(parent_rate, *freq);
234
235 /* Highest possible divider is 256 (p = 3, m = 31) */
236 if (div > 256)
237 div = 256;
238
239 calcp = order_base_2(div);
240 calcm = (parent_rate >> calcp) - 1;
241 *freq = (parent_rate >> calcp) / (calcm + 1);
242
243 /* we were called to round the frequency, we can now return */
244 if (n == NULL)
245 return;
246
247 *m = calcm;
248 *p = calcp;
249}
250
251static struct clk_factors_config sun9i_a80_apb1_config = {
252 .mshift = 0,
253 .mwidth = 5,
254 .pshift = 16,
255 .pwidth = 2,
256};
257
258static const struct factors_data sun9i_a80_apb1_data __initconst = {
259 .mux = 24,
260 .muxmask = BIT(0),
261 .table = &sun9i_a80_apb1_config,
262 .getter = sun9i_a80_get_apb1_factors,
263};
264
265static DEFINE_SPINLOCK(sun9i_a80_apb1_lock);
266
267static void __init sun9i_a80_apb1_setup(struct device_node *node)
268{
269 sunxi_factors_register(node, &sun9i_a80_apb1_data, &sun9i_a80_apb1_lock);
270}
271CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-clk", sun9i_a80_apb1_setup);
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index d5dc951264ca..570202582dcf 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -245,9 +245,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
245} 245}
246 246
247/** 247/**
248 * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 248 * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2
249 * PLL6 rate is calculated as follows 249 * PLL6x2 rate is calculated as follows
250 * rate = parent_rate * n * (k + 1) / 2 250 * rate = parent_rate * (n + 1) * (k + 1)
251 * parent_rate is always 24Mhz 251 * parent_rate is always 24Mhz
252 */ 252 */
253 253
@@ -256,13 +256,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
256{ 256{
257 u8 div; 257 u8 div;
258 258
259 /* 259 /* Normalize value to a parent_rate multiple (24M) */
260 * We always have 24MHz / 2, so we can just say that our
261 * parent clock is 12MHz.
262 */
263 parent_rate = parent_rate / 2;
264
265 /* Normalize value to a parent_rate multiple (24M / 2) */
266 div = *freq / parent_rate; 260 div = *freq / parent_rate;
267 *freq = parent_rate * div; 261 *freq = parent_rate * div;
268 262
@@ -274,7 +268,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
274 if (*k > 3) 268 if (*k > 3)
275 *k = 3; 269 *k = 3;
276 270
277 *n = DIV_ROUND_UP(div, (*k+1)); 271 *n = DIV_ROUND_UP(div, (*k+1)) - 1;
278} 272}
279 273
280/** 274/**
@@ -445,6 +439,7 @@ static struct clk_factors_config sun6i_a31_pll6_config = {
445 .nwidth = 5, 439 .nwidth = 5,
446 .kshift = 4, 440 .kshift = 4,
447 .kwidth = 2, 441 .kwidth = 2,
442 .n_start = 1,
448}; 443};
449 444
450static struct clk_factors_config sun4i_apb1_config = { 445static struct clk_factors_config sun4i_apb1_config = {
@@ -504,9 +499,12 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = {
504 .enable = 31, 499 .enable = 31,
505 .table = &sun6i_a31_pll6_config, 500 .table = &sun6i_a31_pll6_config,
506 .getter = sun6i_a31_get_pll6_factors, 501 .getter = sun6i_a31_get_pll6_factors,
502 .name = "pll6x2",
507}; 503};
508 504
509static const struct factors_data sun4i_apb1_data __initconst = { 505static const struct factors_data sun4i_apb1_data __initconst = {
506 .mux = 24,
507 .muxmask = BIT(1) | BIT(0),
510 .table = &sun4i_apb1_config, 508 .table = &sun4i_apb1_config,
511 .getter = sun4i_get_apb1_factors, 509 .getter = sun4i_get_apb1_factors,
512}; 510};
@@ -514,6 +512,7 @@ static const struct factors_data sun4i_apb1_data __initconst = {
514static const struct factors_data sun7i_a20_out_data __initconst = { 512static const struct factors_data sun7i_a20_out_data __initconst = {
515 .enable = 31, 513 .enable = 31,
516 .mux = 24, 514 .mux = 24,
515 .muxmask = BIT(1) | BIT(0),
517 .table = &sun7i_a20_out_config, 516 .table = &sun7i_a20_out_config,
518 .getter = sun7i_a20_get_out_factors, 517 .getter = sun7i_a20_get_out_factors,
519}; 518};
@@ -544,10 +543,6 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = {
544 .shift = 12, 543 .shift = 12,
545}; 544};
546 545
547static const struct mux_data sun4i_apb1_mux_data __initconst = {
548 .shift = 24,
549};
550
551static void __init sunxi_mux_clk_setup(struct device_node *node, 546static void __init sunxi_mux_clk_setup(struct device_node *node,
552 struct mux_data *data) 547 struct mux_data *data)
553{ 548{
@@ -633,12 +628,6 @@ static const struct div_data sun4i_apb0_data __initconst = {
633 .table = sun4i_apb0_table, 628 .table = sun4i_apb0_table,
634}; 629};
635 630
636static const struct div_data sun6i_a31_apb2_div_data __initconst = {
637 .shift = 0,
638 .pow = 0,
639 .width = 4,
640};
641
642static void __init sunxi_divider_clk_setup(struct device_node *node, 631static void __init sunxi_divider_clk_setup(struct device_node *node,
643 struct div_data *data) 632 struct div_data *data)
644{ 633{
@@ -757,6 +746,18 @@ static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = {
757 .mask = {0x25386742, 0x2505111}, 746 .mask = {0x25386742, 0x2505111},
758}; 747};
759 748
749static const struct gates_data sun9i_a80_ahb0_gates_data __initconst = {
750 .mask = {0xF5F12B},
751};
752
753static const struct gates_data sun9i_a80_ahb1_gates_data __initconst = {
754 .mask = {0x1E20003},
755};
756
757static const struct gates_data sun9i_a80_ahb2_gates_data __initconst = {
758 .mask = {0x9B7},
759};
760
760static const struct gates_data sun4i_apb0_gates_data __initconst = { 761static const struct gates_data sun4i_apb0_gates_data __initconst = {
761 .mask = {0x4EF}, 762 .mask = {0x4EF},
762}; 763};
@@ -773,6 +774,10 @@ static const struct gates_data sun7i_a20_apb0_gates_data __initconst = {
773 .mask = { 0x4ff }, 774 .mask = { 0x4ff },
774}; 775};
775 776
777static const struct gates_data sun9i_a80_apb0_gates_data __initconst = {
778 .mask = {0xEB822},
779};
780
776static const struct gates_data sun4i_apb1_gates_data __initconst = { 781static const struct gates_data sun4i_apb1_gates_data __initconst = {
777 .mask = {0xFF00F7}, 782 .mask = {0xFF00F7},
778}; 783};
@@ -801,6 +806,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
801 .mask = { 0xff80ff }, 806 .mask = { 0xff80ff },
802}; 807};
803 808
809static const struct gates_data sun9i_a80_apb1_gates_data __initconst = {
810 .mask = {0x3F001F},
811};
812
804static const struct gates_data sun8i_a23_apb2_gates_data __initconst = { 813static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
805 .mask = {0x1F0007}, 814 .mask = {0x1F0007},
806}; 815};
@@ -893,6 +902,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
893 902
894struct divs_data { 903struct divs_data {
895 const struct factors_data *factors; /* data for the factor clock */ 904 const struct factors_data *factors; /* data for the factor clock */
905 int ndivs; /* number of children */
896 struct { 906 struct {
897 u8 fixed; /* is it a fixed divisor? if not... */ 907 u8 fixed; /* is it a fixed divisor? if not... */
898 struct clk_div_table *table; /* is it a table based divisor? */ 908 struct clk_div_table *table; /* is it a table based divisor? */
@@ -912,6 +922,7 @@ static struct clk_div_table pll6_sata_tbl[] = {
912 922
913static const struct divs_data pll5_divs_data __initconst = { 923static const struct divs_data pll5_divs_data __initconst = {
914 .factors = &sun4i_pll5_data, 924 .factors = &sun4i_pll5_data,
925 .ndivs = 2,
915 .div = { 926 .div = {
916 { .shift = 0, .pow = 0, }, /* M, DDR */ 927 { .shift = 0, .pow = 0, }, /* M, DDR */
917 { .shift = 16, .pow = 1, }, /* P, other */ 928 { .shift = 16, .pow = 1, }, /* P, other */
@@ -920,12 +931,21 @@ static const struct divs_data pll5_divs_data __initconst = {
920 931
921static const struct divs_data pll6_divs_data __initconst = { 932static const struct divs_data pll6_divs_data __initconst = {
922 .factors = &sun4i_pll6_data, 933 .factors = &sun4i_pll6_data,
934 .ndivs = 2,
923 .div = { 935 .div = {
924 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ 936 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
925 { .fixed = 2 }, /* P, other */ 937 { .fixed = 2 }, /* P, other */
926 } 938 }
927}; 939};
928 940
941static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
942 .factors = &sun6i_a31_pll6_data,
943 .ndivs = 1,
944 .div = {
945 { .fixed = 2 }, /* normal output */
946 }
947};
948
929/** 949/**
930 * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks 950 * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
931 * 951 *
@@ -950,7 +970,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
950 struct clk_fixed_factor *fix_factor; 970 struct clk_fixed_factor *fix_factor;
951 struct clk_divider *divider; 971 struct clk_divider *divider;
952 void __iomem *reg; 972 void __iomem *reg;
953 int i = 0; 973 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
954 int flags, clkflags; 974 int flags, clkflags;
955 975
956 /* Set up factor clock that we will be dividing */ 976 /* Set up factor clock that we will be dividing */
@@ -973,7 +993,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
973 * our RAM clock! */ 993 * our RAM clock! */
974 clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; 994 clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
975 995
976 for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) { 996 /* if number of children known, use it */
997 if (data->ndivs)
998 ndivs = data->ndivs;
999
1000 for (i = 0; i < ndivs; i++) {
977 if (of_property_read_string_index(node, "clock-output-names", 1001 if (of_property_read_string_index(node, "clock-output-names",
978 i, &clk_name) != 0) 1002 i, &clk_name) != 0)
979 break; 1003 break;
@@ -1062,7 +1086,6 @@ static const struct of_device_id clk_factors_match[] __initconst = {
1062 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, 1086 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
1063 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, 1087 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
1064 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, 1088 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
1065 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
1066 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, 1089 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
1067 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, 1090 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
1068 {} 1091 {}
@@ -1074,7 +1097,6 @@ static const struct of_device_id clk_div_match[] __initconst = {
1074 {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, 1097 {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,},
1075 {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, 1098 {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,},
1076 {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, 1099 {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,},
1077 {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
1078 {} 1100 {}
1079}; 1101};
1080 1102
@@ -1082,13 +1104,13 @@ static const struct of_device_id clk_div_match[] __initconst = {
1082static const struct of_device_id clk_divs_match[] __initconst = { 1104static const struct of_device_id clk_divs_match[] __initconst = {
1083 {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, 1105 {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,},
1084 {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, 1106 {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,},
1107 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,},
1085 {} 1108 {}
1086}; 1109};
1087 1110
1088/* Matches for mux clocks */ 1111/* Matches for mux clocks */
1089static const struct of_device_id clk_mux_match[] __initconst = { 1112static const struct of_device_id clk_mux_match[] __initconst = {
1090 {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, 1113 {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,},
1091 {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
1092 {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, 1114 {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
1093 {} 1115 {}
1094}; 1116};
@@ -1102,16 +1124,21 @@ static const struct of_device_id clk_gates_match[] __initconst = {
1102 {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, 1124 {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
1103 {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, 1125 {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
1104 {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,}, 1126 {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,},
1127 {.compatible = "allwinner,sun9i-a80-ahb0-gates-clk", .data = &sun9i_a80_ahb0_gates_data,},
1128 {.compatible = "allwinner,sun9i-a80-ahb1-gates-clk", .data = &sun9i_a80_ahb1_gates_data,},
1129 {.compatible = "allwinner,sun9i-a80-ahb2-gates-clk", .data = &sun9i_a80_ahb2_gates_data,},
1105 {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, 1130 {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
1106 {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, 1131 {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
1107 {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, 1132 {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
1108 {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, 1133 {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,},
1134 {.compatible = "allwinner,sun9i-a80-apb0-gates-clk", .data = &sun9i_a80_apb0_gates_data,},
1109 {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, 1135 {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
1110 {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, 1136 {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,},
1111 {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, 1137 {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
1112 {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, 1138 {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
1113 {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, 1139 {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
1114 {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,}, 1140 {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,},
1141 {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,},
1115 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, 1142 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
1116 {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, 1143 {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
1117 {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, 1144 {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
@@ -1200,3 +1227,9 @@ static void __init sun6i_init_clocks(struct device_node *node)
1200} 1227}
1201CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); 1228CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
1202CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); 1229CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
1230
1231static void __init sun9i_init_clocks(struct device_node *node)
1232{
1233 sunxi_init_clocks(NULL, 0);
1234}
1235CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks);