aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/clk/clk-divider.c58
-rw-r--r--drivers/clk/clk-mux.c75
-rw-r--r--drivers/clk/clk.c63
-rw-r--r--drivers/clk/meson/Kconfig9
-rw-r--r--drivers/clk/meson/Makefile5
-rw-r--r--drivers/clk/meson/axg.c955
-rw-r--r--drivers/clk/meson/axg.h12
-rw-r--r--drivers/clk/meson/clk-audio-divider.c63
-rw-r--r--drivers/clk/meson/clk-cpu.c178
-rw-r--r--drivers/clk/meson/clk-mpll.c125
-rw-r--r--drivers/clk/meson/clk-pll.c306
-rw-r--r--drivers/clk/meson/clk-regmap.c166
-rw-r--r--drivers/clk/meson/clk-regmap.h111
-rw-r--r--drivers/clk/meson/clkc.h107
-rw-r--r--drivers/clk/meson/gxbb-aoclk-regmap.c46
-rw-r--r--drivers/clk/meson/gxbb-aoclk.c20
-rw-r--r--drivers/clk/meson/gxbb-aoclk.h11
-rw-r--r--drivers/clk/meson/gxbb.c1591
-rw-r--r--drivers/clk/meson/gxbb.h14
-rw-r--r--drivers/clk/meson/meson8b.c705
-rw-r--r--drivers/clk/meson/meson8b.h17
-rw-r--r--drivers/clk/qcom/clk-regmap-divider.c20
-rw-r--r--drivers/clk/samsung/Makefile2
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c4
-rw-r--r--drivers/clk/samsung/clk-exynos3250.c114
-rw-r--r--drivers/clk/samsung/clk-exynos4.c103
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.c189
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.h26
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c111
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c90
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c20
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c189
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c121
-rw-r--r--drivers/clk/samsung/clk-exynos7.c2
-rw-r--r--drivers/clk/samsung/clk-pll.h48
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c148
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c25
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c55
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c17
-rw-r--r--drivers/clk/tegra/clk-emc.c2
-rw-r--r--drivers/clk/tegra/clk-pll.c2
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c2
-rw-r--r--drivers/clk/tegra/clk-tegra-super-gen4.c8
-rw-r--r--drivers/clk/tegra/clk-tegra114.c4
-rw-r--r--drivers/clk/tegra/clk-tegra124.c9
-rw-r--r--drivers/clk/tegra/clk-tegra20.c24
-rw-r--r--drivers/clk/tegra/clk-tegra210.c361
-rw-r--r--drivers/clk/tegra/clk-tegra30.c15
-rw-r--r--drivers/clk/tegra/clk.h7
-rw-r--r--drivers/soc/samsung/pm_domains.c11
-rw-r--r--include/dt-bindings/clock/axg-clkc.h1
-rw-r--r--include/dt-bindings/clock/tegra210-car.h2
-rw-r--r--include/linux/clk-provider.h23
-rw-r--r--include/linux/clk/tegra.h1
55 files changed, 3806 insertions, 2588 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 3bdc260e36b7..395ea06c427d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12189,6 +12189,7 @@ M: Tomasz Figa <tomasz.figa@gmail.com>
12189M: Chanwoo Choi <cw00.choi@samsung.com> 12189M: Chanwoo Choi <cw00.choi@samsung.com>
12190S: Supported 12190S: Supported
12191L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) 12191L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
12192T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
12192F: drivers/clk/samsung/ 12193F: drivers/clk/samsung/
12193F: include/dt-bindings/clock/exynos*.h 12194F: include/dt-bindings/clock/exynos*.h
12194F: Documentation/devicetree/bindings/clock/exynos*.txt 12195F: Documentation/devicetree/bindings/clock/exynos*.txt
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index b49942b9fe50..b6234a5da12d 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -28,12 +28,10 @@
28 * parent - fixed parent. No clk_set_parent support 28 * parent - fixed parent. No clk_set_parent support
29 */ 29 */
30 30
31#define div_mask(width) ((1 << (width)) - 1)
32
33static unsigned int _get_table_maxdiv(const struct clk_div_table *table, 31static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
34 u8 width) 32 u8 width)
35{ 33{
36 unsigned int maxdiv = 0, mask = div_mask(width); 34 unsigned int maxdiv = 0, mask = clk_div_mask(width);
37 const struct clk_div_table *clkt; 35 const struct clk_div_table *clkt;
38 36
39 for (clkt = table; clkt->div; clkt++) 37 for (clkt = table; clkt->div; clkt++)
@@ -57,12 +55,12 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
57 unsigned long flags) 55 unsigned long flags)
58{ 56{
59 if (flags & CLK_DIVIDER_ONE_BASED) 57 if (flags & CLK_DIVIDER_ONE_BASED)
60 return div_mask(width); 58 return clk_div_mask(width);
61 if (flags & CLK_DIVIDER_POWER_OF_TWO) 59 if (flags & CLK_DIVIDER_POWER_OF_TWO)
62 return 1 << div_mask(width); 60 return 1 << clk_div_mask(width);
63 if (table) 61 if (table)
64 return _get_table_maxdiv(table, width); 62 return _get_table_maxdiv(table, width);
65 return div_mask(width) + 1; 63 return clk_div_mask(width) + 1;
66} 64}
67 65
68static unsigned int _get_table_div(const struct clk_div_table *table, 66static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -84,7 +82,7 @@ static unsigned int _get_div(const struct clk_div_table *table,
84 if (flags & CLK_DIVIDER_POWER_OF_TWO) 82 if (flags & CLK_DIVIDER_POWER_OF_TWO)
85 return 1 << val; 83 return 1 << val;
86 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 84 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
87 return val ? val : div_mask(width) + 1; 85 return val ? val : clk_div_mask(width) + 1;
88 if (table) 86 if (table)
89 return _get_table_div(table, val); 87 return _get_table_div(table, val);
90 return val + 1; 88 return val + 1;
@@ -109,7 +107,7 @@ static unsigned int _get_val(const struct clk_div_table *table,
109 if (flags & CLK_DIVIDER_POWER_OF_TWO) 107 if (flags & CLK_DIVIDER_POWER_OF_TWO)
110 return __ffs(div); 108 return __ffs(div);
111 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 109 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
112 return (div == div_mask(width) + 1) ? 0 : div; 110 return (div == clk_div_mask(width) + 1) ? 0 : div;
113 if (table) 111 if (table)
114 return _get_table_val(table, div); 112 return _get_table_val(table, div);
115 return div - 1; 113 return div - 1;
@@ -141,7 +139,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
141 unsigned int val; 139 unsigned int val;
142 140
143 val = clk_readl(divider->reg) >> divider->shift; 141 val = clk_readl(divider->reg) >> divider->shift;
144 val &= div_mask(divider->width); 142 val &= clk_div_mask(divider->width);
145 143
146 return divider_recalc_rate(hw, parent_rate, val, divider->table, 144 return divider_recalc_rate(hw, parent_rate, val, divider->table,
147 divider->flags, divider->width); 145 divider->flags, divider->width);
@@ -344,19 +342,43 @@ long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
344} 342}
345EXPORT_SYMBOL_GPL(divider_round_rate_parent); 343EXPORT_SYMBOL_GPL(divider_round_rate_parent);
346 344
345long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
346 unsigned long rate, unsigned long *prate,
347 const struct clk_div_table *table, u8 width,
348 unsigned long flags, unsigned int val)
349{
350 int div;
351
352 div = _get_div(table, val, flags, width);
353
354 /* Even a read-only clock can propagate a rate change */
355 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
356 if (!parent)
357 return -EINVAL;
358
359 *prate = clk_hw_round_rate(parent, rate * div);
360 }
361
362 return DIV_ROUND_UP_ULL((u64)*prate, div);
363}
364EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);
365
366
347static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, 367static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
348 unsigned long *prate) 368 unsigned long *prate)
349{ 369{
350 struct clk_divider *divider = to_clk_divider(hw); 370 struct clk_divider *divider = to_clk_divider(hw);
351 int bestdiv;
352 371
353 /* if read only, just return current value */ 372 /* if read only, just return current value */
354 if (divider->flags & CLK_DIVIDER_READ_ONLY) { 373 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
355 bestdiv = clk_readl(divider->reg) >> divider->shift; 374 u32 val;
356 bestdiv &= div_mask(divider->width); 375
357 bestdiv = _get_div(divider->table, bestdiv, divider->flags, 376 val = clk_readl(divider->reg) >> divider->shift;
358 divider->width); 377 val &= clk_div_mask(divider->width);
359 return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); 378
379 return divider_ro_round_rate(hw, rate, prate, divider->table,
380 divider->width, divider->flags,
381 val);
360 } 382 }
361 383
362 return divider_round_rate(hw, rate, prate, divider->table, 384 return divider_round_rate(hw, rate, prate, divider->table,
@@ -376,7 +398,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
376 398
377 value = _get_val(table, div, flags, width); 399 value = _get_val(table, div, flags, width);
378 400
379 return min_t(unsigned int, value, div_mask(width)); 401 return min_t(unsigned int, value, clk_div_mask(width));
380} 402}
381EXPORT_SYMBOL_GPL(divider_get_val); 403EXPORT_SYMBOL_GPL(divider_get_val);
382 404
@@ -399,10 +421,10 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
399 __acquire(divider->lock); 421 __acquire(divider->lock);
400 422
401 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 423 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
402 val = div_mask(divider->width) << (divider->shift + 16); 424 val = clk_div_mask(divider->width) << (divider->shift + 16);
403 } else { 425 } else {
404 val = clk_readl(divider->reg); 426 val = clk_readl(divider->reg);
405 val &= ~(div_mask(divider->width) << divider->shift); 427 val &= ~(clk_div_mask(divider->width) << divider->shift);
406 } 428 }
407 val |= (u32)value << divider->shift; 429 val |= (u32)value << divider->shift;
408 clk_writel(val, divider->reg); 430 clk_writel(val, divider->reg);
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 39cabe157163..ac4a042f8658 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -26,35 +26,24 @@
26 * parent - parent is adjustable through clk_set_parent 26 * parent - parent is adjustable through clk_set_parent
27 */ 27 */
28 28
29static u8 clk_mux_get_parent(struct clk_hw *hw) 29int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
30 unsigned int val)
30{ 31{
31 struct clk_mux *mux = to_clk_mux(hw);
32 int num_parents = clk_hw_get_num_parents(hw); 32 int num_parents = clk_hw_get_num_parents(hw);
33 u32 val;
34 33
35 /* 34 if (table) {
36 * FIXME need a mux-specific flag to determine if val is bitwise or numeric
37 * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
38 * to 0x7 (index starts at one)
39 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
40 * val = 0x4 really means "bit 2, index starts at bit 0"
41 */
42 val = clk_readl(mux->reg) >> mux->shift;
43 val &= mux->mask;
44
45 if (mux->table) {
46 int i; 35 int i;
47 36
48 for (i = 0; i < num_parents; i++) 37 for (i = 0; i < num_parents; i++)
49 if (mux->table[i] == val) 38 if (table[i] == val)
50 return i; 39 return i;
51 return -EINVAL; 40 return -EINVAL;
52 } 41 }
53 42
54 if (val && (mux->flags & CLK_MUX_INDEX_BIT)) 43 if (val && (flags & CLK_MUX_INDEX_BIT))
55 val = ffs(val) - 1; 44 val = ffs(val) - 1;
56 45
57 if (val && (mux->flags & CLK_MUX_INDEX_ONE)) 46 if (val && (flags & CLK_MUX_INDEX_ONE))
58 val--; 47 val--;
59 48
60 if (val >= num_parents) 49 if (val >= num_parents)
@@ -62,36 +51,58 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
62 51
63 return val; 52 return val;
64} 53}
54EXPORT_SYMBOL_GPL(clk_mux_val_to_index);
65 55
66static int clk_mux_set_parent(struct clk_hw *hw, u8 index) 56unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index)
67{ 57{
68 struct clk_mux *mux = to_clk_mux(hw); 58 unsigned int val = index;
69 u32 val;
70 unsigned long flags = 0;
71 59
72 if (mux->table) { 60 if (table) {
73 index = mux->table[index]; 61 val = table[index];
74 } else { 62 } else {
75 if (mux->flags & CLK_MUX_INDEX_BIT) 63 if (flags & CLK_MUX_INDEX_BIT)
76 index = 1 << index; 64 val = 1 << index;
77 65
78 if (mux->flags & CLK_MUX_INDEX_ONE) 66 if (flags & CLK_MUX_INDEX_ONE)
79 index++; 67 val++;
80 } 68 }
81 69
70 return val;
71}
72EXPORT_SYMBOL_GPL(clk_mux_index_to_val);
73
74static u8 clk_mux_get_parent(struct clk_hw *hw)
75{
76 struct clk_mux *mux = to_clk_mux(hw);
77 u32 val;
78
79 val = clk_readl(mux->reg) >> mux->shift;
80 val &= mux->mask;
81
82 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
83}
84
85static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
86{
87 struct clk_mux *mux = to_clk_mux(hw);
88 u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
89 unsigned long flags = 0;
90 u32 reg;
91
82 if (mux->lock) 92 if (mux->lock)
83 spin_lock_irqsave(mux->lock, flags); 93 spin_lock_irqsave(mux->lock, flags);
84 else 94 else
85 __acquire(mux->lock); 95 __acquire(mux->lock);
86 96
87 if (mux->flags & CLK_MUX_HIWORD_MASK) { 97 if (mux->flags & CLK_MUX_HIWORD_MASK) {
88 val = mux->mask << (mux->shift + 16); 98 reg = mux->mask << (mux->shift + 16);
89 } else { 99 } else {
90 val = clk_readl(mux->reg); 100 reg = clk_readl(mux->reg);
91 val &= ~(mux->mask << mux->shift); 101 reg &= ~(mux->mask << mux->shift);
92 } 102 }
93 val |= index << mux->shift; 103 val = val << mux->shift;
94 clk_writel(val, mux->reg); 104 reg |= val;
105 clk_writel(reg, mux->reg);
95 106
96 if (mux->lock) 107 if (mux->lock)
97 spin_unlock_irqrestore(mux->lock, flags); 108 spin_unlock_irqrestore(mux->lock, flags);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0f686a9dac3e..9d56be6ead39 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
1125{ 1125{
1126 lockdep_assert_held(&prepare_lock); 1126 lockdep_assert_held(&prepare_lock);
1127 1127
1128 if (!core) 1128 if (!core) {
1129 req->rate = 0;
1129 return 0; 1130 return 0;
1131 }
1130 1132
1131 clk_core_init_rate_req(core, req); 1133 clk_core_init_rate_req(core, req);
1132 1134
@@ -2928,6 +2930,17 @@ static int __clk_core_init(struct clk_core *core)
2928 } 2930 }
2929 2931
2930 /* 2932 /*
2933 * optional platform-specific magic
2934 *
2935 * The .init callback is not used by any of the basic clock types, but
2936 * exists for weird hardware that must perform initialization magic.
2937 * Please consider other ways of solving initialization problems before
2938 * using this callback, as its use is discouraged.
2939 */
2940 if (core->ops->init)
2941 core->ops->init(core->hw);
2942
2943 /*
2931 * Set clk's accuracy. The preferred method is to use 2944 * Set clk's accuracy. The preferred method is to use
2932 * .recalc_accuracy. For simple clocks and lazy developers the default 2945 * .recalc_accuracy. For simple clocks and lazy developers the default
2933 * fallback is to use the parent's accuracy. If a clock doesn't have a 2946 * fallback is to use the parent's accuracy. If a clock doesn't have a
@@ -2968,48 +2981,42 @@ static int __clk_core_init(struct clk_core *core)
2968 core->rate = core->req_rate = rate; 2981 core->rate = core->req_rate = rate;
2969 2982
2970 /* 2983 /*
2984 * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
2985 * don't get accidentally disabled when walking the orphan tree and
2986 * reparenting clocks
2987 */
2988 if (core->flags & CLK_IS_CRITICAL) {
2989 unsigned long flags;
2990
2991 clk_core_prepare(core);
2992
2993 flags = clk_enable_lock();
2994 clk_core_enable(core);
2995 clk_enable_unlock(flags);
2996 }
2997
2998 /*
2971 * walk the list of orphan clocks and reparent any that newly finds a 2999 * walk the list of orphan clocks and reparent any that newly finds a
2972 * parent. 3000 * parent.
2973 */ 3001 */
2974 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { 3002 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
2975 struct clk_core *parent = __clk_init_parent(orphan); 3003 struct clk_core *parent = __clk_init_parent(orphan);
2976 unsigned long flags;
2977 3004
2978 /* 3005 /*
2979 * we could call __clk_set_parent, but that would result in a 3006 * We need to use __clk_set_parent_before() and _after() to
2980 * redundant call to the .set_rate op, if it exists 3007 * to properly migrate any prepare/enable count of the orphan
3008 * clock. This is important for CLK_IS_CRITICAL clocks, which
3009 * are enabled during init but might not have a parent yet.
2981 */ 3010 */
2982 if (parent) { 3011 if (parent) {
2983 /* update the clk tree topology */ 3012 /* update the clk tree topology */
2984 flags = clk_enable_lock(); 3013 __clk_set_parent_before(orphan, parent);
2985 clk_reparent(orphan, parent); 3014 __clk_set_parent_after(orphan, parent, NULL);
2986 clk_enable_unlock(flags);
2987 __clk_recalc_accuracies(orphan); 3015 __clk_recalc_accuracies(orphan);
2988 __clk_recalc_rates(orphan, 0); 3016 __clk_recalc_rates(orphan, 0);
2989 } 3017 }
2990 } 3018 }
2991 3019
2992 /*
2993 * optional platform-specific magic
2994 *
2995 * The .init callback is not used by any of the basic clock types, but
2996 * exists for weird hardware that must perform initialization magic.
2997 * Please consider other ways of solving initialization problems before
2998 * using this callback, as its use is discouraged.
2999 */
3000 if (core->ops->init)
3001 core->ops->init(core->hw);
3002
3003 if (core->flags & CLK_IS_CRITICAL) {
3004 unsigned long flags;
3005
3006 clk_core_prepare(core);
3007
3008 flags = clk_enable_lock();
3009 clk_core_enable(core);
3010 clk_enable_unlock(flags);
3011 }
3012
3013 kref_init(&core->ref); 3020 kref_init(&core->ref);
3014out: 3021out:
3015 clk_pm_runtime_put(core); 3022 clk_pm_runtime_put(core);
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 7694302c70a4..d5cbec522aec 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -3,10 +3,15 @@ config COMMON_CLK_AMLOGIC
3 depends on OF 3 depends on OF
4 depends on ARCH_MESON || COMPILE_TEST 4 depends on ARCH_MESON || COMPILE_TEST
5 5
6config COMMON_CLK_REGMAP_MESON
7 bool
8 select REGMAP
9
6config COMMON_CLK_MESON8B 10config COMMON_CLK_MESON8B
7 bool 11 bool
8 depends on COMMON_CLK_AMLOGIC 12 depends on COMMON_CLK_AMLOGIC
9 select RESET_CONTROLLER 13 select RESET_CONTROLLER
14 select COMMON_CLK_REGMAP_MESON
10 help 15 help
11 Support for the clock controller on AmLogic S802 (Meson8), 16 Support for the clock controller on AmLogic S802 (Meson8),
12 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you 17 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
@@ -16,6 +21,8 @@ config COMMON_CLK_GXBB
16 bool 21 bool
17 depends on COMMON_CLK_AMLOGIC 22 depends on COMMON_CLK_AMLOGIC
18 select RESET_CONTROLLER 23 select RESET_CONTROLLER
24 select COMMON_CLK_REGMAP_MESON
25 select MFD_SYSCON
19 help 26 help
20 Support for the clock controller on AmLogic S905 devices, aka gxbb. 27 Support for the clock controller on AmLogic S905 devices, aka gxbb.
21 Say Y if you want peripherals and CPU frequency scaling to work. 28 Say Y if you want peripherals and CPU frequency scaling to work.
@@ -24,6 +31,8 @@ config COMMON_CLK_AXG
24 bool 31 bool
25 depends on COMMON_CLK_AMLOGIC 32 depends on COMMON_CLK_AMLOGIC
26 select RESET_CONTROLLER 33 select RESET_CONTROLLER
34 select COMMON_CLK_REGMAP_MESON
35 select MFD_SYSCON
27 help 36 help
28 Support for the clock controller on AmLogic A113D devices, aka axg. 37 Support for the clock controller on AmLogic A113D devices, aka axg.
29 Say Y if you want peripherals and CPU frequency scaling to work. 38 Say Y if you want peripherals and CPU frequency scaling to work.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 3c03ce583798..ffee82e60b7a 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,7 +2,8 @@
2# Makefile for Meson specific clk 2# Makefile for Meson specific clk
3# 3#
4 4
5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o 5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o
6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o 7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
8obj-$(CONFIG_COMMON_CLK_AXG) += axg.o 8obj-$(CONFIG_COMMON_CLK_AXG) += axg.o
9obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 1294f3ad7cd5..5f5d468c1efe 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -11,125 +11,51 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/init.h>
14#include <linux/of_address.h> 15#include <linux/of_address.h>
15#include <linux/of_device.h> 16#include <linux/of_device.h>
17#include <linux/mfd/syscon.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
17#include <linux/init.h> 19#include <linux/regmap.h>
18 20
19#include "clkc.h" 21#include "clkc.h"
20#include "axg.h" 22#include "axg.h"
21 23
22static DEFINE_SPINLOCK(meson_clk_lock); 24static DEFINE_SPINLOCK(meson_clk_lock);
23 25
24static const struct pll_rate_table sys_pll_rate_table[] = { 26static struct clk_regmap axg_fixed_pll = {
25 PLL_RATE(24000000, 56, 1, 2), 27 .data = &(struct meson_clk_pll_data){
26 PLL_RATE(48000000, 64, 1, 2), 28 .m = {
27 PLL_RATE(72000000, 72, 1, 2), 29 .reg_off = HHI_MPLL_CNTL,
28 PLL_RATE(96000000, 64, 1, 2), 30 .shift = 0,
29 PLL_RATE(120000000, 80, 1, 2), 31 .width = 9,
30 PLL_RATE(144000000, 96, 1, 2), 32 },
31 PLL_RATE(168000000, 56, 1, 1), 33 .n = {
32 PLL_RATE(192000000, 64, 1, 1), 34 .reg_off = HHI_MPLL_CNTL,
33 PLL_RATE(216000000, 72, 1, 1), 35 .shift = 9,
34 PLL_RATE(240000000, 80, 1, 1), 36 .width = 5,
35 PLL_RATE(264000000, 88, 1, 1), 37 },
36 PLL_RATE(288000000, 96, 1, 1), 38 .od = {
37 PLL_RATE(312000000, 52, 1, 2), 39 .reg_off = HHI_MPLL_CNTL,
38 PLL_RATE(336000000, 56, 1, 2), 40 .shift = 16,
39 PLL_RATE(360000000, 60, 1, 2), 41 .width = 2,
40 PLL_RATE(384000000, 64, 1, 2), 42 },
41 PLL_RATE(408000000, 68, 1, 2), 43 .frac = {
42 PLL_RATE(432000000, 72, 1, 2), 44 .reg_off = HHI_MPLL_CNTL2,
43 PLL_RATE(456000000, 76, 1, 2), 45 .shift = 0,
44 PLL_RATE(480000000, 80, 1, 2), 46 .width = 12,
45 PLL_RATE(504000000, 84, 1, 2), 47 },
46 PLL_RATE(528000000, 88, 1, 2), 48 .l = {
47 PLL_RATE(552000000, 92, 1, 2), 49 .reg_off = HHI_MPLL_CNTL,
48 PLL_RATE(576000000, 96, 1, 2), 50 .shift = 31,
49 PLL_RATE(600000000, 50, 1, 1), 51 .width = 1,
50 PLL_RATE(624000000, 52, 1, 1), 52 },
51 PLL_RATE(648000000, 54, 1, 1), 53 .rst = {
52 PLL_RATE(672000000, 56, 1, 1), 54 .reg_off = HHI_MPLL_CNTL,
53 PLL_RATE(696000000, 58, 1, 1), 55 .shift = 29,
54 PLL_RATE(720000000, 60, 1, 1), 56 .width = 1,
55 PLL_RATE(744000000, 62, 1, 1), 57 },
56 PLL_RATE(768000000, 64, 1, 1),
57 PLL_RATE(792000000, 66, 1, 1),
58 PLL_RATE(816000000, 68, 1, 1),
59 PLL_RATE(840000000, 70, 1, 1),
60 PLL_RATE(864000000, 72, 1, 1),
61 PLL_RATE(888000000, 74, 1, 1),
62 PLL_RATE(912000000, 76, 1, 1),
63 PLL_RATE(936000000, 78, 1, 1),
64 PLL_RATE(960000000, 80, 1, 1),
65 PLL_RATE(984000000, 82, 1, 1),
66 PLL_RATE(1008000000, 84, 1, 1),
67 PLL_RATE(1032000000, 86, 1, 1),
68 PLL_RATE(1056000000, 88, 1, 1),
69 PLL_RATE(1080000000, 90, 1, 1),
70 PLL_RATE(1104000000, 92, 1, 1),
71 PLL_RATE(1128000000, 94, 1, 1),
72 PLL_RATE(1152000000, 96, 1, 1),
73 PLL_RATE(1176000000, 98, 1, 1),
74 PLL_RATE(1200000000, 50, 1, 0),
75 PLL_RATE(1224000000, 51, 1, 0),
76 PLL_RATE(1248000000, 52, 1, 0),
77 PLL_RATE(1272000000, 53, 1, 0),
78 PLL_RATE(1296000000, 54, 1, 0),
79 PLL_RATE(1320000000, 55, 1, 0),
80 PLL_RATE(1344000000, 56, 1, 0),
81 PLL_RATE(1368000000, 57, 1, 0),
82 PLL_RATE(1392000000, 58, 1, 0),
83 PLL_RATE(1416000000, 59, 1, 0),
84 PLL_RATE(1440000000, 60, 1, 0),
85 PLL_RATE(1464000000, 61, 1, 0),
86 PLL_RATE(1488000000, 62, 1, 0),
87 PLL_RATE(1512000000, 63, 1, 0),
88 PLL_RATE(1536000000, 64, 1, 0),
89 PLL_RATE(1560000000, 65, 1, 0),
90 PLL_RATE(1584000000, 66, 1, 0),
91 PLL_RATE(1608000000, 67, 1, 0),
92 PLL_RATE(1632000000, 68, 1, 0),
93 PLL_RATE(1656000000, 68, 1, 0),
94 PLL_RATE(1680000000, 68, 1, 0),
95 PLL_RATE(1704000000, 68, 1, 0),
96 PLL_RATE(1728000000, 69, 1, 0),
97 PLL_RATE(1752000000, 69, 1, 0),
98 PLL_RATE(1776000000, 69, 1, 0),
99 PLL_RATE(1800000000, 69, 1, 0),
100 PLL_RATE(1824000000, 70, 1, 0),
101 PLL_RATE(1848000000, 70, 1, 0),
102 PLL_RATE(1872000000, 70, 1, 0),
103 PLL_RATE(1896000000, 70, 1, 0),
104 PLL_RATE(1920000000, 71, 1, 0),
105 PLL_RATE(1944000000, 71, 1, 0),
106 PLL_RATE(1968000000, 71, 1, 0),
107 PLL_RATE(1992000000, 71, 1, 0),
108 PLL_RATE(2016000000, 72, 1, 0),
109 PLL_RATE(2040000000, 72, 1, 0),
110 PLL_RATE(2064000000, 72, 1, 0),
111 PLL_RATE(2088000000, 72, 1, 0),
112 PLL_RATE(2112000000, 73, 1, 0),
113 { /* sentinel */ },
114};
115
116static struct meson_clk_pll axg_fixed_pll = {
117 .m = {
118 .reg_off = HHI_MPLL_CNTL,
119 .shift = 0,
120 .width = 9,
121 },
122 .n = {
123 .reg_off = HHI_MPLL_CNTL,
124 .shift = 9,
125 .width = 5,
126 },
127 .od = {
128 .reg_off = HHI_MPLL_CNTL,
129 .shift = 16,
130 .width = 2,
131 }, 58 },
132 .lock = &meson_clk_lock,
133 .hw.init = &(struct clk_init_data){ 59 .hw.init = &(struct clk_init_data){
134 .name = "fixed_pll", 60 .name = "fixed_pll",
135 .ops = &meson_clk_pll_ro_ops, 61 .ops = &meson_clk_pll_ro_ops,
@@ -138,25 +64,34 @@ static struct meson_clk_pll axg_fixed_pll = {
138 }, 64 },
139}; 65};
140 66
141static struct meson_clk_pll axg_sys_pll = { 67static struct clk_regmap axg_sys_pll = {
142 .m = { 68 .data = &(struct meson_clk_pll_data){
143 .reg_off = HHI_SYS_PLL_CNTL, 69 .m = {
144 .shift = 0, 70 .reg_off = HHI_SYS_PLL_CNTL,
145 .width = 9, 71 .shift = 0,
72 .width = 9,
73 },
74 .n = {
75 .reg_off = HHI_SYS_PLL_CNTL,
76 .shift = 9,
77 .width = 5,
78 },
79 .od = {
80 .reg_off = HHI_SYS_PLL_CNTL,
81 .shift = 16,
82 .width = 2,
83 },
84 .l = {
85 .reg_off = HHI_SYS_PLL_CNTL,
86 .shift = 31,
87 .width = 1,
88 },
89 .rst = {
90 .reg_off = HHI_SYS_PLL_CNTL,
91 .shift = 29,
92 .width = 1,
93 },
146 }, 94 },
147 .n = {
148 .reg_off = HHI_SYS_PLL_CNTL,
149 .shift = 9,
150 .width = 5,
151 },
152 .od = {
153 .reg_off = HHI_SYS_PLL_CNTL,
154 .shift = 10,
155 .width = 2,
156 },
157 .rate_table = sys_pll_rate_table,
158 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
159 .lock = &meson_clk_lock,
160 .hw.init = &(struct clk_init_data){ 95 .hw.init = &(struct clk_init_data){
161 .name = "sys_pll", 96 .name = "sys_pll",
162 .ops = &meson_clk_pll_ro_ops, 97 .ops = &meson_clk_pll_ro_ops,
@@ -257,40 +192,51 @@ static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
257 { /* sentinel */ }, 192 { /* sentinel */ },
258}; 193};
259 194
260static struct pll_params_table axg_gp0_params_table[] = { 195static const struct reg_sequence axg_gp0_init_regs[] = {
261 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x40010250), 196 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
262 PLL_PARAM(HHI_GP0_PLL_CNTL1, 0xc084a000), 197 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
263 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0xb75020be), 198 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
264 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a59a288), 199 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
265 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0xc000004d), 200 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
266 PLL_PARAM(HHI_GP0_PLL_CNTL5, 0x00078000), 201 { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
267}; 202};
268 203
269static struct meson_clk_pll axg_gp0_pll = { 204static struct clk_regmap axg_gp0_pll = {
270 .m = { 205 .data = &(struct meson_clk_pll_data){
271 .reg_off = HHI_GP0_PLL_CNTL, 206 .m = {
272 .shift = 0, 207 .reg_off = HHI_GP0_PLL_CNTL,
273 .width = 9, 208 .shift = 0,
274 }, 209 .width = 9,
275 .n = { 210 },
276 .reg_off = HHI_GP0_PLL_CNTL, 211 .n = {
277 .shift = 9, 212 .reg_off = HHI_GP0_PLL_CNTL,
278 .width = 5, 213 .shift = 9,
279 }, 214 .width = 5,
280 .od = { 215 },
281 .reg_off = HHI_GP0_PLL_CNTL, 216 .od = {
282 .shift = 16, 217 .reg_off = HHI_GP0_PLL_CNTL,
283 .width = 2, 218 .shift = 16,
284 }, 219 .width = 2,
285 .params = { 220 },
286 .params_table = axg_gp0_params_table, 221 .frac = {
287 .params_count = ARRAY_SIZE(axg_gp0_params_table), 222 .reg_off = HHI_GP0_PLL_CNTL1,
288 .no_init_reset = true, 223 .shift = 0,
289 .reset_lock_loop = true, 224 .width = 10,
290 }, 225 },
291 .rate_table = axg_gp0_pll_rate_table, 226 .l = {
292 .rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), 227 .reg_off = HHI_GP0_PLL_CNTL,
293 .lock = &meson_clk_lock, 228 .shift = 31,
229 .width = 1,
230 },
231 .rst = {
232 .reg_off = HHI_GP0_PLL_CNTL,
233 .shift = 29,
234 .width = 1,
235 },
236 .table = axg_gp0_pll_rate_table,
237 .init_regs = axg_gp0_init_regs,
238 .init_count = ARRAY_SIZE(axg_gp0_init_regs),
239 },
294 .hw.init = &(struct clk_init_data){ 240 .hw.init = &(struct clk_init_data){
295 .name = "gp0_pll", 241 .name = "gp0_pll",
296 .ops = &meson_clk_pll_ops, 242 .ops = &meson_clk_pll_ops,
@@ -299,234 +245,427 @@ static struct meson_clk_pll axg_gp0_pll = {
299 }, 245 },
300}; 246};
301 247
248static const struct reg_sequence axg_hifi_init_regs[] = {
249 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 },
250 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be },
251 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 },
252 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d },
253 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 },
254 { .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 },
255};
256
257static struct clk_regmap axg_hifi_pll = {
258 .data = &(struct meson_clk_pll_data){
259 .m = {
260 .reg_off = HHI_HIFI_PLL_CNTL,
261 .shift = 0,
262 .width = 9,
263 },
264 .n = {
265 .reg_off = HHI_HIFI_PLL_CNTL,
266 .shift = 9,
267 .width = 5,
268 },
269 .od = {
270 .reg_off = HHI_HIFI_PLL_CNTL,
271 .shift = 16,
272 .width = 2,
273 },
274 .frac = {
275 .reg_off = HHI_HIFI_PLL_CNTL5,
276 .shift = 0,
277 .width = 13,
278 },
279 .l = {
280 .reg_off = HHI_HIFI_PLL_CNTL,
281 .shift = 31,
282 .width = 1,
283 },
284 .rst = {
285 .reg_off = HHI_HIFI_PLL_CNTL,
286 .shift = 29,
287 .width = 1,
288 },
289 .table = axg_gp0_pll_rate_table,
290 .init_regs = axg_hifi_init_regs,
291 .init_count = ARRAY_SIZE(axg_hifi_init_regs),
292 .flags = CLK_MESON_PLL_ROUND_CLOSEST,
293 },
294 .hw.init = &(struct clk_init_data){
295 .name = "hifi_pll",
296 .ops = &meson_clk_pll_ops,
297 .parent_names = (const char *[]){ "xtal" },
298 .num_parents = 1,
299 },
300};
302 301
303static struct clk_fixed_factor axg_fclk_div2 = { 302static struct clk_fixed_factor axg_fclk_div2_div = {
304 .mult = 1, 303 .mult = 1,
305 .div = 2, 304 .div = 2,
306 .hw.init = &(struct clk_init_data){ 305 .hw.init = &(struct clk_init_data){
307 .name = "fclk_div2", 306 .name = "fclk_div2_div",
308 .ops = &clk_fixed_factor_ops, 307 .ops = &clk_fixed_factor_ops,
309 .parent_names = (const char *[]){ "fixed_pll" }, 308 .parent_names = (const char *[]){ "fixed_pll" },
310 .num_parents = 1, 309 .num_parents = 1,
311 }, 310 },
312}; 311};
313 312
314static struct clk_fixed_factor axg_fclk_div3 = { 313static struct clk_regmap axg_fclk_div2 = {
314 .data = &(struct clk_regmap_gate_data){
315 .offset = HHI_MPLL_CNTL6,
316 .bit_idx = 27,
317 },
318 .hw.init = &(struct clk_init_data){
319 .name = "fclk_div2",
320 .ops = &clk_regmap_gate_ops,
321 .parent_names = (const char *[]){ "fclk_div2_div" },
322 .num_parents = 1,
323 },
324};
325
326static struct clk_fixed_factor axg_fclk_div3_div = {
315 .mult = 1, 327 .mult = 1,
316 .div = 3, 328 .div = 3,
317 .hw.init = &(struct clk_init_data){ 329 .hw.init = &(struct clk_init_data){
318 .name = "fclk_div3", 330 .name = "fclk_div3_div",
319 .ops = &clk_fixed_factor_ops, 331 .ops = &clk_fixed_factor_ops,
320 .parent_names = (const char *[]){ "fixed_pll" }, 332 .parent_names = (const char *[]){ "fixed_pll" },
321 .num_parents = 1, 333 .num_parents = 1,
322 }, 334 },
323}; 335};
324 336
325static struct clk_fixed_factor axg_fclk_div4 = { 337static struct clk_regmap axg_fclk_div3 = {
338 .data = &(struct clk_regmap_gate_data){
339 .offset = HHI_MPLL_CNTL6,
340 .bit_idx = 28,
341 },
342 .hw.init = &(struct clk_init_data){
343 .name = "fclk_div3",
344 .ops = &clk_regmap_gate_ops,
345 .parent_names = (const char *[]){ "fclk_div3_div" },
346 .num_parents = 1,
347 },
348};
349
350static struct clk_fixed_factor axg_fclk_div4_div = {
326 .mult = 1, 351 .mult = 1,
327 .div = 4, 352 .div = 4,
328 .hw.init = &(struct clk_init_data){ 353 .hw.init = &(struct clk_init_data){
329 .name = "fclk_div4", 354 .name = "fclk_div4_div",
330 .ops = &clk_fixed_factor_ops, 355 .ops = &clk_fixed_factor_ops,
331 .parent_names = (const char *[]){ "fixed_pll" }, 356 .parent_names = (const char *[]){ "fixed_pll" },
332 .num_parents = 1, 357 .num_parents = 1,
333 }, 358 },
334}; 359};
335 360
336static struct clk_fixed_factor axg_fclk_div5 = { 361static struct clk_regmap axg_fclk_div4 = {
362 .data = &(struct clk_regmap_gate_data){
363 .offset = HHI_MPLL_CNTL6,
364 .bit_idx = 29,
365 },
366 .hw.init = &(struct clk_init_data){
367 .name = "fclk_div4",
368 .ops = &clk_regmap_gate_ops,
369 .parent_names = (const char *[]){ "fclk_div4_div" },
370 .num_parents = 1,
371 },
372};
373
374static struct clk_fixed_factor axg_fclk_div5_div = {
337 .mult = 1, 375 .mult = 1,
338 .div = 5, 376 .div = 5,
339 .hw.init = &(struct clk_init_data){ 377 .hw.init = &(struct clk_init_data){
340 .name = "fclk_div5", 378 .name = "fclk_div5_div",
341 .ops = &clk_fixed_factor_ops, 379 .ops = &clk_fixed_factor_ops,
342 .parent_names = (const char *[]){ "fixed_pll" }, 380 .parent_names = (const char *[]){ "fixed_pll" },
343 .num_parents = 1, 381 .num_parents = 1,
344 }, 382 },
345}; 383};
346 384
347static struct clk_fixed_factor axg_fclk_div7 = { 385static struct clk_regmap axg_fclk_div5 = {
386 .data = &(struct clk_regmap_gate_data){
387 .offset = HHI_MPLL_CNTL6,
388 .bit_idx = 30,
389 },
390 .hw.init = &(struct clk_init_data){
391 .name = "fclk_div5",
392 .ops = &clk_regmap_gate_ops,
393 .parent_names = (const char *[]){ "fclk_div5_div" },
394 .num_parents = 1,
395 },
396};
397
398static struct clk_fixed_factor axg_fclk_div7_div = {
348 .mult = 1, 399 .mult = 1,
349 .div = 7, 400 .div = 7,
350 .hw.init = &(struct clk_init_data){ 401 .hw.init = &(struct clk_init_data){
351 .name = "fclk_div7", 402 .name = "fclk_div7_div",
352 .ops = &clk_fixed_factor_ops, 403 .ops = &clk_fixed_factor_ops,
353 .parent_names = (const char *[]){ "fixed_pll" }, 404 .parent_names = (const char *[]){ "fixed_pll" },
354 .num_parents = 1, 405 .num_parents = 1,
355 }, 406 },
356}; 407};
357 408
358static struct meson_clk_mpll axg_mpll0 = { 409static struct clk_regmap axg_fclk_div7 = {
359 .sdm = { 410 .data = &(struct clk_regmap_gate_data){
360 .reg_off = HHI_MPLL_CNTL7, 411 .offset = HHI_MPLL_CNTL6,
361 .shift = 0, 412 .bit_idx = 31,
362 .width = 14,
363 }, 413 },
364 .sdm_en = { 414 .hw.init = &(struct clk_init_data){
365 .reg_off = HHI_MPLL_CNTL7, 415 .name = "fclk_div7",
366 .shift = 15, 416 .ops = &clk_regmap_gate_ops,
367 .width = 1, 417 .parent_names = (const char *[]){ "fclk_div7_div" },
418 .num_parents = 1,
368 }, 419 },
369 .n2 = { 420};
370 .reg_off = HHI_MPLL_CNTL7, 421
371 .shift = 16, 422static struct clk_regmap axg_mpll_prediv = {
372 .width = 9, 423 .data = &(struct clk_regmap_div_data){
424 .offset = HHI_MPLL_CNTL5,
425 .shift = 12,
426 .width = 1,
373 }, 427 },
374 .en = { 428 .hw.init = &(struct clk_init_data){
375 .reg_off = HHI_MPLL_CNTL7, 429 .name = "mpll_prediv",
376 .shift = 14, 430 .ops = &clk_regmap_divider_ro_ops,
377 .width = 1, 431 .parent_names = (const char *[]){ "fixed_pll" },
432 .num_parents = 1,
378 }, 433 },
379 .ssen = { 434};
380 .reg_off = HHI_MPLL_CNTL, 435
381 .shift = 25, 436static struct clk_regmap axg_mpll0_div = {
382 .width = 1, 437 .data = &(struct meson_clk_mpll_data){
438 .sdm = {
439 .reg_off = HHI_MPLL_CNTL7,
440 .shift = 0,
441 .width = 14,
442 },
443 .sdm_en = {
444 .reg_off = HHI_MPLL_CNTL7,
445 .shift = 15,
446 .width = 1,
447 },
448 .n2 = {
449 .reg_off = HHI_MPLL_CNTL7,
450 .shift = 16,
451 .width = 9,
452 },
453 .ssen = {
454 .reg_off = HHI_MPLL_CNTL,
455 .shift = 25,
456 .width = 1,
457 },
458 .misc = {
459 .reg_off = HHI_PLL_TOP_MISC,
460 .shift = 0,
461 .width = 1,
462 },
463 .lock = &meson_clk_lock,
383 }, 464 },
384 .lock = &meson_clk_lock,
385 .hw.init = &(struct clk_init_data){ 465 .hw.init = &(struct clk_init_data){
386 .name = "mpll0", 466 .name = "mpll0_div",
387 .ops = &meson_clk_mpll_ops, 467 .ops = &meson_clk_mpll_ops,
388 .parent_names = (const char *[]){ "fixed_pll" }, 468 .parent_names = (const char *[]){ "mpll_prediv" },
389 .num_parents = 1, 469 .num_parents = 1,
390 }, 470 },
391}; 471};
392 472
393static struct meson_clk_mpll axg_mpll1 = { 473static struct clk_regmap axg_mpll0 = {
394 .sdm = { 474 .data = &(struct clk_regmap_gate_data){
395 .reg_off = HHI_MPLL_CNTL8, 475 .offset = HHI_MPLL_CNTL7,
396 .shift = 0, 476 .bit_idx = 14,
397 .width = 14,
398 }, 477 },
399 .sdm_en = { 478 .hw.init = &(struct clk_init_data){
400 .reg_off = HHI_MPLL_CNTL8, 479 .name = "mpll0",
401 .shift = 15, 480 .ops = &clk_regmap_gate_ops,
402 .width = 1, 481 .parent_names = (const char *[]){ "mpll0_div" },
403 }, 482 .num_parents = 1,
404 .n2 = { 483 .flags = CLK_SET_RATE_PARENT,
405 .reg_off = HHI_MPLL_CNTL8,
406 .shift = 16,
407 .width = 9,
408 }, 484 },
409 .en = { 485};
410 .reg_off = HHI_MPLL_CNTL8, 486
411 .shift = 14, 487static struct clk_regmap axg_mpll1_div = {
412 .width = 1, 488 .data = &(struct meson_clk_mpll_data){
489 .sdm = {
490 .reg_off = HHI_MPLL_CNTL8,
491 .shift = 0,
492 .width = 14,
493 },
494 .sdm_en = {
495 .reg_off = HHI_MPLL_CNTL8,
496 .shift = 15,
497 .width = 1,
498 },
499 .n2 = {
500 .reg_off = HHI_MPLL_CNTL8,
501 .shift = 16,
502 .width = 9,
503 },
504 .misc = {
505 .reg_off = HHI_PLL_TOP_MISC,
506 .shift = 1,
507 .width = 1,
508 },
509 .lock = &meson_clk_lock,
413 }, 510 },
414 .lock = &meson_clk_lock,
415 .hw.init = &(struct clk_init_data){ 511 .hw.init = &(struct clk_init_data){
416 .name = "mpll1", 512 .name = "mpll1_div",
417 .ops = &meson_clk_mpll_ops, 513 .ops = &meson_clk_mpll_ops,
418 .parent_names = (const char *[]){ "fixed_pll" }, 514 .parent_names = (const char *[]){ "mpll_prediv" },
419 .num_parents = 1, 515 .num_parents = 1,
420 }, 516 },
421}; 517};
422 518
423static struct meson_clk_mpll axg_mpll2 = { 519static struct clk_regmap axg_mpll1 = {
424 .sdm = { 520 .data = &(struct clk_regmap_gate_data){
425 .reg_off = HHI_MPLL_CNTL9, 521 .offset = HHI_MPLL_CNTL8,
426 .shift = 0, 522 .bit_idx = 14,
427 .width = 14,
428 }, 523 },
429 .sdm_en = { 524 .hw.init = &(struct clk_init_data){
430 .reg_off = HHI_MPLL_CNTL9, 525 .name = "mpll1",
431 .shift = 15, 526 .ops = &clk_regmap_gate_ops,
432 .width = 1, 527 .parent_names = (const char *[]){ "mpll1_div" },
433 }, 528 .num_parents = 1,
434 .n2 = { 529 .flags = CLK_SET_RATE_PARENT,
435 .reg_off = HHI_MPLL_CNTL9,
436 .shift = 16,
437 .width = 9,
438 }, 530 },
439 .en = { 531};
440 .reg_off = HHI_MPLL_CNTL9, 532
441 .shift = 14, 533static struct clk_regmap axg_mpll2_div = {
442 .width = 1, 534 .data = &(struct meson_clk_mpll_data){
535 .sdm = {
536 .reg_off = HHI_MPLL_CNTL9,
537 .shift = 0,
538 .width = 14,
539 },
540 .sdm_en = {
541 .reg_off = HHI_MPLL_CNTL9,
542 .shift = 15,
543 .width = 1,
544 },
545 .n2 = {
546 .reg_off = HHI_MPLL_CNTL9,
547 .shift = 16,
548 .width = 9,
549 },
550 .misc = {
551 .reg_off = HHI_PLL_TOP_MISC,
552 .shift = 2,
553 .width = 1,
554 },
555 .lock = &meson_clk_lock,
443 }, 556 },
444 .lock = &meson_clk_lock,
445 .hw.init = &(struct clk_init_data){ 557 .hw.init = &(struct clk_init_data){
446 .name = "mpll2", 558 .name = "mpll2_div",
447 .ops = &meson_clk_mpll_ops, 559 .ops = &meson_clk_mpll_ops,
448 .parent_names = (const char *[]){ "fixed_pll" }, 560 .parent_names = (const char *[]){ "mpll_prediv" },
449 .num_parents = 1, 561 .num_parents = 1,
450 }, 562 },
451}; 563};
452 564
453static struct meson_clk_mpll axg_mpll3 = { 565static struct clk_regmap axg_mpll2 = {
454 .sdm = { 566 .data = &(struct clk_regmap_gate_data){
455 .reg_off = HHI_MPLL3_CNTL0, 567 .offset = HHI_MPLL_CNTL9,
456 .shift = 12, 568 .bit_idx = 14,
457 .width = 14,
458 }, 569 },
459 .sdm_en = { 570 .hw.init = &(struct clk_init_data){
460 .reg_off = HHI_MPLL3_CNTL0, 571 .name = "mpll2",
461 .shift = 11, 572 .ops = &clk_regmap_gate_ops,
462 .width = 1, 573 .parent_names = (const char *[]){ "mpll2_div" },
574 .num_parents = 1,
575 .flags = CLK_SET_RATE_PARENT,
576 },
577};
578
579static struct clk_regmap axg_mpll3_div = {
580 .data = &(struct meson_clk_mpll_data){
581 .sdm = {
582 .reg_off = HHI_MPLL3_CNTL0,
583 .shift = 12,
584 .width = 14,
585 },
586 .sdm_en = {
587 .reg_off = HHI_MPLL3_CNTL0,
588 .shift = 11,
589 .width = 1,
590 },
591 .n2 = {
592 .reg_off = HHI_MPLL3_CNTL0,
593 .shift = 2,
594 .width = 9,
595 },
596 .misc = {
597 .reg_off = HHI_PLL_TOP_MISC,
598 .shift = 3,
599 .width = 1,
600 },
601 .lock = &meson_clk_lock,
463 }, 602 },
464 .n2 = { 603 .hw.init = &(struct clk_init_data){
465 .reg_off = HHI_MPLL3_CNTL0, 604 .name = "mpll3_div",
466 .shift = 2, 605 .ops = &meson_clk_mpll_ops,
467 .width = 9, 606 .parent_names = (const char *[]){ "mpll_prediv" },
607 .num_parents = 1,
468 }, 608 },
469 .en = { 609};
470 .reg_off = HHI_MPLL3_CNTL0, 610
471 .shift = 0, 611static struct clk_regmap axg_mpll3 = {
472 .width = 1, 612 .data = &(struct clk_regmap_gate_data){
613 .offset = HHI_MPLL3_CNTL0,
614 .bit_idx = 0,
473 }, 615 },
474 .lock = &meson_clk_lock,
475 .hw.init = &(struct clk_init_data){ 616 .hw.init = &(struct clk_init_data){
476 .name = "mpll3", 617 .name = "mpll3",
477 .ops = &meson_clk_mpll_ops, 618 .ops = &clk_regmap_gate_ops,
478 .parent_names = (const char *[]){ "fixed_pll" }, 619 .parent_names = (const char *[]){ "mpll3_div" },
479 .num_parents = 1, 620 .num_parents = 1,
621 .flags = CLK_SET_RATE_PARENT,
480 }, 622 },
481}; 623};
482 624
483/*
484 * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers
485 * and should be modeled with their respective PLLs via the forthcoming
486 * coordinated clock rates feature
487 */
488static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 625static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
489static const char * const clk81_parent_names[] = { 626static const char * const clk81_parent_names[] = {
490 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 627 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
491 "fclk_div3", "fclk_div5" 628 "fclk_div3", "fclk_div5"
492}; 629};
493 630
494static struct clk_mux axg_mpeg_clk_sel = { 631static struct clk_regmap axg_mpeg_clk_sel = {
495 .reg = (void *)HHI_MPEG_CLK_CNTL, 632 .data = &(struct clk_regmap_mux_data){
496 .mask = 0x7, 633 .offset = HHI_MPEG_CLK_CNTL,
497 .shift = 12, 634 .mask = 0x7,
498 .flags = CLK_MUX_READ_ONLY, 635 .shift = 12,
499 .table = mux_table_clk81, 636 .table = mux_table_clk81,
500 .lock = &meson_clk_lock, 637 },
501 .hw.init = &(struct clk_init_data){ 638 .hw.init = &(struct clk_init_data){
502 .name = "mpeg_clk_sel", 639 .name = "mpeg_clk_sel",
503 .ops = &clk_mux_ro_ops, 640 .ops = &clk_regmap_mux_ro_ops,
504 .parent_names = clk81_parent_names, 641 .parent_names = clk81_parent_names,
505 .num_parents = ARRAY_SIZE(clk81_parent_names), 642 .num_parents = ARRAY_SIZE(clk81_parent_names),
506 }, 643 },
507}; 644};
508 645
509static struct clk_divider axg_mpeg_clk_div = { 646static struct clk_regmap axg_mpeg_clk_div = {
510 .reg = (void *)HHI_MPEG_CLK_CNTL, 647 .data = &(struct clk_regmap_div_data){
511 .shift = 0, 648 .offset = HHI_MPEG_CLK_CNTL,
512 .width = 7, 649 .shift = 0,
513 .lock = &meson_clk_lock, 650 .width = 7,
651 },
514 .hw.init = &(struct clk_init_data){ 652 .hw.init = &(struct clk_init_data){
515 .name = "mpeg_clk_div", 653 .name = "mpeg_clk_div",
516 .ops = &clk_divider_ops, 654 .ops = &clk_regmap_divider_ops,
517 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 655 .parent_names = (const char *[]){ "mpeg_clk_sel" },
518 .num_parents = 1, 656 .num_parents = 1,
519 .flags = CLK_SET_RATE_PARENT, 657 .flags = CLK_SET_RATE_PARENT,
520 }, 658 },
521}; 659};
522 660
523static struct clk_gate axg_clk81 = { 661static struct clk_regmap axg_clk81 = {
524 .reg = (void *)HHI_MPEG_CLK_CNTL, 662 .data = &(struct clk_regmap_gate_data){
525 .bit_idx = 7, 663 .offset = HHI_MPEG_CLK_CNTL,
526 .lock = &meson_clk_lock, 664 .bit_idx = 7,
665 },
527 .hw.init = &(struct clk_init_data){ 666 .hw.init = &(struct clk_init_data){
528 .name = "clk81", 667 .name = "clk81",
529 .ops = &clk_gate_ops, 668 .ops = &clk_regmap_gate_ops,
530 .parent_names = (const char *[]){ "mpeg_clk_div" }, 669 .parent_names = (const char *[]){ "mpeg_clk_div" },
531 .num_parents = 1, 670 .num_parents = 1,
532 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 671 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
@@ -545,42 +684,45 @@ static const char * const axg_sd_emmc_clk0_parent_names[] = {
545}; 684};
546 685
547/* SDcard clock */ 686/* SDcard clock */
548static struct clk_mux axg_sd_emmc_b_clk0_sel = { 687static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
549 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 688 .data = &(struct clk_regmap_mux_data){
550 .mask = 0x7, 689 .offset = HHI_SD_EMMC_CLK_CNTL,
551 .shift = 25, 690 .mask = 0x7,
552 .lock = &meson_clk_lock, 691 .shift = 25,
692 },
553 .hw.init = &(struct clk_init_data) { 693 .hw.init = &(struct clk_init_data) {
554 .name = "sd_emmc_b_clk0_sel", 694 .name = "sd_emmc_b_clk0_sel",
555 .ops = &clk_mux_ops, 695 .ops = &clk_regmap_mux_ops,
556 .parent_names = axg_sd_emmc_clk0_parent_names, 696 .parent_names = axg_sd_emmc_clk0_parent_names,
557 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 697 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
558 .flags = CLK_SET_RATE_PARENT, 698 .flags = CLK_SET_RATE_PARENT,
559 }, 699 },
560}; 700};
561 701
562static struct clk_divider axg_sd_emmc_b_clk0_div = { 702static struct clk_regmap axg_sd_emmc_b_clk0_div = {
563 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 703 .data = &(struct clk_regmap_div_data){
564 .shift = 16, 704 .offset = HHI_SD_EMMC_CLK_CNTL,
565 .width = 7, 705 .shift = 16,
566 .lock = &meson_clk_lock, 706 .width = 7,
567 .flags = CLK_DIVIDER_ROUND_CLOSEST, 707 .flags = CLK_DIVIDER_ROUND_CLOSEST,
708 },
568 .hw.init = &(struct clk_init_data) { 709 .hw.init = &(struct clk_init_data) {
569 .name = "sd_emmc_b_clk0_div", 710 .name = "sd_emmc_b_clk0_div",
570 .ops = &clk_divider_ops, 711 .ops = &clk_regmap_divider_ops,
571 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 712 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
572 .num_parents = 1, 713 .num_parents = 1,
573 .flags = CLK_SET_RATE_PARENT, 714 .flags = CLK_SET_RATE_PARENT,
574 }, 715 },
575}; 716};
576 717
577static struct clk_gate axg_sd_emmc_b_clk0 = { 718static struct clk_regmap axg_sd_emmc_b_clk0 = {
578 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 719 .data = &(struct clk_regmap_gate_data){
579 .bit_idx = 23, 720 .offset = HHI_SD_EMMC_CLK_CNTL,
580 .lock = &meson_clk_lock, 721 .bit_idx = 23,
722 },
581 .hw.init = &(struct clk_init_data){ 723 .hw.init = &(struct clk_init_data){
582 .name = "sd_emmc_b_clk0", 724 .name = "sd_emmc_b_clk0",
583 .ops = &clk_gate_ops, 725 .ops = &clk_regmap_gate_ops,
584 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 726 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
585 .num_parents = 1, 727 .num_parents = 1,
586 .flags = CLK_SET_RATE_PARENT, 728 .flags = CLK_SET_RATE_PARENT,
@@ -588,42 +730,45 @@ static struct clk_gate axg_sd_emmc_b_clk0 = {
588}; 730};
589 731
590/* EMMC/NAND clock */ 732/* EMMC/NAND clock */
591static struct clk_mux axg_sd_emmc_c_clk0_sel = { 733static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
592 .reg = (void *)HHI_NAND_CLK_CNTL, 734 .data = &(struct clk_regmap_mux_data){
593 .mask = 0x7, 735 .offset = HHI_NAND_CLK_CNTL,
594 .shift = 9, 736 .mask = 0x7,
595 .lock = &meson_clk_lock, 737 .shift = 9,
738 },
596 .hw.init = &(struct clk_init_data) { 739 .hw.init = &(struct clk_init_data) {
597 .name = "sd_emmc_c_clk0_sel", 740 .name = "sd_emmc_c_clk0_sel",
598 .ops = &clk_mux_ops, 741 .ops = &clk_regmap_mux_ops,
599 .parent_names = axg_sd_emmc_clk0_parent_names, 742 .parent_names = axg_sd_emmc_clk0_parent_names,
600 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 743 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
601 .flags = CLK_SET_RATE_PARENT, 744 .flags = CLK_SET_RATE_PARENT,
602 }, 745 },
603}; 746};
604 747
605static struct clk_divider axg_sd_emmc_c_clk0_div = { 748static struct clk_regmap axg_sd_emmc_c_clk0_div = {
606 .reg = (void *)HHI_NAND_CLK_CNTL, 749 .data = &(struct clk_regmap_div_data){
607 .shift = 0, 750 .offset = HHI_NAND_CLK_CNTL,
608 .width = 7, 751 .shift = 0,
609 .lock = &meson_clk_lock, 752 .width = 7,
610 .flags = CLK_DIVIDER_ROUND_CLOSEST, 753 .flags = CLK_DIVIDER_ROUND_CLOSEST,
754 },
611 .hw.init = &(struct clk_init_data) { 755 .hw.init = &(struct clk_init_data) {
612 .name = "sd_emmc_c_clk0_div", 756 .name = "sd_emmc_c_clk0_div",
613 .ops = &clk_divider_ops, 757 .ops = &clk_regmap_divider_ops,
614 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 758 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
615 .num_parents = 1, 759 .num_parents = 1,
616 .flags = CLK_SET_RATE_PARENT, 760 .flags = CLK_SET_RATE_PARENT,
617 }, 761 },
618}; 762};
619 763
620static struct clk_gate axg_sd_emmc_c_clk0 = { 764static struct clk_regmap axg_sd_emmc_c_clk0 = {
621 .reg = (void *)HHI_NAND_CLK_CNTL, 765 .data = &(struct clk_regmap_gate_data){
622 .bit_idx = 7, 766 .offset = HHI_NAND_CLK_CNTL,
623 .lock = &meson_clk_lock, 767 .bit_idx = 7,
768 },
624 .hw.init = &(struct clk_init_data){ 769 .hw.init = &(struct clk_init_data){
625 .name = "sd_emmc_c_clk0", 770 .name = "sd_emmc_c_clk0",
626 .ops = &clk_gate_ops, 771 .ops = &clk_regmap_gate_ops,
627 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 772 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
628 .num_parents = 1, 773 .num_parents = 1,
629 .flags = CLK_SET_RATE_PARENT, 774 .flags = CLK_SET_RATE_PARENT,
@@ -750,27 +895,24 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
750 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw, 895 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw,
751 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw, 896 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw,
752 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw, 897 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw,
898 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw,
899 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw,
900 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw,
901 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw,
902 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw,
903 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw,
904 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw,
905 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw,
906 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw,
907 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw,
908 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw,
753 [NR_CLKS] = NULL, 909 [NR_CLKS] = NULL,
754 }, 910 },
755 .num = NR_CLKS, 911 .num = NR_CLKS,
756}; 912};
757 913
758/* Convenience tables to populate base addresses in .probe */ 914/* Convenience table to populate regmap in .probe */
759 915static struct clk_regmap *const axg_clk_regmaps[] = {
760static struct meson_clk_pll *const axg_clk_plls[] = {
761 &axg_fixed_pll,
762 &axg_sys_pll,
763 &axg_gp0_pll,
764};
765
766static struct meson_clk_mpll *const axg_clk_mplls[] = {
767 &axg_mpll0,
768 &axg_mpll1,
769 &axg_mpll2,
770 &axg_mpll3,
771};
772
773static struct clk_gate *const axg_clk_gates[] = {
774 &axg_clk81, 916 &axg_clk81,
775 &axg_ddr, 917 &axg_ddr,
776 &axg_audio_locker, 918 &axg_audio_locker,
@@ -818,113 +960,100 @@ static struct clk_gate *const axg_clk_gates[] = {
818 &axg_ao_i2c, 960 &axg_ao_i2c,
819 &axg_sd_emmc_b_clk0, 961 &axg_sd_emmc_b_clk0,
820 &axg_sd_emmc_c_clk0, 962 &axg_sd_emmc_c_clk0,
821};
822
823static struct clk_mux *const axg_clk_muxes[] = {
824 &axg_mpeg_clk_sel,
825 &axg_sd_emmc_b_clk0_sel,
826 &axg_sd_emmc_c_clk0_sel,
827};
828
829static struct clk_divider *const axg_clk_dividers[] = {
830 &axg_mpeg_clk_div, 963 &axg_mpeg_clk_div,
831 &axg_sd_emmc_b_clk0_div, 964 &axg_sd_emmc_b_clk0_div,
832 &axg_sd_emmc_c_clk0_div, 965 &axg_sd_emmc_c_clk0_div,
833}; 966 &axg_mpeg_clk_sel,
834 967 &axg_sd_emmc_b_clk0_sel,
835struct clkc_data { 968 &axg_sd_emmc_c_clk0_sel,
836 struct clk_gate *const *clk_gates; 969 &axg_mpll0,
837 unsigned int clk_gates_count; 970 &axg_mpll1,
838 struct meson_clk_mpll *const *clk_mplls; 971 &axg_mpll2,
839 unsigned int clk_mplls_count; 972 &axg_mpll3,
840 struct meson_clk_pll *const *clk_plls; 973 &axg_mpll0_div,
841 unsigned int clk_plls_count; 974 &axg_mpll1_div,
842 struct clk_mux *const *clk_muxes; 975 &axg_mpll2_div,
843 unsigned int clk_muxes_count; 976 &axg_mpll3_div,
844 struct clk_divider *const *clk_dividers; 977 &axg_fixed_pll,
845 unsigned int clk_dividers_count; 978 &axg_sys_pll,
846 struct clk_hw_onecell_data *hw_onecell_data; 979 &axg_gp0_pll,
847}; 980 &axg_hifi_pll,
848 981 &axg_mpll_prediv,
849static const struct clkc_data axg_clkc_data = { 982 &axg_fclk_div2,
850 .clk_gates = axg_clk_gates, 983 &axg_fclk_div3,
851 .clk_gates_count = ARRAY_SIZE(axg_clk_gates), 984 &axg_fclk_div4,
852 .clk_mplls = axg_clk_mplls, 985 &axg_fclk_div5,
853 .clk_mplls_count = ARRAY_SIZE(axg_clk_mplls), 986 &axg_fclk_div7,
854 .clk_plls = axg_clk_plls,
855 .clk_plls_count = ARRAY_SIZE(axg_clk_plls),
856 .clk_muxes = axg_clk_muxes,
857 .clk_muxes_count = ARRAY_SIZE(axg_clk_muxes),
858 .clk_dividers = axg_clk_dividers,
859 .clk_dividers_count = ARRAY_SIZE(axg_clk_dividers),
860 .hw_onecell_data = &axg_hw_onecell_data,
861}; 987};
862 988
863static const struct of_device_id clkc_match_table[] = { 989static const struct of_device_id clkc_match_table[] = {
864 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data }, 990 { .compatible = "amlogic,axg-clkc" },
865 {} 991 {}
866}; 992};
867 993
994static const struct regmap_config clkc_regmap_config = {
995 .reg_bits = 32,
996 .val_bits = 32,
997 .reg_stride = 4,
998};
999
868static int axg_clkc_probe(struct platform_device *pdev) 1000static int axg_clkc_probe(struct platform_device *pdev)
869{ 1001{
870 struct device *dev = &pdev->dev; 1002 struct device *dev = &pdev->dev;
871 const struct clkc_data *clkc_data;
872 struct resource *res; 1003 struct resource *res;
873 void __iomem *clk_base; 1004 void __iomem *clk_base = NULL;
874 int ret, clkid, i; 1005 struct regmap *map;
875 1006 int ret, i;
876 clkc_data = of_device_get_match_data(&pdev->dev);
877 if (!clkc_data)
878 return -EINVAL;
879
880 /* Generic clocks and PLLs */
881 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
882 if (!res)
883 return -EINVAL;
884 clk_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
885 if (!clk_base) {
886 dev_err(&pdev->dev, "Unable to map clk base\n");
887 return -ENXIO;
888 }
889 1007
890 /* Populate base address for PLLs */ 1008 /* Get the hhi system controller node if available */
891 for (i = 0; i < clkc_data->clk_plls_count; i++) 1009 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
892 clkc_data->clk_plls[i]->base = clk_base; 1010 if (IS_ERR(map)) {
1011 dev_err(dev,
1012 "failed to get HHI regmap - Trying obsolete regs\n");
893 1013
894 /* Populate base address for MPLLs */ 1014 /*
895 for (i = 0; i < clkc_data->clk_mplls_count; i++) 1015 * FIXME: HHI registers should be accessed through
896 clkc_data->clk_mplls[i]->base = clk_base; 1016 * the appropriate system controller. This is required because
1017 * there is more than just clocks in this register space
1018 *
1019 * This fallback method is only provided temporarily until
1020 * all the platform DTs are properly using the syscon node
1021 */
1022 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1023 if (!res)
1024 return -EINVAL;
897 1025
898 /* Populate base address for gates */
899 for (i = 0; i < clkc_data->clk_gates_count; i++)
900 clkc_data->clk_gates[i]->reg = clk_base +
901 (u64)clkc_data->clk_gates[i]->reg;
902 1026
903 /* Populate base address for muxes */ 1027 clk_base = devm_ioremap(dev, res->start, resource_size(res));
904 for (i = 0; i < clkc_data->clk_muxes_count; i++) 1028 if (!clk_base) {
905 clkc_data->clk_muxes[i]->reg = clk_base + 1029 dev_err(dev, "Unable to map clk base\n");
906 (u64)clkc_data->clk_muxes[i]->reg; 1030 return -ENXIO;
1031 }
1032
1033 map = devm_regmap_init_mmio(dev, clk_base,
1034 &clkc_regmap_config);
1035 if (IS_ERR(map))
1036 return PTR_ERR(map);
1037 }
907 1038
908 /* Populate base address for dividers */ 1039 /* Populate regmap for the regmap backed clocks */
909 for (i = 0; i < clkc_data->clk_dividers_count; i++) 1040 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
910 clkc_data->clk_dividers[i]->reg = clk_base + 1041 axg_clk_regmaps[i]->map = map;
911 (u64)clkc_data->clk_dividers[i]->reg;
912 1042
913 for (clkid = 0; clkid < clkc_data->hw_onecell_data->num; clkid++) { 1043 for (i = 0; i < axg_hw_onecell_data.num; i++) {
914 /* array might be sparse */ 1044 /* array might be sparse */
915 if (!clkc_data->hw_onecell_data->hws[clkid]) 1045 if (!axg_hw_onecell_data.hws[i])
916 continue; 1046 continue;
917 1047
918 ret = devm_clk_hw_register(dev, 1048 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]);
919 clkc_data->hw_onecell_data->hws[clkid]);
920 if (ret) { 1049 if (ret) {
921 dev_err(&pdev->dev, "Clock registration failed\n"); 1050 dev_err(dev, "Clock registration failed\n");
922 return ret; 1051 return ret;
923 } 1052 }
924 } 1053 }
925 1054
926 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 1055 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
927 clkc_data->hw_onecell_data); 1056 &axg_hw_onecell_data);
928} 1057}
929 1058
930static struct platform_driver axg_driver = { 1059static struct platform_driver axg_driver = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index ce0bafdb6b28..b421df6a7ea0 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -117,8 +117,18 @@
117#define CLKID_SD_EMMC_B_CLK0_DIV 62 117#define CLKID_SD_EMMC_B_CLK0_DIV 62
118#define CLKID_SD_EMMC_C_CLK0_SEL 63 118#define CLKID_SD_EMMC_C_CLK0_SEL 63
119#define CLKID_SD_EMMC_C_CLK0_DIV 64 119#define CLKID_SD_EMMC_C_CLK0_DIV 64
120#define CLKID_MPLL0_DIV 65
121#define CLKID_MPLL1_DIV 66
122#define CLKID_MPLL2_DIV 67
123#define CLKID_MPLL3_DIV 68
124#define CLKID_MPLL_PREDIV 70
125#define CLKID_FCLK_DIV2_DIV 71
126#define CLKID_FCLK_DIV3_DIV 72
127#define CLKID_FCLK_DIV4_DIV 73
128#define CLKID_FCLK_DIV5_DIV 74
129#define CLKID_FCLK_DIV7_DIV 75
120 130
121#define NR_CLKS 65 131#define NR_CLKS 76
122 132
123/* include the CLKIDs that have been made part of the DT binding */ 133/* include the CLKIDs that have been made part of the DT binding */
124#include <dt-bindings/clock/axg-clkc.h> 134#include <dt-bindings/clock/axg-clkc.h>
diff --git a/drivers/clk/meson/clk-audio-divider.c b/drivers/clk/meson/clk-audio-divider.c
index 6c07db06642d..f7ab5b1db342 100644
--- a/drivers/clk/meson/clk-audio-divider.c
+++ b/drivers/clk/meson/clk-audio-divider.c
@@ -28,8 +28,11 @@
28#include <linux/clk-provider.h> 28#include <linux/clk-provider.h>
29#include "clkc.h" 29#include "clkc.h"
30 30
31#define to_meson_clk_audio_divider(_hw) container_of(_hw, \ 31static inline struct meson_clk_audio_div_data *
32 struct meson_clk_audio_divider, hw) 32meson_clk_audio_div_data(struct clk_regmap *clk)
33{
34 return (struct meson_clk_audio_div_data *)clk->data;
35}
33 36
34static int _div_round(unsigned long parent_rate, unsigned long rate, 37static int _div_round(unsigned long parent_rate, unsigned long rate,
35 unsigned long flags) 38 unsigned long flags)
@@ -45,15 +48,9 @@ static int _get_val(unsigned long parent_rate, unsigned long rate)
45 return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; 48 return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
46} 49}
47 50
48static int _valid_divider(struct clk_hw *hw, int divider) 51static int _valid_divider(unsigned int width, int divider)
49{ 52{
50 struct meson_clk_audio_divider *adiv = 53 int max_divider = 1 << width;
51 to_meson_clk_audio_divider(hw);
52 int max_divider;
53 u8 width;
54
55 width = adiv->div.width;
56 max_divider = 1 << width;
57 54
58 return clamp(divider, 1, max_divider); 55 return clamp(divider, 1, max_divider);
59} 56}
@@ -61,14 +58,11 @@ static int _valid_divider(struct clk_hw *hw, int divider)
61static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, 58static unsigned long audio_divider_recalc_rate(struct clk_hw *hw,
62 unsigned long parent_rate) 59 unsigned long parent_rate)
63{ 60{
64 struct meson_clk_audio_divider *adiv = 61 struct clk_regmap *clk = to_clk_regmap(hw);
65 to_meson_clk_audio_divider(hw); 62 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
66 struct parm *p; 63 unsigned long divider;
67 unsigned long reg, divider;
68 64
69 p = &adiv->div; 65 divider = meson_parm_read(clk->map, &adiv->div);
70 reg = readl(adiv->base + p->reg_off);
71 divider = PARM_GET(p->width, p->shift, reg) + 1;
72 66
73 return DIV_ROUND_UP_ULL((u64)parent_rate, divider); 67 return DIV_ROUND_UP_ULL((u64)parent_rate, divider);
74} 68}
@@ -77,14 +71,14 @@ static long audio_divider_round_rate(struct clk_hw *hw,
77 unsigned long rate, 71 unsigned long rate,
78 unsigned long *parent_rate) 72 unsigned long *parent_rate)
79{ 73{
80 struct meson_clk_audio_divider *adiv = 74 struct clk_regmap *clk = to_clk_regmap(hw);
81 to_meson_clk_audio_divider(hw); 75 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
82 unsigned long max_prate; 76 unsigned long max_prate;
83 int divider; 77 int divider;
84 78
85 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 79 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
86 divider = _div_round(*parent_rate, rate, adiv->flags); 80 divider = _div_round(*parent_rate, rate, adiv->flags);
87 divider = _valid_divider(hw, divider); 81 divider = _valid_divider(adiv->div.width, divider);
88 return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); 82 return DIV_ROUND_UP_ULL((u64)*parent_rate, divider);
89 } 83 }
90 84
@@ -93,7 +87,7 @@ static long audio_divider_round_rate(struct clk_hw *hw,
93 87
94 /* Get the corresponding rounded down divider */ 88 /* Get the corresponding rounded down divider */
95 divider = max_prate / rate; 89 divider = max_prate / rate;
96 divider = _valid_divider(hw, divider); 90 divider = _valid_divider(adiv->div.width, divider);
97 91
98 /* Get actual rate of the parent */ 92 /* Get actual rate of the parent */
99 *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 93 *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
@@ -106,28 +100,11 @@ static int audio_divider_set_rate(struct clk_hw *hw,
106 unsigned long rate, 100 unsigned long rate,
107 unsigned long parent_rate) 101 unsigned long parent_rate)
108{ 102{
109 struct meson_clk_audio_divider *adiv = 103 struct clk_regmap *clk = to_clk_regmap(hw);
110 to_meson_clk_audio_divider(hw); 104 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
111 struct parm *p; 105 int val = _get_val(parent_rate, rate);
112 unsigned long reg, flags = 0; 106
113 int val; 107 meson_parm_write(clk->map, &adiv->div, val);
114
115 val = _get_val(parent_rate, rate);
116
117 if (adiv->lock)
118 spin_lock_irqsave(adiv->lock, flags);
119 else
120 __acquire(adiv->lock);
121
122 p = &adiv->div;
123 reg = readl(adiv->base + p->reg_off);
124 reg = PARM_SET(p->width, p->shift, reg, val);
125 writel(reg, adiv->base + p->reg_off);
126
127 if (adiv->lock)
128 spin_unlock_irqrestore(adiv->lock, flags);
129 else
130 __release(adiv->lock);
131 108
132 return 0; 109 return 0;
133} 110}
diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
deleted file mode 100644
index f8b2b7efd016..000000000000
--- a/drivers/clk/meson/clk-cpu.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * CPU clock path:
20 *
21 * +-[/N]-----|3|
22 * MUX2 +--[/3]-+----------|2| MUX1
23 * [sys_pll]---|1| |--[/2]------------|1|-|1|
24 * | |---+------------------|0| | |----- [a5_clk]
25 * +--|0| | |
26 * [xtal]---+-------------------------------|0|
27 *
28 *
29 *
30 */
31
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/io.h>
35#include <linux/module.h>
36#include <linux/of_address.h>
37#include <linux/slab.h>
38#include <linux/clk.h>
39#include <linux/clk-provider.h>
40
41#define MESON_CPU_CLK_CNTL1 0x00
42#define MESON_CPU_CLK_CNTL 0x40
43
44#define MESON_CPU_CLK_MUX1 BIT(7)
45#define MESON_CPU_CLK_MUX2 BIT(0)
46
47#define MESON_N_WIDTH 9
48#define MESON_N_SHIFT 20
49#define MESON_SEL_WIDTH 2
50#define MESON_SEL_SHIFT 2
51
52#include "clkc.h"
53
54#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
55#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
56
57static long meson_clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59{
60 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
61
62 return divider_round_rate(hw, rate, prate, clk_cpu->div_table,
63 MESON_N_WIDTH, CLK_DIVIDER_ROUND_CLOSEST);
64}
65
66static int meson_clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
67 unsigned long parent_rate)
68{
69 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
70 unsigned int div, sel, N = 0;
71 u32 reg;
72
73 div = DIV_ROUND_UP(parent_rate, rate);
74
75 if (div <= 3) {
76 sel = div - 1;
77 } else {
78 sel = 3;
79 N = div / 2;
80 }
81
82 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
83 reg = PARM_SET(MESON_N_WIDTH, MESON_N_SHIFT, reg, N);
84 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
85
86 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
87 reg = PARM_SET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg, sel);
88 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
89
90 return 0;
91}
92
93static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
94 unsigned long parent_rate)
95{
96 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
97 unsigned int N, sel;
98 unsigned int div = 1;
99 u32 reg;
100
101 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
102 N = PARM_GET(MESON_N_WIDTH, MESON_N_SHIFT, reg);
103
104 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
105 sel = PARM_GET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg);
106
107 if (sel < 3)
108 div = sel + 1;
109 else
110 div = 2 * N;
111
112 return parent_rate / div;
113}
114
115/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
116static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
117 struct clk_notifier_data *ndata)
118{
119 u32 cpu_clk_cntl;
120
121 /* switch MUX1 to xtal */
122 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
123 + MESON_CPU_CLK_CNTL);
124 cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
125 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
126 + MESON_CPU_CLK_CNTL);
127 udelay(100);
128
129 /* switch MUX2 to sys-pll */
130 cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
131 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
132 + MESON_CPU_CLK_CNTL);
133
134 return 0;
135}
136
137/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
138static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
139 struct clk_notifier_data *ndata)
140{
141 u32 cpu_clk_cntl;
142
143 /* switch MUX1 to divisors' output */
144 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
145 + MESON_CPU_CLK_CNTL);
146 cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
147 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
148 + MESON_CPU_CLK_CNTL);
149 udelay(100);
150
151 return 0;
152}
153
154/*
155 * This clock notifier is called when the frequency of the of the parent
156 * PLL clock is to be changed. We use the xtal input as temporary parent
157 * while the PLL frequency is stabilized.
158 */
159int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
160 unsigned long event, void *data)
161{
162 struct clk_notifier_data *ndata = data;
163 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
164 int ret = 0;
165
166 if (event == PRE_RATE_CHANGE)
167 ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
168 else if (event == POST_RATE_CHANGE)
169 ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
170
171 return notifier_from_errno(ret);
172}
173
174const struct clk_ops meson_clk_cpu_ops = {
175 .recalc_rate = meson_clk_cpu_recalc_rate,
176 .round_rate = meson_clk_cpu_round_rate,
177 .set_rate = meson_clk_cpu_set_rate,
178};
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 5144360e2c80..0df1227b65b3 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -68,11 +68,15 @@
68#define N2_MIN 4 68#define N2_MIN 4
69#define N2_MAX 511 69#define N2_MAX 511
70 70
71#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw) 71static inline struct meson_clk_mpll_data *
72meson_clk_mpll_data(struct clk_regmap *clk)
73{
74 return (struct meson_clk_mpll_data *)clk->data;
75}
72 76
73static long rate_from_params(unsigned long parent_rate, 77static long rate_from_params(unsigned long parent_rate,
74 unsigned long sdm, 78 unsigned int sdm,
75 unsigned long n2) 79 unsigned int n2)
76{ 80{
77 unsigned long divisor = (SDM_DEN * n2) + sdm; 81 unsigned long divisor = (SDM_DEN * n2) + sdm;
78 82
@@ -84,8 +88,8 @@ static long rate_from_params(unsigned long parent_rate,
84 88
85static void params_from_rate(unsigned long requested_rate, 89static void params_from_rate(unsigned long requested_rate,
86 unsigned long parent_rate, 90 unsigned long parent_rate,
87 unsigned long *sdm, 91 unsigned int *sdm,
88 unsigned long *n2) 92 unsigned int *n2)
89{ 93{
90 uint64_t div = parent_rate; 94 uint64_t div = parent_rate;
91 unsigned long rem = do_div(div, requested_rate); 95 unsigned long rem = do_div(div, requested_rate);
@@ -105,31 +109,23 @@ static void params_from_rate(unsigned long requested_rate,
105static unsigned long mpll_recalc_rate(struct clk_hw *hw, 109static unsigned long mpll_recalc_rate(struct clk_hw *hw,
106 unsigned long parent_rate) 110 unsigned long parent_rate)
107{ 111{
108 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 112 struct clk_regmap *clk = to_clk_regmap(hw);
109 struct parm *p; 113 struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
110 unsigned long reg, sdm, n2; 114 unsigned int sdm, n2;
111 long rate; 115 long rate;
112 116
113 p = &mpll->sdm; 117 sdm = meson_parm_read(clk->map, &mpll->sdm);
114 reg = readl(mpll->base + p->reg_off); 118 n2 = meson_parm_read(clk->map, &mpll->n2);
115 sdm = PARM_GET(p->width, p->shift, reg);
116
117 p = &mpll->n2;
118 reg = readl(mpll->base + p->reg_off);
119 n2 = PARM_GET(p->width, p->shift, reg);
120 119
121 rate = rate_from_params(parent_rate, sdm, n2); 120 rate = rate_from_params(parent_rate, sdm, n2);
122 if (rate < 0) 121 return rate < 0 ? 0 : rate;
123 return 0;
124
125 return rate;
126} 122}
127 123
128static long mpll_round_rate(struct clk_hw *hw, 124static long mpll_round_rate(struct clk_hw *hw,
129 unsigned long rate, 125 unsigned long rate,
130 unsigned long *parent_rate) 126 unsigned long *parent_rate)
131{ 127{
132 unsigned long sdm, n2; 128 unsigned int sdm, n2;
133 129
134 params_from_rate(rate, *parent_rate, &sdm, &n2); 130 params_from_rate(rate, *parent_rate, &sdm, &n2);
135 return rate_from_params(*parent_rate, sdm, n2); 131 return rate_from_params(*parent_rate, sdm, n2);
@@ -139,9 +135,9 @@ static int mpll_set_rate(struct clk_hw *hw,
139 unsigned long rate, 135 unsigned long rate,
140 unsigned long parent_rate) 136 unsigned long parent_rate)
141{ 137{
142 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 138 struct clk_regmap *clk = to_clk_regmap(hw);
143 struct parm *p; 139 struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
144 unsigned long reg, sdm, n2; 140 unsigned int sdm, n2;
145 unsigned long flags = 0; 141 unsigned long flags = 0;
146 142
147 params_from_rate(rate, parent_rate, &sdm, &n2); 143 params_from_rate(rate, parent_rate, &sdm, &n2);
@@ -151,97 +147,36 @@ static int mpll_set_rate(struct clk_hw *hw,
151 else 147 else
152 __acquire(mpll->lock); 148 __acquire(mpll->lock);
153 149
154 p = &mpll->sdm; 150 /* Enable and set the fractional part */
155 reg = readl(mpll->base + p->reg_off); 151 meson_parm_write(clk->map, &mpll->sdm, sdm);
156 reg = PARM_SET(p->width, p->shift, reg, sdm); 152 meson_parm_write(clk->map, &mpll->sdm_en, 1);
157 writel(reg, mpll->base + p->reg_off);
158
159 p = &mpll->sdm_en;
160 reg = readl(mpll->base + p->reg_off);
161 reg = PARM_SET(p->width, p->shift, reg, 1);
162 writel(reg, mpll->base + p->reg_off);
163
164 p = &mpll->ssen;
165 if (p->width != 0) {
166 reg = readl(mpll->base + p->reg_off);
167 reg = PARM_SET(p->width, p->shift, reg, 1);
168 writel(reg, mpll->base + p->reg_off);
169 }
170
171 p = &mpll->n2;
172 reg = readl(mpll->base + p->reg_off);
173 reg = PARM_SET(p->width, p->shift, reg, n2);
174 writel(reg, mpll->base + p->reg_off);
175
176 if (mpll->lock)
177 spin_unlock_irqrestore(mpll->lock, flags);
178 else
179 __release(mpll->lock);
180
181 return 0;
182}
183 153
184static void mpll_enable_core(struct clk_hw *hw, int enable) 154 /* Set additional fractional part enable if required */
185{ 155 if (MESON_PARM_APPLICABLE(&mpll->ssen))
186 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 156 meson_parm_write(clk->map, &mpll->ssen, 1);
187 struct parm *p;
188 unsigned long reg;
189 unsigned long flags = 0;
190 157
191 if (mpll->lock) 158 /* Set the integer divider part */
192 spin_lock_irqsave(mpll->lock, flags); 159 meson_parm_write(clk->map, &mpll->n2, n2);
193 else
194 __acquire(mpll->lock);
195 160
196 p = &mpll->en; 161 /* Set the magic misc bit if required */
197 reg = readl(mpll->base + p->reg_off); 162 if (MESON_PARM_APPLICABLE(&mpll->misc))
198 reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0); 163 meson_parm_write(clk->map, &mpll->misc, 1);
199 writel(reg, mpll->base + p->reg_off);
200 164
201 if (mpll->lock) 165 if (mpll->lock)
202 spin_unlock_irqrestore(mpll->lock, flags); 166 spin_unlock_irqrestore(mpll->lock, flags);
203 else 167 else
204 __release(mpll->lock); 168 __release(mpll->lock);
205}
206
207
208static int mpll_enable(struct clk_hw *hw)
209{
210 mpll_enable_core(hw, 1);
211 169
212 return 0; 170 return 0;
213} 171}
214 172
215static void mpll_disable(struct clk_hw *hw)
216{
217 mpll_enable_core(hw, 0);
218}
219
220static int mpll_is_enabled(struct clk_hw *hw)
221{
222 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
223 struct parm *p;
224 unsigned long reg;
225 int en;
226
227 p = &mpll->en;
228 reg = readl(mpll->base + p->reg_off);
229 en = PARM_GET(p->width, p->shift, reg);
230
231 return en;
232}
233
234const struct clk_ops meson_clk_mpll_ro_ops = { 173const struct clk_ops meson_clk_mpll_ro_ops = {
235 .recalc_rate = mpll_recalc_rate, 174 .recalc_rate = mpll_recalc_rate,
236 .round_rate = mpll_round_rate, 175 .round_rate = mpll_round_rate,
237 .is_enabled = mpll_is_enabled,
238}; 176};
239 177
240const struct clk_ops meson_clk_mpll_ops = { 178const struct clk_ops meson_clk_mpll_ops = {
241 .recalc_rate = mpll_recalc_rate, 179 .recalc_rate = mpll_recalc_rate,
242 .round_rate = mpll_round_rate, 180 .round_rate = mpll_round_rate,
243 .set_rate = mpll_set_rate, 181 .set_rate = mpll_set_rate,
244 .enable = mpll_enable,
245 .disable = mpll_disable,
246 .is_enabled = mpll_is_enabled,
247}; 182};
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 01341553f50b..65a7bd903551 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -2,6 +2,9 @@
2 * Copyright (c) 2015 Endless Mobile, Inc. 2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com> 3 * Author: Carlo Caione <carlo@endlessm.com>
4 * 4 *
5 * Copyright (c) 2018 Baylibre, SAS.
6 * Author: Jerome Brunet <jbrunet@baylibre.com>
7 *
5 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License, 9 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation. 10 * version 2, as published by the Free Software Foundation.
@@ -27,13 +30,14 @@
27 * | | 30 * | |
28 * FREF VCO 31 * FREF VCO
29 * 32 *
30 * out = (in * M / N) >> OD 33 * out = in * (m + frac / frac_max) / (n << sum(ods))
31 */ 34 */
32 35
33#include <linux/clk-provider.h> 36#include <linux/clk-provider.h>
34#include <linux/delay.h> 37#include <linux/delay.h>
35#include <linux/err.h> 38#include <linux/err.h>
36#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/math64.h>
37#include <linux/module.h> 41#include <linux/module.h>
38#include <linux/of_address.h> 42#include <linux/of_address.h>
39#include <linux/slab.h> 43#include <linux/slab.h>
@@ -41,209 +45,213 @@
41 45
42#include "clkc.h" 46#include "clkc.h"
43 47
44#define MESON_PLL_RESET BIT(29) 48static inline struct meson_clk_pll_data *
45#define MESON_PLL_LOCK BIT(31) 49meson_clk_pll_data(struct clk_regmap *clk)
46
47#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
48
49static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
50 unsigned long parent_rate)
51{ 50{
52 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 51 return (struct meson_clk_pll_data *)clk->data;
53 struct parm *p;
54 unsigned long parent_rate_mhz = parent_rate / 1000000;
55 unsigned long rate_mhz;
56 u16 n, m, frac = 0, od, od2 = 0;
57 u32 reg;
58
59 p = &pll->n;
60 reg = readl(pll->base + p->reg_off);
61 n = PARM_GET(p->width, p->shift, reg);
62
63 p = &pll->m;
64 reg = readl(pll->base + p->reg_off);
65 m = PARM_GET(p->width, p->shift, reg);
66
67 p = &pll->od;
68 reg = readl(pll->base + p->reg_off);
69 od = PARM_GET(p->width, p->shift, reg);
70
71 p = &pll->od2;
72 if (p->width) {
73 reg = readl(pll->base + p->reg_off);
74 od2 = PARM_GET(p->width, p->shift, reg);
75 }
76
77 p = &pll->frac;
78 if (p->width) {
79 reg = readl(pll->base + p->reg_off);
80 frac = PARM_GET(p->width, p->shift, reg);
81 rate_mhz = (parent_rate_mhz * m + \
82 (parent_rate_mhz * frac >> 12)) * 2 / n;
83 rate_mhz = rate_mhz >> od >> od2;
84 } else
85 rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;
86
87 return rate_mhz * 1000000;
88} 52}
89 53
90static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 54static unsigned long __pll_params_to_rate(unsigned long parent_rate,
91 unsigned long *parent_rate) 55 const struct pll_rate_table *pllt,
56 u16 frac,
57 struct meson_clk_pll_data *pll)
92{ 58{
93 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 59 u64 rate = (u64)parent_rate * pllt->m;
94 const struct pll_rate_table *rate_table = pll->rate_table; 60 unsigned int od = pllt->od + pllt->od2 + pllt->od3;
95 int i;
96 61
97 for (i = 0; i < pll->rate_count; i++) { 62 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) {
98 if (rate <= rate_table[i].rate) 63 u64 frac_rate = (u64)parent_rate * frac;
99 return rate_table[i].rate; 64
65 rate += DIV_ROUND_UP_ULL(frac_rate,
66 (1 << pll->frac.width));
100 } 67 }
101 68
102 /* else return the smallest value */ 69 return DIV_ROUND_UP_ULL(rate, pllt->n << od);
103 return rate_table[0].rate;
104} 70}
105 71
106static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll, 72static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
107 unsigned long rate) 73 unsigned long parent_rate)
108{ 74{
109 const struct pll_rate_table *rate_table = pll->rate_table; 75 struct clk_regmap *clk = to_clk_regmap(hw);
110 int i; 76 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
77 struct pll_rate_table pllt;
78 u16 frac;
111 79
112 for (i = 0; i < pll->rate_count; i++) { 80 pllt.n = meson_parm_read(clk->map, &pll->n);
113 if (rate == rate_table[i].rate) 81 pllt.m = meson_parm_read(clk->map, &pll->m);
114 return &rate_table[i]; 82 pllt.od = meson_parm_read(clk->map, &pll->od);
115 } 83
116 return NULL; 84 pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ?
85 meson_parm_read(clk->map, &pll->od2) :
86 0;
87
88 pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ?
89 meson_parm_read(clk->map, &pll->od3) :
90 0;
91
92 frac = MESON_PARM_APPLICABLE(&pll->frac) ?
93 meson_parm_read(clk->map, &pll->frac) :
94 0;
95
96 return __pll_params_to_rate(parent_rate, &pllt, frac, pll);
117} 97}
118 98
119/* Specific wait loop for GXL/GXM GP0 PLL */ 99static u16 __pll_params_with_frac(unsigned long rate,
120static int meson_clk_pll_wait_lock_reset(struct meson_clk_pll *pll, 100 unsigned long parent_rate,
121 struct parm *p_n) 101 const struct pll_rate_table *pllt,
102 struct meson_clk_pll_data *pll)
122{ 103{
123 int delay = 100; 104 u16 frac_max = (1 << pll->frac.width);
124 u32 reg; 105 u64 val = (u64)rate * pllt->n;
125 106
126 while (delay > 0) { 107 val <<= pllt->od + pllt->od2 + pllt->od3;
127 reg = readl(pll->base + p_n->reg_off);
128 writel(reg | MESON_PLL_RESET, pll->base + p_n->reg_off);
129 udelay(10);
130 writel(reg & ~MESON_PLL_RESET, pll->base + p_n->reg_off);
131 108
132 /* This delay comes from AMLogic tree clk-gp0-gxl driver */ 109 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
133 mdelay(1); 110 val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
111 else
112 val = div_u64(val * frac_max, parent_rate);
134 113
135 reg = readl(pll->base + p_n->reg_off); 114 val -= pllt->m * frac_max;
136 if (reg & MESON_PLL_LOCK) 115
137 return 0; 116 return min((u16)val, (u16)(frac_max - 1));
138 delay--; 117}
118
119static const struct pll_rate_table *
120meson_clk_get_pll_settings(unsigned long rate,
121 struct meson_clk_pll_data *pll)
122{
123 const struct pll_rate_table *table = pll->table;
124 unsigned int i = 0;
125
126 if (!table)
127 return NULL;
128
129 /* Find the first table element exceeding rate */
130 while (table[i].rate && table[i].rate <= rate)
131 i++;
132
133 if (i != 0) {
134 if (MESON_PARM_APPLICABLE(&pll->frac) ||
135 !(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
136 (abs(rate - table[i - 1].rate) <
137 abs(rate - table[i].rate)))
138 i--;
139 } 139 }
140 return -ETIMEDOUT; 140
141 return (struct pll_rate_table *)&table[i];
141} 142}
142 143
143static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, 144static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
144 struct parm *p_n) 145 unsigned long *parent_rate)
145{ 146{
146 int delay = 24000000; 147 struct clk_regmap *clk = to_clk_regmap(hw);
147 u32 reg; 148 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
149 const struct pll_rate_table *pllt =
150 meson_clk_get_pll_settings(rate, pll);
151 u16 frac;
152
153 if (!pllt)
154 return meson_clk_pll_recalc_rate(hw, *parent_rate);
155
156 if (!MESON_PARM_APPLICABLE(&pll->frac)
157 || rate == pllt->rate)
158 return pllt->rate;
159
160 /*
161 * The rate provided by the setting is not an exact match, let's
162 * try to improve the result using the fractional parameter
163 */
164 frac = __pll_params_with_frac(rate, *parent_rate, pllt, pll);
165
166 return __pll_params_to_rate(*parent_rate, pllt, frac, pll);
167}
148 168
149 while (delay > 0) { 169static int meson_clk_pll_wait_lock(struct clk_hw *hw)
150 reg = readl(pll->base + p_n->reg_off); 170{
171 struct clk_regmap *clk = to_clk_regmap(hw);
172 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
173 int delay = 24000000;
151 174
152 if (reg & MESON_PLL_LOCK) 175 do {
176 /* Is the clock locked now ? */
177 if (meson_parm_read(clk->map, &pll->l))
153 return 0; 178 return 0;
179
154 delay--; 180 delay--;
155 } 181 } while (delay > 0);
182
156 return -ETIMEDOUT; 183 return -ETIMEDOUT;
157} 184}
158 185
159static void meson_clk_pll_init_params(struct meson_clk_pll *pll) 186static void meson_clk_pll_init(struct clk_hw *hw)
160{ 187{
161 int i; 188 struct clk_regmap *clk = to_clk_regmap(hw);
162 189 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
163 for (i = 0 ; i < pll->params.params_count ; ++i) 190
164 writel(pll->params.params_table[i].value, 191 if (pll->init_count) {
165 pll->base + pll->params.params_table[i].reg_off); 192 meson_parm_write(clk->map, &pll->rst, 1);
193 regmap_multi_reg_write(clk->map, pll->init_regs,
194 pll->init_count);
195 meson_parm_write(clk->map, &pll->rst, 0);
196 }
166} 197}
167 198
168static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 199static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
169 unsigned long parent_rate) 200 unsigned long parent_rate)
170{ 201{
171 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 202 struct clk_regmap *clk = to_clk_regmap(hw);
172 struct parm *p; 203 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
173 const struct pll_rate_table *rate_set; 204 const struct pll_rate_table *pllt;
174 unsigned long old_rate; 205 unsigned long old_rate;
175 int ret = 0; 206 u16 frac = 0;
176 u32 reg;
177 207
178 if (parent_rate == 0 || rate == 0) 208 if (parent_rate == 0 || rate == 0)
179 return -EINVAL; 209 return -EINVAL;
180 210
181 old_rate = rate; 211 old_rate = rate;
182 212
183 rate_set = meson_clk_get_pll_settings(pll, rate); 213 pllt = meson_clk_get_pll_settings(rate, pll);
184 if (!rate_set) 214 if (!pllt)
185 return -EINVAL; 215 return -EINVAL;
186 216
187 /* Initialize the PLL in a clean state if specified */ 217 /* Put the pll in reset to write the params */
188 if (pll->params.params_count) 218 meson_parm_write(clk->map, &pll->rst, 1);
189 meson_clk_pll_init_params(pll);
190
191 /* PLL reset */
192 p = &pll->n;
193 reg = readl(pll->base + p->reg_off);
194 /* If no_init_reset is provided, avoid resetting at this point */
195 if (!pll->params.no_init_reset)
196 writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
197
198 reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
199 writel(reg, pll->base + p->reg_off);
200
201 p = &pll->m;
202 reg = readl(pll->base + p->reg_off);
203 reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
204 writel(reg, pll->base + p->reg_off);
205
206 p = &pll->od;
207 reg = readl(pll->base + p->reg_off);
208 reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
209 writel(reg, pll->base + p->reg_off);
210
211 p = &pll->od2;
212 if (p->width) {
213 reg = readl(pll->base + p->reg_off);
214 reg = PARM_SET(p->width, p->shift, reg, rate_set->od2);
215 writel(reg, pll->base + p->reg_off);
216 }
217 219
218 p = &pll->frac; 220 meson_parm_write(clk->map, &pll->n, pllt->n);
219 if (p->width) { 221 meson_parm_write(clk->map, &pll->m, pllt->m);
220 reg = readl(pll->base + p->reg_off); 222 meson_parm_write(clk->map, &pll->od, pllt->od);
221 reg = PARM_SET(p->width, p->shift, reg, rate_set->frac); 223
222 writel(reg, pll->base + p->reg_off); 224 if (MESON_PARM_APPLICABLE(&pll->od2))
223 } 225 meson_parm_write(clk->map, &pll->od2, pllt->od2);
226
227 if (MESON_PARM_APPLICABLE(&pll->od3))
228 meson_parm_write(clk->map, &pll->od3, pllt->od3);
224 229
225 p = &pll->n; 230 if (MESON_PARM_APPLICABLE(&pll->frac)) {
226 /* If clear_reset_for_lock is provided, remove the reset bit here */ 231 frac = __pll_params_with_frac(rate, parent_rate, pllt, pll);
227 if (pll->params.clear_reset_for_lock) { 232 meson_parm_write(clk->map, &pll->frac, frac);
228 reg = readl(pll->base + p->reg_off);
229 writel(reg & ~MESON_PLL_RESET, pll->base + p->reg_off);
230 } 233 }
231 234
232 /* If reset_lock_loop, use a special loop including resetting */ 235 /* make sure the reset is cleared at this point */
233 if (pll->params.reset_lock_loop) 236 meson_parm_write(clk->map, &pll->rst, 0);
234 ret = meson_clk_pll_wait_lock_reset(pll, p); 237
235 else 238 if (meson_clk_pll_wait_lock(hw)) {
236 ret = meson_clk_pll_wait_lock(pll, p);
237 if (ret) {
238 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", 239 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
239 __func__, old_rate); 240 __func__, old_rate);
241 /*
242 * FIXME: Do we really need/want this HACK ?
243 * It looks unsafe. what happens if the clock gets into a
244 * broken state and we can't lock back on the old_rate ? Looks
245 * like an infinite recursion is possible
246 */
240 meson_clk_pll_set_rate(hw, old_rate, parent_rate); 247 meson_clk_pll_set_rate(hw, old_rate, parent_rate);
241 } 248 }
242 249
243 return ret; 250 return 0;
244} 251}
245 252
246const struct clk_ops meson_clk_pll_ops = { 253const struct clk_ops meson_clk_pll_ops = {
254 .init = meson_clk_pll_init,
247 .recalc_rate = meson_clk_pll_recalc_rate, 255 .recalc_rate = meson_clk_pll_recalc_rate,
248 .round_rate = meson_clk_pll_round_rate, 256 .round_rate = meson_clk_pll_round_rate,
249 .set_rate = meson_clk_pll_set_rate, 257 .set_rate = meson_clk_pll_set_rate,
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
new file mode 100644
index 000000000000..3645fdb62343
--- /dev/null
+++ b/drivers/clk/meson/clk-regmap.c
@@ -0,0 +1,166 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 BayLibre, SAS.
3// Author: Jerome Brunet <jbrunet@baylibre.com>
4
5#include "clk-regmap.h"
6
7static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable)
8{
9 struct clk_regmap *clk = to_clk_regmap(hw);
10 struct clk_regmap_gate_data *gate = clk_get_regmap_gate_data(clk);
11 int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
12
13 set ^= enable;
14
15 return regmap_update_bits(clk->map, gate->offset, BIT(gate->bit_idx),
16 set ? BIT(gate->bit_idx) : 0);
17}
18
19static int clk_regmap_gate_enable(struct clk_hw *hw)
20{
21 return clk_regmap_gate_endisable(hw, 1);
22}
23
24static void clk_regmap_gate_disable(struct clk_hw *hw)
25{
26 clk_regmap_gate_endisable(hw, 0);
27}
28
29static int clk_regmap_gate_is_enabled(struct clk_hw *hw)
30{
31 struct clk_regmap *clk = to_clk_regmap(hw);
32 struct clk_regmap_gate_data *gate = clk_get_regmap_gate_data(clk);
33 unsigned int val;
34
35 regmap_read(clk->map, gate->offset, &val);
36 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
37 val ^= BIT(gate->bit_idx);
38
39 val &= BIT(gate->bit_idx);
40
41 return val ? 1 : 0;
42}
43
44const struct clk_ops clk_regmap_gate_ops = {
45 .enable = clk_regmap_gate_enable,
46 .disable = clk_regmap_gate_disable,
47 .is_enabled = clk_regmap_gate_is_enabled,
48};
49EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
50
51static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw,
52 unsigned long prate)
53{
54 struct clk_regmap *clk = to_clk_regmap(hw);
55 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
56 unsigned int val;
57 int ret;
58
59 ret = regmap_read(clk->map, div->offset, &val);
60 if (ret)
61 /* Gives a hint that something is wrong */
62 return 0;
63
64 val >>= div->shift;
65 val &= clk_div_mask(div->width);
66 return divider_recalc_rate(hw, prate, val, div->table, div->flags,
67 div->width);
68}
69
70static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate,
71 unsigned long *prate)
72{
73 struct clk_regmap *clk = to_clk_regmap(hw);
74 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
75 unsigned int val;
76 int ret;
77
78 /* if read only, just return current value */
79 if (div->flags & CLK_DIVIDER_READ_ONLY) {
80 ret = regmap_read(clk->map, div->offset, &val);
81 if (ret)
82 /* Gives a hint that something is wrong */
83 return 0;
84
85 val >>= div->shift;
86 val &= clk_div_mask(div->width);
87
88 return divider_ro_round_rate(hw, rate, prate, div->table,
89 div->width, div->flags, val);
90 }
91
92 return divider_round_rate(hw, rate, prate, div->table, div->width,
93 div->flags);
94}
95
96static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate,
97 unsigned long parent_rate)
98{
99 struct clk_regmap *clk = to_clk_regmap(hw);
100 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
101 unsigned int val;
102 int ret;
103
104 ret = divider_get_val(rate, parent_rate, div->table, div->width,
105 div->flags);
106 if (ret < 0)
107 return ret;
108
109 val = (unsigned int)ret << div->shift;
110 return regmap_update_bits(clk->map, div->offset,
111 clk_div_mask(div->width) << div->shift, val);
112};
113
114/* Would prefer clk_regmap_div_ro_ops but clashes with qcom */
115
116const struct clk_ops clk_regmap_divider_ops = {
117 .recalc_rate = clk_regmap_div_recalc_rate,
118 .round_rate = clk_regmap_div_round_rate,
119 .set_rate = clk_regmap_div_set_rate,
120};
121EXPORT_SYMBOL_GPL(clk_regmap_divider_ops);
122
123const struct clk_ops clk_regmap_divider_ro_ops = {
124 .recalc_rate = clk_regmap_div_recalc_rate,
125 .round_rate = clk_regmap_div_round_rate,
126};
127EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops);
128
129static u8 clk_regmap_mux_get_parent(struct clk_hw *hw)
130{
131 struct clk_regmap *clk = to_clk_regmap(hw);
132 struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk);
133 unsigned int val;
134 int ret;
135
136 ret = regmap_read(clk->map, mux->offset, &val);
137 if (ret)
138 return ret;
139
140 val >>= mux->shift;
141 val &= mux->mask;
142 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
143}
144
145static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index)
146{
147 struct clk_regmap *clk = to_clk_regmap(hw);
148 struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk);
149 unsigned int val = clk_mux_index_to_val(mux->table, mux->flags, index);
150
151 return regmap_update_bits(clk->map, mux->offset,
152 mux->mask << mux->shift,
153 val << mux->shift);
154}
155
156const struct clk_ops clk_regmap_mux_ops = {
157 .get_parent = clk_regmap_mux_get_parent,
158 .set_parent = clk_regmap_mux_set_parent,
159 .determine_rate = __clk_mux_determine_rate,
160};
161EXPORT_SYMBOL_GPL(clk_regmap_mux_ops);
162
163const struct clk_ops clk_regmap_mux_ro_ops = {
164 .get_parent = clk_regmap_mux_get_parent,
165};
166EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops);
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
new file mode 100644
index 000000000000..627c888026d7
--- /dev/null
+++ b/drivers/clk/meson/clk-regmap.h
@@ -0,0 +1,111 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 BayLibre, SAS.
3// Author: Jerome Brunet <jbrunet@baylibre.com>
4
5#ifndef __CLK_REGMAP_H
6#define __CLK_REGMAP_H
7
8#include <linux/clk-provider.h>
9#include <linux/regmap.h>
10
11/**
12 * struct clk_regmap - regmap backed clock
13 *
14 * @hw: handle between common and hardware-specific interfaces
15 * @map: pointer to the regmap structure controlling the clock
16 * @data: data specific to the clock type
17 *
18 * Clock which is controlled by regmap backed registers. The actual type of
19 * of the clock is controlled by the clock_ops and data.
20 */
21struct clk_regmap {
22 struct clk_hw hw;
23 struct regmap *map;
24 void *data;
25};
26
27#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
28
29/**
30 * struct clk_regmap_gate_data - regmap backed gate specific data
31 *
32 * @offset: offset of the register controlling gate
33 * @bit_idx: single bit controlling gate
34 * @flags: hardware-specific flags
35 *
36 * Flags:
37 * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
38 */
39struct clk_regmap_gate_data {
40 unsigned int offset;
41 u8 bit_idx;
42 u8 flags;
43};
44
45static inline struct clk_regmap_gate_data *
46clk_get_regmap_gate_data(struct clk_regmap *clk)
47{
48 return (struct clk_regmap_gate_data *)clk->data;
49}
50
51extern const struct clk_ops clk_regmap_gate_ops;
52
53/**
54 * struct clk_regmap_div_data - regmap backed adjustable divider specific data
55 *
56 * @offset: offset of the register controlling the divider
57 * @shift: shift to the divider bit field
58 * @width: width of the divider bit field
59 * @table: array of value/divider pairs, last entry should have div = 0
60 *
61 * Flags:
62 * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
63 */
64struct clk_regmap_div_data {
65 unsigned int offset;
66 u8 shift;
67 u8 width;
68 u8 flags;
69 const struct clk_div_table *table;
70};
71
72static inline struct clk_regmap_div_data *
73clk_get_regmap_div_data(struct clk_regmap *clk)
74{
75 return (struct clk_regmap_div_data *)clk->data;
76}
77
78extern const struct clk_ops clk_regmap_divider_ops;
79extern const struct clk_ops clk_regmap_divider_ro_ops;
80
81/**
82 * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
83 *
84 * @hw: handle between common and hardware-specific interfaces
85 * @offset: offset of theregister controlling multiplexer
86 * @table: array of parent indexed register values
87 * @shift: shift to multiplexer bit field
88 * @mask: mask of mutliplexer bit field
89 * @flags: hardware-specific flags
90 *
91 * Flags:
92 * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
93 */
94struct clk_regmap_mux_data {
95 unsigned int offset;
96 u32 *table;
97 u32 mask;
98 u8 shift;
99 u8 flags;
100};
101
102static inline struct clk_regmap_mux_data *
103clk_get_regmap_mux_data(struct clk_regmap *clk)
104{
105 return (struct clk_regmap_mux_data *)clk->data;
106}
107
108extern const struct clk_ops clk_regmap_mux_ops;
109extern const struct clk_ops clk_regmap_mux_ro_ops;
110
111#endif /* __CLK_REGMAP_H */
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index c2ff0520ce53..8fe73c4edca8 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -18,6 +18,9 @@
18#ifndef __CLKC_H 18#ifndef __CLKC_H
19#define __CLKC_H 19#define __CLKC_H
20 20
21#include <linux/clk-provider.h>
22#include "clk-regmap.h"
23
21#define PMASK(width) GENMASK(width - 1, 0) 24#define PMASK(width) GENMASK(width - 1, 0)
22#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift) 25#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
23#define CLRPMASK(width, shift) (~SETPMASK(width, shift)) 26#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
@@ -35,13 +38,29 @@ struct parm {
35 u8 width; 38 u8 width;
36}; 39};
37 40
41static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
42{
43 unsigned int val;
44
45 regmap_read(map, p->reg_off, &val);
46 return PARM_GET(p->width, p->shift, val);
47}
48
49static inline void meson_parm_write(struct regmap *map, struct parm *p,
50 unsigned int val)
51{
52 regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
53 val << p->shift);
54}
55
56
38struct pll_rate_table { 57struct pll_rate_table {
39 unsigned long rate; 58 unsigned long rate;
40 u16 m; 59 u16 m;
41 u16 n; 60 u16 n;
42 u16 od; 61 u16 od;
43 u16 od2; 62 u16 od2;
44 u16 frac; 63 u16 od3;
45}; 64};
46 65
47#define PLL_RATE(_r, _m, _n, _od) \ 66#define PLL_RATE(_r, _m, _n, _od) \
@@ -50,97 +69,53 @@ struct pll_rate_table {
50 .m = (_m), \ 69 .m = (_m), \
51 .n = (_n), \ 70 .n = (_n), \
52 .od = (_od), \ 71 .od = (_od), \
53 } \
54
55#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
56 { \
57 .rate = (_r), \
58 .m = (_m), \
59 .n = (_n), \
60 .od = (_od), \
61 .od2 = (_od2), \
62 .frac = (_frac), \
63 } \
64
65struct pll_params_table {
66 unsigned int reg_off;
67 unsigned int value;
68};
69
70#define PLL_PARAM(_reg, _val) \
71 { \
72 .reg_off = (_reg), \
73 .value = (_val), \
74 } 72 }
75 73
76struct pll_setup_params { 74#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
77 struct pll_params_table *params_table;
78 unsigned int params_count;
79 /* Workaround for GP0, do not reset before configuring */
80 bool no_init_reset;
81 /* Workaround for GP0, unreset right before checking for lock */
82 bool clear_reset_for_lock;
83 /* Workaround for GXL GP0, reset in the lock checking loop */
84 bool reset_lock_loop;
85};
86 75
87struct meson_clk_pll { 76struct meson_clk_pll_data {
88 struct clk_hw hw;
89 void __iomem *base;
90 struct parm m; 77 struct parm m;
91 struct parm n; 78 struct parm n;
92 struct parm frac; 79 struct parm frac;
93 struct parm od; 80 struct parm od;
94 struct parm od2; 81 struct parm od2;
95 const struct pll_setup_params params; 82 struct parm od3;
96 const struct pll_rate_table *rate_table; 83 struct parm l;
97 unsigned int rate_count; 84 struct parm rst;
98 spinlock_t *lock; 85 const struct reg_sequence *init_regs;
86 unsigned int init_count;
87 const struct pll_rate_table *table;
88 u8 flags;
99}; 89};
100 90
101#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) 91#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
102 92
103struct meson_clk_cpu { 93struct meson_clk_mpll_data {
104 struct clk_hw hw;
105 void __iomem *base;
106 u16 reg_off;
107 struct notifier_block clk_nb;
108 const struct clk_div_table *div_table;
109};
110
111int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
112 void *data);
113
114struct meson_clk_mpll {
115 struct clk_hw hw;
116 void __iomem *base;
117 struct parm sdm; 94 struct parm sdm;
118 struct parm sdm_en; 95 struct parm sdm_en;
119 struct parm n2; 96 struct parm n2;
120 struct parm en;
121 struct parm ssen; 97 struct parm ssen;
98 struct parm misc;
122 spinlock_t *lock; 99 spinlock_t *lock;
123}; 100};
124 101
125struct meson_clk_audio_divider { 102struct meson_clk_audio_div_data {
126 struct clk_hw hw;
127 void __iomem *base;
128 struct parm div; 103 struct parm div;
129 u8 flags; 104 u8 flags;
130 spinlock_t *lock;
131}; 105};
132 106
133#define MESON_GATE(_name, _reg, _bit) \ 107#define MESON_GATE(_name, _reg, _bit) \
134struct clk_gate _name = { \ 108struct clk_regmap _name = { \
135 .reg = (void __iomem *) _reg, \ 109 .data = &(struct clk_regmap_gate_data){ \
136 .bit_idx = (_bit), \ 110 .offset = (_reg), \
137 .lock = &meson_clk_lock, \ 111 .bit_idx = (_bit), \
138 .hw.init = &(struct clk_init_data) { \ 112 }, \
139 .name = #_name, \ 113 .hw.init = &(struct clk_init_data) { \
140 .ops = &clk_gate_ops, \ 114 .name = #_name, \
115 .ops = &clk_regmap_gate_ops, \
141 .parent_names = (const char *[]){ "clk81" }, \ 116 .parent_names = (const char *[]){ "clk81" }, \
142 .num_parents = 1, \ 117 .num_parents = 1, \
143 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 118 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
144 }, \ 119 }, \
145}; 120};
146 121
diff --git a/drivers/clk/meson/gxbb-aoclk-regmap.c b/drivers/clk/meson/gxbb-aoclk-regmap.c
deleted file mode 100644
index 2515fbfa0467..000000000000
--- a/drivers/clk/meson/gxbb-aoclk-regmap.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <linux/clk-provider.h>
9#include <linux/bitfield.h>
10#include <linux/regmap.h>
11#include "gxbb-aoclk.h"
12
13static int aoclk_gate_regmap_enable(struct clk_hw *hw)
14{
15 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
16
17 return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
18 BIT(gate->bit_idx), BIT(gate->bit_idx));
19}
20
21static void aoclk_gate_regmap_disable(struct clk_hw *hw)
22{
23 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
24
25 regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
26 BIT(gate->bit_idx), 0);
27}
28
29static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw)
30{
31 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
32 unsigned int val;
33 int ret;
34
35 ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val);
36 if (ret)
37 return ret;
38
39 return (val & BIT(gate->bit_idx)) != 0;
40}
41
42const struct clk_ops meson_aoclk_gate_regmap_ops = {
43 .enable = aoclk_gate_regmap_enable,
44 .disable = aoclk_gate_regmap_disable,
45 .is_enabled = aoclk_gate_regmap_is_enabled,
46};
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index 6c161e0a8e59..9ec23ae9a219 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -62,10 +62,9 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <dt-bindings/clock/gxbb-aoclkc.h> 63#include <dt-bindings/clock/gxbb-aoclkc.h>
64#include <dt-bindings/reset/gxbb-aoclkc.h> 64#include <dt-bindings/reset/gxbb-aoclkc.h>
65#include "clk-regmap.h"
65#include "gxbb-aoclk.h" 66#include "gxbb-aoclk.h"
66 67
67static DEFINE_SPINLOCK(gxbb_aoclk_lock);
68
69struct gxbb_aoclk_reset_controller { 68struct gxbb_aoclk_reset_controller {
70 struct reset_controller_dev reset; 69 struct reset_controller_dev reset;
71 unsigned int *data; 70 unsigned int *data;
@@ -87,12 +86,14 @@ static const struct reset_control_ops gxbb_aoclk_reset_ops = {
87}; 86};
88 87
89#define GXBB_AO_GATE(_name, _bit) \ 88#define GXBB_AO_GATE(_name, _bit) \
90static struct aoclk_gate_regmap _name##_ao = { \ 89static struct clk_regmap _name##_ao = { \
91 .bit_idx = (_bit), \ 90 .data = &(struct clk_regmap_gate_data) { \
92 .lock = &gxbb_aoclk_lock, \ 91 .offset = AO_RTI_GEN_CNTL_REG0, \
92 .bit_idx = (_bit), \
93 }, \
93 .hw.init = &(struct clk_init_data) { \ 94 .hw.init = &(struct clk_init_data) { \
94 .name = #_name "_ao", \ 95 .name = #_name "_ao", \
95 .ops = &meson_aoclk_gate_regmap_ops, \ 96 .ops = &clk_regmap_gate_ops, \
96 .parent_names = (const char *[]){ "clk81" }, \ 97 .parent_names = (const char *[]){ "clk81" }, \
97 .num_parents = 1, \ 98 .num_parents = 1, \
98 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 99 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
@@ -107,7 +108,6 @@ GXBB_AO_GATE(uart2, 5);
107GXBB_AO_GATE(ir_blaster, 6); 108GXBB_AO_GATE(ir_blaster, 6);
108 109
109static struct aoclk_cec_32k cec_32k_ao = { 110static struct aoclk_cec_32k cec_32k_ao = {
110 .lock = &gxbb_aoclk_lock,
111 .hw.init = &(struct clk_init_data) { 111 .hw.init = &(struct clk_init_data) {
112 .name = "cec_32k_ao", 112 .name = "cec_32k_ao",
113 .ops = &meson_aoclk_cec_32k_ops, 113 .ops = &meson_aoclk_cec_32k_ops,
@@ -126,7 +126,7 @@ static unsigned int gxbb_aoclk_reset[] = {
126 [RESET_AO_IR_BLASTER] = 23, 126 [RESET_AO_IR_BLASTER] = 23,
127}; 127};
128 128
129static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { 129static struct clk_regmap *gxbb_aoclk_gate[] = {
130 [CLKID_AO_REMOTE] = &remote_ao, 130 [CLKID_AO_REMOTE] = &remote_ao,
131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, 132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
@@ -177,10 +177,10 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev)
177 * Populate regmap and register all clks 177 * Populate regmap and register all clks
178 */ 178 */
179 for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { 179 for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) {
180 gxbb_aoclk_gate[clkid]->regmap = regmap; 180 gxbb_aoclk_gate[clkid]->map = regmap;
181 181
182 ret = devm_clk_hw_register(dev, 182 ret = devm_clk_hw_register(dev,
183 gxbb_aoclk_onecell_data.hws[clkid]); 183 gxbb_aoclk_onecell_data.hws[clkid]);
184 if (ret) 184 if (ret)
185 return ret; 185 return ret;
186 } 186 }
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h
index e8604c8f7eee..0be78383f257 100644
--- a/drivers/clk/meson/gxbb-aoclk.h
+++ b/drivers/clk/meson/gxbb-aoclk.h
@@ -17,22 +17,11 @@
17#define AO_RTC_ALT_CLK_CNTL0 0x94 17#define AO_RTC_ALT_CLK_CNTL0 0x94
18#define AO_RTC_ALT_CLK_CNTL1 0x98 18#define AO_RTC_ALT_CLK_CNTL1 0x98
19 19
20struct aoclk_gate_regmap {
21 struct clk_hw hw;
22 unsigned bit_idx;
23 struct regmap *regmap;
24 spinlock_t *lock;
25};
26
27#define to_aoclk_gate_regmap(_hw) \
28 container_of(_hw, struct aoclk_gate_regmap, hw)
29
30extern const struct clk_ops meson_aoclk_gate_regmap_ops; 20extern const struct clk_ops meson_aoclk_gate_regmap_ops;
31 21
32struct aoclk_cec_32k { 22struct aoclk_cec_32k {
33 struct clk_hw hw; 23 struct clk_hw hw;
34 struct regmap *regmap; 24 struct regmap *regmap;
35 spinlock_t *lock;
36}; 25};
37 26
38#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw) 27#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index af24455af5b4..b1e4d9557610 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -19,108 +19,19 @@
19 19
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/clk-provider.h> 21#include <linux/clk-provider.h>
22#include <linux/init.h>
22#include <linux/of_address.h> 23#include <linux/of_address.h>
23#include <linux/of_device.h> 24#include <linux/of_device.h>
25#include <linux/mfd/syscon.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
25#include <linux/init.h> 27#include <linux/regmap.h>
26 28
27#include "clkc.h" 29#include "clkc.h"
28#include "gxbb.h" 30#include "gxbb.h"
31#include "clk-regmap.h"
29 32
30static DEFINE_SPINLOCK(meson_clk_lock); 33static DEFINE_SPINLOCK(meson_clk_lock);
31 34
32static const struct pll_rate_table sys_pll_rate_table[] = {
33 PLL_RATE(24000000, 56, 1, 2),
34 PLL_RATE(48000000, 64, 1, 2),
35 PLL_RATE(72000000, 72, 1, 2),
36 PLL_RATE(96000000, 64, 1, 2),
37 PLL_RATE(120000000, 80, 1, 2),
38 PLL_RATE(144000000, 96, 1, 2),
39 PLL_RATE(168000000, 56, 1, 1),
40 PLL_RATE(192000000, 64, 1, 1),
41 PLL_RATE(216000000, 72, 1, 1),
42 PLL_RATE(240000000, 80, 1, 1),
43 PLL_RATE(264000000, 88, 1, 1),
44 PLL_RATE(288000000, 96, 1, 1),
45 PLL_RATE(312000000, 52, 1, 2),
46 PLL_RATE(336000000, 56, 1, 2),
47 PLL_RATE(360000000, 60, 1, 2),
48 PLL_RATE(384000000, 64, 1, 2),
49 PLL_RATE(408000000, 68, 1, 2),
50 PLL_RATE(432000000, 72, 1, 2),
51 PLL_RATE(456000000, 76, 1, 2),
52 PLL_RATE(480000000, 80, 1, 2),
53 PLL_RATE(504000000, 84, 1, 2),
54 PLL_RATE(528000000, 88, 1, 2),
55 PLL_RATE(552000000, 92, 1, 2),
56 PLL_RATE(576000000, 96, 1, 2),
57 PLL_RATE(600000000, 50, 1, 1),
58 PLL_RATE(624000000, 52, 1, 1),
59 PLL_RATE(648000000, 54, 1, 1),
60 PLL_RATE(672000000, 56, 1, 1),
61 PLL_RATE(696000000, 58, 1, 1),
62 PLL_RATE(720000000, 60, 1, 1),
63 PLL_RATE(744000000, 62, 1, 1),
64 PLL_RATE(768000000, 64, 1, 1),
65 PLL_RATE(792000000, 66, 1, 1),
66 PLL_RATE(816000000, 68, 1, 1),
67 PLL_RATE(840000000, 70, 1, 1),
68 PLL_RATE(864000000, 72, 1, 1),
69 PLL_RATE(888000000, 74, 1, 1),
70 PLL_RATE(912000000, 76, 1, 1),
71 PLL_RATE(936000000, 78, 1, 1),
72 PLL_RATE(960000000, 80, 1, 1),
73 PLL_RATE(984000000, 82, 1, 1),
74 PLL_RATE(1008000000, 84, 1, 1),
75 PLL_RATE(1032000000, 86, 1, 1),
76 PLL_RATE(1056000000, 88, 1, 1),
77 PLL_RATE(1080000000, 90, 1, 1),
78 PLL_RATE(1104000000, 92, 1, 1),
79 PLL_RATE(1128000000, 94, 1, 1),
80 PLL_RATE(1152000000, 96, 1, 1),
81 PLL_RATE(1176000000, 98, 1, 1),
82 PLL_RATE(1200000000, 50, 1, 0),
83 PLL_RATE(1224000000, 51, 1, 0),
84 PLL_RATE(1248000000, 52, 1, 0),
85 PLL_RATE(1272000000, 53, 1, 0),
86 PLL_RATE(1296000000, 54, 1, 0),
87 PLL_RATE(1320000000, 55, 1, 0),
88 PLL_RATE(1344000000, 56, 1, 0),
89 PLL_RATE(1368000000, 57, 1, 0),
90 PLL_RATE(1392000000, 58, 1, 0),
91 PLL_RATE(1416000000, 59, 1, 0),
92 PLL_RATE(1440000000, 60, 1, 0),
93 PLL_RATE(1464000000, 61, 1, 0),
94 PLL_RATE(1488000000, 62, 1, 0),
95 PLL_RATE(1512000000, 63, 1, 0),
96 PLL_RATE(1536000000, 64, 1, 0),
97 PLL_RATE(1560000000, 65, 1, 0),
98 PLL_RATE(1584000000, 66, 1, 0),
99 PLL_RATE(1608000000, 67, 1, 0),
100 PLL_RATE(1632000000, 68, 1, 0),
101 PLL_RATE(1656000000, 68, 1, 0),
102 PLL_RATE(1680000000, 68, 1, 0),
103 PLL_RATE(1704000000, 68, 1, 0),
104 PLL_RATE(1728000000, 69, 1, 0),
105 PLL_RATE(1752000000, 69, 1, 0),
106 PLL_RATE(1776000000, 69, 1, 0),
107 PLL_RATE(1800000000, 69, 1, 0),
108 PLL_RATE(1824000000, 70, 1, 0),
109 PLL_RATE(1848000000, 70, 1, 0),
110 PLL_RATE(1872000000, 70, 1, 0),
111 PLL_RATE(1896000000, 70, 1, 0),
112 PLL_RATE(1920000000, 71, 1, 0),
113 PLL_RATE(1944000000, 71, 1, 0),
114 PLL_RATE(1968000000, 71, 1, 0),
115 PLL_RATE(1992000000, 71, 1, 0),
116 PLL_RATE(2016000000, 72, 1, 0),
117 PLL_RATE(2040000000, 72, 1, 0),
118 PLL_RATE(2064000000, 72, 1, 0),
119 PLL_RATE(2088000000, 72, 1, 0),
120 PLL_RATE(2112000000, 73, 1, 0),
121 { /* sentinel */ },
122};
123
124static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { 35static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = {
125 PLL_RATE(96000000, 32, 1, 3), 36 PLL_RATE(96000000, 32, 1, 3),
126 PLL_RATE(99000000, 33, 1, 3), 37 PLL_RATE(99000000, 33, 1, 3),
@@ -278,23 +189,39 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
278 { /* sentinel */ }, 189 { /* sentinel */ },
279}; 190};
280 191
281static struct meson_clk_pll gxbb_fixed_pll = { 192static struct clk_regmap gxbb_fixed_pll = {
282 .m = { 193 .data = &(struct meson_clk_pll_data){
283 .reg_off = HHI_MPLL_CNTL, 194 .m = {
284 .shift = 0, 195 .reg_off = HHI_MPLL_CNTL,
285 .width = 9, 196 .shift = 0,
197 .width = 9,
198 },
199 .n = {
200 .reg_off = HHI_MPLL_CNTL,
201 .shift = 9,
202 .width = 5,
203 },
204 .od = {
205 .reg_off = HHI_MPLL_CNTL,
206 .shift = 16,
207 .width = 2,
208 },
209 .frac = {
210 .reg_off = HHI_MPLL_CNTL2,
211 .shift = 0,
212 .width = 12,
213 },
214 .l = {
215 .reg_off = HHI_MPLL_CNTL,
216 .shift = 31,
217 .width = 1,
218 },
219 .rst = {
220 .reg_off = HHI_MPLL_CNTL,
221 .shift = 29,
222 .width = 1,
223 },
286 }, 224 },
287 .n = {
288 .reg_off = HHI_MPLL_CNTL,
289 .shift = 9,
290 .width = 5,
291 },
292 .od = {
293 .reg_off = HHI_MPLL_CNTL,
294 .shift = 16,
295 .width = 2,
296 },
297 .lock = &meson_clk_lock,
298 .hw.init = &(struct clk_init_data){ 225 .hw.init = &(struct clk_init_data){
299 .name = "fixed_pll", 226 .name = "fixed_pll",
300 .ops = &meson_clk_pll_ro_ops, 227 .ops = &meson_clk_pll_ro_ops,
@@ -304,33 +231,118 @@ static struct meson_clk_pll gxbb_fixed_pll = {
304 }, 231 },
305}; 232};
306 233
307static struct meson_clk_pll gxbb_hdmi_pll = { 234static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
308 .m = { 235 .mult = 2,
309 .reg_off = HHI_HDMI_PLL_CNTL, 236 .div = 1,
310 .shift = 0, 237 .hw.init = &(struct clk_init_data){
311 .width = 9, 238 .name = "hdmi_pll_pre_mult",
312 }, 239 .ops = &clk_fixed_factor_ops,
313 .n = { 240 .parent_names = (const char *[]){ "xtal" },
314 .reg_off = HHI_HDMI_PLL_CNTL, 241 .num_parents = 1,
315 .shift = 9,
316 .width = 5,
317 }, 242 },
318 .frac = { 243};
319 .reg_off = HHI_HDMI_PLL_CNTL2, 244
320 .shift = 0, 245static struct clk_regmap gxbb_hdmi_pll = {
321 .width = 12, 246 .data = &(struct meson_clk_pll_data){
247 .m = {
248 .reg_off = HHI_HDMI_PLL_CNTL,
249 .shift = 0,
250 .width = 9,
251 },
252 .n = {
253 .reg_off = HHI_HDMI_PLL_CNTL,
254 .shift = 9,
255 .width = 5,
256 },
257 .frac = {
258 .reg_off = HHI_HDMI_PLL_CNTL2,
259 .shift = 0,
260 .width = 12,
261 },
262 .od = {
263 .reg_off = HHI_HDMI_PLL_CNTL2,
264 .shift = 16,
265 .width = 2,
266 },
267 .od2 = {
268 .reg_off = HHI_HDMI_PLL_CNTL2,
269 .shift = 22,
270 .width = 2,
271 },
272 .od3 = {
273 .reg_off = HHI_HDMI_PLL_CNTL2,
274 .shift = 18,
275 .width = 2,
276 },
277 .l = {
278 .reg_off = HHI_HDMI_PLL_CNTL,
279 .shift = 31,
280 .width = 1,
281 },
282 .rst = {
283 .reg_off = HHI_HDMI_PLL_CNTL,
284 .shift = 28,
285 .width = 1,
286 },
322 }, 287 },
323 .od = { 288 .hw.init = &(struct clk_init_data){
324 .reg_off = HHI_HDMI_PLL_CNTL2, 289 .name = "hdmi_pll",
325 .shift = 16, 290 .ops = &meson_clk_pll_ro_ops,
326 .width = 2, 291 .parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
292 .num_parents = 1,
293 .flags = CLK_GET_RATE_NOCACHE,
327 }, 294 },
328 .od2 = { 295};
329 .reg_off = HHI_HDMI_PLL_CNTL2, 296
330 .shift = 22, 297static struct clk_regmap gxl_hdmi_pll = {
331 .width = 2, 298 .data = &(struct meson_clk_pll_data){
299 .m = {
300 .reg_off = HHI_HDMI_PLL_CNTL,
301 .shift = 0,
302 .width = 9,
303 },
304 .n = {
305 .reg_off = HHI_HDMI_PLL_CNTL,
306 .shift = 9,
307 .width = 5,
308 },
309 .frac = {
310 /*
311 * On gxl, there is a register shift due to
312 * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb,
313 * so we compute the register offset based on the PLL
314 * base to get it right
315 */
316 .reg_off = HHI_HDMI_PLL_CNTL + 4,
317 .shift = 0,
318 .width = 12,
319 },
320 .od = {
321 .reg_off = HHI_HDMI_PLL_CNTL + 8,
322 .shift = 21,
323 .width = 2,
324 },
325 .od2 = {
326 .reg_off = HHI_HDMI_PLL_CNTL + 8,
327 .shift = 23,
328 .width = 2,
329 },
330 .od3 = {
331 .reg_off = HHI_HDMI_PLL_CNTL + 8,
332 .shift = 19,
333 .width = 2,
334 },
335 .l = {
336 .reg_off = HHI_HDMI_PLL_CNTL,
337 .shift = 31,
338 .width = 1,
339 },
340 .rst = {
341 .reg_off = HHI_HDMI_PLL_CNTL,
342 .shift = 29,
343 .width = 1,
344 },
332 }, 345 },
333 .lock = &meson_clk_lock,
334 .hw.init = &(struct clk_init_data){ 346 .hw.init = &(struct clk_init_data){
335 .name = "hdmi_pll", 347 .name = "hdmi_pll",
336 .ops = &meson_clk_pll_ro_ops, 348 .ops = &meson_clk_pll_ro_ops,
@@ -340,25 +352,34 @@ static struct meson_clk_pll gxbb_hdmi_pll = {
340 }, 352 },
341}; 353};
342 354
343static struct meson_clk_pll gxbb_sys_pll = { 355static struct clk_regmap gxbb_sys_pll = {
344 .m = { 356 .data = &(struct meson_clk_pll_data){
345 .reg_off = HHI_SYS_PLL_CNTL, 357 .m = {
346 .shift = 0, 358 .reg_off = HHI_SYS_PLL_CNTL,
347 .width = 9, 359 .shift = 0,
348 }, 360 .width = 9,
349 .n = { 361 },
350 .reg_off = HHI_SYS_PLL_CNTL, 362 .n = {
351 .shift = 9, 363 .reg_off = HHI_SYS_PLL_CNTL,
352 .width = 5, 364 .shift = 9,
365 .width = 5,
366 },
367 .od = {
368 .reg_off = HHI_SYS_PLL_CNTL,
369 .shift = 10,
370 .width = 2,
371 },
372 .l = {
373 .reg_off = HHI_SYS_PLL_CNTL,
374 .shift = 31,
375 .width = 1,
376 },
377 .rst = {
378 .reg_off = HHI_SYS_PLL_CNTL,
379 .shift = 29,
380 .width = 1,
381 },
353 }, 382 },
354 .od = {
355 .reg_off = HHI_SYS_PLL_CNTL,
356 .shift = 10,
357 .width = 2,
358 },
359 .rate_table = sys_pll_rate_table,
360 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
361 .lock = &meson_clk_lock,
362 .hw.init = &(struct clk_init_data){ 383 .hw.init = &(struct clk_init_data){
363 .name = "sys_pll", 384 .name = "sys_pll",
364 .ops = &meson_clk_pll_ro_ops, 385 .ops = &meson_clk_pll_ro_ops,
@@ -368,38 +389,44 @@ static struct meson_clk_pll gxbb_sys_pll = {
368 }, 389 },
369}; 390};
370 391
371struct pll_params_table gxbb_gp0_params_table[] = { 392static const struct reg_sequence gxbb_gp0_init_regs[] = {
372 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x6a000228), 393 { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 },
373 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0x69c80000), 394 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 },
374 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a5590c4), 395 { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d },
375 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0x0000500d), 396 { .reg = HHI_GP0_PLL_CNTL, .def = 0x4a000228 },
376}; 397};
377 398
378static struct meson_clk_pll gxbb_gp0_pll = { 399static struct clk_regmap gxbb_gp0_pll = {
379 .m = { 400 .data = &(struct meson_clk_pll_data){
380 .reg_off = HHI_GP0_PLL_CNTL, 401 .m = {
381 .shift = 0, 402 .reg_off = HHI_GP0_PLL_CNTL,
382 .width = 9, 403 .shift = 0,
383 }, 404 .width = 9,
384 .n = { 405 },
385 .reg_off = HHI_GP0_PLL_CNTL, 406 .n = {
386 .shift = 9, 407 .reg_off = HHI_GP0_PLL_CNTL,
387 .width = 5, 408 .shift = 9,
388 }, 409 .width = 5,
389 .od = { 410 },
390 .reg_off = HHI_GP0_PLL_CNTL, 411 .od = {
391 .shift = 16, 412 .reg_off = HHI_GP0_PLL_CNTL,
392 .width = 2, 413 .shift = 16,
393 }, 414 .width = 2,
394 .params = { 415 },
395 .params_table = gxbb_gp0_params_table, 416 .l = {
396 .params_count = ARRAY_SIZE(gxbb_gp0_params_table), 417 .reg_off = HHI_GP0_PLL_CNTL,
397 .no_init_reset = true, 418 .shift = 31,
398 .clear_reset_for_lock = true, 419 .width = 1,
420 },
421 .rst = {
422 .reg_off = HHI_GP0_PLL_CNTL,
423 .shift = 29,
424 .width = 1,
425 },
426 .table = gxbb_gp0_pll_rate_table,
427 .init_regs = gxbb_gp0_init_regs,
428 .init_count = ARRAY_SIZE(gxbb_gp0_init_regs),
399 }, 429 },
400 .rate_table = gxbb_gp0_pll_rate_table,
401 .rate_count = ARRAY_SIZE(gxbb_gp0_pll_rate_table),
402 .lock = &meson_clk_lock,
403 .hw.init = &(struct clk_init_data){ 430 .hw.init = &(struct clk_init_data){
404 .name = "gp0_pll", 431 .name = "gp0_pll",
405 .ops = &meson_clk_pll_ops, 432 .ops = &meson_clk_pll_ops,
@@ -409,40 +436,51 @@ static struct meson_clk_pll gxbb_gp0_pll = {
409 }, 436 },
410}; 437};
411 438
412struct pll_params_table gxl_gp0_params_table[] = { 439static const struct reg_sequence gxl_gp0_init_regs[] = {
413 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x40010250), 440 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
414 PLL_PARAM(HHI_GP0_PLL_CNTL1, 0xc084a000), 441 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
415 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0xb75020be), 442 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
416 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a59a288), 443 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
417 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0xc000004d), 444 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
418 PLL_PARAM(HHI_GP0_PLL_CNTL5, 0x00078000), 445 { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
419}; 446};
420 447
421static struct meson_clk_pll gxl_gp0_pll = { 448static struct clk_regmap gxl_gp0_pll = {
422 .m = { 449 .data = &(struct meson_clk_pll_data){
423 .reg_off = HHI_GP0_PLL_CNTL, 450 .m = {
424 .shift = 0, 451 .reg_off = HHI_GP0_PLL_CNTL,
425 .width = 9, 452 .shift = 0,
426 }, 453 .width = 9,
427 .n = { 454 },
428 .reg_off = HHI_GP0_PLL_CNTL, 455 .n = {
429 .shift = 9, 456 .reg_off = HHI_GP0_PLL_CNTL,
430 .width = 5, 457 .shift = 9,
431 }, 458 .width = 5,
432 .od = { 459 },
433 .reg_off = HHI_GP0_PLL_CNTL, 460 .od = {
434 .shift = 16, 461 .reg_off = HHI_GP0_PLL_CNTL,
435 .width = 2, 462 .shift = 16,
463 .width = 2,
464 },
465 .frac = {
466 .reg_off = HHI_GP0_PLL_CNTL1,
467 .shift = 0,
468 .width = 10,
469 },
470 .l = {
471 .reg_off = HHI_GP0_PLL_CNTL,
472 .shift = 31,
473 .width = 1,
474 },
475 .rst = {
476 .reg_off = HHI_GP0_PLL_CNTL,
477 .shift = 29,
478 .width = 1,
479 },
480 .table = gxl_gp0_pll_rate_table,
481 .init_regs = gxl_gp0_init_regs,
482 .init_count = ARRAY_SIZE(gxl_gp0_init_regs),
436 }, 483 },
437 .params = {
438 .params_table = gxl_gp0_params_table,
439 .params_count = ARRAY_SIZE(gxl_gp0_params_table),
440 .no_init_reset = true,
441 .reset_lock_loop = true,
442 },
443 .rate_table = gxl_gp0_pll_rate_table,
444 .rate_count = ARRAY_SIZE(gxl_gp0_pll_rate_table),
445 .lock = &meson_clk_lock,
446 .hw.init = &(struct clk_init_data){ 484 .hw.init = &(struct clk_init_data){
447 .name = "gp0_pll", 485 .name = "gp0_pll",
448 .ops = &meson_clk_pll_ops, 486 .ops = &meson_clk_pll_ops,
@@ -452,161 +490,267 @@ static struct meson_clk_pll gxl_gp0_pll = {
452 }, 490 },
453}; 491};
454 492
455static struct clk_fixed_factor gxbb_fclk_div2 = { 493static struct clk_fixed_factor gxbb_fclk_div2_div = {
456 .mult = 1, 494 .mult = 1,
457 .div = 2, 495 .div = 2,
458 .hw.init = &(struct clk_init_data){ 496 .hw.init = &(struct clk_init_data){
459 .name = "fclk_div2", 497 .name = "fclk_div2_div",
460 .ops = &clk_fixed_factor_ops, 498 .ops = &clk_fixed_factor_ops,
461 .parent_names = (const char *[]){ "fixed_pll" }, 499 .parent_names = (const char *[]){ "fixed_pll" },
462 .num_parents = 1, 500 .num_parents = 1,
463 }, 501 },
464}; 502};
465 503
466static struct clk_fixed_factor gxbb_fclk_div3 = { 504static struct clk_regmap gxbb_fclk_div2 = {
505 .data = &(struct clk_regmap_gate_data){
506 .offset = HHI_MPLL_CNTL6,
507 .bit_idx = 27,
508 },
509 .hw.init = &(struct clk_init_data){
510 .name = "fclk_div2",
511 .ops = &clk_regmap_gate_ops,
512 .parent_names = (const char *[]){ "fclk_div2_div" },
513 .num_parents = 1,
514 },
515};
516
517static struct clk_fixed_factor gxbb_fclk_div3_div = {
467 .mult = 1, 518 .mult = 1,
468 .div = 3, 519 .div = 3,
469 .hw.init = &(struct clk_init_data){ 520 .hw.init = &(struct clk_init_data){
470 .name = "fclk_div3", 521 .name = "fclk_div3_div",
471 .ops = &clk_fixed_factor_ops, 522 .ops = &clk_fixed_factor_ops,
472 .parent_names = (const char *[]){ "fixed_pll" }, 523 .parent_names = (const char *[]){ "fixed_pll" },
473 .num_parents = 1, 524 .num_parents = 1,
474 }, 525 },
475}; 526};
476 527
477static struct clk_fixed_factor gxbb_fclk_div4 = { 528static struct clk_regmap gxbb_fclk_div3 = {
529 .data = &(struct clk_regmap_gate_data){
530 .offset = HHI_MPLL_CNTL6,
531 .bit_idx = 28,
532 },
533 .hw.init = &(struct clk_init_data){
534 .name = "fclk_div3",
535 .ops = &clk_regmap_gate_ops,
536 .parent_names = (const char *[]){ "fclk_div3_div" },
537 .num_parents = 1,
538 },
539};
540
541static struct clk_fixed_factor gxbb_fclk_div4_div = {
478 .mult = 1, 542 .mult = 1,
479 .div = 4, 543 .div = 4,
480 .hw.init = &(struct clk_init_data){ 544 .hw.init = &(struct clk_init_data){
481 .name = "fclk_div4", 545 .name = "fclk_div4_div",
482 .ops = &clk_fixed_factor_ops, 546 .ops = &clk_fixed_factor_ops,
483 .parent_names = (const char *[]){ "fixed_pll" }, 547 .parent_names = (const char *[]){ "fixed_pll" },
484 .num_parents = 1, 548 .num_parents = 1,
485 }, 549 },
486}; 550};
487 551
488static struct clk_fixed_factor gxbb_fclk_div5 = { 552static struct clk_regmap gxbb_fclk_div4 = {
553 .data = &(struct clk_regmap_gate_data){
554 .offset = HHI_MPLL_CNTL6,
555 .bit_idx = 29,
556 },
557 .hw.init = &(struct clk_init_data){
558 .name = "fclk_div4",
559 .ops = &clk_regmap_gate_ops,
560 .parent_names = (const char *[]){ "fclk_div4_div" },
561 .num_parents = 1,
562 },
563};
564
565static struct clk_fixed_factor gxbb_fclk_div5_div = {
489 .mult = 1, 566 .mult = 1,
490 .div = 5, 567 .div = 5,
491 .hw.init = &(struct clk_init_data){ 568 .hw.init = &(struct clk_init_data){
492 .name = "fclk_div5", 569 .name = "fclk_div5_div",
493 .ops = &clk_fixed_factor_ops, 570 .ops = &clk_fixed_factor_ops,
494 .parent_names = (const char *[]){ "fixed_pll" }, 571 .parent_names = (const char *[]){ "fixed_pll" },
495 .num_parents = 1, 572 .num_parents = 1,
496 }, 573 },
497}; 574};
498 575
499static struct clk_fixed_factor gxbb_fclk_div7 = { 576static struct clk_regmap gxbb_fclk_div5 = {
577 .data = &(struct clk_regmap_gate_data){
578 .offset = HHI_MPLL_CNTL6,
579 .bit_idx = 30,
580 },
581 .hw.init = &(struct clk_init_data){
582 .name = "fclk_div5",
583 .ops = &clk_regmap_gate_ops,
584 .parent_names = (const char *[]){ "fclk_div5_div" },
585 .num_parents = 1,
586 },
587};
588
589static struct clk_fixed_factor gxbb_fclk_div7_div = {
500 .mult = 1, 590 .mult = 1,
501 .div = 7, 591 .div = 7,
502 .hw.init = &(struct clk_init_data){ 592 .hw.init = &(struct clk_init_data){
503 .name = "fclk_div7", 593 .name = "fclk_div7_div",
504 .ops = &clk_fixed_factor_ops, 594 .ops = &clk_fixed_factor_ops,
505 .parent_names = (const char *[]){ "fixed_pll" }, 595 .parent_names = (const char *[]){ "fixed_pll" },
506 .num_parents = 1, 596 .num_parents = 1,
507 }, 597 },
508}; 598};
509 599
510static struct meson_clk_mpll gxbb_mpll0 = { 600static struct clk_regmap gxbb_fclk_div7 = {
511 .sdm = { 601 .data = &(struct clk_regmap_gate_data){
512 .reg_off = HHI_MPLL_CNTL7, 602 .offset = HHI_MPLL_CNTL6,
513 .shift = 0, 603 .bit_idx = 31,
514 .width = 14,
515 }, 604 },
516 .sdm_en = { 605 .hw.init = &(struct clk_init_data){
517 .reg_off = HHI_MPLL_CNTL7, 606 .name = "fclk_div7",
518 .shift = 15, 607 .ops = &clk_regmap_gate_ops,
519 .width = 1, 608 .parent_names = (const char *[]){ "fclk_div7_div" },
609 .num_parents = 1,
520 }, 610 },
521 .n2 = { 611};
522 .reg_off = HHI_MPLL_CNTL7, 612
523 .shift = 16, 613static struct clk_regmap gxbb_mpll_prediv = {
524 .width = 9, 614 .data = &(struct clk_regmap_div_data){
615 .offset = HHI_MPLL_CNTL5,
616 .shift = 12,
617 .width = 1,
525 }, 618 },
526 .en = { 619 .hw.init = &(struct clk_init_data){
527 .reg_off = HHI_MPLL_CNTL7, 620 .name = "mpll_prediv",
528 .shift = 14, 621 .ops = &clk_regmap_divider_ro_ops,
529 .width = 1, 622 .parent_names = (const char *[]){ "fixed_pll" },
623 .num_parents = 1,
530 }, 624 },
531 .ssen = { 625};
532 .reg_off = HHI_MPLL_CNTL, 626
533 .shift = 25, 627static struct clk_regmap gxbb_mpll0_div = {
534 .width = 1, 628 .data = &(struct meson_clk_mpll_data){
629 .sdm = {
630 .reg_off = HHI_MPLL_CNTL7,
631 .shift = 0,
632 .width = 14,
633 },
634 .sdm_en = {
635 .reg_off = HHI_MPLL_CNTL7,
636 .shift = 15,
637 .width = 1,
638 },
639 .n2 = {
640 .reg_off = HHI_MPLL_CNTL7,
641 .shift = 16,
642 .width = 9,
643 },
644 .ssen = {
645 .reg_off = HHI_MPLL_CNTL,
646 .shift = 25,
647 .width = 1,
648 },
649 .lock = &meson_clk_lock,
535 }, 650 },
536 .lock = &meson_clk_lock,
537 .hw.init = &(struct clk_init_data){ 651 .hw.init = &(struct clk_init_data){
538 .name = "mpll0", 652 .name = "mpll0_div",
539 .ops = &meson_clk_mpll_ops, 653 .ops = &meson_clk_mpll_ops,
540 .parent_names = (const char *[]){ "fixed_pll" }, 654 .parent_names = (const char *[]){ "mpll_prediv" },
541 .num_parents = 1, 655 .num_parents = 1,
542 }, 656 },
543}; 657};
544 658
545static struct meson_clk_mpll gxbb_mpll1 = { 659static struct clk_regmap gxbb_mpll0 = {
546 .sdm = { 660 .data = &(struct clk_regmap_gate_data){
547 .reg_off = HHI_MPLL_CNTL8, 661 .offset = HHI_MPLL_CNTL7,
548 .shift = 0, 662 .bit_idx = 14,
549 .width = 14,
550 },
551 .sdm_en = {
552 .reg_off = HHI_MPLL_CNTL8,
553 .shift = 15,
554 .width = 1,
555 }, 663 },
556 .n2 = { 664 .hw.init = &(struct clk_init_data){
557 .reg_off = HHI_MPLL_CNTL8, 665 .name = "mpll0",
558 .shift = 16, 666 .ops = &clk_regmap_gate_ops,
559 .width = 9, 667 .parent_names = (const char *[]){ "mpll0_div" },
668 .num_parents = 1,
669 .flags = CLK_SET_RATE_PARENT,
560 }, 670 },
561 .en = { 671};
562 .reg_off = HHI_MPLL_CNTL8, 672
563 .shift = 14, 673static struct clk_regmap gxbb_mpll1_div = {
564 .width = 1, 674 .data = &(struct meson_clk_mpll_data){
675 .sdm = {
676 .reg_off = HHI_MPLL_CNTL8,
677 .shift = 0,
678 .width = 14,
679 },
680 .sdm_en = {
681 .reg_off = HHI_MPLL_CNTL8,
682 .shift = 15,
683 .width = 1,
684 },
685 .n2 = {
686 .reg_off = HHI_MPLL_CNTL8,
687 .shift = 16,
688 .width = 9,
689 },
690 .lock = &meson_clk_lock,
565 }, 691 },
566 .lock = &meson_clk_lock,
567 .hw.init = &(struct clk_init_data){ 692 .hw.init = &(struct clk_init_data){
568 .name = "mpll1", 693 .name = "mpll1_div",
569 .ops = &meson_clk_mpll_ops, 694 .ops = &meson_clk_mpll_ops,
570 .parent_names = (const char *[]){ "fixed_pll" }, 695 .parent_names = (const char *[]){ "mpll_prediv" },
571 .num_parents = 1, 696 .num_parents = 1,
572 }, 697 },
573}; 698};
574 699
575static struct meson_clk_mpll gxbb_mpll2 = { 700static struct clk_regmap gxbb_mpll1 = {
576 .sdm = { 701 .data = &(struct clk_regmap_gate_data){
577 .reg_off = HHI_MPLL_CNTL9, 702 .offset = HHI_MPLL_CNTL8,
578 .shift = 0, 703 .bit_idx = 14,
579 .width = 14,
580 },
581 .sdm_en = {
582 .reg_off = HHI_MPLL_CNTL9,
583 .shift = 15,
584 .width = 1,
585 }, 704 },
586 .n2 = { 705 .hw.init = &(struct clk_init_data){
587 .reg_off = HHI_MPLL_CNTL9, 706 .name = "mpll1",
588 .shift = 16, 707 .ops = &clk_regmap_gate_ops,
589 .width = 9, 708 .parent_names = (const char *[]){ "mpll1_div" },
709 .num_parents = 1,
710 .flags = CLK_SET_RATE_PARENT,
590 }, 711 },
591 .en = { 712};
592 .reg_off = HHI_MPLL_CNTL9, 713
593 .shift = 14, 714static struct clk_regmap gxbb_mpll2_div = {
594 .width = 1, 715 .data = &(struct meson_clk_mpll_data){
716 .sdm = {
717 .reg_off = HHI_MPLL_CNTL9,
718 .shift = 0,
719 .width = 14,
720 },
721 .sdm_en = {
722 .reg_off = HHI_MPLL_CNTL9,
723 .shift = 15,
724 .width = 1,
725 },
726 .n2 = {
727 .reg_off = HHI_MPLL_CNTL9,
728 .shift = 16,
729 .width = 9,
730 },
731 .lock = &meson_clk_lock,
595 }, 732 },
596 .lock = &meson_clk_lock,
597 .hw.init = &(struct clk_init_data){ 733 .hw.init = &(struct clk_init_data){
598 .name = "mpll2", 734 .name = "mpll2_div",
599 .ops = &meson_clk_mpll_ops, 735 .ops = &meson_clk_mpll_ops,
600 .parent_names = (const char *[]){ "fixed_pll" }, 736 .parent_names = (const char *[]){ "mpll_prediv" },
601 .num_parents = 1, 737 .num_parents = 1,
602 }, 738 },
603}; 739};
604 740
605/* 741static struct clk_regmap gxbb_mpll2 = {
606 * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers 742 .data = &(struct clk_regmap_gate_data){
607 * and should be modeled with their respective PLLs via the forthcoming 743 .offset = HHI_MPLL_CNTL9,
608 * coordinated clock rates feature 744 .bit_idx = 14,
609 */ 745 },
746 .hw.init = &(struct clk_init_data){
747 .name = "mpll2",
748 .ops = &clk_regmap_gate_ops,
749 .parent_names = (const char *[]){ "mpll2_div" },
750 .num_parents = 1,
751 .flags = CLK_SET_RATE_PARENT,
752 },
753};
610 754
611static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 755static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
612static const char * const clk81_parent_names[] = { 756static const char * const clk81_parent_names[] = {
@@ -614,16 +758,16 @@ static const char * const clk81_parent_names[] = {
614 "fclk_div3", "fclk_div5" 758 "fclk_div3", "fclk_div5"
615}; 759};
616 760
617static struct clk_mux gxbb_mpeg_clk_sel = { 761static struct clk_regmap gxbb_mpeg_clk_sel = {
618 .reg = (void *)HHI_MPEG_CLK_CNTL, 762 .data = &(struct clk_regmap_mux_data){
619 .mask = 0x7, 763 .offset = HHI_MPEG_CLK_CNTL,
620 .shift = 12, 764 .mask = 0x7,
621 .flags = CLK_MUX_READ_ONLY, 765 .shift = 12,
622 .table = mux_table_clk81, 766 .table = mux_table_clk81,
623 .lock = &meson_clk_lock, 767 },
624 .hw.init = &(struct clk_init_data){ 768 .hw.init = &(struct clk_init_data){
625 .name = "mpeg_clk_sel", 769 .name = "mpeg_clk_sel",
626 .ops = &clk_mux_ro_ops, 770 .ops = &clk_regmap_mux_ro_ops,
627 /* 771 /*
628 * bits 14:12 selects from 8 possible parents: 772 * bits 14:12 selects from 8 possible parents:
629 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 773 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
@@ -631,72 +775,75 @@ static struct clk_mux gxbb_mpeg_clk_sel = {
631 */ 775 */
632 .parent_names = clk81_parent_names, 776 .parent_names = clk81_parent_names,
633 .num_parents = ARRAY_SIZE(clk81_parent_names), 777 .num_parents = ARRAY_SIZE(clk81_parent_names),
634 .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
635 }, 778 },
636}; 779};
637 780
638static struct clk_divider gxbb_mpeg_clk_div = { 781static struct clk_regmap gxbb_mpeg_clk_div = {
639 .reg = (void *)HHI_MPEG_CLK_CNTL, 782 .data = &(struct clk_regmap_div_data){
640 .shift = 0, 783 .offset = HHI_MPEG_CLK_CNTL,
641 .width = 7, 784 .shift = 0,
642 .lock = &meson_clk_lock, 785 .width = 7,
786 },
643 .hw.init = &(struct clk_init_data){ 787 .hw.init = &(struct clk_init_data){
644 .name = "mpeg_clk_div", 788 .name = "mpeg_clk_div",
645 .ops = &clk_divider_ops, 789 .ops = &clk_regmap_divider_ro_ops,
646 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 790 .parent_names = (const char *[]){ "mpeg_clk_sel" },
647 .num_parents = 1, 791 .num_parents = 1,
648 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
649 }, 792 },
650}; 793};
651 794
652/* the mother of dragons^W gates */ 795/* the mother of dragons gates */
653static struct clk_gate gxbb_clk81 = { 796static struct clk_regmap gxbb_clk81 = {
654 .reg = (void *)HHI_MPEG_CLK_CNTL, 797 .data = &(struct clk_regmap_gate_data){
655 .bit_idx = 7, 798 .offset = HHI_MPEG_CLK_CNTL,
656 .lock = &meson_clk_lock, 799 .bit_idx = 7,
800 },
657 .hw.init = &(struct clk_init_data){ 801 .hw.init = &(struct clk_init_data){
658 .name = "clk81", 802 .name = "clk81",
659 .ops = &clk_gate_ops, 803 .ops = &clk_regmap_gate_ops,
660 .parent_names = (const char *[]){ "mpeg_clk_div" }, 804 .parent_names = (const char *[]){ "mpeg_clk_div" },
661 .num_parents = 1, 805 .num_parents = 1,
662 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 806 .flags = CLK_IS_CRITICAL,
663 }, 807 },
664}; 808};
665 809
666static struct clk_mux gxbb_sar_adc_clk_sel = { 810static struct clk_regmap gxbb_sar_adc_clk_sel = {
667 .reg = (void *)HHI_SAR_CLK_CNTL, 811 .data = &(struct clk_regmap_mux_data){
668 .mask = 0x3, 812 .offset = HHI_SAR_CLK_CNTL,
669 .shift = 9, 813 .mask = 0x3,
670 .lock = &meson_clk_lock, 814 .shift = 9,
815 },
671 .hw.init = &(struct clk_init_data){ 816 .hw.init = &(struct clk_init_data){
672 .name = "sar_adc_clk_sel", 817 .name = "sar_adc_clk_sel",
673 .ops = &clk_mux_ops, 818 .ops = &clk_regmap_mux_ops,
674 /* NOTE: The datasheet doesn't list the parents for bit 10 */ 819 /* NOTE: The datasheet doesn't list the parents for bit 10 */
675 .parent_names = (const char *[]){ "xtal", "clk81", }, 820 .parent_names = (const char *[]){ "xtal", "clk81", },
676 .num_parents = 2, 821 .num_parents = 2,
677 }, 822 },
678}; 823};
679 824
680static struct clk_divider gxbb_sar_adc_clk_div = { 825static struct clk_regmap gxbb_sar_adc_clk_div = {
681 .reg = (void *)HHI_SAR_CLK_CNTL, 826 .data = &(struct clk_regmap_div_data){
682 .shift = 0, 827 .offset = HHI_SAR_CLK_CNTL,
683 .width = 8, 828 .shift = 0,
684 .lock = &meson_clk_lock, 829 .width = 8,
830 },
685 .hw.init = &(struct clk_init_data){ 831 .hw.init = &(struct clk_init_data){
686 .name = "sar_adc_clk_div", 832 .name = "sar_adc_clk_div",
687 .ops = &clk_divider_ops, 833 .ops = &clk_regmap_divider_ops,
688 .parent_names = (const char *[]){ "sar_adc_clk_sel" }, 834 .parent_names = (const char *[]){ "sar_adc_clk_sel" },
689 .num_parents = 1, 835 .num_parents = 1,
690 }, 836 },
691}; 837};
692 838
693static struct clk_gate gxbb_sar_adc_clk = { 839static struct clk_regmap gxbb_sar_adc_clk = {
694 .reg = (void *)HHI_SAR_CLK_CNTL, 840 .data = &(struct clk_regmap_gate_data){
695 .bit_idx = 8, 841 .offset = HHI_SAR_CLK_CNTL,
696 .lock = &meson_clk_lock, 842 .bit_idx = 8,
843 },
697 .hw.init = &(struct clk_init_data){ 844 .hw.init = &(struct clk_init_data){
698 .name = "sar_adc_clk", 845 .name = "sar_adc_clk",
699 .ops = &clk_gate_ops, 846 .ops = &clk_regmap_gate_ops,
700 .parent_names = (const char *[]){ "sar_adc_clk_div" }, 847 .parent_names = (const char *[]){ "sar_adc_clk_div" },
701 .num_parents = 1, 848 .num_parents = 1,
702 .flags = CLK_SET_RATE_PARENT, 849 .flags = CLK_SET_RATE_PARENT,
@@ -708,21 +855,20 @@ static struct clk_gate gxbb_sar_adc_clk = {
708 * muxed by a glitch-free switch. 855 * muxed by a glitch-free switch.
709 */ 856 */
710 857
711static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7};
712static const char * const gxbb_mali_0_1_parent_names[] = { 858static const char * const gxbb_mali_0_1_parent_names[] = {
713 "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", 859 "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
714 "fclk_div4", "fclk_div3", "fclk_div5" 860 "fclk_div4", "fclk_div3", "fclk_div5"
715}; 861};
716 862
717static struct clk_mux gxbb_mali_0_sel = { 863static struct clk_regmap gxbb_mali_0_sel = {
718 .reg = (void *)HHI_MALI_CLK_CNTL, 864 .data = &(struct clk_regmap_mux_data){
719 .mask = 0x7, 865 .offset = HHI_MALI_CLK_CNTL,
720 .shift = 9, 866 .mask = 0x7,
721 .table = mux_table_mali_0_1, 867 .shift = 9,
722 .lock = &meson_clk_lock, 868 },
723 .hw.init = &(struct clk_init_data){ 869 .hw.init = &(struct clk_init_data){
724 .name = "mali_0_sel", 870 .name = "mali_0_sel",
725 .ops = &clk_mux_ops, 871 .ops = &clk_regmap_mux_ops,
726 /* 872 /*
727 * bits 10:9 selects from 8 possible parents: 873 * bits 10:9 selects from 8 possible parents:
728 * xtal, gp0_pll, mpll2, mpll1, fclk_div7, 874 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
@@ -734,42 +880,44 @@ static struct clk_mux gxbb_mali_0_sel = {
734 }, 880 },
735}; 881};
736 882
737static struct clk_divider gxbb_mali_0_div = { 883static struct clk_regmap gxbb_mali_0_div = {
738 .reg = (void *)HHI_MALI_CLK_CNTL, 884 .data = &(struct clk_regmap_div_data){
739 .shift = 0, 885 .offset = HHI_MALI_CLK_CNTL,
740 .width = 7, 886 .shift = 0,
741 .lock = &meson_clk_lock, 887 .width = 7,
888 },
742 .hw.init = &(struct clk_init_data){ 889 .hw.init = &(struct clk_init_data){
743 .name = "mali_0_div", 890 .name = "mali_0_div",
744 .ops = &clk_divider_ops, 891 .ops = &clk_regmap_divider_ops,
745 .parent_names = (const char *[]){ "mali_0_sel" }, 892 .parent_names = (const char *[]){ "mali_0_sel" },
746 .num_parents = 1, 893 .num_parents = 1,
747 .flags = CLK_SET_RATE_NO_REPARENT, 894 .flags = CLK_SET_RATE_NO_REPARENT,
748 }, 895 },
749}; 896};
750 897
751static struct clk_gate gxbb_mali_0 = { 898static struct clk_regmap gxbb_mali_0 = {
752 .reg = (void *)HHI_MALI_CLK_CNTL, 899 .data = &(struct clk_regmap_gate_data){
753 .bit_idx = 8, 900 .offset = HHI_MALI_CLK_CNTL,
754 .lock = &meson_clk_lock, 901 .bit_idx = 8,
902 },
755 .hw.init = &(struct clk_init_data){ 903 .hw.init = &(struct clk_init_data){
756 .name = "mali_0", 904 .name = "mali_0",
757 .ops = &clk_gate_ops, 905 .ops = &clk_regmap_gate_ops,
758 .parent_names = (const char *[]){ "mali_0_div" }, 906 .parent_names = (const char *[]){ "mali_0_div" },
759 .num_parents = 1, 907 .num_parents = 1,
760 .flags = CLK_SET_RATE_PARENT, 908 .flags = CLK_SET_RATE_PARENT,
761 }, 909 },
762}; 910};
763 911
764static struct clk_mux gxbb_mali_1_sel = { 912static struct clk_regmap gxbb_mali_1_sel = {
765 .reg = (void *)HHI_MALI_CLK_CNTL, 913 .data = &(struct clk_regmap_mux_data){
766 .mask = 0x7, 914 .offset = HHI_MALI_CLK_CNTL,
767 .shift = 25, 915 .mask = 0x7,
768 .table = mux_table_mali_0_1, 916 .shift = 25,
769 .lock = &meson_clk_lock, 917 },
770 .hw.init = &(struct clk_init_data){ 918 .hw.init = &(struct clk_init_data){
771 .name = "mali_1_sel", 919 .name = "mali_1_sel",
772 .ops = &clk_mux_ops, 920 .ops = &clk_regmap_mux_ops,
773 /* 921 /*
774 * bits 10:9 selects from 8 possible parents: 922 * bits 10:9 selects from 8 possible parents:
775 * xtal, gp0_pll, mpll2, mpll1, fclk_div7, 923 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
@@ -781,77 +929,79 @@ static struct clk_mux gxbb_mali_1_sel = {
781 }, 929 },
782}; 930};
783 931
784static struct clk_divider gxbb_mali_1_div = { 932static struct clk_regmap gxbb_mali_1_div = {
785 .reg = (void *)HHI_MALI_CLK_CNTL, 933 .data = &(struct clk_regmap_div_data){
786 .shift = 16, 934 .offset = HHI_MALI_CLK_CNTL,
787 .width = 7, 935 .shift = 16,
788 .lock = &meson_clk_lock, 936 .width = 7,
937 },
789 .hw.init = &(struct clk_init_data){ 938 .hw.init = &(struct clk_init_data){
790 .name = "mali_1_div", 939 .name = "mali_1_div",
791 .ops = &clk_divider_ops, 940 .ops = &clk_regmap_divider_ops,
792 .parent_names = (const char *[]){ "mali_1_sel" }, 941 .parent_names = (const char *[]){ "mali_1_sel" },
793 .num_parents = 1, 942 .num_parents = 1,
794 .flags = CLK_SET_RATE_NO_REPARENT, 943 .flags = CLK_SET_RATE_NO_REPARENT,
795 }, 944 },
796}; 945};
797 946
798static struct clk_gate gxbb_mali_1 = { 947static struct clk_regmap gxbb_mali_1 = {
799 .reg = (void *)HHI_MALI_CLK_CNTL, 948 .data = &(struct clk_regmap_gate_data){
800 .bit_idx = 24, 949 .offset = HHI_MALI_CLK_CNTL,
801 .lock = &meson_clk_lock, 950 .bit_idx = 24,
951 },
802 .hw.init = &(struct clk_init_data){ 952 .hw.init = &(struct clk_init_data){
803 .name = "mali_1", 953 .name = "mali_1",
804 .ops = &clk_gate_ops, 954 .ops = &clk_regmap_gate_ops,
805 .parent_names = (const char *[]){ "mali_1_div" }, 955 .parent_names = (const char *[]){ "mali_1_div" },
806 .num_parents = 1, 956 .num_parents = 1,
807 .flags = CLK_SET_RATE_PARENT, 957 .flags = CLK_SET_RATE_PARENT,
808 }, 958 },
809}; 959};
810 960
811static u32 mux_table_mali[] = {0, 1};
812static const char * const gxbb_mali_parent_names[] = { 961static const char * const gxbb_mali_parent_names[] = {
813 "mali_0", "mali_1" 962 "mali_0", "mali_1"
814}; 963};
815 964
816static struct clk_mux gxbb_mali = { 965static struct clk_regmap gxbb_mali = {
817 .reg = (void *)HHI_MALI_CLK_CNTL, 966 .data = &(struct clk_regmap_mux_data){
818 .mask = 1, 967 .offset = HHI_MALI_CLK_CNTL,
819 .shift = 31, 968 .mask = 1,
820 .table = mux_table_mali, 969 .shift = 31,
821 .lock = &meson_clk_lock, 970 },
822 .hw.init = &(struct clk_init_data){ 971 .hw.init = &(struct clk_init_data){
823 .name = "mali", 972 .name = "mali",
824 .ops = &clk_mux_ops, 973 .ops = &clk_regmap_mux_ops,
825 .parent_names = gxbb_mali_parent_names, 974 .parent_names = gxbb_mali_parent_names,
826 .num_parents = 2, 975 .num_parents = 2,
827 .flags = CLK_SET_RATE_NO_REPARENT, 976 .flags = CLK_SET_RATE_NO_REPARENT,
828 }, 977 },
829}; 978};
830 979
831static struct clk_mux gxbb_cts_amclk_sel = { 980static struct clk_regmap gxbb_cts_amclk_sel = {
832 .reg = (void *) HHI_AUD_CLK_CNTL, 981 .data = &(struct clk_regmap_mux_data){
833 .mask = 0x3, 982 .offset = HHI_AUD_CLK_CNTL,
834 .shift = 9, 983 .mask = 0x3,
835 /* Default parent unknown (register reset value: 0) */ 984 .shift = 9,
836 .table = (u32[]){ 1, 2, 3 }, 985 .table = (u32[]){ 1, 2, 3 },
837 .lock = &meson_clk_lock, 986 },
838 .hw.init = &(struct clk_init_data){ 987 .hw.init = &(struct clk_init_data){
839 .name = "cts_amclk_sel", 988 .name = "cts_amclk_sel",
840 .ops = &clk_mux_ops, 989 .ops = &clk_regmap_mux_ops,
841 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 990 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
842 .num_parents = 3, 991 .num_parents = 3,
843 .flags = CLK_SET_RATE_PARENT, 992 .flags = CLK_SET_RATE_PARENT,
844 }, 993 },
845}; 994};
846 995
847static struct meson_clk_audio_divider gxbb_cts_amclk_div = { 996static struct clk_regmap gxbb_cts_amclk_div = {
848 .div = { 997 .data = &(struct meson_clk_audio_div_data){
849 .reg_off = HHI_AUD_CLK_CNTL, 998 .div = {
850 .shift = 0, 999 .reg_off = HHI_AUD_CLK_CNTL,
851 .width = 8, 1000 .shift = 0,
1001 .width = 8,
1002 },
1003 .flags = CLK_DIVIDER_ROUND_CLOSEST,
852 }, 1004 },
853 .flags = CLK_DIVIDER_ROUND_CLOSEST,
854 .lock = &meson_clk_lock,
855 .hw.init = &(struct clk_init_data){ 1005 .hw.init = &(struct clk_init_data){
856 .name = "cts_amclk_div", 1006 .name = "cts_amclk_div",
857 .ops = &meson_clk_audio_divider_ops, 1007 .ops = &meson_clk_audio_divider_ops,
@@ -861,71 +1011,75 @@ static struct meson_clk_audio_divider gxbb_cts_amclk_div = {
861 }, 1011 },
862}; 1012};
863 1013
864static struct clk_gate gxbb_cts_amclk = { 1014static struct clk_regmap gxbb_cts_amclk = {
865 .reg = (void *) HHI_AUD_CLK_CNTL, 1015 .data = &(struct clk_regmap_gate_data){
866 .bit_idx = 8, 1016 .offset = HHI_AUD_CLK_CNTL,
867 .lock = &meson_clk_lock, 1017 .bit_idx = 8,
1018 },
868 .hw.init = &(struct clk_init_data){ 1019 .hw.init = &(struct clk_init_data){
869 .name = "cts_amclk", 1020 .name = "cts_amclk",
870 .ops = &clk_gate_ops, 1021 .ops = &clk_regmap_gate_ops,
871 .parent_names = (const char *[]){ "cts_amclk_div" }, 1022 .parent_names = (const char *[]){ "cts_amclk_div" },
872 .num_parents = 1, 1023 .num_parents = 1,
873 .flags = CLK_SET_RATE_PARENT, 1024 .flags = CLK_SET_RATE_PARENT,
874 }, 1025 },
875}; 1026};
876 1027
877static struct clk_mux gxbb_cts_mclk_i958_sel = { 1028static struct clk_regmap gxbb_cts_mclk_i958_sel = {
878 .reg = (void *)HHI_AUD_CLK_CNTL2, 1029 .data = &(struct clk_regmap_mux_data){
879 .mask = 0x3, 1030 .offset = HHI_AUD_CLK_CNTL2,
880 .shift = 25, 1031 .mask = 0x3,
881 /* Default parent unknown (register reset value: 0) */ 1032 .shift = 25,
882 .table = (u32[]){ 1, 2, 3 }, 1033 .table = (u32[]){ 1, 2, 3 },
883 .lock = &meson_clk_lock, 1034 },
884 .hw.init = &(struct clk_init_data) { 1035 .hw.init = &(struct clk_init_data) {
885 .name = "cts_mclk_i958_sel", 1036 .name = "cts_mclk_i958_sel",
886 .ops = &clk_mux_ops, 1037 .ops = &clk_regmap_mux_ops,
887 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 1038 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
888 .num_parents = 3, 1039 .num_parents = 3,
889 .flags = CLK_SET_RATE_PARENT, 1040 .flags = CLK_SET_RATE_PARENT,
890 }, 1041 },
891}; 1042};
892 1043
893static struct clk_divider gxbb_cts_mclk_i958_div = { 1044static struct clk_regmap gxbb_cts_mclk_i958_div = {
894 .reg = (void *)HHI_AUD_CLK_CNTL2, 1045 .data = &(struct clk_regmap_div_data){
895 .shift = 16, 1046 .offset = HHI_AUD_CLK_CNTL2,
896 .width = 8, 1047 .shift = 16,
897 .lock = &meson_clk_lock, 1048 .width = 8,
898 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1049 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1050 },
899 .hw.init = &(struct clk_init_data) { 1051 .hw.init = &(struct clk_init_data) {
900 .name = "cts_mclk_i958_div", 1052 .name = "cts_mclk_i958_div",
901 .ops = &clk_divider_ops, 1053 .ops = &clk_regmap_divider_ops,
902 .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, 1054 .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
903 .num_parents = 1, 1055 .num_parents = 1,
904 .flags = CLK_SET_RATE_PARENT, 1056 .flags = CLK_SET_RATE_PARENT,
905 }, 1057 },
906}; 1058};
907 1059
908static struct clk_gate gxbb_cts_mclk_i958 = { 1060static struct clk_regmap gxbb_cts_mclk_i958 = {
909 .reg = (void *)HHI_AUD_CLK_CNTL2, 1061 .data = &(struct clk_regmap_gate_data){
910 .bit_idx = 24, 1062 .offset = HHI_AUD_CLK_CNTL2,
911 .lock = &meson_clk_lock, 1063 .bit_idx = 24,
1064 },
912 .hw.init = &(struct clk_init_data){ 1065 .hw.init = &(struct clk_init_data){
913 .name = "cts_mclk_i958", 1066 .name = "cts_mclk_i958",
914 .ops = &clk_gate_ops, 1067 .ops = &clk_regmap_gate_ops,
915 .parent_names = (const char *[]){ "cts_mclk_i958_div" }, 1068 .parent_names = (const char *[]){ "cts_mclk_i958_div" },
916 .num_parents = 1, 1069 .num_parents = 1,
917 .flags = CLK_SET_RATE_PARENT, 1070 .flags = CLK_SET_RATE_PARENT,
918 }, 1071 },
919}; 1072};
920 1073
921static struct clk_mux gxbb_cts_i958 = { 1074static struct clk_regmap gxbb_cts_i958 = {
922 .reg = (void *)HHI_AUD_CLK_CNTL2, 1075 .data = &(struct clk_regmap_mux_data){
923 .mask = 0x1, 1076 .offset = HHI_AUD_CLK_CNTL2,
924 .shift = 27, 1077 .mask = 0x1,
925 .lock = &meson_clk_lock, 1078 .shift = 27,
926 .hw.init = &(struct clk_init_data){ 1079 },
1080 .hw.init = &(struct clk_init_data){
927 .name = "cts_i958", 1081 .name = "cts_i958",
928 .ops = &clk_mux_ops, 1082 .ops = &clk_regmap_mux_ops,
929 .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" }, 1083 .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" },
930 .num_parents = 2, 1084 .num_parents = 2,
931 /* 1085 /*
@@ -936,27 +1090,29 @@ static struct clk_mux gxbb_cts_i958 = {
936 }, 1090 },
937}; 1091};
938 1092
939static struct clk_divider gxbb_32k_clk_div = { 1093static struct clk_regmap gxbb_32k_clk_div = {
940 .reg = (void *)HHI_32K_CLK_CNTL, 1094 .data = &(struct clk_regmap_div_data){
941 .shift = 0, 1095 .offset = HHI_32K_CLK_CNTL,
942 .width = 14, 1096 .shift = 0,
943 .lock = &meson_clk_lock, 1097 .width = 14,
1098 },
944 .hw.init = &(struct clk_init_data){ 1099 .hw.init = &(struct clk_init_data){
945 .name = "32k_clk_div", 1100 .name = "32k_clk_div",
946 .ops = &clk_divider_ops, 1101 .ops = &clk_regmap_divider_ops,
947 .parent_names = (const char *[]){ "32k_clk_sel" }, 1102 .parent_names = (const char *[]){ "32k_clk_sel" },
948 .num_parents = 1, 1103 .num_parents = 1,
949 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 1104 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
950 }, 1105 },
951}; 1106};
952 1107
953static struct clk_gate gxbb_32k_clk = { 1108static struct clk_regmap gxbb_32k_clk = {
954 .reg = (void *)HHI_32K_CLK_CNTL, 1109 .data = &(struct clk_regmap_gate_data){
955 .bit_idx = 15, 1110 .offset = HHI_32K_CLK_CNTL,
956 .lock = &meson_clk_lock, 1111 .bit_idx = 15,
1112 },
957 .hw.init = &(struct clk_init_data){ 1113 .hw.init = &(struct clk_init_data){
958 .name = "32k_clk", 1114 .name = "32k_clk",
959 .ops = &clk_gate_ops, 1115 .ops = &clk_regmap_gate_ops,
960 .parent_names = (const char *[]){ "32k_clk_div" }, 1116 .parent_names = (const char *[]){ "32k_clk_div" },
961 .num_parents = 1, 1117 .num_parents = 1,
962 .flags = CLK_SET_RATE_PARENT, 1118 .flags = CLK_SET_RATE_PARENT,
@@ -967,14 +1123,15 @@ static const char * const gxbb_32k_clk_parent_names[] = {
967 "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" 1123 "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
968}; 1124};
969 1125
970static struct clk_mux gxbb_32k_clk_sel = { 1126static struct clk_regmap gxbb_32k_clk_sel = {
971 .reg = (void *)HHI_32K_CLK_CNTL, 1127 .data = &(struct clk_regmap_mux_data){
972 .mask = 0x3, 1128 .offset = HHI_32K_CLK_CNTL,
973 .shift = 16, 1129 .mask = 0x3,
974 .lock = &meson_clk_lock, 1130 .shift = 16,
975 .hw.init = &(struct clk_init_data){ 1131 },
1132 .hw.init = &(struct clk_init_data){
976 .name = "32k_clk_sel", 1133 .name = "32k_clk_sel",
977 .ops = &clk_mux_ops, 1134 .ops = &clk_regmap_mux_ops,
978 .parent_names = gxbb_32k_clk_parent_names, 1135 .parent_names = gxbb_32k_clk_parent_names,
979 .num_parents = 4, 1136 .num_parents = 4,
980 .flags = CLK_SET_RATE_PARENT, 1137 .flags = CLK_SET_RATE_PARENT,
@@ -993,42 +1150,45 @@ static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
993}; 1150};
994 1151
995/* SDIO clock */ 1152/* SDIO clock */
996static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { 1153static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = {
997 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1154 .data = &(struct clk_regmap_mux_data){
998 .mask = 0x7, 1155 .offset = HHI_SD_EMMC_CLK_CNTL,
999 .shift = 9, 1156 .mask = 0x7,
1000 .lock = &meson_clk_lock, 1157 .shift = 9,
1158 },
1001 .hw.init = &(struct clk_init_data) { 1159 .hw.init = &(struct clk_init_data) {
1002 .name = "sd_emmc_a_clk0_sel", 1160 .name = "sd_emmc_a_clk0_sel",
1003 .ops = &clk_mux_ops, 1161 .ops = &clk_regmap_mux_ops,
1004 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1162 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1005 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1163 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1006 .flags = CLK_SET_RATE_PARENT, 1164 .flags = CLK_SET_RATE_PARENT,
1007 }, 1165 },
1008}; 1166};
1009 1167
1010static struct clk_divider gxbb_sd_emmc_a_clk0_div = { 1168static struct clk_regmap gxbb_sd_emmc_a_clk0_div = {
1011 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1169 .data = &(struct clk_regmap_div_data){
1012 .shift = 0, 1170 .offset = HHI_SD_EMMC_CLK_CNTL,
1013 .width = 7, 1171 .shift = 0,
1014 .lock = &meson_clk_lock, 1172 .width = 7,
1015 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1173 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1174 },
1016 .hw.init = &(struct clk_init_data) { 1175 .hw.init = &(struct clk_init_data) {
1017 .name = "sd_emmc_a_clk0_div", 1176 .name = "sd_emmc_a_clk0_div",
1018 .ops = &clk_divider_ops, 1177 .ops = &clk_regmap_divider_ops,
1019 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, 1178 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
1020 .num_parents = 1, 1179 .num_parents = 1,
1021 .flags = CLK_SET_RATE_PARENT, 1180 .flags = CLK_SET_RATE_PARENT,
1022 }, 1181 },
1023}; 1182};
1024 1183
1025static struct clk_gate gxbb_sd_emmc_a_clk0 = { 1184static struct clk_regmap gxbb_sd_emmc_a_clk0 = {
1026 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1185 .data = &(struct clk_regmap_gate_data){
1027 .bit_idx = 7, 1186 .offset = HHI_SD_EMMC_CLK_CNTL,
1028 .lock = &meson_clk_lock, 1187 .bit_idx = 7,
1188 },
1029 .hw.init = &(struct clk_init_data){ 1189 .hw.init = &(struct clk_init_data){
1030 .name = "sd_emmc_a_clk0", 1190 .name = "sd_emmc_a_clk0",
1031 .ops = &clk_gate_ops, 1191 .ops = &clk_regmap_gate_ops,
1032 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, 1192 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
1033 .num_parents = 1, 1193 .num_parents = 1,
1034 .flags = CLK_SET_RATE_PARENT, 1194 .flags = CLK_SET_RATE_PARENT,
@@ -1036,42 +1196,45 @@ static struct clk_gate gxbb_sd_emmc_a_clk0 = {
1036}; 1196};
1037 1197
1038/* SDcard clock */ 1198/* SDcard clock */
1039static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { 1199static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = {
1040 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1200 .data = &(struct clk_regmap_mux_data){
1041 .mask = 0x7, 1201 .offset = HHI_SD_EMMC_CLK_CNTL,
1042 .shift = 25, 1202 .mask = 0x7,
1043 .lock = &meson_clk_lock, 1203 .shift = 25,
1204 },
1044 .hw.init = &(struct clk_init_data) { 1205 .hw.init = &(struct clk_init_data) {
1045 .name = "sd_emmc_b_clk0_sel", 1206 .name = "sd_emmc_b_clk0_sel",
1046 .ops = &clk_mux_ops, 1207 .ops = &clk_regmap_mux_ops,
1047 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1208 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1048 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1209 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1049 .flags = CLK_SET_RATE_PARENT, 1210 .flags = CLK_SET_RATE_PARENT,
1050 }, 1211 },
1051}; 1212};
1052 1213
1053static struct clk_divider gxbb_sd_emmc_b_clk0_div = { 1214static struct clk_regmap gxbb_sd_emmc_b_clk0_div = {
1054 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1215 .data = &(struct clk_regmap_div_data){
1055 .shift = 16, 1216 .offset = HHI_SD_EMMC_CLK_CNTL,
1056 .width = 7, 1217 .shift = 16,
1057 .lock = &meson_clk_lock, 1218 .width = 7,
1058 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1219 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1220 },
1059 .hw.init = &(struct clk_init_data) { 1221 .hw.init = &(struct clk_init_data) {
1060 .name = "sd_emmc_b_clk0_div", 1222 .name = "sd_emmc_b_clk0_div",
1061 .ops = &clk_divider_ops, 1223 .ops = &clk_regmap_divider_ops,
1062 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 1224 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
1063 .num_parents = 1, 1225 .num_parents = 1,
1064 .flags = CLK_SET_RATE_PARENT, 1226 .flags = CLK_SET_RATE_PARENT,
1065 }, 1227 },
1066}; 1228};
1067 1229
1068static struct clk_gate gxbb_sd_emmc_b_clk0 = { 1230static struct clk_regmap gxbb_sd_emmc_b_clk0 = {
1069 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1231 .data = &(struct clk_regmap_gate_data){
1070 .bit_idx = 23, 1232 .offset = HHI_SD_EMMC_CLK_CNTL,
1071 .lock = &meson_clk_lock, 1233 .bit_idx = 23,
1234 },
1072 .hw.init = &(struct clk_init_data){ 1235 .hw.init = &(struct clk_init_data){
1073 .name = "sd_emmc_b_clk0", 1236 .name = "sd_emmc_b_clk0",
1074 .ops = &clk_gate_ops, 1237 .ops = &clk_regmap_gate_ops,
1075 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 1238 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
1076 .num_parents = 1, 1239 .num_parents = 1,
1077 .flags = CLK_SET_RATE_PARENT, 1240 .flags = CLK_SET_RATE_PARENT,
@@ -1079,42 +1242,45 @@ static struct clk_gate gxbb_sd_emmc_b_clk0 = {
1079}; 1242};
1080 1243
1081/* EMMC/NAND clock */ 1244/* EMMC/NAND clock */
1082static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { 1245static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = {
1083 .reg = (void *)HHI_NAND_CLK_CNTL, 1246 .data = &(struct clk_regmap_mux_data){
1084 .mask = 0x7, 1247 .offset = HHI_NAND_CLK_CNTL,
1085 .shift = 9, 1248 .mask = 0x7,
1086 .lock = &meson_clk_lock, 1249 .shift = 9,
1250 },
1087 .hw.init = &(struct clk_init_data) { 1251 .hw.init = &(struct clk_init_data) {
1088 .name = "sd_emmc_c_clk0_sel", 1252 .name = "sd_emmc_c_clk0_sel",
1089 .ops = &clk_mux_ops, 1253 .ops = &clk_regmap_mux_ops,
1090 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1254 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1091 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1255 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1092 .flags = CLK_SET_RATE_PARENT, 1256 .flags = CLK_SET_RATE_PARENT,
1093 }, 1257 },
1094}; 1258};
1095 1259
1096static struct clk_divider gxbb_sd_emmc_c_clk0_div = { 1260static struct clk_regmap gxbb_sd_emmc_c_clk0_div = {
1097 .reg = (void *)HHI_NAND_CLK_CNTL, 1261 .data = &(struct clk_regmap_div_data){
1098 .shift = 0, 1262 .offset = HHI_NAND_CLK_CNTL,
1099 .width = 7, 1263 .shift = 0,
1100 .lock = &meson_clk_lock, 1264 .width = 7,
1101 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1265 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1266 },
1102 .hw.init = &(struct clk_init_data) { 1267 .hw.init = &(struct clk_init_data) {
1103 .name = "sd_emmc_c_clk0_div", 1268 .name = "sd_emmc_c_clk0_div",
1104 .ops = &clk_divider_ops, 1269 .ops = &clk_regmap_divider_ops,
1105 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 1270 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
1106 .num_parents = 1, 1271 .num_parents = 1,
1107 .flags = CLK_SET_RATE_PARENT, 1272 .flags = CLK_SET_RATE_PARENT,
1108 }, 1273 },
1109}; 1274};
1110 1275
1111static struct clk_gate gxbb_sd_emmc_c_clk0 = { 1276static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
1112 .reg = (void *)HHI_NAND_CLK_CNTL, 1277 .data = &(struct clk_regmap_gate_data){
1113 .bit_idx = 7, 1278 .offset = HHI_NAND_CLK_CNTL,
1114 .lock = &meson_clk_lock, 1279 .bit_idx = 7,
1280 },
1115 .hw.init = &(struct clk_init_data){ 1281 .hw.init = &(struct clk_init_data){
1116 .name = "sd_emmc_c_clk0", 1282 .name = "sd_emmc_c_clk0",
1117 .ops = &clk_gate_ops, 1283 .ops = &clk_regmap_gate_ops,
1118 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 1284 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
1119 .num_parents = 1, 1285 .num_parents = 1,
1120 .flags = CLK_SET_RATE_PARENT, 1286 .flags = CLK_SET_RATE_PARENT,
@@ -1123,20 +1289,19 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = {
1123 1289
1124/* VPU Clock */ 1290/* VPU Clock */
1125 1291
1126static u32 mux_table_vpu[] = {0, 1, 2, 3};
1127static const char * const gxbb_vpu_parent_names[] = { 1292static const char * const gxbb_vpu_parent_names[] = {
1128 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" 1293 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
1129}; 1294};
1130 1295
1131static struct clk_mux gxbb_vpu_0_sel = { 1296static struct clk_regmap gxbb_vpu_0_sel = {
1132 .reg = (void *)HHI_VPU_CLK_CNTL, 1297 .data = &(struct clk_regmap_mux_data){
1133 .mask = 0x3, 1298 .offset = HHI_VPU_CLK_CNTL,
1134 .shift = 9, 1299 .mask = 0x3,
1135 .lock = &meson_clk_lock, 1300 .shift = 9,
1136 .table = mux_table_vpu, 1301 },
1137 .hw.init = &(struct clk_init_data){ 1302 .hw.init = &(struct clk_init_data){
1138 .name = "vpu_0_sel", 1303 .name = "vpu_0_sel",
1139 .ops = &clk_mux_ops, 1304 .ops = &clk_regmap_mux_ops,
1140 /* 1305 /*
1141 * bits 9:10 selects from 4 possible parents: 1306 * bits 9:10 selects from 4 possible parents:
1142 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1307 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1147,42 +1312,44 @@ static struct clk_mux gxbb_vpu_0_sel = {
1147 }, 1312 },
1148}; 1313};
1149 1314
1150static struct clk_divider gxbb_vpu_0_div = { 1315static struct clk_regmap gxbb_vpu_0_div = {
1151 .reg = (void *)HHI_VPU_CLK_CNTL, 1316 .data = &(struct clk_regmap_div_data){
1152 .shift = 0, 1317 .offset = HHI_VPU_CLK_CNTL,
1153 .width = 7, 1318 .shift = 0,
1154 .lock = &meson_clk_lock, 1319 .width = 7,
1320 },
1155 .hw.init = &(struct clk_init_data){ 1321 .hw.init = &(struct clk_init_data){
1156 .name = "vpu_0_div", 1322 .name = "vpu_0_div",
1157 .ops = &clk_divider_ops, 1323 .ops = &clk_regmap_divider_ops,
1158 .parent_names = (const char *[]){ "vpu_0_sel" }, 1324 .parent_names = (const char *[]){ "vpu_0_sel" },
1159 .num_parents = 1, 1325 .num_parents = 1,
1160 .flags = CLK_SET_RATE_PARENT, 1326 .flags = CLK_SET_RATE_PARENT,
1161 }, 1327 },
1162}; 1328};
1163 1329
1164static struct clk_gate gxbb_vpu_0 = { 1330static struct clk_regmap gxbb_vpu_0 = {
1165 .reg = (void *)HHI_VPU_CLK_CNTL, 1331 .data = &(struct clk_regmap_gate_data){
1166 .bit_idx = 8, 1332 .offset = HHI_VPU_CLK_CNTL,
1167 .lock = &meson_clk_lock, 1333 .bit_idx = 8,
1334 },
1168 .hw.init = &(struct clk_init_data) { 1335 .hw.init = &(struct clk_init_data) {
1169 .name = "vpu_0", 1336 .name = "vpu_0",
1170 .ops = &clk_gate_ops, 1337 .ops = &clk_regmap_gate_ops,
1171 .parent_names = (const char *[]){ "vpu_0_div" }, 1338 .parent_names = (const char *[]){ "vpu_0_div" },
1172 .num_parents = 1, 1339 .num_parents = 1,
1173 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1340 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1174 }, 1341 },
1175}; 1342};
1176 1343
1177static struct clk_mux gxbb_vpu_1_sel = { 1344static struct clk_regmap gxbb_vpu_1_sel = {
1178 .reg = (void *)HHI_VPU_CLK_CNTL, 1345 .data = &(struct clk_regmap_mux_data){
1179 .mask = 0x3, 1346 .offset = HHI_VPU_CLK_CNTL,
1180 .shift = 25, 1347 .mask = 0x3,
1181 .lock = &meson_clk_lock, 1348 .shift = 25,
1182 .table = mux_table_vpu, 1349 },
1183 .hw.init = &(struct clk_init_data){ 1350 .hw.init = &(struct clk_init_data){
1184 .name = "vpu_1_sel", 1351 .name = "vpu_1_sel",
1185 .ops = &clk_mux_ops, 1352 .ops = &clk_regmap_mux_ops,
1186 /* 1353 /*
1187 * bits 25:26 selects from 4 possible parents: 1354 * bits 25:26 selects from 4 possible parents:
1188 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1355 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1193,41 +1360,44 @@ static struct clk_mux gxbb_vpu_1_sel = {
1193 }, 1360 },
1194}; 1361};
1195 1362
1196static struct clk_divider gxbb_vpu_1_div = { 1363static struct clk_regmap gxbb_vpu_1_div = {
1197 .reg = (void *)HHI_VPU_CLK_CNTL, 1364 .data = &(struct clk_regmap_div_data){
1198 .shift = 16, 1365 .offset = HHI_VPU_CLK_CNTL,
1199 .width = 7, 1366 .shift = 16,
1200 .lock = &meson_clk_lock, 1367 .width = 7,
1368 },
1201 .hw.init = &(struct clk_init_data){ 1369 .hw.init = &(struct clk_init_data){
1202 .name = "vpu_1_div", 1370 .name = "vpu_1_div",
1203 .ops = &clk_divider_ops, 1371 .ops = &clk_regmap_divider_ops,
1204 .parent_names = (const char *[]){ "vpu_1_sel" }, 1372 .parent_names = (const char *[]){ "vpu_1_sel" },
1205 .num_parents = 1, 1373 .num_parents = 1,
1206 .flags = CLK_SET_RATE_PARENT, 1374 .flags = CLK_SET_RATE_PARENT,
1207 }, 1375 },
1208}; 1376};
1209 1377
1210static struct clk_gate gxbb_vpu_1 = { 1378static struct clk_regmap gxbb_vpu_1 = {
1211 .reg = (void *)HHI_VPU_CLK_CNTL, 1379 .data = &(struct clk_regmap_gate_data){
1212 .bit_idx = 24, 1380 .offset = HHI_VPU_CLK_CNTL,
1213 .lock = &meson_clk_lock, 1381 .bit_idx = 24,
1382 },
1214 .hw.init = &(struct clk_init_data) { 1383 .hw.init = &(struct clk_init_data) {
1215 .name = "vpu_1", 1384 .name = "vpu_1",
1216 .ops = &clk_gate_ops, 1385 .ops = &clk_regmap_gate_ops,
1217 .parent_names = (const char *[]){ "vpu_1_div" }, 1386 .parent_names = (const char *[]){ "vpu_1_div" },
1218 .num_parents = 1, 1387 .num_parents = 1,
1219 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1388 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1220 }, 1389 },
1221}; 1390};
1222 1391
1223static struct clk_mux gxbb_vpu = { 1392static struct clk_regmap gxbb_vpu = {
1224 .reg = (void *)HHI_VPU_CLK_CNTL, 1393 .data = &(struct clk_regmap_mux_data){
1225 .mask = 1, 1394 .offset = HHI_VPU_CLK_CNTL,
1226 .shift = 31, 1395 .mask = 1,
1227 .lock = &meson_clk_lock, 1396 .shift = 31,
1397 },
1228 .hw.init = &(struct clk_init_data){ 1398 .hw.init = &(struct clk_init_data){
1229 .name = "vpu", 1399 .name = "vpu",
1230 .ops = &clk_mux_ops, 1400 .ops = &clk_regmap_mux_ops,
1231 /* 1401 /*
1232 * bit 31 selects from 2 possible parents: 1402 * bit 31 selects from 2 possible parents:
1233 * vpu_0 or vpu_1 1403 * vpu_0 or vpu_1
@@ -1240,20 +1410,19 @@ static struct clk_mux gxbb_vpu = {
1240 1410
1241/* VAPB Clock */ 1411/* VAPB Clock */
1242 1412
1243static u32 mux_table_vapb[] = {0, 1, 2, 3};
1244static const char * const gxbb_vapb_parent_names[] = { 1413static const char * const gxbb_vapb_parent_names[] = {
1245 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" 1414 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
1246}; 1415};
1247 1416
1248static struct clk_mux gxbb_vapb_0_sel = { 1417static struct clk_regmap gxbb_vapb_0_sel = {
1249 .reg = (void *)HHI_VAPBCLK_CNTL, 1418 .data = &(struct clk_regmap_mux_data){
1250 .mask = 0x3, 1419 .offset = HHI_VAPBCLK_CNTL,
1251 .shift = 9, 1420 .mask = 0x3,
1252 .lock = &meson_clk_lock, 1421 .shift = 9,
1253 .table = mux_table_vapb, 1422 },
1254 .hw.init = &(struct clk_init_data){ 1423 .hw.init = &(struct clk_init_data){
1255 .name = "vapb_0_sel", 1424 .name = "vapb_0_sel",
1256 .ops = &clk_mux_ops, 1425 .ops = &clk_regmap_mux_ops,
1257 /* 1426 /*
1258 * bits 9:10 selects from 4 possible parents: 1427 * bits 9:10 selects from 4 possible parents:
1259 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1428 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1264,42 +1433,44 @@ static struct clk_mux gxbb_vapb_0_sel = {
1264 }, 1433 },
1265}; 1434};
1266 1435
1267static struct clk_divider gxbb_vapb_0_div = { 1436static struct clk_regmap gxbb_vapb_0_div = {
1268 .reg = (void *)HHI_VAPBCLK_CNTL, 1437 .data = &(struct clk_regmap_div_data){
1269 .shift = 0, 1438 .offset = HHI_VAPBCLK_CNTL,
1270 .width = 7, 1439 .shift = 0,
1271 .lock = &meson_clk_lock, 1440 .width = 7,
1441 },
1272 .hw.init = &(struct clk_init_data){ 1442 .hw.init = &(struct clk_init_data){
1273 .name = "vapb_0_div", 1443 .name = "vapb_0_div",
1274 .ops = &clk_divider_ops, 1444 .ops = &clk_regmap_divider_ops,
1275 .parent_names = (const char *[]){ "vapb_0_sel" }, 1445 .parent_names = (const char *[]){ "vapb_0_sel" },
1276 .num_parents = 1, 1446 .num_parents = 1,
1277 .flags = CLK_SET_RATE_PARENT, 1447 .flags = CLK_SET_RATE_PARENT,
1278 }, 1448 },
1279}; 1449};
1280 1450
1281static struct clk_gate gxbb_vapb_0 = { 1451static struct clk_regmap gxbb_vapb_0 = {
1282 .reg = (void *)HHI_VAPBCLK_CNTL, 1452 .data = &(struct clk_regmap_gate_data){
1283 .bit_idx = 8, 1453 .offset = HHI_VAPBCLK_CNTL,
1284 .lock = &meson_clk_lock, 1454 .bit_idx = 8,
1455 },
1285 .hw.init = &(struct clk_init_data) { 1456 .hw.init = &(struct clk_init_data) {
1286 .name = "vapb_0", 1457 .name = "vapb_0",
1287 .ops = &clk_gate_ops, 1458 .ops = &clk_regmap_gate_ops,
1288 .parent_names = (const char *[]){ "vapb_0_div" }, 1459 .parent_names = (const char *[]){ "vapb_0_div" },
1289 .num_parents = 1, 1460 .num_parents = 1,
1290 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1461 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1291 }, 1462 },
1292}; 1463};
1293 1464
1294static struct clk_mux gxbb_vapb_1_sel = { 1465static struct clk_regmap gxbb_vapb_1_sel = {
1295 .reg = (void *)HHI_VAPBCLK_CNTL, 1466 .data = &(struct clk_regmap_mux_data){
1296 .mask = 0x3, 1467 .offset = HHI_VAPBCLK_CNTL,
1297 .shift = 25, 1468 .mask = 0x3,
1298 .lock = &meson_clk_lock, 1469 .shift = 25,
1299 .table = mux_table_vapb, 1470 },
1300 .hw.init = &(struct clk_init_data){ 1471 .hw.init = &(struct clk_init_data){
1301 .name = "vapb_1_sel", 1472 .name = "vapb_1_sel",
1302 .ops = &clk_mux_ops, 1473 .ops = &clk_regmap_mux_ops,
1303 /* 1474 /*
1304 * bits 25:26 selects from 4 possible parents: 1475 * bits 25:26 selects from 4 possible parents:
1305 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1476 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1310,41 +1481,44 @@ static struct clk_mux gxbb_vapb_1_sel = {
1310 }, 1481 },
1311}; 1482};
1312 1483
1313static struct clk_divider gxbb_vapb_1_div = { 1484static struct clk_regmap gxbb_vapb_1_div = {
1314 .reg = (void *)HHI_VAPBCLK_CNTL, 1485 .data = &(struct clk_regmap_div_data){
1315 .shift = 16, 1486 .offset = HHI_VAPBCLK_CNTL,
1316 .width = 7, 1487 .shift = 16,
1317 .lock = &meson_clk_lock, 1488 .width = 7,
1489 },
1318 .hw.init = &(struct clk_init_data){ 1490 .hw.init = &(struct clk_init_data){
1319 .name = "vapb_1_div", 1491 .name = "vapb_1_div",
1320 .ops = &clk_divider_ops, 1492 .ops = &clk_regmap_divider_ops,
1321 .parent_names = (const char *[]){ "vapb_1_sel" }, 1493 .parent_names = (const char *[]){ "vapb_1_sel" },
1322 .num_parents = 1, 1494 .num_parents = 1,
1323 .flags = CLK_SET_RATE_PARENT, 1495 .flags = CLK_SET_RATE_PARENT,
1324 }, 1496 },
1325}; 1497};
1326 1498
1327static struct clk_gate gxbb_vapb_1 = { 1499static struct clk_regmap gxbb_vapb_1 = {
1328 .reg = (void *)HHI_VAPBCLK_CNTL, 1500 .data = &(struct clk_regmap_gate_data){
1329 .bit_idx = 24, 1501 .offset = HHI_VAPBCLK_CNTL,
1330 .lock = &meson_clk_lock, 1502 .bit_idx = 24,
1503 },
1331 .hw.init = &(struct clk_init_data) { 1504 .hw.init = &(struct clk_init_data) {
1332 .name = "vapb_1", 1505 .name = "vapb_1",
1333 .ops = &clk_gate_ops, 1506 .ops = &clk_regmap_gate_ops,
1334 .parent_names = (const char *[]){ "vapb_1_div" }, 1507 .parent_names = (const char *[]){ "vapb_1_div" },
1335 .num_parents = 1, 1508 .num_parents = 1,
1336 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1509 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1337 }, 1510 },
1338}; 1511};
1339 1512
1340static struct clk_mux gxbb_vapb_sel = { 1513static struct clk_regmap gxbb_vapb_sel = {
1341 .reg = (void *)HHI_VAPBCLK_CNTL, 1514 .data = &(struct clk_regmap_mux_data){
1342 .mask = 1, 1515 .offset = HHI_VAPBCLK_CNTL,
1343 .shift = 31, 1516 .mask = 1,
1344 .lock = &meson_clk_lock, 1517 .shift = 31,
1518 },
1345 .hw.init = &(struct clk_init_data){ 1519 .hw.init = &(struct clk_init_data){
1346 .name = "vapb_sel", 1520 .name = "vapb_sel",
1347 .ops = &clk_mux_ops, 1521 .ops = &clk_regmap_mux_ops,
1348 /* 1522 /*
1349 * bit 31 selects from 2 possible parents: 1523 * bit 31 selects from 2 possible parents:
1350 * vapb_0 or vapb_1 1524 * vapb_0 or vapb_1
@@ -1355,13 +1529,14 @@ static struct clk_mux gxbb_vapb_sel = {
1355 }, 1529 },
1356}; 1530};
1357 1531
1358static struct clk_gate gxbb_vapb = { 1532static struct clk_regmap gxbb_vapb = {
1359 .reg = (void *)HHI_VAPBCLK_CNTL, 1533 .data = &(struct clk_regmap_gate_data){
1360 .bit_idx = 30, 1534 .offset = HHI_VAPBCLK_CNTL,
1361 .lock = &meson_clk_lock, 1535 .bit_idx = 30,
1536 },
1362 .hw.init = &(struct clk_init_data) { 1537 .hw.init = &(struct clk_init_data) {
1363 .name = "vapb", 1538 .name = "vapb",
1364 .ops = &clk_gate_ops, 1539 .ops = &clk_regmap_gate_ops,
1365 .parent_names = (const char *[]){ "vapb_sel" }, 1540 .parent_names = (const char *[]){ "vapb_sel" },
1366 .num_parents = 1, 1541 .num_parents = 1,
1367 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1542 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
@@ -1601,6 +1776,16 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
1601 [CLKID_VAPB_1] = &gxbb_vapb_1.hw, 1776 [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
1602 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, 1777 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
1603 [CLKID_VAPB] = &gxbb_vapb.hw, 1778 [CLKID_VAPB] = &gxbb_vapb.hw,
1779 [CLKID_HDMI_PLL_PRE_MULT] = &gxbb_hdmi_pll_pre_mult.hw,
1780 [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw,
1781 [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw,
1782 [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw,
1783 [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw,
1784 [CLKID_FCLK_DIV2_DIV] = &gxbb_fclk_div2_div.hw,
1785 [CLKID_FCLK_DIV3_DIV] = &gxbb_fclk_div3_div.hw,
1786 [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw,
1787 [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw,
1788 [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw,
1604 [NR_CLKS] = NULL, 1789 [NR_CLKS] = NULL,
1605 }, 1790 },
1606 .num = NR_CLKS, 1791 .num = NR_CLKS,
@@ -1609,7 +1794,7 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
1609static struct clk_hw_onecell_data gxl_hw_onecell_data = { 1794static struct clk_hw_onecell_data gxl_hw_onecell_data = {
1610 .hws = { 1795 .hws = {
1611 [CLKID_SYS_PLL] = &gxbb_sys_pll.hw, 1796 [CLKID_SYS_PLL] = &gxbb_sys_pll.hw,
1612 [CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw, 1797 [CLKID_HDMI_PLL] = &gxl_hdmi_pll.hw,
1613 [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw, 1798 [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw,
1614 [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw, 1799 [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw,
1615 [CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw, 1800 [CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw,
@@ -1748,34 +1933,31 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
1748 [CLKID_VAPB_1] = &gxbb_vapb_1.hw, 1933 [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
1749 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, 1934 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
1750 [CLKID_VAPB] = &gxbb_vapb.hw, 1935 [CLKID_VAPB] = &gxbb_vapb.hw,
1936 [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw,
1937 [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw,
1938 [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw,
1939 [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw,
1940 [CLKID_FCLK_DIV2_DIV] = &gxbb_fclk_div2_div.hw,
1941 [CLKID_FCLK_DIV3_DIV] = &gxbb_fclk_div3_div.hw,
1942 [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw,
1943 [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw,
1944 [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw,
1751 [NR_CLKS] = NULL, 1945 [NR_CLKS] = NULL,
1752 }, 1946 },
1753 .num = NR_CLKS, 1947 .num = NR_CLKS,
1754}; 1948};
1755 1949
1756/* Convenience tables to populate base addresses in .probe */ 1950static struct clk_regmap *const gxbb_clk_regmaps[] = {
1757
1758static struct meson_clk_pll *const gxbb_clk_plls[] = {
1759 &gxbb_fixed_pll,
1760 &gxbb_hdmi_pll,
1761 &gxbb_sys_pll,
1762 &gxbb_gp0_pll, 1951 &gxbb_gp0_pll,
1763};
1764
1765static struct meson_clk_pll *const gxl_clk_plls[] = {
1766 &gxbb_fixed_pll,
1767 &gxbb_hdmi_pll, 1952 &gxbb_hdmi_pll,
1768 &gxbb_sys_pll,
1769 &gxl_gp0_pll,
1770}; 1953};
1771 1954
1772static struct meson_clk_mpll *const gxbb_clk_mplls[] = { 1955static struct clk_regmap *const gxl_clk_regmaps[] = {
1773 &gxbb_mpll0, 1956 &gxl_gp0_pll,
1774 &gxbb_mpll1, 1957 &gxl_hdmi_pll,
1775 &gxbb_mpll2,
1776}; 1958};
1777 1959
1778static struct clk_gate *const gxbb_clk_gates[] = { 1960static struct clk_regmap *const gx_clk_regmaps[] = {
1779 &gxbb_clk81, 1961 &gxbb_clk81,
1780 &gxbb_ddr, 1962 &gxbb_ddr,
1781 &gxbb_dos, 1963 &gxbb_dos,
@@ -1872,9 +2054,19 @@ static struct clk_gate *const gxbb_clk_gates[] = {
1872 &gxbb_vapb_0, 2054 &gxbb_vapb_0,
1873 &gxbb_vapb_1, 2055 &gxbb_vapb_1,
1874 &gxbb_vapb, 2056 &gxbb_vapb,
1875}; 2057 &gxbb_mpeg_clk_div,
1876 2058 &gxbb_sar_adc_clk_div,
1877static struct clk_mux *const gxbb_clk_muxes[] = { 2059 &gxbb_mali_0_div,
2060 &gxbb_mali_1_div,
2061 &gxbb_cts_mclk_i958_div,
2062 &gxbb_32k_clk_div,
2063 &gxbb_sd_emmc_a_clk0_div,
2064 &gxbb_sd_emmc_b_clk0_div,
2065 &gxbb_sd_emmc_c_clk0_div,
2066 &gxbb_vpu_0_div,
2067 &gxbb_vpu_1_div,
2068 &gxbb_vapb_0_div,
2069 &gxbb_vapb_1_div,
1878 &gxbb_mpeg_clk_sel, 2070 &gxbb_mpeg_clk_sel,
1879 &gxbb_sar_adc_clk_sel, 2071 &gxbb_sar_adc_clk_sel,
1880 &gxbb_mali_0_sel, 2072 &gxbb_mali_0_sel,
@@ -1893,73 +2085,38 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
1893 &gxbb_vapb_0_sel, 2085 &gxbb_vapb_0_sel,
1894 &gxbb_vapb_1_sel, 2086 &gxbb_vapb_1_sel,
1895 &gxbb_vapb_sel, 2087 &gxbb_vapb_sel,
1896}; 2088 &gxbb_mpll0,
1897 2089 &gxbb_mpll1,
1898static struct clk_divider *const gxbb_clk_dividers[] = { 2090 &gxbb_mpll2,
1899 &gxbb_mpeg_clk_div, 2091 &gxbb_mpll0_div,
1900 &gxbb_sar_adc_clk_div, 2092 &gxbb_mpll1_div,
1901 &gxbb_mali_0_div, 2093 &gxbb_mpll2_div,
1902 &gxbb_mali_1_div,
1903 &gxbb_cts_mclk_i958_div,
1904 &gxbb_32k_clk_div,
1905 &gxbb_sd_emmc_a_clk0_div,
1906 &gxbb_sd_emmc_b_clk0_div,
1907 &gxbb_sd_emmc_c_clk0_div,
1908 &gxbb_vpu_0_div,
1909 &gxbb_vpu_1_div,
1910 &gxbb_vapb_0_div,
1911 &gxbb_vapb_1_div,
1912};
1913
1914static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
1915 &gxbb_cts_amclk_div, 2094 &gxbb_cts_amclk_div,
2095 &gxbb_fixed_pll,
2096 &gxbb_sys_pll,
2097 &gxbb_mpll_prediv,
2098 &gxbb_fclk_div2,
2099 &gxbb_fclk_div3,
2100 &gxbb_fclk_div4,
2101 &gxbb_fclk_div5,
2102 &gxbb_fclk_div7,
1916}; 2103};
1917 2104
1918struct clkc_data { 2105struct clkc_data {
1919 struct clk_gate *const *clk_gates; 2106 struct clk_regmap *const *regmap_clks;
1920 unsigned int clk_gates_count; 2107 unsigned int regmap_clks_count;
1921 struct meson_clk_mpll *const *clk_mplls;
1922 unsigned int clk_mplls_count;
1923 struct meson_clk_pll *const *clk_plls;
1924 unsigned int clk_plls_count;
1925 struct clk_mux *const *clk_muxes;
1926 unsigned int clk_muxes_count;
1927 struct clk_divider *const *clk_dividers;
1928 unsigned int clk_dividers_count;
1929 struct meson_clk_audio_divider *const *clk_audio_dividers;
1930 unsigned int clk_audio_dividers_count;
1931 struct clk_hw_onecell_data *hw_onecell_data; 2108 struct clk_hw_onecell_data *hw_onecell_data;
1932}; 2109};
1933 2110
1934static const struct clkc_data gxbb_clkc_data = { 2111static const struct clkc_data gxbb_clkc_data = {
1935 .clk_gates = gxbb_clk_gates, 2112 .regmap_clks = gxbb_clk_regmaps,
1936 .clk_gates_count = ARRAY_SIZE(gxbb_clk_gates), 2113 .regmap_clks_count = ARRAY_SIZE(gxbb_clk_regmaps),
1937 .clk_mplls = gxbb_clk_mplls,
1938 .clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
1939 .clk_plls = gxbb_clk_plls,
1940 .clk_plls_count = ARRAY_SIZE(gxbb_clk_plls),
1941 .clk_muxes = gxbb_clk_muxes,
1942 .clk_muxes_count = ARRAY_SIZE(gxbb_clk_muxes),
1943 .clk_dividers = gxbb_clk_dividers,
1944 .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
1945 .clk_audio_dividers = gxbb_audio_dividers,
1946 .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
1947 .hw_onecell_data = &gxbb_hw_onecell_data, 2114 .hw_onecell_data = &gxbb_hw_onecell_data,
1948}; 2115};
1949 2116
1950static const struct clkc_data gxl_clkc_data = { 2117static const struct clkc_data gxl_clkc_data = {
1951 .clk_gates = gxbb_clk_gates, 2118 .regmap_clks = gxl_clk_regmaps,
1952 .clk_gates_count = ARRAY_SIZE(gxbb_clk_gates), 2119 .regmap_clks_count = ARRAY_SIZE(gxl_clk_regmaps),
1953 .clk_mplls = gxbb_clk_mplls,
1954 .clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
1955 .clk_plls = gxl_clk_plls,
1956 .clk_plls_count = ARRAY_SIZE(gxl_clk_plls),
1957 .clk_muxes = gxbb_clk_muxes,
1958 .clk_muxes_count = ARRAY_SIZE(gxbb_clk_muxes),
1959 .clk_dividers = gxbb_clk_dividers,
1960 .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
1961 .clk_audio_dividers = gxbb_audio_dividers,
1962 .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
1963 .hw_onecell_data = &gxl_hw_onecell_data, 2120 .hw_onecell_data = &gxl_hw_onecell_data,
1964}; 2121};
1965 2122
@@ -1969,71 +2126,79 @@ static const struct of_device_id clkc_match_table[] = {
1969 {}, 2126 {},
1970}; 2127};
1971 2128
2129static const struct regmap_config clkc_regmap_config = {
2130 .reg_bits = 32,
2131 .val_bits = 32,
2132 .reg_stride = 4,
2133};
2134
1972static int gxbb_clkc_probe(struct platform_device *pdev) 2135static int gxbb_clkc_probe(struct platform_device *pdev)
1973{ 2136{
1974 const struct clkc_data *clkc_data; 2137 const struct clkc_data *clkc_data;
2138 struct resource *res;
1975 void __iomem *clk_base; 2139 void __iomem *clk_base;
1976 int ret, clkid, i; 2140 struct regmap *map;
2141 int ret, i;
1977 struct device *dev = &pdev->dev; 2142 struct device *dev = &pdev->dev;
1978 2143
1979 clkc_data = of_device_get_match_data(&pdev->dev); 2144 clkc_data = of_device_get_match_data(dev);
1980 if (!clkc_data) 2145 if (!clkc_data)
1981 return -EINVAL; 2146 return -EINVAL;
1982 2147
1983 /* Generic clocks and PLLs */ 2148 /* Get the hhi system controller node if available */
1984 clk_base = of_iomap(dev->of_node, 0); 2149 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
1985 if (!clk_base) { 2150 if (IS_ERR(map)) {
1986 pr_err("%s: Unable to map clk base\n", __func__); 2151 dev_err(dev,
1987 return -ENXIO; 2152 "failed to get HHI regmap - Trying obsolete regs\n");
1988 }
1989
1990 /* Populate base address for PLLs */
1991 for (i = 0; i < clkc_data->clk_plls_count; i++)
1992 clkc_data->clk_plls[i]->base = clk_base;
1993
1994 /* Populate base address for MPLLs */
1995 for (i = 0; i < clkc_data->clk_mplls_count; i++)
1996 clkc_data->clk_mplls[i]->base = clk_base;
1997 2153
1998 /* Populate base address for gates */ 2154 /*
1999 for (i = 0; i < clkc_data->clk_gates_count; i++) 2155 * FIXME: HHI registers should be accessed through
2000 clkc_data->clk_gates[i]->reg = clk_base + 2156 * the appropriate system controller. This is required because
2001 (u64)clkc_data->clk_gates[i]->reg; 2157 * there is more than just clocks in this register space
2002 2158 *
2003 /* Populate base address for muxes */ 2159 * This fallback method is only provided temporarily until
2004 for (i = 0; i < clkc_data->clk_muxes_count; i++) 2160 * all the platform DTs are properly using the syscon node
2005 clkc_data->clk_muxes[i]->reg = clk_base + 2161 */
2006 (u64)clkc_data->clk_muxes[i]->reg; 2162 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2163 if (!res)
2164 return -EINVAL;
2165
2166 clk_base = devm_ioremap(dev, res->start, resource_size(res));
2167 if (!clk_base) {
2168 dev_err(dev, "Unable to map clk base\n");
2169 return -ENXIO;
2170 }
2171
2172 map = devm_regmap_init_mmio(dev, clk_base,
2173 &clkc_regmap_config);
2174 if (IS_ERR(map))
2175 return PTR_ERR(map);
2176 }
2007 2177
2008 /* Populate base address for dividers */ 2178 /* Populate regmap for the common regmap backed clocks */
2009 for (i = 0; i < clkc_data->clk_dividers_count; i++) 2179 for (i = 0; i < ARRAY_SIZE(gx_clk_regmaps); i++)
2010 clkc_data->clk_dividers[i]->reg = clk_base + 2180 gx_clk_regmaps[i]->map = map;
2011 (u64)clkc_data->clk_dividers[i]->reg;
2012 2181
2013 /* Populate base address for the audio dividers */ 2182 /* Populate regmap for soc specific clocks */
2014 for (i = 0; i < clkc_data->clk_audio_dividers_count; i++) 2183 for (i = 0; i < clkc_data->regmap_clks_count; i++)
2015 clkc_data->clk_audio_dividers[i]->base = clk_base; 2184 clkc_data->regmap_clks[i]->map = map;
2016 2185
2017 /* 2186 /* Register all clks */
2018 * register all clks 2187 for (i = 0; i < clkc_data->hw_onecell_data->num; i++) {
2019 */
2020 for (clkid = 0; clkid < clkc_data->hw_onecell_data->num; clkid++) {
2021 /* array might be sparse */ 2188 /* array might be sparse */
2022 if (!clkc_data->hw_onecell_data->hws[clkid]) 2189 if (!clkc_data->hw_onecell_data->hws[i])
2023 continue; 2190 continue;
2024 2191
2025 ret = devm_clk_hw_register(dev, 2192 ret = devm_clk_hw_register(dev,
2026 clkc_data->hw_onecell_data->hws[clkid]); 2193 clkc_data->hw_onecell_data->hws[i]);
2027 if (ret) 2194 if (ret) {
2028 goto iounmap; 2195 dev_err(dev, "Clock registration failed\n");
2196 return ret;
2197 }
2029 } 2198 }
2030 2199
2031 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 2200 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
2032 clkc_data->hw_onecell_data); 2201 clkc_data->hw_onecell_data);
2033
2034iounmap:
2035 iounmap(clk_base);
2036 return ret;
2037} 2202}
2038 2203
2039static struct platform_driver gxbb_driver = { 2204static struct platform_driver gxbb_driver = {
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index aee6fbba2004..9febf3f03739 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -194,8 +194,18 @@
194#define CLKID_VPU_1_DIV 130 194#define CLKID_VPU_1_DIV 130
195#define CLKID_VAPB_0_DIV 134 195#define CLKID_VAPB_0_DIV 134
196#define CLKID_VAPB_1_DIV 137 196#define CLKID_VAPB_1_DIV 137
197 197#define CLKID_HDMI_PLL_PRE_MULT 141
198#define NR_CLKS 141 198#define CLKID_MPLL0_DIV 142
199#define CLKID_MPLL1_DIV 143
200#define CLKID_MPLL2_DIV 144
201#define CLKID_MPLL_PREDIV 145
202#define CLKID_FCLK_DIV2_DIV 146
203#define CLKID_FCLK_DIV3_DIV 147
204#define CLKID_FCLK_DIV4_DIV 148
205#define CLKID_FCLK_DIV5_DIV 149
206#define CLKID_FCLK_DIV7_DIV 150
207
208#define NR_CLKS 151
199 209
200/* include the CLKIDs that have been made part of the DT binding */ 210/* include the CLKIDs that have been made part of the DT binding */
201#include <dt-bindings/clock/gxbb-clkc.h> 211#include <dt-bindings/clock/gxbb-clkc.h>
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 3ffea80c1308..cc2992493e0b 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -23,14 +23,16 @@
23 23
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/clk-provider.h> 25#include <linux/clk-provider.h>
26#include <linux/init.h>
26#include <linux/of_address.h> 27#include <linux/of_address.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/reset-controller.h> 29#include <linux/reset-controller.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/init.h> 31#include <linux/regmap.h>
31 32
32#include "clkc.h" 33#include "clkc.h"
33#include "meson8b.h" 34#include "meson8b.h"
35#include "clk-regmap.h"
34 36
35static DEFINE_SPINLOCK(meson_clk_lock); 37static DEFINE_SPINLOCK(meson_clk_lock);
36 38
@@ -97,20 +99,6 @@ static const struct pll_rate_table sys_pll_rate_table[] = {
97 { /* sentinel */ }, 99 { /* sentinel */ },
98}; 100};
99 101
100static const struct clk_div_table cpu_div_table[] = {
101 { .val = 1, .div = 1 },
102 { .val = 2, .div = 2 },
103 { .val = 3, .div = 3 },
104 { .val = 2, .div = 4 },
105 { .val = 3, .div = 6 },
106 { .val = 4, .div = 8 },
107 { .val = 5, .div = 10 },
108 { .val = 6, .div = 12 },
109 { .val = 7, .div = 14 },
110 { .val = 8, .div = 16 },
111 { /* sentinel */ },
112};
113
114static struct clk_fixed_rate meson8b_xtal = { 102static struct clk_fixed_rate meson8b_xtal = {
115 .fixed_rate = 24000000, 103 .fixed_rate = 24000000,
116 .hw.init = &(struct clk_init_data){ 104 .hw.init = &(struct clk_init_data){
@@ -120,23 +108,39 @@ static struct clk_fixed_rate meson8b_xtal = {
120 }, 108 },
121}; 109};
122 110
123static struct meson_clk_pll meson8b_fixed_pll = { 111static struct clk_regmap meson8b_fixed_pll = {
124 .m = { 112 .data = &(struct meson_clk_pll_data){
125 .reg_off = HHI_MPLL_CNTL, 113 .m = {
126 .shift = 0, 114 .reg_off = HHI_MPLL_CNTL,
127 .width = 9, 115 .shift = 0,
128 }, 116 .width = 9,
129 .n = { 117 },
130 .reg_off = HHI_MPLL_CNTL, 118 .n = {
131 .shift = 9, 119 .reg_off = HHI_MPLL_CNTL,
132 .width = 5, 120 .shift = 9,
133 }, 121 .width = 5,
134 .od = { 122 },
135 .reg_off = HHI_MPLL_CNTL, 123 .od = {
136 .shift = 16, 124 .reg_off = HHI_MPLL_CNTL,
137 .width = 2, 125 .shift = 16,
126 .width = 2,
127 },
128 .frac = {
129 .reg_off = HHI_MPLL_CNTL2,
130 .shift = 0,
131 .width = 12,
132 },
133 .l = {
134 .reg_off = HHI_MPLL_CNTL,
135 .shift = 31,
136 .width = 1,
137 },
138 .rst = {
139 .reg_off = HHI_MPLL_CNTL,
140 .shift = 29,
141 .width = 1,
142 },
138 }, 143 },
139 .lock = &meson_clk_lock,
140 .hw.init = &(struct clk_init_data){ 144 .hw.init = &(struct clk_init_data){
141 .name = "fixed_pll", 145 .name = "fixed_pll",
142 .ops = &meson_clk_pll_ro_ops, 146 .ops = &meson_clk_pll_ro_ops,
@@ -146,23 +150,34 @@ static struct meson_clk_pll meson8b_fixed_pll = {
146 }, 150 },
147}; 151};
148 152
149static struct meson_clk_pll meson8b_vid_pll = { 153static struct clk_regmap meson8b_vid_pll = {
150 .m = { 154 .data = &(struct meson_clk_pll_data){
151 .reg_off = HHI_VID_PLL_CNTL, 155 .m = {
152 .shift = 0, 156 .reg_off = HHI_VID_PLL_CNTL,
153 .width = 9, 157 .shift = 0,
158 .width = 9,
159 },
160 .n = {
161 .reg_off = HHI_VID_PLL_CNTL,
162 .shift = 9,
163 .width = 5,
164 },
165 .od = {
166 .reg_off = HHI_VID_PLL_CNTL,
167 .shift = 16,
168 .width = 2,
169 },
170 .l = {
171 .reg_off = HHI_VID_PLL_CNTL,
172 .shift = 31,
173 .width = 1,
174 },
175 .rst = {
176 .reg_off = HHI_VID_PLL_CNTL,
177 .shift = 29,
178 .width = 1,
179 },
154 }, 180 },
155 .n = {
156 .reg_off = HHI_VID_PLL_CNTL,
157 .shift = 9,
158 .width = 5,
159 },
160 .od = {
161 .reg_off = HHI_VID_PLL_CNTL,
162 .shift = 16,
163 .width = 2,
164 },
165 .lock = &meson_clk_lock,
166 .hw.init = &(struct clk_init_data){ 181 .hw.init = &(struct clk_init_data){
167 .name = "vid_pll", 182 .name = "vid_pll",
168 .ops = &meson_clk_pll_ro_ops, 183 .ops = &meson_clk_pll_ro_ops,
@@ -172,213 +187,317 @@ static struct meson_clk_pll meson8b_vid_pll = {
172 }, 187 },
173}; 188};
174 189
175static struct meson_clk_pll meson8b_sys_pll = { 190static struct clk_regmap meson8b_sys_pll = {
176 .m = { 191 .data = &(struct meson_clk_pll_data){
177 .reg_off = HHI_SYS_PLL_CNTL, 192 .m = {
178 .shift = 0, 193 .reg_off = HHI_SYS_PLL_CNTL,
179 .width = 9, 194 .shift = 0,
180 }, 195 .width = 9,
181 .n = { 196 },
182 .reg_off = HHI_SYS_PLL_CNTL, 197 .n = {
183 .shift = 9, 198 .reg_off = HHI_SYS_PLL_CNTL,
184 .width = 5, 199 .shift = 9,
200 .width = 5,
201 },
202 .od = {
203 .reg_off = HHI_SYS_PLL_CNTL,
204 .shift = 16,
205 .width = 2,
206 },
207 .l = {
208 .reg_off = HHI_SYS_PLL_CNTL,
209 .shift = 31,
210 .width = 1,
211 },
212 .rst = {
213 .reg_off = HHI_SYS_PLL_CNTL,
214 .shift = 29,
215 .width = 1,
216 },
217 .table = sys_pll_rate_table,
185 }, 218 },
186 .od = {
187 .reg_off = HHI_SYS_PLL_CNTL,
188 .shift = 16,
189 .width = 2,
190 },
191 .rate_table = sys_pll_rate_table,
192 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
193 .lock = &meson_clk_lock,
194 .hw.init = &(struct clk_init_data){ 219 .hw.init = &(struct clk_init_data){
195 .name = "sys_pll", 220 .name = "sys_pll",
196 .ops = &meson_clk_pll_ops, 221 .ops = &meson_clk_pll_ro_ops,
197 .parent_names = (const char *[]){ "xtal" }, 222 .parent_names = (const char *[]){ "xtal" },
198 .num_parents = 1, 223 .num_parents = 1,
199 .flags = CLK_GET_RATE_NOCACHE, 224 .flags = CLK_GET_RATE_NOCACHE,
200 }, 225 },
201}; 226};
202 227
203static struct clk_fixed_factor meson8b_fclk_div2 = { 228static struct clk_fixed_factor meson8b_fclk_div2_div = {
204 .mult = 1, 229 .mult = 1,
205 .div = 2, 230 .div = 2,
206 .hw.init = &(struct clk_init_data){ 231 .hw.init = &(struct clk_init_data){
207 .name = "fclk_div2", 232 .name = "fclk_div2_div",
208 .ops = &clk_fixed_factor_ops, 233 .ops = &clk_fixed_factor_ops,
209 .parent_names = (const char *[]){ "fixed_pll" }, 234 .parent_names = (const char *[]){ "fixed_pll" },
210 .num_parents = 1, 235 .num_parents = 1,
211 }, 236 },
212}; 237};
213 238
214static struct clk_fixed_factor meson8b_fclk_div3 = { 239static struct clk_regmap meson8b_fclk_div2 = {
240 .data = &(struct clk_regmap_gate_data){
241 .offset = HHI_MPLL_CNTL6,
242 .bit_idx = 27,
243 },
244 .hw.init = &(struct clk_init_data){
245 .name = "fclk_div2",
246 .ops = &clk_regmap_gate_ops,
247 .parent_names = (const char *[]){ "fclk_div2_div" },
248 .num_parents = 1,
249 },
250};
251
252static struct clk_fixed_factor meson8b_fclk_div3_div = {
215 .mult = 1, 253 .mult = 1,
216 .div = 3, 254 .div = 3,
217 .hw.init = &(struct clk_init_data){ 255 .hw.init = &(struct clk_init_data){
218 .name = "fclk_div3", 256 .name = "fclk_div_div3",
219 .ops = &clk_fixed_factor_ops, 257 .ops = &clk_fixed_factor_ops,
220 .parent_names = (const char *[]){ "fixed_pll" }, 258 .parent_names = (const char *[]){ "fixed_pll" },
221 .num_parents = 1, 259 .num_parents = 1,
222 }, 260 },
223}; 261};
224 262
225static struct clk_fixed_factor meson8b_fclk_div4 = { 263static struct clk_regmap meson8b_fclk_div3 = {
264 .data = &(struct clk_regmap_gate_data){
265 .offset = HHI_MPLL_CNTL6,
266 .bit_idx = 28,
267 },
268 .hw.init = &(struct clk_init_data){
269 .name = "fclk_div3",
270 .ops = &clk_regmap_gate_ops,
271 .parent_names = (const char *[]){ "fclk_div3_div" },
272 .num_parents = 1,
273 },
274};
275
276static struct clk_fixed_factor meson8b_fclk_div4_div = {
226 .mult = 1, 277 .mult = 1,
227 .div = 4, 278 .div = 4,
228 .hw.init = &(struct clk_init_data){ 279 .hw.init = &(struct clk_init_data){
229 .name = "fclk_div4", 280 .name = "fclk_div4_div",
230 .ops = &clk_fixed_factor_ops, 281 .ops = &clk_fixed_factor_ops,
231 .parent_names = (const char *[]){ "fixed_pll" }, 282 .parent_names = (const char *[]){ "fixed_pll" },
232 .num_parents = 1, 283 .num_parents = 1,
233 }, 284 },
234}; 285};
235 286
236static struct clk_fixed_factor meson8b_fclk_div5 = { 287static struct clk_regmap meson8b_fclk_div4 = {
288 .data = &(struct clk_regmap_gate_data){
289 .offset = HHI_MPLL_CNTL6,
290 .bit_idx = 29,
291 },
292 .hw.init = &(struct clk_init_data){
293 .name = "fclk_div4",
294 .ops = &clk_regmap_gate_ops,
295 .parent_names = (const char *[]){ "fclk_div4_div" },
296 .num_parents = 1,
297 },
298};
299
300static struct clk_fixed_factor meson8b_fclk_div5_div = {
237 .mult = 1, 301 .mult = 1,
238 .div = 5, 302 .div = 5,
239 .hw.init = &(struct clk_init_data){ 303 .hw.init = &(struct clk_init_data){
240 .name = "fclk_div5", 304 .name = "fclk_div5_div",
241 .ops = &clk_fixed_factor_ops, 305 .ops = &clk_fixed_factor_ops,
242 .parent_names = (const char *[]){ "fixed_pll" }, 306 .parent_names = (const char *[]){ "fixed_pll" },
243 .num_parents = 1, 307 .num_parents = 1,
244 }, 308 },
245}; 309};
246 310
247static struct clk_fixed_factor meson8b_fclk_div7 = { 311static struct clk_regmap meson8b_fclk_div5 = {
312 .data = &(struct clk_regmap_gate_data){
313 .offset = HHI_MPLL_CNTL6,
314 .bit_idx = 30,
315 },
316 .hw.init = &(struct clk_init_data){
317 .name = "fclk_div5",
318 .ops = &clk_regmap_gate_ops,
319 .parent_names = (const char *[]){ "fclk_div5_div" },
320 .num_parents = 1,
321 },
322};
323
324static struct clk_fixed_factor meson8b_fclk_div7_div = {
248 .mult = 1, 325 .mult = 1,
249 .div = 7, 326 .div = 7,
250 .hw.init = &(struct clk_init_data){ 327 .hw.init = &(struct clk_init_data){
251 .name = "fclk_div7", 328 .name = "fclk_div7_div",
252 .ops = &clk_fixed_factor_ops, 329 .ops = &clk_fixed_factor_ops,
253 .parent_names = (const char *[]){ "fixed_pll" }, 330 .parent_names = (const char *[]){ "fixed_pll" },
254 .num_parents = 1, 331 .num_parents = 1,
255 }, 332 },
256}; 333};
257 334
258static struct meson_clk_mpll meson8b_mpll0 = { 335static struct clk_regmap meson8b_fclk_div7 = {
259 .sdm = { 336 .data = &(struct clk_regmap_gate_data){
260 .reg_off = HHI_MPLL_CNTL7, 337 .offset = HHI_MPLL_CNTL6,
261 .shift = 0, 338 .bit_idx = 31,
262 .width = 14,
263 }, 339 },
264 .sdm_en = { 340 .hw.init = &(struct clk_init_data){
265 .reg_off = HHI_MPLL_CNTL7, 341 .name = "fclk_div7",
266 .shift = 15, 342 .ops = &clk_regmap_gate_ops,
267 .width = 1, 343 .parent_names = (const char *[]){ "fclk_div7_div" },
344 .num_parents = 1,
268 }, 345 },
269 .n2 = { 346};
270 .reg_off = HHI_MPLL_CNTL7, 347
271 .shift = 16, 348static struct clk_regmap meson8b_mpll_prediv = {
272 .width = 9, 349 .data = &(struct clk_regmap_div_data){
350 .offset = HHI_MPLL_CNTL5,
351 .shift = 12,
352 .width = 1,
273 }, 353 },
274 .en = { 354 .hw.init = &(struct clk_init_data){
275 .reg_off = HHI_MPLL_CNTL7, 355 .name = "mpll_prediv",
276 .shift = 14, 356 .ops = &clk_regmap_divider_ro_ops,
277 .width = 1, 357 .parent_names = (const char *[]){ "fixed_pll" },
358 .num_parents = 1,
278 }, 359 },
279 .ssen = { 360};
280 .reg_off = HHI_MPLL_CNTL, 361
281 .shift = 25, 362static struct clk_regmap meson8b_mpll0_div = {
282 .width = 1, 363 .data = &(struct meson_clk_mpll_data){
364 .sdm = {
365 .reg_off = HHI_MPLL_CNTL7,
366 .shift = 0,
367 .width = 14,
368 },
369 .sdm_en = {
370 .reg_off = HHI_MPLL_CNTL7,
371 .shift = 15,
372 .width = 1,
373 },
374 .n2 = {
375 .reg_off = HHI_MPLL_CNTL7,
376 .shift = 16,
377 .width = 9,
378 },
379 .ssen = {
380 .reg_off = HHI_MPLL_CNTL,
381 .shift = 25,
382 .width = 1,
383 },
384 .lock = &meson_clk_lock,
283 }, 385 },
284 .lock = &meson_clk_lock,
285 .hw.init = &(struct clk_init_data){ 386 .hw.init = &(struct clk_init_data){
286 .name = "mpll0", 387 .name = "mpll0_div",
287 .ops = &meson_clk_mpll_ops, 388 .ops = &meson_clk_mpll_ops,
288 .parent_names = (const char *[]){ "fixed_pll" }, 389 .parent_names = (const char *[]){ "mpll_prediv" },
289 .num_parents = 1, 390 .num_parents = 1,
290 }, 391 },
291}; 392};
292 393
293static struct meson_clk_mpll meson8b_mpll1 = { 394static struct clk_regmap meson8b_mpll0 = {
294 .sdm = { 395 .data = &(struct clk_regmap_gate_data){
295 .reg_off = HHI_MPLL_CNTL8, 396 .offset = HHI_MPLL_CNTL7,
296 .shift = 0, 397 .bit_idx = 14,
297 .width = 14,
298 }, 398 },
299 .sdm_en = { 399 .hw.init = &(struct clk_init_data){
300 .reg_off = HHI_MPLL_CNTL8, 400 .name = "mpll0",
301 .shift = 15, 401 .ops = &clk_regmap_gate_ops,
302 .width = 1, 402 .parent_names = (const char *[]){ "mpll0_div" },
303 }, 403 .num_parents = 1,
304 .n2 = { 404 .flags = CLK_SET_RATE_PARENT,
305 .reg_off = HHI_MPLL_CNTL8,
306 .shift = 16,
307 .width = 9,
308 }, 405 },
309 .en = { 406};
310 .reg_off = HHI_MPLL_CNTL8, 407
311 .shift = 14, 408static struct clk_regmap meson8b_mpll1_div = {
312 .width = 1, 409 .data = &(struct meson_clk_mpll_data){
410 .sdm = {
411 .reg_off = HHI_MPLL_CNTL8,
412 .shift = 0,
413 .width = 14,
414 },
415 .sdm_en = {
416 .reg_off = HHI_MPLL_CNTL8,
417 .shift = 15,
418 .width = 1,
419 },
420 .n2 = {
421 .reg_off = HHI_MPLL_CNTL8,
422 .shift = 16,
423 .width = 9,
424 },
425 .lock = &meson_clk_lock,
313 }, 426 },
314 .lock = &meson_clk_lock,
315 .hw.init = &(struct clk_init_data){ 427 .hw.init = &(struct clk_init_data){
316 .name = "mpll1", 428 .name = "mpll1_div",
317 .ops = &meson_clk_mpll_ops, 429 .ops = &meson_clk_mpll_ops,
318 .parent_names = (const char *[]){ "fixed_pll" }, 430 .parent_names = (const char *[]){ "mpll_prediv" },
319 .num_parents = 1, 431 .num_parents = 1,
320 }, 432 },
321}; 433};
322 434
323static struct meson_clk_mpll meson8b_mpll2 = { 435static struct clk_regmap meson8b_mpll1 = {
324 .sdm = { 436 .data = &(struct clk_regmap_gate_data){
325 .reg_off = HHI_MPLL_CNTL9, 437 .offset = HHI_MPLL_CNTL8,
326 .shift = 0, 438 .bit_idx = 14,
327 .width = 14,
328 },
329 .sdm_en = {
330 .reg_off = HHI_MPLL_CNTL9,
331 .shift = 15,
332 .width = 1,
333 }, 439 },
334 .n2 = { 440 .hw.init = &(struct clk_init_data){
335 .reg_off = HHI_MPLL_CNTL9, 441 .name = "mpll1",
336 .shift = 16, 442 .ops = &clk_regmap_gate_ops,
337 .width = 9, 443 .parent_names = (const char *[]){ "mpll1_div" },
444 .num_parents = 1,
445 .flags = CLK_SET_RATE_PARENT,
338 }, 446 },
339 .en = { 447};
340 .reg_off = HHI_MPLL_CNTL9, 448
341 .shift = 14, 449static struct clk_regmap meson8b_mpll2_div = {
342 .width = 1, 450 .data = &(struct meson_clk_mpll_data){
451 .sdm = {
452 .reg_off = HHI_MPLL_CNTL9,
453 .shift = 0,
454 .width = 14,
455 },
456 .sdm_en = {
457 .reg_off = HHI_MPLL_CNTL9,
458 .shift = 15,
459 .width = 1,
460 },
461 .n2 = {
462 .reg_off = HHI_MPLL_CNTL9,
463 .shift = 16,
464 .width = 9,
465 },
466 .lock = &meson_clk_lock,
343 }, 467 },
344 .lock = &meson_clk_lock,
345 .hw.init = &(struct clk_init_data){ 468 .hw.init = &(struct clk_init_data){
346 .name = "mpll2", 469 .name = "mpll2_div",
347 .ops = &meson_clk_mpll_ops, 470 .ops = &meson_clk_mpll_ops,
348 .parent_names = (const char *[]){ "fixed_pll" }, 471 .parent_names = (const char *[]){ "mpll_prediv" },
349 .num_parents = 1, 472 .num_parents = 1,
350 }, 473 },
351}; 474};
352 475
353/* 476static struct clk_regmap meson8b_mpll2 = {
354 * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL 477 .data = &(struct clk_regmap_gate_data){
355 * post-dividers and should be modeled with their respective PLLs via the 478 .offset = HHI_MPLL_CNTL9,
356 * forthcoming coordinated clock rates feature 479 .bit_idx = 14,
357 */ 480 },
358static struct meson_clk_cpu meson8b_cpu_clk = {
359 .reg_off = HHI_SYS_CPU_CLK_CNTL1,
360 .div_table = cpu_div_table,
361 .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
362 .hw.init = &(struct clk_init_data){ 481 .hw.init = &(struct clk_init_data){
363 .name = "cpu_clk", 482 .name = "mpll2",
364 .ops = &meson_clk_cpu_ops, 483 .ops = &clk_regmap_gate_ops,
365 .parent_names = (const char *[]){ "sys_pll" }, 484 .parent_names = (const char *[]){ "mpll2_div" },
366 .num_parents = 1, 485 .num_parents = 1,
486 .flags = CLK_SET_RATE_PARENT,
367 }, 487 },
368}; 488};
369 489
370static u32 mux_table_clk81[] = { 6, 5, 7 }; 490static u32 mux_table_clk81[] = { 6, 5, 7 };
371 491static struct clk_regmap meson8b_mpeg_clk_sel = {
372struct clk_mux meson8b_mpeg_clk_sel = { 492 .data = &(struct clk_regmap_mux_data){
373 .reg = (void *)HHI_MPEG_CLK_CNTL, 493 .offset = HHI_MPEG_CLK_CNTL,
374 .mask = 0x7, 494 .mask = 0x7,
375 .shift = 12, 495 .shift = 12,
376 .flags = CLK_MUX_READ_ONLY, 496 .table = mux_table_clk81,
377 .table = mux_table_clk81, 497 },
378 .lock = &meson_clk_lock,
379 .hw.init = &(struct clk_init_data){ 498 .hw.init = &(struct clk_init_data){
380 .name = "mpeg_clk_sel", 499 .name = "mpeg_clk_sel",
381 .ops = &clk_mux_ro_ops, 500 .ops = &clk_regmap_mux_ro_ops,
382 /* 501 /*
383 * FIXME bits 14:12 selects from 8 possible parents: 502 * FIXME bits 14:12 selects from 8 possible parents:
384 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 503 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
@@ -387,34 +506,136 @@ struct clk_mux meson8b_mpeg_clk_sel = {
387 .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", 506 .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
388 "fclk_div5" }, 507 "fclk_div5" },
389 .num_parents = 3, 508 .num_parents = 3,
390 .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
391 }, 509 },
392}; 510};
393 511
394struct clk_divider meson8b_mpeg_clk_div = { 512static struct clk_regmap meson8b_mpeg_clk_div = {
395 .reg = (void *)HHI_MPEG_CLK_CNTL, 513 .data = &(struct clk_regmap_div_data){
396 .shift = 0, 514 .offset = HHI_MPEG_CLK_CNTL,
397 .width = 7, 515 .shift = 0,
398 .lock = &meson_clk_lock, 516 .width = 7,
517 },
399 .hw.init = &(struct clk_init_data){ 518 .hw.init = &(struct clk_init_data){
400 .name = "mpeg_clk_div", 519 .name = "mpeg_clk_div",
401 .ops = &clk_divider_ops, 520 .ops = &clk_regmap_divider_ro_ops,
402 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 521 .parent_names = (const char *[]){ "mpeg_clk_sel" },
403 .num_parents = 1, 522 .num_parents = 1,
404 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
405 }, 523 },
406}; 524};
407 525
408struct clk_gate meson8b_clk81 = { 526static struct clk_regmap meson8b_clk81 = {
409 .reg = (void *)HHI_MPEG_CLK_CNTL, 527 .data = &(struct clk_regmap_gate_data){
410 .bit_idx = 7, 528 .offset = HHI_MPEG_CLK_CNTL,
411 .lock = &meson_clk_lock, 529 .bit_idx = 7,
530 },
412 .hw.init = &(struct clk_init_data){ 531 .hw.init = &(struct clk_init_data){
413 .name = "clk81", 532 .name = "clk81",
414 .ops = &clk_gate_ops, 533 .ops = &clk_regmap_gate_ops,
415 .parent_names = (const char *[]){ "mpeg_clk_div" }, 534 .parent_names = (const char *[]){ "mpeg_clk_div" },
416 .num_parents = 1, 535 .num_parents = 1,
417 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 536 .flags = CLK_IS_CRITICAL,
537 },
538};
539
540static struct clk_regmap meson8b_cpu_in_sel = {
541 .data = &(struct clk_regmap_mux_data){
542 .offset = HHI_SYS_CPU_CLK_CNTL0,
543 .mask = 0x1,
544 .shift = 0,
545 },
546 .hw.init = &(struct clk_init_data){
547 .name = "cpu_in_sel",
548 .ops = &clk_regmap_mux_ro_ops,
549 .parent_names = (const char *[]){ "xtal", "sys_pll" },
550 .num_parents = 2,
551 .flags = (CLK_SET_RATE_PARENT |
552 CLK_SET_RATE_NO_REPARENT),
553 },
554};
555
556static struct clk_fixed_factor meson8b_cpu_div2 = {
557 .mult = 1,
558 .div = 2,
559 .hw.init = &(struct clk_init_data){
560 .name = "cpu_div2",
561 .ops = &clk_fixed_factor_ops,
562 .parent_names = (const char *[]){ "cpu_in_sel" },
563 .num_parents = 1,
564 .flags = CLK_SET_RATE_PARENT,
565 },
566};
567
568static struct clk_fixed_factor meson8b_cpu_div3 = {
569 .mult = 1,
570 .div = 3,
571 .hw.init = &(struct clk_init_data){
572 .name = "cpu_div3",
573 .ops = &clk_fixed_factor_ops,
574 .parent_names = (const char *[]){ "cpu_in_sel" },
575 .num_parents = 1,
576 .flags = CLK_SET_RATE_PARENT,
577 },
578};
579
580static const struct clk_div_table cpu_scale_table[] = {
581 { .val = 2, .div = 4 },
582 { .val = 3, .div = 6 },
583 { .val = 4, .div = 8 },
584 { .val = 5, .div = 10 },
585 { .val = 6, .div = 12 },
586 { .val = 7, .div = 14 },
587 { .val = 8, .div = 16 },
588 { /* sentinel */ },
589};
590
591static struct clk_regmap meson8b_cpu_scale_div = {
592 .data = &(struct clk_regmap_div_data){
593 .offset = HHI_SYS_CPU_CLK_CNTL1,
594 .shift = 20,
595 .width = 9,
596 .table = cpu_scale_table,
597 .flags = CLK_DIVIDER_ALLOW_ZERO,
598 },
599 .hw.init = &(struct clk_init_data){
600 .name = "cpu_scale_div",
601 .ops = &clk_regmap_divider_ro_ops,
602 .parent_names = (const char *[]){ "cpu_in_sel" },
603 .num_parents = 1,
604 .flags = CLK_SET_RATE_PARENT,
605 },
606};
607
608static struct clk_regmap meson8b_cpu_scale_out_sel = {
609 .data = &(struct clk_regmap_mux_data){
610 .offset = HHI_SYS_CPU_CLK_CNTL0,
611 .mask = 0x3,
612 .shift = 2,
613 },
614 .hw.init = &(struct clk_init_data){
615 .name = "cpu_scale_out_sel",
616 .ops = &clk_regmap_mux_ro_ops,
617 .parent_names = (const char *[]) { "cpu_in_sel",
618 "cpu_div2",
619 "cpu_div3",
620 "cpu_scale_div" },
621 .num_parents = 4,
622 .flags = CLK_SET_RATE_PARENT,
623 },
624};
625
626static struct clk_regmap meson8b_cpu_clk = {
627 .data = &(struct clk_regmap_mux_data){
628 .offset = HHI_SYS_CPU_CLK_CNTL0,
629 .mask = 0x1,
630 .shift = 7,
631 },
632 .hw.init = &(struct clk_init_data){
633 .name = "cpu_clk",
634 .ops = &clk_regmap_mux_ro_ops,
635 .parent_names = (const char *[]){ "xtal", "cpu_out_sel" },
636 .num_parents = 2,
637 .flags = (CLK_SET_RATE_PARENT |
638 CLK_SET_RATE_NO_REPARENT),
418 }, 639 },
419}; 640};
420 641
@@ -599,24 +820,26 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
599 [CLKID_MPLL0] = &meson8b_mpll0.hw, 820 [CLKID_MPLL0] = &meson8b_mpll0.hw,
600 [CLKID_MPLL1] = &meson8b_mpll1.hw, 821 [CLKID_MPLL1] = &meson8b_mpll1.hw,
601 [CLKID_MPLL2] = &meson8b_mpll2.hw, 822 [CLKID_MPLL2] = &meson8b_mpll2.hw,
823 [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
824 [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
825 [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
826 [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
827 [CLKID_CPU_DIV2] = &meson8b_cpu_div2.hw,
828 [CLKID_CPU_DIV3] = &meson8b_cpu_div3.hw,
829 [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
830 [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
831 [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
832 [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
833 [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
834 [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
835 [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
836 [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
602 [CLK_NR_CLKS] = NULL, 837 [CLK_NR_CLKS] = NULL,
603 }, 838 },
604 .num = CLK_NR_CLKS, 839 .num = CLK_NR_CLKS,
605}; 840};
606 841
607static struct meson_clk_pll *const meson8b_clk_plls[] = { 842static struct clk_regmap *const meson8b_clk_regmaps[] = {
608 &meson8b_fixed_pll,
609 &meson8b_vid_pll,
610 &meson8b_sys_pll,
611};
612
613static struct meson_clk_mpll *const meson8b_clk_mplls[] = {
614 &meson8b_mpll0,
615 &meson8b_mpll1,
616 &meson8b_mpll2,
617};
618
619static struct clk_gate *const meson8b_clk_gates[] = {
620 &meson8b_clk81, 843 &meson8b_clk81,
621 &meson8b_ddr, 844 &meson8b_ddr,
622 &meson8b_dos, 845 &meson8b_dos,
@@ -695,14 +918,27 @@ static struct clk_gate *const meson8b_clk_gates[] = {
695 &meson8b_ao_ahb_sram, 918 &meson8b_ao_ahb_sram,
696 &meson8b_ao_ahb_bus, 919 &meson8b_ao_ahb_bus,
697 &meson8b_ao_iface, 920 &meson8b_ao_iface,
698};
699
700static struct clk_mux *const meson8b_clk_muxes[] = {
701 &meson8b_mpeg_clk_sel,
702};
703
704static struct clk_divider *const meson8b_clk_dividers[] = {
705 &meson8b_mpeg_clk_div, 921 &meson8b_mpeg_clk_div,
922 &meson8b_mpeg_clk_sel,
923 &meson8b_mpll0,
924 &meson8b_mpll1,
925 &meson8b_mpll2,
926 &meson8b_mpll0_div,
927 &meson8b_mpll1_div,
928 &meson8b_mpll2_div,
929 &meson8b_fixed_pll,
930 &meson8b_vid_pll,
931 &meson8b_sys_pll,
932 &meson8b_cpu_in_sel,
933 &meson8b_cpu_scale_div,
934 &meson8b_cpu_scale_out_sel,
935 &meson8b_cpu_clk,
936 &meson8b_mpll_prediv,
937 &meson8b_fclk_div2,
938 &meson8b_fclk_div3,
939 &meson8b_fclk_div4,
940 &meson8b_fclk_div5,
941 &meson8b_fclk_div7,
706}; 942};
707 943
708static const struct meson8b_clk_reset_line { 944static const struct meson8b_clk_reset_line {
@@ -804,82 +1040,45 @@ static const struct reset_control_ops meson8b_clk_reset_ops = {
804 .deassert = meson8b_clk_reset_deassert, 1040 .deassert = meson8b_clk_reset_deassert,
805}; 1041};
806 1042
1043static const struct regmap_config clkc_regmap_config = {
1044 .reg_bits = 32,
1045 .val_bits = 32,
1046 .reg_stride = 4,
1047};
1048
807static int meson8b_clkc_probe(struct platform_device *pdev) 1049static int meson8b_clkc_probe(struct platform_device *pdev)
808{ 1050{
809 int ret, clkid, i; 1051 int ret, i;
810 struct clk_hw *parent_hw;
811 struct clk *parent_clk;
812 struct device *dev = &pdev->dev; 1052 struct device *dev = &pdev->dev;
1053 struct regmap *map;
813 1054
814 if (!clk_base) 1055 if (!clk_base)
815 return -ENXIO; 1056 return -ENXIO;
816 1057
817 /* Populate base address for PLLs */ 1058 map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
818 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) 1059 if (IS_ERR(map))
819 meson8b_clk_plls[i]->base = clk_base; 1060 return PTR_ERR(map);
820
821 /* Populate base address for MPLLs */
822 for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++)
823 meson8b_clk_mplls[i]->base = clk_base;
824
825 /* Populate the base address for CPU clk */
826 meson8b_cpu_clk.base = clk_base;
827
828 /* Populate base address for gates */
829 for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
830 meson8b_clk_gates[i]->reg = clk_base +
831 (u32)meson8b_clk_gates[i]->reg;
832
833 /* Populate base address for muxes */
834 for (i = 0; i < ARRAY_SIZE(meson8b_clk_muxes); i++)
835 meson8b_clk_muxes[i]->reg = clk_base +
836 (u32)meson8b_clk_muxes[i]->reg;
837 1061
838 /* Populate base address for dividers */ 1062 /* Populate regmap for the regmap backed clocks */
839 for (i = 0; i < ARRAY_SIZE(meson8b_clk_dividers); i++) 1063 for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
840 meson8b_clk_dividers[i]->reg = clk_base + 1064 meson8b_clk_regmaps[i]->map = map;
841 (u32)meson8b_clk_dividers[i]->reg;
842 1065
843 /* 1066 /*
844 * register all clks 1067 * register all clks
845 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 1068 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
846 */ 1069 */
847 for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) { 1070 for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
848 /* array might be sparse */ 1071 /* array might be sparse */
849 if (!meson8b_hw_onecell_data.hws[clkid]) 1072 if (!meson8b_hw_onecell_data.hws[i])
850 continue; 1073 continue;
851 1074
852 /* FIXME convert to devm_clk_register */ 1075 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
853 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
854 if (ret) 1076 if (ret)
855 return ret; 1077 return ret;
856 } 1078 }
857 1079
858 /* 1080 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
859 * Register CPU clk notifier 1081 &meson8b_hw_onecell_data);
860 *
861 * FIXME this is wrong for a lot of reasons. First, the muxes should be
862 * struct clk_hw objects. Second, we shouldn't program the muxes in
863 * notifier handlers. The tricky programming sequence will be handled
864 * by the forthcoming coordinated clock rates mechanism once that
865 * feature is released.
866 *
867 * Furthermore, looking up the parent this way is terrible. At some
868 * point we will stop allocating a default struct clk when registering
869 * a new clk_hw, and this hack will no longer work. Releasing the ccr
870 * feature before that time solves the problem :-)
871 */
872 parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
873 parent_clk = parent_hw->clk;
874 ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
875 if (ret) {
876 pr_err("%s: failed to register clock notifier for cpu_clk\n",
877 __func__);
878 return ret;
879 }
880
881 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
882 &meson8b_hw_onecell_data);
883} 1082}
884 1083
885static const struct of_device_id meson8b_clkc_match_table[] = { 1084static const struct of_device_id meson8b_clkc_match_table[] = {
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 2eaf8a52e7dd..6e414bd36981 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -69,7 +69,22 @@
69 * will remain defined here. 69 * will remain defined here.
70 */ 70 */
71 71
72#define CLK_NR_CLKS 96 72#define CLKID_MPLL0_DIV 96
73#define CLKID_MPLL1_DIV 97
74#define CLKID_MPLL2_DIV 98
75#define CLKID_CPU_IN_SEL 99
76#define CLKID_CPU_DIV2 100
77#define CLKID_CPU_DIV3 101
78#define CLKID_CPU_SCALE_DIV 102
79#define CLKID_CPU_SCALE_OUT_SEL 103
80#define CLKID_MPLL_PREDIV 104
81#define CLKID_FCLK_DIV2_DIV 105
82#define CLKID_FCLK_DIV3_DIV 106
83#define CLKID_FCLK_DIV4_DIV 107
84#define CLKID_FCLK_DIV5_DIV 108
85#define CLKID_FCLK_DIV7_DIV 109
86
87#define CLK_NR_CLKS 110
73 88
74/* 89/*
75 * include the CLKID and RESETID that have 90 * include the CLKID and RESETID that have
diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c
index 4e9b8c2c8980..1ee75a5e93f4 100644
--- a/drivers/clk/qcom/clk-regmap-divider.c
+++ b/drivers/clk/qcom/clk-regmap-divider.c
@@ -28,22 +28,14 @@ static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
28{ 28{
29 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 29 struct clk_regmap_div *divider = to_clk_regmap_div(hw);
30 struct clk_regmap *clkr = &divider->clkr; 30 struct clk_regmap *clkr = &divider->clkr;
31 u32 div; 31 u32 val;
32 struct clk_hw *hw_parent = clk_hw_get_parent(hw);
33
34 regmap_read(clkr->regmap, divider->reg, &div);
35 div >>= divider->shift;
36 div &= BIT(divider->width) - 1;
37 div += 1;
38
39 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
40 if (!hw_parent)
41 return -EINVAL;
42 32
43 *prate = clk_hw_round_rate(hw_parent, rate * div); 33 regmap_read(clkr->regmap, divider->reg, &val);
44 } 34 val >>= divider->shift;
35 val &= BIT(divider->width) - 1;
45 36
46 return DIV_ROUND_UP_ULL((u64)*prate, div); 37 return divider_ro_round_rate(hw, rate, prate, NULL, divider->width,
38 CLK_DIVIDER_ROUND_CLOSEST, val);
47} 39}
48 40
49static long div_round_rate(struct clk_hw *hw, unsigned long rate, 41static long div_round_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index ef8900bc077f..513826393158 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,9 +8,11 @@ obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
8obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o 8obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
9obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o 9obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o
10obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o 10obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
11obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o
11obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o 12obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
12obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o 13obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
13obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 14obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
15obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o
14obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o 16obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
15obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 17obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
16obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o 18obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 5bfc92ee3129..b4b057c7301c 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -143,10 +143,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
143 143
144 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 144 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
145 reg_base = devm_ioremap_resource(dev, res); 145 reg_base = devm_ioremap_resource(dev, res);
146 if (IS_ERR(reg_base)) { 146 if (IS_ERR(reg_base))
147 dev_err(dev, "failed to map audss registers\n");
148 return PTR_ERR(reg_base); 147 return PTR_ERR(reg_base);
149 }
150 148
151 epll = ERR_PTR(-ENODEV); 149 epll = ERR_PTR(-ENODEV);
152 150
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 1b81e283f605..27c9d23657b3 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -670,73 +670,73 @@ static const struct samsung_gate_clock gate_clks[] __initconst = {
670 670
671/* APLL & MPLL & BPLL & UPLL */ 671/* APLL & MPLL & BPLL & UPLL */
672static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = { 672static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = {
673 PLL_35XX_RATE(1200000000, 400, 4, 1), 673 PLL_35XX_RATE(24 * MHZ, 1200000000, 400, 4, 1),
674 PLL_35XX_RATE(1100000000, 275, 3, 1), 674 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
675 PLL_35XX_RATE(1066000000, 533, 6, 1), 675 PLL_35XX_RATE(24 * MHZ, 1066000000, 533, 6, 1),
676 PLL_35XX_RATE(1000000000, 250, 3, 1), 676 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
677 PLL_35XX_RATE( 960000000, 320, 4, 1), 677 PLL_35XX_RATE(24 * MHZ, 960000000, 320, 4, 1),
678 PLL_35XX_RATE( 900000000, 300, 4, 1), 678 PLL_35XX_RATE(24 * MHZ, 900000000, 300, 4, 1),
679 PLL_35XX_RATE( 850000000, 425, 6, 1), 679 PLL_35XX_RATE(24 * MHZ, 850000000, 425, 6, 1),
680 PLL_35XX_RATE( 800000000, 200, 3, 1), 680 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
681 PLL_35XX_RATE( 700000000, 175, 3, 1), 681 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
682 PLL_35XX_RATE( 667000000, 667, 12, 1), 682 PLL_35XX_RATE(24 * MHZ, 667000000, 667, 12, 1),
683 PLL_35XX_RATE( 600000000, 400, 4, 2), 683 PLL_35XX_RATE(24 * MHZ, 600000000, 400, 4, 2),
684 PLL_35XX_RATE( 533000000, 533, 6, 2), 684 PLL_35XX_RATE(24 * MHZ, 533000000, 533, 6, 2),
685 PLL_35XX_RATE( 520000000, 260, 3, 2), 685 PLL_35XX_RATE(24 * MHZ, 520000000, 260, 3, 2),
686 PLL_35XX_RATE( 500000000, 250, 3, 2), 686 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
687 PLL_35XX_RATE( 400000000, 200, 3, 2), 687 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
688 PLL_35XX_RATE( 200000000, 200, 3, 3), 688 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
689 PLL_35XX_RATE( 100000000, 200, 3, 4), 689 PLL_35XX_RATE(24 * MHZ, 100000000, 200, 3, 4),
690 { /* sentinel */ } 690 { /* sentinel */ }
691}; 691};
692 692
693/* EPLL */ 693/* EPLL */
694static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = { 694static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = {
695 PLL_36XX_RATE(800000000, 200, 3, 1, 0), 695 PLL_36XX_RATE(24 * MHZ, 800000000, 200, 3, 1, 0),
696 PLL_36XX_RATE(288000000, 96, 2, 2, 0), 696 PLL_36XX_RATE(24 * MHZ, 288000000, 96, 2, 2, 0),
697 PLL_36XX_RATE(192000000, 128, 2, 3, 0), 697 PLL_36XX_RATE(24 * MHZ, 192000000, 128, 2, 3, 0),
698 PLL_36XX_RATE(144000000, 96, 2, 3, 0), 698 PLL_36XX_RATE(24 * MHZ, 144000000, 96, 2, 3, 0),
699 PLL_36XX_RATE( 96000000, 128, 2, 4, 0), 699 PLL_36XX_RATE(24 * MHZ, 96000000, 128, 2, 4, 0),
700 PLL_36XX_RATE( 84000000, 112, 2, 4, 0), 700 PLL_36XX_RATE(24 * MHZ, 84000000, 112, 2, 4, 0),
701 PLL_36XX_RATE( 80000004, 106, 2, 4, 43691), 701 PLL_36XX_RATE(24 * MHZ, 80000003, 106, 2, 4, 43691),
702 PLL_36XX_RATE( 73728000, 98, 2, 4, 19923), 702 PLL_36XX_RATE(24 * MHZ, 73728000, 98, 2, 4, 19923),
703 PLL_36XX_RATE( 67737598, 270, 3, 5, 62285), 703 PLL_36XX_RATE(24 * MHZ, 67737598, 270, 3, 5, 62285),
704 PLL_36XX_RATE( 65535999, 174, 2, 5, 49982), 704 PLL_36XX_RATE(24 * MHZ, 65535999, 174, 2, 5, 49982),
705 PLL_36XX_RATE( 50000000, 200, 3, 5, 0), 705 PLL_36XX_RATE(24 * MHZ, 50000000, 200, 3, 5, 0),
706 PLL_36XX_RATE( 49152002, 131, 2, 5, 4719), 706 PLL_36XX_RATE(24 * MHZ, 49152002, 131, 2, 5, 4719),
707 PLL_36XX_RATE( 48000000, 128, 2, 5, 0), 707 PLL_36XX_RATE(24 * MHZ, 48000000, 128, 2, 5, 0),
708 PLL_36XX_RATE( 45158401, 180, 3, 5, 41524), 708 PLL_36XX_RATE(24 * MHZ, 45158401, 180, 3, 5, 41524),
709 { /* sentinel */ } 709 { /* sentinel */ }
710}; 710};
711 711
712/* VPLL */ 712/* VPLL */
713static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = { 713static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = {
714 PLL_36XX_RATE(600000000, 100, 2, 1, 0), 714 PLL_36XX_RATE(24 * MHZ, 600000000, 100, 2, 1, 0),
715 PLL_36XX_RATE(533000000, 266, 3, 2, 32768), 715 PLL_36XX_RATE(24 * MHZ, 533000000, 266, 3, 2, 32768),
716 PLL_36XX_RATE(519230987, 173, 2, 2, 5046), 716 PLL_36XX_RATE(24 * MHZ, 519230987, 173, 2, 2, 5046),
717 PLL_36XX_RATE(500000000, 250, 3, 2, 0), 717 PLL_36XX_RATE(24 * MHZ, 500000000, 250, 3, 2, 0),
718 PLL_36XX_RATE(445500000, 148, 2, 2, 32768), 718 PLL_36XX_RATE(24 * MHZ, 445500000, 148, 2, 2, 32768),
719 PLL_36XX_RATE(445055007, 148, 2, 2, 23047), 719 PLL_36XX_RATE(24 * MHZ, 445055007, 148, 2, 2, 23047),
720 PLL_36XX_RATE(400000000, 200, 3, 2, 0), 720 PLL_36XX_RATE(24 * MHZ, 400000000, 200, 3, 2, 0),
721 PLL_36XX_RATE(371250000, 123, 2, 2, 49152), 721 PLL_36XX_RATE(24 * MHZ, 371250000, 123, 2, 2, 49152),
722 PLL_36XX_RATE(370878997, 185, 3, 2, 28803), 722 PLL_36XX_RATE(24 * MHZ, 370878997, 185, 3, 2, 28803),
723 PLL_36XX_RATE(340000000, 170, 3, 2, 0), 723 PLL_36XX_RATE(24 * MHZ, 340000000, 170, 3, 2, 0),
724 PLL_36XX_RATE(335000015, 111, 2, 2, 43691), 724 PLL_36XX_RATE(24 * MHZ, 335000015, 111, 2, 2, 43691),
725 PLL_36XX_RATE(333000000, 111, 2, 2, 0), 725 PLL_36XX_RATE(24 * MHZ, 333000000, 111, 2, 2, 0),
726 PLL_36XX_RATE(330000000, 110, 2, 2, 0), 726 PLL_36XX_RATE(24 * MHZ, 330000000, 110, 2, 2, 0),
727 PLL_36XX_RATE(320000015, 106, 2, 2, 43691), 727 PLL_36XX_RATE(24 * MHZ, 320000015, 106, 2, 2, 43691),
728 PLL_36XX_RATE(300000000, 100, 2, 2, 0), 728 PLL_36XX_RATE(24 * MHZ, 300000000, 100, 2, 2, 0),
729 PLL_36XX_RATE(275000000, 275, 3, 3, 0), 729 PLL_36XX_RATE(24 * MHZ, 275000000, 275, 3, 3, 0),
730 PLL_36XX_RATE(222750000, 148, 2, 3, 32768), 730 PLL_36XX_RATE(24 * MHZ, 222750000, 148, 2, 3, 32768),
731 PLL_36XX_RATE(222528007, 148, 2, 3, 23069), 731 PLL_36XX_RATE(24 * MHZ, 222528007, 148, 2, 3, 23069),
732 PLL_36XX_RATE(160000000, 160, 3, 3, 0), 732 PLL_36XX_RATE(24 * MHZ, 160000000, 160, 3, 3, 0),
733 PLL_36XX_RATE(148500000, 99, 2, 3, 0), 733 PLL_36XX_RATE(24 * MHZ, 148500000, 99, 2, 3, 0),
734 PLL_36XX_RATE(148352005, 98, 2, 3, 59070), 734 PLL_36XX_RATE(24 * MHZ, 148352005, 98, 2, 3, 59070),
735 PLL_36XX_RATE(108000000, 144, 2, 4, 0), 735 PLL_36XX_RATE(24 * MHZ, 108000000, 144, 2, 4, 0),
736 PLL_36XX_RATE( 74250000, 99, 2, 4, 0), 736 PLL_36XX_RATE(24 * MHZ, 74250000, 99, 2, 4, 0),
737 PLL_36XX_RATE( 74176002, 98, 3, 4, 59070), 737 PLL_36XX_RATE(24 * MHZ, 74176002, 98, 2, 4, 59070),
738 PLL_36XX_RATE( 54054000, 216, 3, 5, 14156), 738 PLL_36XX_RATE(24 * MHZ, 54054000, 216, 3, 5, 14156),
739 PLL_36XX_RATE( 54000000, 144, 2, 5, 0), 739 PLL_36XX_RATE(24 * MHZ, 54000000, 144, 2, 5, 0),
740 { /* sentinel */ } 740 { /* sentinel */ }
741}; 741};
742 742
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 134f25f2a913..0421960eb963 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1266,77 +1266,78 @@ static const struct of_device_id ext_clk_match[] __initconst = {
1266 1266
1267/* PLLs PMS values */ 1267/* PLLs PMS values */
1268static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = { 1268static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = {
1269 PLL_45XX_RATE(1200000000, 150, 3, 1, 28), 1269 PLL_4508_RATE(24 * MHZ, 1200000000, 150, 3, 1, 28),
1270 PLL_45XX_RATE(1000000000, 250, 6, 1, 28), 1270 PLL_4508_RATE(24 * MHZ, 1000000000, 250, 6, 1, 28),
1271 PLL_45XX_RATE( 800000000, 200, 6, 1, 28), 1271 PLL_4508_RATE(24 * MHZ, 800000000, 200, 6, 1, 28),
1272 PLL_45XX_RATE( 666857142, 389, 14, 1, 13), 1272 PLL_4508_RATE(24 * MHZ, 666857142, 389, 14, 1, 13),
1273 PLL_45XX_RATE( 600000000, 100, 4, 1, 13), 1273 PLL_4508_RATE(24 * MHZ, 600000000, 100, 4, 1, 13),
1274 PLL_45XX_RATE( 533000000, 533, 24, 1, 5), 1274 PLL_4508_RATE(24 * MHZ, 533000000, 533, 24, 1, 5),
1275 PLL_45XX_RATE( 500000000, 250, 6, 2, 28), 1275 PLL_4508_RATE(24 * MHZ, 500000000, 250, 6, 2, 28),
1276 PLL_45XX_RATE( 400000000, 200, 6, 2, 28), 1276 PLL_4508_RATE(24 * MHZ, 400000000, 200, 6, 2, 28),
1277 PLL_45XX_RATE( 200000000, 200, 6, 3, 28), 1277 PLL_4508_RATE(24 * MHZ, 200000000, 200, 6, 3, 28),
1278 { /* sentinel */ } 1278 { /* sentinel */ }
1279}; 1279};
1280 1280
1281static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = { 1281static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = {
1282 PLL_4600_RATE(192000000, 48, 3, 1, 0, 0), 1282 PLL_4600_RATE(24 * MHZ, 192000000, 48, 3, 1, 0, 0),
1283 PLL_4600_RATE(180633605, 45, 3, 1, 10381, 0), 1283 PLL_4600_RATE(24 * MHZ, 180633605, 45, 3, 1, 10381, 0),
1284 PLL_4600_RATE(180000000, 45, 3, 1, 0, 0), 1284 PLL_4600_RATE(24 * MHZ, 180000000, 45, 3, 1, 0, 0),
1285 PLL_4600_RATE( 73727996, 73, 3, 3, 47710, 1), 1285 PLL_4600_RATE(24 * MHZ, 73727996, 73, 3, 3, 47710, 1),
1286 PLL_4600_RATE( 67737602, 90, 4, 3, 20762, 1), 1286 PLL_4600_RATE(24 * MHZ, 67737602, 90, 4, 3, 20762, 1),
1287 PLL_4600_RATE( 49151992, 49, 3, 3, 9961, 0), 1287 PLL_4600_RATE(24 * MHZ, 49151992, 49, 3, 3, 9961, 0),
1288 PLL_4600_RATE( 45158401, 45, 3, 3, 10381, 0), 1288 PLL_4600_RATE(24 * MHZ, 45158401, 45, 3, 3, 10381, 0),
1289 { /* sentinel */ } 1289 { /* sentinel */ }
1290}; 1290};
1291 1291
1292static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = { 1292static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = {
1293 PLL_4650_RATE(360000000, 44, 3, 0, 1024, 0, 14, 0), 1293 PLL_4650_RATE(24 * MHZ, 360000000, 44, 3, 0, 1024, 0, 14, 0),
1294 PLL_4650_RATE(324000000, 53, 2, 1, 1024, 1, 1, 1), 1294 PLL_4650_RATE(24 * MHZ, 324000000, 53, 2, 1, 1024, 1, 1, 1),
1295 PLL_4650_RATE(259617187, 63, 3, 1, 1950, 0, 20, 1), 1295 PLL_4650_RATE(24 * MHZ, 259617187, 63, 3, 1, 1950, 0, 20, 1),
1296 PLL_4650_RATE(110000000, 53, 3, 2, 2048, 0, 17, 0), 1296 PLL_4650_RATE(24 * MHZ, 110000000, 53, 3, 2, 2048, 0, 17, 0),
1297 PLL_4650_RATE( 55360351, 53, 3, 3, 2417, 0, 17, 0), 1297 PLL_4650_RATE(24 * MHZ, 55360351, 53, 3, 3, 2417, 0, 17, 0),
1298 { /* sentinel */ } 1298 { /* sentinel */ }
1299}; 1299};
1300 1300
1301static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = { 1301static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = {
1302 PLL_35XX_RATE(1704000000, 213, 3, 0), 1302 PLL_35XX_RATE(24 * MHZ, 1704000000, 213, 3, 0),
1303 PLL_35XX_RATE(1600000000, 200, 3, 0), 1303 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
1304 PLL_35XX_RATE(1500000000, 250, 4, 0), 1304 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
1305 PLL_35XX_RATE(1400000000, 175, 3, 0), 1305 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
1306 PLL_35XX_RATE(1300000000, 325, 6, 0), 1306 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
1307 PLL_35XX_RATE(1200000000, 200, 4, 0), 1307 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 4, 0),
1308 PLL_35XX_RATE(1100000000, 275, 6, 0), 1308 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 6, 0),
1309 PLL_35XX_RATE(1000000000, 125, 3, 0), 1309 PLL_35XX_RATE(24 * MHZ, 1000000000, 125, 3, 0),
1310 PLL_35XX_RATE( 900000000, 150, 4, 0), 1310 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 4, 0),
1311 PLL_35XX_RATE( 800000000, 100, 3, 0), 1311 PLL_35XX_RATE(24 * MHZ, 800000000, 100, 3, 0),
1312 PLL_35XX_RATE( 700000000, 175, 3, 1), 1312 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
1313 PLL_35XX_RATE( 600000000, 200, 4, 1), 1313 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 4, 1),
1314 PLL_35XX_RATE( 500000000, 125, 3, 1), 1314 PLL_35XX_RATE(24 * MHZ, 500000000, 125, 3, 1),
1315 PLL_35XX_RATE( 400000000, 100, 3, 1), 1315 PLL_35XX_RATE(24 * MHZ, 400000000, 100, 3, 1),
1316 PLL_35XX_RATE( 300000000, 200, 4, 2), 1316 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 4, 2),
1317 PLL_35XX_RATE( 200000000, 100, 3, 2), 1317 PLL_35XX_RATE(24 * MHZ, 200000000, 100, 3, 2),
1318 { /* sentinel */ } 1318 { /* sentinel */ }
1319}; 1319};
1320 1320
1321static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = { 1321static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = {
1322 PLL_36XX_RATE(192000000, 48, 3, 1, 0), 1322 PLL_36XX_RATE(24 * MHZ, 196608001, 197, 3, 3, -25690),
1323 PLL_36XX_RATE(180633605, 45, 3, 1, 10381), 1323 PLL_36XX_RATE(24 * MHZ, 192000000, 48, 3, 1, 0),
1324 PLL_36XX_RATE(180000000, 45, 3, 1, 0), 1324 PLL_36XX_RATE(24 * MHZ, 180633605, 45, 3, 1, 10381),
1325 PLL_36XX_RATE( 73727996, 73, 3, 3, 47710), 1325 PLL_36XX_RATE(24 * MHZ, 180000000, 45, 3, 1, 0),
1326 PLL_36XX_RATE( 67737602, 90, 4, 3, 20762), 1326 PLL_36XX_RATE(24 * MHZ, 73727996, 73, 3, 3, 47710),
1327 PLL_36XX_RATE( 49151992, 49, 3, 3, 9961), 1327 PLL_36XX_RATE(24 * MHZ, 67737602, 90, 4, 3, 20762),
1328 PLL_36XX_RATE( 45158401, 45, 3, 3, 10381), 1328 PLL_36XX_RATE(24 * MHZ, 49151992, 49, 3, 3, 9961),
1329 PLL_36XX_RATE(24 * MHZ, 45158401, 45, 3, 3, 10381),
1329 { /* sentinel */ } 1330 { /* sentinel */ }
1330}; 1331};
1331 1332
1332static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = { 1333static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = {
1333 PLL_36XX_RATE(533000000, 133, 3, 1, 16384), 1334 PLL_36XX_RATE(24 * MHZ, 533000000, 133, 3, 1, 16384),
1334 PLL_36XX_RATE(440000000, 110, 3, 1, 0), 1335 PLL_36XX_RATE(24 * MHZ, 440000000, 110, 3, 1, 0),
1335 PLL_36XX_RATE(350000000, 175, 3, 2, 0), 1336 PLL_36XX_RATE(24 * MHZ, 350000000, 175, 3, 2, 0),
1336 PLL_36XX_RATE(266000000, 133, 3, 2, 0), 1337 PLL_36XX_RATE(24 * MHZ, 266000000, 133, 3, 2, 0),
1337 PLL_36XX_RATE(160000000, 160, 3, 3, 0), 1338 PLL_36XX_RATE(24 * MHZ, 160000000, 160, 3, 3, 0),
1338 PLL_36XX_RATE(106031250, 53, 3, 2, 1024), 1339 PLL_36XX_RATE(24 * MHZ, 106031250, 53, 3, 2, 1024),
1339 PLL_36XX_RATE( 53015625, 53, 3, 3, 1024), 1340 PLL_36XX_RATE(24 * MHZ, 53015625, 53, 3, 3, 1024),
1340 { /* sentinel */ } 1341 { /* sentinel */ }
1341}; 1342};
1342 1343
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.c b/drivers/clk/samsung/clk-exynos5-subcmu.c
new file mode 100644
index 000000000000..93306283d764
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
@@ -0,0 +1,189 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 Samsung Electronics Co., Ltd.
4// Author: Marek Szyprowski <m.szyprowski@samsung.com>
5// Common Clock Framework support for Exynos5 power-domain dependent clocks
6
7#include <linux/of_platform.h>
8#include <linux/platform_device.h>
9#include <linux/pm_domain.h>
10#include <linux/pm_runtime.h>
11
12#include "clk.h"
13#include "clk-exynos5-subcmu.h"
14
15static struct samsung_clk_provider *ctx;
16static const struct exynos5_subcmu_info *cmu;
17static int nr_cmus;
18
19static void exynos5_subcmu_clk_save(void __iomem *base,
20 struct exynos5_subcmu_reg_dump *rd,
21 unsigned int num_regs)
22{
23 for (; num_regs > 0; --num_regs, ++rd) {
24 rd->save = readl(base + rd->offset);
25 writel((rd->save & ~rd->mask) | rd->value, base + rd->offset);
26 rd->save &= rd->mask;
27 }
28};
29
30static void exynos5_subcmu_clk_restore(void __iomem *base,
31 struct exynos5_subcmu_reg_dump *rd,
32 unsigned int num_regs)
33{
34 for (; num_regs > 0; --num_regs, ++rd)
35 writel((readl(base + rd->offset) & ~rd->mask) | rd->save,
36 base + rd->offset);
37}
38
39static void exynos5_subcmu_defer_gate(struct samsung_clk_provider *ctx,
40 const struct samsung_gate_clock *list, int nr_clk)
41{
42 while (nr_clk--)
43 samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER), list++->id);
44}
45
46/*
47 * Pass the needed clock provider context and register sub-CMU clocks
48 *
49 * NOTE: This function has to be called from the main, OF_CLK_DECLARE-
50 * initialized clock provider driver. This happens very early during boot
51 * process. Then this driver, during core_initcall registers two platform
52 * drivers: one which binds to the same device-tree node as OF_CLK_DECLARE
53 * driver and second, for handling its per-domain child-devices. Those
54 * platform drivers are bound to their devices a bit later in arch_initcall,
55 * when OF-core populates all device-tree nodes.
56 */
57void exynos5_subcmus_init(struct samsung_clk_provider *_ctx, int _nr_cmus,
58 const struct exynos5_subcmu_info *_cmu)
59{
60 ctx = _ctx;
61 cmu = _cmu;
62 nr_cmus = _nr_cmus;
63
64 for (; _nr_cmus--; _cmu++) {
65 exynos5_subcmu_defer_gate(ctx, _cmu->gate_clks,
66 _cmu->nr_gate_clks);
67 exynos5_subcmu_clk_save(ctx->reg_base, _cmu->suspend_regs,
68 _cmu->nr_suspend_regs);
69 }
70}
71
72static int __maybe_unused exynos5_subcmu_suspend(struct device *dev)
73{
74 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
75 unsigned long flags;
76
77 spin_lock_irqsave(&ctx->lock, flags);
78 exynos5_subcmu_clk_save(ctx->reg_base, info->suspend_regs,
79 info->nr_suspend_regs);
80 spin_unlock_irqrestore(&ctx->lock, flags);
81
82 return 0;
83}
84
85static int __maybe_unused exynos5_subcmu_resume(struct device *dev)
86{
87 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
88 unsigned long flags;
89
90 spin_lock_irqsave(&ctx->lock, flags);
91 exynos5_subcmu_clk_restore(ctx->reg_base, info->suspend_regs,
92 info->nr_suspend_regs);
93 spin_unlock_irqrestore(&ctx->lock, flags);
94
95 return 0;
96}
97
98static int __init exynos5_subcmu_probe(struct platform_device *pdev)
99{
100 struct device *dev = &pdev->dev;
101 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
102
103 pm_runtime_set_suspended(dev);
104 pm_runtime_enable(dev);
105 pm_runtime_get(dev);
106
107 ctx->dev = dev;
108 samsung_clk_register_div(ctx, info->div_clks, info->nr_div_clks);
109 samsung_clk_register_gate(ctx, info->gate_clks, info->nr_gate_clks);
110 ctx->dev = NULL;
111
112 pm_runtime_put_sync(dev);
113
114 return 0;
115}
116
117static const struct dev_pm_ops exynos5_subcmu_pm_ops = {
118 SET_RUNTIME_PM_OPS(exynos5_subcmu_suspend,
119 exynos5_subcmu_resume, NULL)
120 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
121 pm_runtime_force_resume)
122};
123
124static struct platform_driver exynos5_subcmu_driver __refdata = {
125 .driver = {
126 .name = "exynos5-subcmu",
127 .suppress_bind_attrs = true,
128 .pm = &exynos5_subcmu_pm_ops,
129 },
130 .probe = exynos5_subcmu_probe,
131};
132
133static int __init exynos5_clk_register_subcmu(struct device *parent,
134 const struct exynos5_subcmu_info *info,
135 struct device_node *pd_node)
136{
137 struct of_phandle_args genpdspec = { .np = pd_node };
138 struct platform_device *pdev;
139
140 pdev = platform_device_alloc(info->pd_name, -1);
141 pdev->dev.parent = parent;
142 pdev->driver_override = "exynos5-subcmu";
143 platform_set_drvdata(pdev, (void *)info);
144 of_genpd_add_device(&genpdspec, &pdev->dev);
145 platform_device_add(pdev);
146
147 return 0;
148}
149
150static int __init exynos5_clk_probe(struct platform_device *pdev)
151{
152 struct device_node *np;
153 const char *name;
154 int i;
155
156 for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
157 if (of_property_read_string(np, "label", &name) < 0)
158 continue;
159 for (i = 0; i < nr_cmus; i++)
160 if (strcmp(cmu[i].pd_name, name) == 0)
161 exynos5_clk_register_subcmu(&pdev->dev,
162 &cmu[i], np);
163 }
164 return 0;
165}
166
167static const struct of_device_id exynos5_clk_of_match[] = {
168 { .compatible = "samsung,exynos5250-clock", },
169 { .compatible = "samsung,exynos5420-clock", },
170 { .compatible = "samsung,exynos5800-clock", },
171 { },
172};
173
174static struct platform_driver exynos5_clk_driver __refdata = {
175 .driver = {
176 .name = "exynos5-clock",
177 .of_match_table = exynos5_clk_of_match,
178 .suppress_bind_attrs = true,
179 },
180 .probe = exynos5_clk_probe,
181};
182
183static int __init exynos5_clk_drv_init(void)
184{
185 platform_driver_register(&exynos5_clk_driver);
186 platform_driver_register(&exynos5_subcmu_driver);
187 return 0;
188}
189core_initcall(exynos5_clk_drv_init);
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.h b/drivers/clk/samsung/clk-exynos5-subcmu.h
new file mode 100644
index 000000000000..755ee8aaa3de
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.h
@@ -0,0 +1,26 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __CLK_EXYNOS5_SUBCMU_H
4#define __CLK_EXYNOS5_SUBCMU_H
5
6struct exynos5_subcmu_reg_dump {
7 u32 offset;
8 u32 value;
9 u32 mask;
10 u32 save;
11};
12
13struct exynos5_subcmu_info {
14 const struct samsung_div_clock *div_clks;
15 unsigned int nr_div_clks;
16 const struct samsung_gate_clock *gate_clks;
17 unsigned int nr_gate_clks;
18 struct exynos5_subcmu_reg_dump *suspend_regs;
19 unsigned int nr_suspend_regs;
20 const char *pd_name;
21};
22
23void exynos5_subcmus_init(struct samsung_clk_provider *ctx, int nr_cmus,
24 const struct exynos5_subcmu_info *cmu);
25
26#endif
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 9b073c98a891..347fd80c351b 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -18,6 +18,7 @@
18 18
19#include "clk.h" 19#include "clk.h"
20#include "clk-cpu.h" 20#include "clk-cpu.h"
21#include "clk-exynos5-subcmu.h"
21 22
22#define APLL_LOCK 0x0 23#define APLL_LOCK 0x0
23#define APLL_CON0 0x100 24#define APLL_CON0 0x100
@@ -560,6 +561,8 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
560 0), 561 0),
561 GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0, 562 GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0,
562 0), 563 0),
564 GATE(CLK_CAMIF_TOP, "camif_top", "mout_aclk266_gscl_sub",
565 GATE_IP_GSCL, 4, 0, 0),
563 GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0), 566 GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
564 GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0), 567 GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
565 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub", 568 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub",
@@ -570,18 +573,11 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
570 GATE_IP_GSCL, 9, 0, 0), 573 GATE_IP_GSCL, 9, 0, 0),
571 GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub", 574 GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub",
572 GATE_IP_GSCL, 10, 0, 0), 575 GATE_IP_GSCL, 10, 0, 0),
576 GATE(CLK_SMMU_FIMC_LITE0, "smmu_fimc_lite0", "mout_aclk266_gscl_sub",
577 GATE_IP_GSCL, 11, 0, 0),
578 GATE(CLK_SMMU_FIMC_LITE1, "smmu_fimc_lite1", "mout_aclk266_gscl_sub",
579 GATE_IP_GSCL, 12, 0, 0),
573 580
574 GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0,
575 0),
576 GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0,
577 0),
578 GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0,
579 0),
580 GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0),
581 GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0,
582 0),
583 GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0,
584 0),
585 581
586 GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0), 582 GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0),
587 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0, 583 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0,
@@ -671,10 +667,6 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
671 GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0), 667 GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0),
672 GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0), 668 GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0),
673 GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0), 669 GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0),
674 GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub",
675 GATE_IP_DISP1, 9, 0, 0),
676 GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub",
677 GATE_IP_DISP1, 8, 0, 0),
678 GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0), 670 GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0),
679 GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp", "mout_aclk_266_isp_sub", 671 GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp", "mout_aclk_266_isp_sub",
680 GATE_IP_ISP0, 8, 0, 0), 672 GATE_IP_ISP0, 8, 0, 0),
@@ -698,48 +690,80 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
698 GATE_IP_ISP1, 7, 0, 0), 690 GATE_IP_ISP1, 7, 0, 0),
699}; 691};
700 692
693static const struct samsung_gate_clock exynos5250_disp_gate_clks[] __initconst = {
694 GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0,
695 0),
696 GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0,
697 0),
698 GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0,
699 0),
700 GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0),
701 GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0,
702 0),
703 GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0,
704 0),
705 GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub",
706 GATE_IP_DISP1, 9, 0, 0),
707 GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub",
708 GATE_IP_DISP1, 8, 0, 0),
709};
710
711static struct exynos5_subcmu_reg_dump exynos5250_disp_suspend_regs[] = {
712 { GATE_IP_DISP1, 0xffffffff, 0xffffffff }, /* DISP1 gates */
713 { SRC_TOP3, 0, BIT(4) }, /* MUX mout_aclk200_disp1_sub */
714 { SRC_TOP3, 0, BIT(6) }, /* MUX mout_aclk300_disp1_sub */
715};
716
717static const struct exynos5_subcmu_info exynos5250_disp_subcmu = {
718 .gate_clks = exynos5250_disp_gate_clks,
719 .nr_gate_clks = ARRAY_SIZE(exynos5250_disp_gate_clks),
720 .suspend_regs = exynos5250_disp_suspend_regs,
721 .nr_suspend_regs = ARRAY_SIZE(exynos5250_disp_suspend_regs),
722 .pd_name = "DISP1",
723};
724
701static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { 725static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = {
702 /* sorted in descending order */ 726 /* sorted in descending order */
703 /* PLL_36XX_RATE(rate, m, p, s, k) */ 727 /* PLL_36XX_RATE(rate, m, p, s, k) */
704 PLL_36XX_RATE(266000000, 266, 3, 3, 0), 728 PLL_36XX_RATE(24 * MHZ, 266000000, 266, 3, 3, 0),
705 /* Not in UM, but need for eDP on snow */ 729 /* Not in UM, but need for eDP on snow */
706 PLL_36XX_RATE(70500000, 94, 2, 4, 0), 730 PLL_36XX_RATE(24 * MHZ, 70500000, 94, 2, 4, 0),
707 { }, 731 { },
708}; 732};
709 733
710static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = { 734static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = {
711 /* sorted in descending order */ 735 /* sorted in descending order */
712 /* PLL_36XX_RATE(rate, m, p, s, k) */ 736 /* PLL_36XX_RATE(rate, m, p, s, k) */
713 PLL_36XX_RATE(192000000, 64, 2, 2, 0), 737 PLL_36XX_RATE(24 * MHZ, 192000000, 64, 2, 2, 0),
714 PLL_36XX_RATE(180633600, 90, 3, 2, 20762), 738 PLL_36XX_RATE(24 * MHZ, 180633605, 90, 3, 2, 20762),
715 PLL_36XX_RATE(180000000, 90, 3, 2, 0), 739 PLL_36XX_RATE(24 * MHZ, 180000000, 90, 3, 2, 0),
716 PLL_36XX_RATE(73728000, 98, 2, 4, 19923), 740 PLL_36XX_RATE(24 * MHZ, 73728000, 98, 2, 4, 19923),
717 PLL_36XX_RATE(67737600, 90, 2, 4, 20762), 741 PLL_36XX_RATE(24 * MHZ, 67737602, 90, 2, 4, 20762),
718 PLL_36XX_RATE(49152000, 98, 3, 4, 19923), 742 PLL_36XX_RATE(24 * MHZ, 49152000, 98, 3, 4, 19923),
719 PLL_36XX_RATE(45158400, 90, 3, 4, 20762), 743 PLL_36XX_RATE(24 * MHZ, 45158401, 90, 3, 4, 20762),
720 PLL_36XX_RATE(32768000, 131, 3, 5, 4719), 744 PLL_36XX_RATE(24 * MHZ, 32768001, 131, 3, 5, 4719),
721 { }, 745 { },
722}; 746};
723 747
724static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = { 748static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = {
725 /* sorted in descending order */ 749 /* sorted in descending order */
726 /* PLL_35XX_RATE(rate, m, p, s) */ 750 /* PLL_35XX_RATE(fin, rate, m, p, s) */
727 PLL_35XX_RATE(1700000000, 425, 6, 0), 751 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
728 PLL_35XX_RATE(1600000000, 200, 3, 0), 752 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
729 PLL_35XX_RATE(1500000000, 250, 4, 0), 753 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
730 PLL_35XX_RATE(1400000000, 175, 3, 0), 754 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
731 PLL_35XX_RATE(1300000000, 325, 6, 0), 755 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
732 PLL_35XX_RATE(1200000000, 200, 4, 0), 756 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 4, 0),
733 PLL_35XX_RATE(1100000000, 275, 6, 0), 757 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 6, 0),
734 PLL_35XX_RATE(1000000000, 125, 3, 0), 758 PLL_35XX_RATE(24 * MHZ, 1000000000, 125, 3, 0),
735 PLL_35XX_RATE(900000000, 150, 4, 0), 759 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 4, 0),
736 PLL_35XX_RATE(800000000, 100, 3, 0), 760 PLL_35XX_RATE(24 * MHZ, 800000000, 100, 3, 0),
737 PLL_35XX_RATE(700000000, 175, 3, 1), 761 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
738 PLL_35XX_RATE(600000000, 200, 4, 1), 762 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 4, 1),
739 PLL_35XX_RATE(500000000, 125, 3, 1), 763 PLL_35XX_RATE(24 * MHZ, 500000000, 125, 3, 1),
740 PLL_35XX_RATE(400000000, 100, 3, 1), 764 PLL_35XX_RATE(24 * MHZ, 400000000, 100, 3, 1),
741 PLL_35XX_RATE(300000000, 200, 4, 2), 765 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 4, 2),
742 PLL_35XX_RATE(200000000, 100, 3, 2), 766 PLL_35XX_RATE(24 * MHZ, 200000000, 100, 3, 2),
743}; 767};
744 768
745static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { 769static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
@@ -859,10 +883,11 @@ static void __init exynos5250_clk_init(struct device_node *np)
859 __raw_writel(tmp, reg_base + PWR_CTRL2); 883 __raw_writel(tmp, reg_base + PWR_CTRL2);
860 884
861 exynos5250_clk_sleep_init(); 885 exynos5250_clk_sleep_init();
886 exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu);
862 887
863 samsung_clk_of_add_provider(np, ctx); 888 samsung_clk_of_add_provider(np, ctx);
864 889
865 pr_info("Exynos5250: clock setup completed, armclk=%ld\n", 890 pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
866 _get_rate("div_arm2")); 891 _get_rate("div_arm2"));
867} 892}
868CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); 893CLK_OF_DECLARE_DRIVER(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index fd1d9bfc151b..2cc2583abd87 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -23,57 +23,57 @@
23 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. 23 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
24 */ 24 */
25static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = { 25static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = {
26 PLL_35XX_RATE(1700000000, 425, 6, 0), 26 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
27 PLL_35XX_RATE(1600000000, 200, 3, 0), 27 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
28 PLL_35XX_RATE(1500000000, 250, 4, 0), 28 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
29 PLL_35XX_RATE(1400000000, 175, 3, 0), 29 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
30 PLL_35XX_RATE(1300000000, 325, 6, 0), 30 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
31 PLL_35XX_RATE(1200000000, 400, 4, 1), 31 PLL_35XX_RATE(24 * MHZ, 1200000000, 400, 4, 1),
32 PLL_35XX_RATE(1100000000, 275, 3, 1), 32 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
33 PLL_35XX_RATE(1000000000, 250, 3, 1), 33 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
34 PLL_35XX_RATE(933000000, 311, 4, 1), 34 PLL_35XX_RATE(24 * MHZ, 933000000, 311, 4, 1),
35 PLL_35XX_RATE(900000000, 300, 4, 1), 35 PLL_35XX_RATE(24 * MHZ, 900000000, 300, 4, 1),
36 PLL_35XX_RATE(800000000, 200, 3, 1), 36 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
37 PLL_35XX_RATE(733000000, 733, 12, 1), 37 PLL_35XX_RATE(24 * MHZ, 733000000, 733, 12, 1),
38 PLL_35XX_RATE(700000000, 175, 3, 1), 38 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
39 PLL_35XX_RATE(667000000, 667, 12, 1), 39 PLL_35XX_RATE(24 * MHZ, 667000000, 667, 12, 1),
40 PLL_35XX_RATE(633000000, 211, 4, 1), 40 PLL_35XX_RATE(24 * MHZ, 633000000, 211, 4, 1),
41 PLL_35XX_RATE(620000000, 310, 3, 2), 41 PLL_35XX_RATE(24 * MHZ, 620000000, 310, 3, 2),
42 PLL_35XX_RATE(600000000, 400, 4, 2), 42 PLL_35XX_RATE(24 * MHZ, 600000000, 400, 4, 2),
43 PLL_35XX_RATE(543000000, 362, 4, 2), 43 PLL_35XX_RATE(24 * MHZ, 543000000, 362, 4, 2),
44 PLL_35XX_RATE(533000000, 533, 6, 2), 44 PLL_35XX_RATE(24 * MHZ, 533000000, 533, 6, 2),
45 PLL_35XX_RATE(500000000, 250, 3, 2), 45 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
46 PLL_35XX_RATE(450000000, 300, 4, 2), 46 PLL_35XX_RATE(24 * MHZ, 450000000, 300, 4, 2),
47 PLL_35XX_RATE(400000000, 200, 3, 2), 47 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
48 PLL_35XX_RATE(350000000, 175, 3, 2), 48 PLL_35XX_RATE(24 * MHZ, 350000000, 175, 3, 2),
49 PLL_35XX_RATE(300000000, 400, 4, 3), 49 PLL_35XX_RATE(24 * MHZ, 300000000, 400, 4, 3),
50 PLL_35XX_RATE(266000000, 266, 3, 3), 50 PLL_35XX_RATE(24 * MHZ, 266000000, 266, 3, 3),
51 PLL_35XX_RATE(200000000, 200, 3, 3), 51 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
52 PLL_35XX_RATE(160000000, 160, 3, 3), 52 PLL_35XX_RATE(24 * MHZ, 160000000, 160, 3, 3),
53}; 53};
54 54
55/* 55/*
56 * Applicable for 2650 Type PLL for AUD_PLL. 56 * Applicable for 2650 Type PLL for AUD_PLL.
57 */ 57 */
58static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = { 58static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = {
59 PLL_36XX_RATE(1600000000, 200, 3, 0, 0), 59 PLL_36XX_RATE(24 * MHZ, 1600000000, 200, 3, 0, 0),
60 PLL_36XX_RATE(1200000000, 100, 2, 0, 0), 60 PLL_36XX_RATE(24 * MHZ, 1200000000, 100, 2, 0, 0),
61 PLL_36XX_RATE(1000000000, 250, 3, 1, 0), 61 PLL_36XX_RATE(24 * MHZ, 1000000000, 250, 3, 1, 0),
62 PLL_36XX_RATE(800000000, 200, 3, 1, 0), 62 PLL_36XX_RATE(24 * MHZ, 800000000, 200, 3, 1, 0),
63 PLL_36XX_RATE(600000000, 100, 2, 1, 0), 63 PLL_36XX_RATE(24 * MHZ, 600000000, 100, 2, 1, 0),
64 PLL_36XX_RATE(532000000, 266, 3, 2, 0), 64 PLL_36XX_RATE(24 * MHZ, 532000000, 266, 3, 2, 0),
65 PLL_36XX_RATE(480000000, 160, 2, 2, 0), 65 PLL_36XX_RATE(24 * MHZ, 480000000, 160, 2, 2, 0),
66 PLL_36XX_RATE(432000000, 144, 2, 2, 0), 66 PLL_36XX_RATE(24 * MHZ, 432000000, 144, 2, 2, 0),
67 PLL_36XX_RATE(400000000, 200, 3, 2, 0), 67 PLL_36XX_RATE(24 * MHZ, 400000000, 200, 3, 2, 0),
68 PLL_36XX_RATE(394073130, 459, 7, 2, 49282), 68 PLL_36XX_RATE(24 * MHZ, 394073128, 459, 7, 2, 49282),
69 PLL_36XX_RATE(333000000, 111, 2, 2, 0), 69 PLL_36XX_RATE(24 * MHZ, 333000000, 111, 2, 2, 0),
70 PLL_36XX_RATE(300000000, 100, 2, 2, 0), 70 PLL_36XX_RATE(24 * MHZ, 300000000, 100, 2, 2, 0),
71 PLL_36XX_RATE(266000000, 266, 3, 3, 0), 71 PLL_36XX_RATE(24 * MHZ, 266000000, 266, 3, 3, 0),
72 PLL_36XX_RATE(200000000, 200, 3, 3, 0), 72 PLL_36XX_RATE(24 * MHZ, 200000000, 200, 3, 3, 0),
73 PLL_36XX_RATE(166000000, 166, 3, 3, 0), 73 PLL_36XX_RATE(24 * MHZ, 166000000, 166, 3, 3, 0),
74 PLL_36XX_RATE(133000000, 266, 3, 4, 0), 74 PLL_36XX_RATE(24 * MHZ, 133000000, 266, 3, 4, 0),
75 PLL_36XX_RATE(100000000, 200, 3, 4, 0), 75 PLL_36XX_RATE(24 * MHZ, 100000000, 200, 3, 4, 0),
76 PLL_36XX_RATE(66000000, 176, 2, 5, 0), 76 PLL_36XX_RATE(24 * MHZ, 66000000, 176, 2, 5, 0),
77}; 77};
78 78
79/* CMU_AUD */ 79/* CMU_AUD */
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index fc471a49e8f4..0a0b09591e6f 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -226,16 +226,16 @@ static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
226}; 226};
227 227
228static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = { 228static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = {
229 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 229 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
230 PLL_36XX_RATE(333000000U, 111, 2, 2, 0), 230 PLL_36XX_RATE(24 * MHZ, 333000000U, 111, 2, 2, 0),
231 PLL_36XX_RATE(300000000U, 100, 2, 2, 0), 231 PLL_36XX_RATE(24 * MHZ, 300000000U, 100, 2, 2, 0),
232 PLL_36XX_RATE(266000000U, 266, 3, 3, 0), 232 PLL_36XX_RATE(24 * MHZ, 266000000U, 266, 3, 3, 0),
233 PLL_36XX_RATE(200000000U, 200, 3, 3, 0), 233 PLL_36XX_RATE(24 * MHZ, 200000000U, 200, 3, 3, 0),
234 PLL_36XX_RATE(192000000U, 192, 3, 3, 0), 234 PLL_36XX_RATE(24 * MHZ, 192000000U, 192, 3, 3, 0),
235 PLL_36XX_RATE(166000000U, 166, 3, 3, 0), 235 PLL_36XX_RATE(24 * MHZ, 166000000U, 166, 3, 3, 0),
236 PLL_36XX_RATE(133000000U, 266, 3, 4, 0), 236 PLL_36XX_RATE(24 * MHZ, 133000000U, 266, 3, 4, 0),
237 PLL_36XX_RATE(100000000U, 200, 3, 4, 0), 237 PLL_36XX_RATE(24 * MHZ, 100000000U, 200, 3, 4, 0),
238 PLL_36XX_RATE(66000000U, 176, 2, 5, 0), 238 PLL_36XX_RATE(24 * MHZ, 66000000U, 176, 2, 5, 0),
239}; 239};
240 240
241static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { 241static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 45d34f601e9e..95e1bf69449b 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -19,6 +19,7 @@
19 19
20#include "clk.h" 20#include "clk.h"
21#include "clk-cpu.h" 21#include "clk-cpu.h"
22#include "clk-exynos5-subcmu.h"
22 23
23#define APLL_LOCK 0x0 24#define APLL_LOCK 0x0
24#define APLL_CON0 0x100 25#define APLL_CON0 0x100
@@ -620,7 +621,8 @@ static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
620 621
621 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", 622 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
622 mout_group5_5800_p, SRC_TOP7, 16, 2), 623 mout_group5_5800_p, SRC_TOP7, 16, 2),
623 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), 624 MUX_F(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2,
625 CLK_SET_RATE_PARENT, 0),
624 626
625 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), 627 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1),
626}; 628};
@@ -863,7 +865,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
863 DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), 865 DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
864 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), 866 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
865 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), 867 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
866 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
867 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1", 868 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1",
868 "mout_aclk400_disp1", DIV_TOP2, 4, 3), 869 "mout_aclk400_disp1", DIV_TOP2, 4, 3),
869 870
@@ -912,8 +913,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
912 DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), 913 DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4),
913 DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), 914 DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4),
914 915
915 /* Mfc Block */
916 DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
917 916
918 /* PCM */ 917 /* PCM */
919 DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), 918 DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8),
@@ -932,8 +931,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
932 DIV(0, "dout_spi2_pre", "dout_spi2", DIV_PERIC4, 24, 8), 931 DIV(0, "dout_spi2_pre", "dout_spi2", DIV_PERIC4, 24, 8),
933 932
934 /* GSCL Block */ 933 /* GSCL Block */
935 DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl",
936 DIV2_RATIO0, 4, 2),
937 DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2), 934 DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2),
938 935
939 /* MSCL Block */ 936 /* MSCL Block */
@@ -1190,8 +1187,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1190 GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "mout_user_aclk333_432_gscl", 1187 GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "mout_user_aclk333_432_gscl",
1191 GATE_TOP_SCLK_GSCL, 7, 0, 0), 1188 GATE_TOP_SCLK_GSCL, 7, 0, 0),
1192 1189
1193 GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
1194 GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
1195 GATE(CLK_FIMC_3AA, "fimc_3aa", "aclk333_432_gscl", 1190 GATE(CLK_FIMC_3AA, "fimc_3aa", "aclk333_432_gscl",
1196 GATE_IP_GSCL0, 4, 0, 0), 1191 GATE_IP_GSCL0, 4, 0, 0),
1197 GATE(CLK_FIMC_LITE0, "fimc_lite0", "aclk333_432_gscl", 1192 GATE(CLK_FIMC_LITE0, "fimc_lite0", "aclk333_432_gscl",
@@ -1205,10 +1200,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1205 GATE_IP_GSCL1, 3, 0, 0), 1200 GATE_IP_GSCL1, 3, 0, 0),
1206 GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333", 1201 GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333",
1207 GATE_IP_GSCL1, 4, 0, 0), 1202 GATE_IP_GSCL1, 4, 0, 0),
1208 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "dout_gscl_blk_300",
1209 GATE_IP_GSCL1, 6, 0, 0),
1210 GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "dout_gscl_blk_300",
1211 GATE_IP_GSCL1, 7, 0, 0),
1212 GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0), 1203 GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0),
1213 GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0), 1204 GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0),
1214 GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333", 1205 GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333",
@@ -1227,18 +1218,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1227 GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk", 1218 GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk",
1228 GATE_IP_MSCL, 10, 0, 0), 1219 GATE_IP_MSCL, 10, 0, 0),
1229 1220
1230 GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
1231 GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
1232 GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
1233 GATE(CLK_MIXER, "mixer", "aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
1234 GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
1235 GATE(CLK_SMMU_FIMD1M0, "smmu_fimd1m0", "dout_disp1_blk",
1236 GATE_IP_DISP1, 7, 0, 0),
1237 GATE(CLK_SMMU_FIMD1M1, "smmu_fimd1m1", "dout_disp1_blk",
1238 GATE_IP_DISP1, 8, 0, 0),
1239 GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1",
1240 GATE_IP_DISP1, 9, 0, 0),
1241
1242 /* ISP */ 1221 /* ISP */
1243 GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp", 1222 GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp",
1244 GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0), 1223 GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0),
@@ -1255,48 +1234,138 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1255 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2", 1234 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2",
1256 GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), 1235 GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0),
1257 1236
1237 GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
1238};
1239
1240static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = {
1241 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
1242};
1243
1244static const struct samsung_gate_clock exynos5x_disp_gate_clks[] __initconst = {
1245 GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
1246 GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
1247 GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
1248 GATE(CLK_MIXER, "mixer", "aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
1249 GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
1250 GATE(CLK_SMMU_FIMD1M0, "smmu_fimd1m0", "dout_disp1_blk",
1251 GATE_IP_DISP1, 7, 0, 0),
1252 GATE(CLK_SMMU_FIMD1M1, "smmu_fimd1m1", "dout_disp1_blk",
1253 GATE_IP_DISP1, 8, 0, 0),
1254 GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1",
1255 GATE_IP_DISP1, 9, 0, 0),
1256};
1257
1258static struct exynos5_subcmu_reg_dump exynos5x_disp_suspend_regs[] = {
1259 { GATE_IP_DISP1, 0xffffffff, 0xffffffff }, /* DISP1 gates */
1260 { SRC_TOP5, 0, BIT(0) }, /* MUX mout_user_aclk400_disp1 */
1261 { SRC_TOP5, 0, BIT(24) }, /* MUX mout_user_aclk300_disp1 */
1262 { SRC_TOP3, 0, BIT(8) }, /* MUX mout_user_aclk200_disp1 */
1263 { DIV2_RATIO0, 0, 0x30000 }, /* DIV dout_disp1_blk */
1264};
1265
1266static const struct samsung_div_clock exynos5x_gsc_div_clks[] __initconst = {
1267 DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl",
1268 DIV2_RATIO0, 4, 2),
1269};
1270
1271static const struct samsung_gate_clock exynos5x_gsc_gate_clks[] __initconst = {
1272 GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
1273 GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
1274 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "dout_gscl_blk_300",
1275 GATE_IP_GSCL1, 6, 0, 0),
1276 GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "dout_gscl_blk_300",
1277 GATE_IP_GSCL1, 7, 0, 0),
1278};
1279
1280static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = {
1281 { GATE_IP_GSCL0, 0x3, 0x3 }, /* GSC gates */
1282 { GATE_IP_GSCL1, 0xc0, 0xc0 }, /* GSC gates */
1283 { SRC_TOP5, 0, BIT(28) }, /* MUX mout_user_aclk300_gscl */
1284 { DIV2_RATIO0, 0, 0x30 }, /* DIV dout_gscl_blk_300 */
1285};
1286
1287static const struct samsung_div_clock exynos5x_mfc_div_clks[] __initconst = {
1288 DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
1289};
1290
1291static const struct samsung_gate_clock exynos5x_mfc_gate_clks[] __initconst = {
1258 GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), 1292 GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
1259 GATE(CLK_SMMU_MFCL, "smmu_mfcl", "dout_mfc_blk", GATE_IP_MFC, 1, 0, 0), 1293 GATE(CLK_SMMU_MFCL, "smmu_mfcl", "dout_mfc_blk", GATE_IP_MFC, 1, 0, 0),
1260 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "dout_mfc_blk", GATE_IP_MFC, 2, 0, 0), 1294 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "dout_mfc_blk", GATE_IP_MFC, 2, 0, 0),
1295};
1261 1296
1262 GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), 1297static struct exynos5_subcmu_reg_dump exynos5x_mfc_suspend_regs[] = {
1298 { GATE_IP_MFC, 0xffffffff, 0xffffffff }, /* MFC gates */
1299 { SRC_TOP4, 0, BIT(28) }, /* MUX mout_user_aclk333 */
1300 { DIV4_RATIO, 0, 0x3 }, /* DIV dout_mfc_blk */
1301};
1302
1303static const struct exynos5_subcmu_info exynos5x_subcmus[] = {
1304 {
1305 .div_clks = exynos5x_disp_div_clks,
1306 .nr_div_clks = ARRAY_SIZE(exynos5x_disp_div_clks),
1307 .gate_clks = exynos5x_disp_gate_clks,
1308 .nr_gate_clks = ARRAY_SIZE(exynos5x_disp_gate_clks),
1309 .suspend_regs = exynos5x_disp_suspend_regs,
1310 .nr_suspend_regs = ARRAY_SIZE(exynos5x_disp_suspend_regs),
1311 .pd_name = "DISP",
1312 }, {
1313 .div_clks = exynos5x_gsc_div_clks,
1314 .nr_div_clks = ARRAY_SIZE(exynos5x_gsc_div_clks),
1315 .gate_clks = exynos5x_gsc_gate_clks,
1316 .nr_gate_clks = ARRAY_SIZE(exynos5x_gsc_gate_clks),
1317 .suspend_regs = exynos5x_gsc_suspend_regs,
1318 .nr_suspend_regs = ARRAY_SIZE(exynos5x_gsc_suspend_regs),
1319 .pd_name = "GSC",
1320 }, {
1321 .div_clks = exynos5x_mfc_div_clks,
1322 .nr_div_clks = ARRAY_SIZE(exynos5x_mfc_div_clks),
1323 .gate_clks = exynos5x_mfc_gate_clks,
1324 .nr_gate_clks = ARRAY_SIZE(exynos5x_mfc_gate_clks),
1325 .suspend_regs = exynos5x_mfc_suspend_regs,
1326 .nr_suspend_regs = ARRAY_SIZE(exynos5x_mfc_suspend_regs),
1327 .pd_name = "MFC",
1328 },
1263}; 1329};
1264 1330
1265static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = { 1331static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = {
1266 PLL_35XX_RATE(2000000000, 250, 3, 0), 1332 PLL_35XX_RATE(24 * MHZ, 2000000000, 250, 3, 0),
1267 PLL_35XX_RATE(1900000000, 475, 6, 0), 1333 PLL_35XX_RATE(24 * MHZ, 1900000000, 475, 6, 0),
1268 PLL_35XX_RATE(1800000000, 225, 3, 0), 1334 PLL_35XX_RATE(24 * MHZ, 1800000000, 225, 3, 0),
1269 PLL_35XX_RATE(1700000000, 425, 6, 0), 1335 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
1270 PLL_35XX_RATE(1600000000, 200, 3, 0), 1336 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
1271 PLL_35XX_RATE(1500000000, 250, 4, 0), 1337 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
1272 PLL_35XX_RATE(1400000000, 175, 3, 0), 1338 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
1273 PLL_35XX_RATE(1300000000, 325, 6, 0), 1339 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
1274 PLL_35XX_RATE(1200000000, 200, 2, 1), 1340 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 2, 1),
1275 PLL_35XX_RATE(1100000000, 275, 3, 1), 1341 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
1276 PLL_35XX_RATE(1000000000, 250, 3, 1), 1342 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
1277 PLL_35XX_RATE(900000000, 150, 2, 1), 1343 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 2, 1),
1278 PLL_35XX_RATE(800000000, 200, 3, 1), 1344 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
1279 PLL_35XX_RATE(700000000, 175, 3, 1), 1345 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
1280 PLL_35XX_RATE(600000000, 200, 2, 2), 1346 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 2, 2),
1281 PLL_35XX_RATE(500000000, 250, 3, 2), 1347 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
1282 PLL_35XX_RATE(400000000, 200, 3, 2), 1348 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
1283 PLL_35XX_RATE(300000000, 200, 2, 3), 1349 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 2, 3),
1284 PLL_35XX_RATE(200000000, 200, 3, 3), 1350 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
1285}; 1351};
1286 1352
1287static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { 1353static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
1288 PLL_36XX_RATE(600000000U, 100, 2, 1, 0), 1354 PLL_36XX_RATE(24 * MHZ, 600000000U, 100, 2, 1, 0),
1289 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 1355 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
1290 PLL_36XX_RATE(393216003U, 197, 3, 2, -25690), 1356 PLL_36XX_RATE(24 * MHZ, 393216003U, 197, 3, 2, -25690),
1291 PLL_36XX_RATE(361267218U, 301, 5, 2, 3671), 1357 PLL_36XX_RATE(24 * MHZ, 361267218U, 301, 5, 2, 3671),
1292 PLL_36XX_RATE(200000000U, 200, 3, 3, 0), 1358 PLL_36XX_RATE(24 * MHZ, 200000000U, 200, 3, 3, 0),
1293 PLL_36XX_RATE(196608001U, 197, 3, 3, -25690), 1359 PLL_36XX_RATE(24 * MHZ, 196608001U, 197, 3, 3, -25690),
1294 PLL_36XX_RATE(180633609U, 301, 5, 3, 3671), 1360 PLL_36XX_RATE(24 * MHZ, 180633609U, 301, 5, 3, 3671),
1295 PLL_36XX_RATE(131072006U, 131, 3, 3, 4719), 1361 PLL_36XX_RATE(24 * MHZ, 131072006U, 131, 3, 3, 4719),
1296 PLL_36XX_RATE(100000000U, 200, 3, 4, 0), 1362 PLL_36XX_RATE(24 * MHZ, 100000000U, 200, 3, 4, 0),
1297 PLL_36XX_RATE( 65536003U, 131, 3, 4, 4719), 1363 PLL_36XX_RATE(24 * MHZ, 73728000U, 98, 2, 4, 19923),
1298 PLL_36XX_RATE( 49152000U, 197, 3, 5, -25690), 1364 PLL_36XX_RATE(24 * MHZ, 67737602U, 90, 2, 4, 20762),
1299 PLL_36XX_RATE( 32768001U, 131, 3, 5, 4719), 1365 PLL_36XX_RATE(24 * MHZ, 65536003U, 131, 3, 4, 4719),
1366 PLL_36XX_RATE(24 * MHZ, 49152000U, 197, 3, 5, -25690),
1367 PLL_36XX_RATE(24 * MHZ, 45158401U, 90, 3, 4, 20762),
1368 PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719),
1300}; 1369};
1301 1370
1302static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { 1371static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
@@ -1472,6 +1541,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
1472 exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0); 1541 exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
1473 1542
1474 exynos5420_clk_sleep_init(); 1543 exynos5420_clk_sleep_init();
1544 exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus),
1545 exynos5x_subcmus);
1475 1546
1476 samsung_clk_of_add_provider(np, ctx); 1547 samsung_clk_of_add_provider(np, ctx);
1477} 1548}
@@ -1480,10 +1551,12 @@ static void __init exynos5420_clk_init(struct device_node *np)
1480{ 1551{
1481 exynos5x_clk_init(np, EXYNOS5420); 1552 exynos5x_clk_init(np, EXYNOS5420);
1482} 1553}
1483CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); 1554CLK_OF_DECLARE_DRIVER(exynos5420_clk, "samsung,exynos5420-clock",
1555 exynos5420_clk_init);
1484 1556
1485static void __init exynos5800_clk_init(struct device_node *np) 1557static void __init exynos5800_clk_init(struct device_node *np)
1486{ 1558{
1487 exynos5x_clk_init(np, EXYNOS5800); 1559 exynos5x_clk_init(np, EXYNOS5800);
1488} 1560}
1489CLK_OF_DECLARE(exynos5800_clk, "samsung,exynos5800-clock", exynos5800_clk_init); 1561CLK_OF_DECLARE_DRIVER(exynos5800_clk, "samsung,exynos5800-clock",
1562 exynos5800_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index db270908037a..5305ace514b2 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -703,68 +703,69 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
703 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL 703 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL
704 */ 704 */
705static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = { 705static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = {
706 PLL_35XX_RATE(2500000000U, 625, 6, 0), 706 PLL_35XX_RATE(24 * MHZ, 2500000000U, 625, 6, 0),
707 PLL_35XX_RATE(2400000000U, 500, 5, 0), 707 PLL_35XX_RATE(24 * MHZ, 2400000000U, 500, 5, 0),
708 PLL_35XX_RATE(2300000000U, 575, 6, 0), 708 PLL_35XX_RATE(24 * MHZ, 2300000000U, 575, 6, 0),
709 PLL_35XX_RATE(2200000000U, 550, 6, 0), 709 PLL_35XX_RATE(24 * MHZ, 2200000000U, 550, 6, 0),
710 PLL_35XX_RATE(2100000000U, 350, 4, 0), 710 PLL_35XX_RATE(24 * MHZ, 2100000000U, 350, 4, 0),
711 PLL_35XX_RATE(2000000000U, 500, 6, 0), 711 PLL_35XX_RATE(24 * MHZ, 2000000000U, 500, 6, 0),
712 PLL_35XX_RATE(1900000000U, 475, 6, 0), 712 PLL_35XX_RATE(24 * MHZ, 1900000000U, 475, 6, 0),
713 PLL_35XX_RATE(1800000000U, 375, 5, 0), 713 PLL_35XX_RATE(24 * MHZ, 1800000000U, 375, 5, 0),
714 PLL_35XX_RATE(1700000000U, 425, 6, 0), 714 PLL_35XX_RATE(24 * MHZ, 1700000000U, 425, 6, 0),
715 PLL_35XX_RATE(1600000000U, 400, 6, 0), 715 PLL_35XX_RATE(24 * MHZ, 1600000000U, 400, 6, 0),
716 PLL_35XX_RATE(1500000000U, 250, 4, 0), 716 PLL_35XX_RATE(24 * MHZ, 1500000000U, 250, 4, 0),
717 PLL_35XX_RATE(1400000000U, 350, 6, 0), 717 PLL_35XX_RATE(24 * MHZ, 1400000000U, 350, 6, 0),
718 PLL_35XX_RATE(1332000000U, 222, 4, 0), 718 PLL_35XX_RATE(24 * MHZ, 1332000000U, 222, 4, 0),
719 PLL_35XX_RATE(1300000000U, 325, 6, 0), 719 PLL_35XX_RATE(24 * MHZ, 1300000000U, 325, 6, 0),
720 PLL_35XX_RATE(1200000000U, 500, 5, 1), 720 PLL_35XX_RATE(24 * MHZ, 1200000000U, 500, 5, 1),
721 PLL_35XX_RATE(1100000000U, 550, 6, 1), 721 PLL_35XX_RATE(24 * MHZ, 1100000000U, 550, 6, 1),
722 PLL_35XX_RATE(1086000000U, 362, 4, 1), 722 PLL_35XX_RATE(24 * MHZ, 1086000000U, 362, 4, 1),
723 PLL_35XX_RATE(1066000000U, 533, 6, 1), 723 PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 6, 1),
724 PLL_35XX_RATE(1000000000U, 500, 6, 1), 724 PLL_35XX_RATE(24 * MHZ, 1000000000U, 500, 6, 1),
725 PLL_35XX_RATE(933000000U, 311, 4, 1), 725 PLL_35XX_RATE(24 * MHZ, 933000000U, 311, 4, 1),
726 PLL_35XX_RATE(921000000U, 307, 4, 1), 726 PLL_35XX_RATE(24 * MHZ, 921000000U, 307, 4, 1),
727 PLL_35XX_RATE(900000000U, 375, 5, 1), 727 PLL_35XX_RATE(24 * MHZ, 900000000U, 375, 5, 1),
728 PLL_35XX_RATE(825000000U, 275, 4, 1), 728 PLL_35XX_RATE(24 * MHZ, 825000000U, 275, 4, 1),
729 PLL_35XX_RATE(800000000U, 400, 6, 1), 729 PLL_35XX_RATE(24 * MHZ, 800000000U, 400, 6, 1),
730 PLL_35XX_RATE(733000000U, 733, 12, 1), 730 PLL_35XX_RATE(24 * MHZ, 733000000U, 733, 12, 1),
731 PLL_35XX_RATE(700000000U, 175, 3, 1), 731 PLL_35XX_RATE(24 * MHZ, 700000000U, 175, 3, 1),
732 PLL_35XX_RATE(667000000U, 222, 4, 1), 732 PLL_35XX_RATE(24 * MHZ, 666000000U, 222, 4, 1),
733 PLL_35XX_RATE(633000000U, 211, 4, 1), 733 PLL_35XX_RATE(24 * MHZ, 633000000U, 211, 4, 1),
734 PLL_35XX_RATE(600000000U, 500, 5, 2), 734 PLL_35XX_RATE(24 * MHZ, 600000000U, 500, 5, 2),
735 PLL_35XX_RATE(552000000U, 460, 5, 2), 735 PLL_35XX_RATE(24 * MHZ, 552000000U, 460, 5, 2),
736 PLL_35XX_RATE(550000000U, 550, 6, 2), 736 PLL_35XX_RATE(24 * MHZ, 550000000U, 550, 6, 2),
737 PLL_35XX_RATE(543000000U, 362, 4, 2), 737 PLL_35XX_RATE(24 * MHZ, 543000000U, 362, 4, 2),
738 PLL_35XX_RATE(533000000U, 533, 6, 2), 738 PLL_35XX_RATE(24 * MHZ, 533000000U, 533, 6, 2),
739 PLL_35XX_RATE(500000000U, 500, 6, 2), 739 PLL_35XX_RATE(24 * MHZ, 500000000U, 500, 6, 2),
740 PLL_35XX_RATE(444000000U, 370, 5, 2), 740 PLL_35XX_RATE(24 * MHZ, 444000000U, 370, 5, 2),
741 PLL_35XX_RATE(420000000U, 350, 5, 2), 741 PLL_35XX_RATE(24 * MHZ, 420000000U, 350, 5, 2),
742 PLL_35XX_RATE(400000000U, 400, 6, 2), 742 PLL_35XX_RATE(24 * MHZ, 400000000U, 400, 6, 2),
743 PLL_35XX_RATE(350000000U, 350, 6, 2), 743 PLL_35XX_RATE(24 * MHZ, 350000000U, 350, 6, 2),
744 PLL_35XX_RATE(333000000U, 222, 4, 2), 744 PLL_35XX_RATE(24 * MHZ, 333000000U, 222, 4, 2),
745 PLL_35XX_RATE(300000000U, 500, 5, 3), 745 PLL_35XX_RATE(24 * MHZ, 300000000U, 500, 5, 3),
746 PLL_35XX_RATE(278000000U, 556, 6, 3), 746 PLL_35XX_RATE(24 * MHZ, 278000000U, 556, 6, 3),
747 PLL_35XX_RATE(266000000U, 532, 6, 3), 747 PLL_35XX_RATE(24 * MHZ, 266000000U, 532, 6, 3),
748 PLL_35XX_RATE(250000000U, 500, 6, 3), 748 PLL_35XX_RATE(24 * MHZ, 250000000U, 500, 6, 3),
749 PLL_35XX_RATE(200000000U, 400, 6, 3), 749 PLL_35XX_RATE(24 * MHZ, 200000000U, 400, 6, 3),
750 PLL_35XX_RATE(166000000U, 332, 6, 3), 750 PLL_35XX_RATE(24 * MHZ, 166000000U, 332, 6, 3),
751 PLL_35XX_RATE(160000000U, 320, 6, 3), 751 PLL_35XX_RATE(24 * MHZ, 160000000U, 320, 6, 3),
752 PLL_35XX_RATE(133000000U, 532, 6, 4), 752 PLL_35XX_RATE(24 * MHZ, 133000000U, 532, 6, 4),
753 PLL_35XX_RATE(100000000U, 400, 6, 4), 753 PLL_35XX_RATE(24 * MHZ, 100000000U, 400, 6, 4),
754 { /* sentinel */ } 754 { /* sentinel */ }
755}; 755};
756 756
757/* AUD_PLL */ 757/* AUD_PLL */
758static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = { 758static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = {
759 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 759 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
760 PLL_36XX_RATE(393216000U, 197, 3, 2, -25690), 760 PLL_36XX_RATE(24 * MHZ, 393216003U, 197, 3, 2, -25690),
761 PLL_36XX_RATE(384000000U, 128, 2, 2, 0), 761 PLL_36XX_RATE(24 * MHZ, 384000000U, 128, 2, 2, 0),
762 PLL_36XX_RATE(368640000U, 246, 4, 2, -15729), 762 PLL_36XX_RATE(24 * MHZ, 368639991U, 246, 4, 2, -15729),
763 PLL_36XX_RATE(361507200U, 181, 3, 2, -16148), 763 PLL_36XX_RATE(24 * MHZ, 361507202U, 181, 3, 2, -16148),
764 PLL_36XX_RATE(338688000U, 113, 2, 2, -6816), 764 PLL_36XX_RATE(24 * MHZ, 338687988U, 113, 2, 2, -6816),
765 PLL_36XX_RATE(294912000U, 98, 1, 3, 19923), 765 PLL_36XX_RATE(24 * MHZ, 294912002U, 98, 1, 3, 19923),
766 PLL_36XX_RATE(288000000U, 96, 1, 3, 0), 766 PLL_36XX_RATE(24 * MHZ, 288000000U, 96, 1, 3, 0),
767 PLL_36XX_RATE(252000000U, 84, 1, 3, 0), 767 PLL_36XX_RATE(24 * MHZ, 252000000U, 84, 1, 3, 0),
768 PLL_36XX_RATE(24 * MHZ, 196608001U, 197, 3, 3, -25690),
768 { /* sentinel */ } 769 { /* sentinel */ }
769}; 770};
770 771
@@ -1672,7 +1673,7 @@ static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
1672 ENABLE_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0), 1673 ENABLE_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0),
1673 GATE(CLK_SCLK_IOCLK_I2S1_BCLK, "sclk_ioclk_i2s1_bclk", 1674 GATE(CLK_SCLK_IOCLK_I2S1_BCLK, "sclk_ioclk_i2s1_bclk",
1674 "ioclk_i2s1_bclk_in", ENABLE_SCLK_PERIC, 10, 1675 "ioclk_i2s1_bclk_in", ENABLE_SCLK_PERIC, 10,
1675 CLK_SET_RATE_PARENT, 0), 1676 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
1676 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "sclk_spdif_peric", 1677 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "sclk_spdif_peric",
1677 ENABLE_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), 1678 ENABLE_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0),
1678 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric", 1679 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric",
@@ -5513,10 +5514,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
5513 5514
5514 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
5515 reg_base = devm_ioremap_resource(dev, res); 5516 reg_base = devm_ioremap_resource(dev, res);
5516 if (IS_ERR(reg_base)) { 5517 if (IS_ERR(reg_base))
5517 dev_err(dev, "failed to map registers\n");
5518 return PTR_ERR(reg_base); 5518 return PTR_ERR(reg_base);
5519 }
5520 5519
5521 for (i = 0; i < info->nr_clk_ids; ++i) 5520 for (i = 0; i < info->nr_clk_ids; ++i)
5522 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); 5521 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c
index 5931a4140c3d..492d51691080 100644
--- a/drivers/clk/samsung/clk-exynos7.c
+++ b/drivers/clk/samsung/clk-exynos7.c
@@ -140,7 +140,7 @@ static const struct samsung_div_clock topc_div_clks[] __initconst = {
140}; 140};
141 141
142static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = { 142static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = {
143 PLL_36XX_RATE(491520000, 20, 1, 0, 31457), 143 PLL_36XX_RATE(24 * MHZ, 491519897, 20, 1, 0, 31457),
144 {}, 144 {},
145}; 145};
146 146
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 61eb8abbfd9c..ca57b3dfa814 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -41,35 +41,62 @@ enum samsung_pll_type {
41 pll_1460x, 41 pll_1460x,
42}; 42};
43 43
44#define PLL_35XX_RATE(_rate, _m, _p, _s) \ 44#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
45 ((u64)(_fin) * (BIT(_ks) * (_m) + (_k)) / BIT(_ks) / ((_p) << (_s)))
46#define PLL_VALID_RATE(_fin, _fout, _m, _p, _s, _k, _ks) ((_fout) + \
47 BUILD_BUG_ON_ZERO(PLL_RATE(_fin, _m, _p, _s, _k, _ks) != (_fout)))
48
49#define PLL_35XX_RATE(_fin, _rate, _m, _p, _s) \
50 { \
51 .rate = PLL_VALID_RATE(_fin, _rate, \
52 _m, _p, _s, 0, 16), \
53 .mdiv = (_m), \
54 .pdiv = (_p), \
55 .sdiv = (_s), \
56 }
57
58#define PLL_S3C2410_MPLL_RATE(_fin, _rate, _m, _p, _s) \
59 { \
60 .rate = PLL_VALID_RATE(_fin, _rate, \
61 _m + 8, _p + 2, _s, 0, 16), \
62 .mdiv = (_m), \
63 .pdiv = (_p), \
64 .sdiv = (_s), \
65 }
66
67#define PLL_S3C2440_MPLL_RATE(_fin, _rate, _m, _p, _s) \
45 { \ 68 { \
46 .rate = (_rate), \ 69 .rate = PLL_VALID_RATE(_fin, _rate, \
70 2 * (_m + 8), _p + 2, _s, 0, 16), \
47 .mdiv = (_m), \ 71 .mdiv = (_m), \
48 .pdiv = (_p), \ 72 .pdiv = (_p), \
49 .sdiv = (_s), \ 73 .sdiv = (_s), \
50 } 74 }
51 75
52#define PLL_36XX_RATE(_rate, _m, _p, _s, _k) \ 76#define PLL_36XX_RATE(_fin, _rate, _m, _p, _s, _k) \
53 { \ 77 { \
54 .rate = (_rate), \ 78 .rate = PLL_VALID_RATE(_fin, _rate, \
79 _m, _p, _s, _k, 16), \
55 .mdiv = (_m), \ 80 .mdiv = (_m), \
56 .pdiv = (_p), \ 81 .pdiv = (_p), \
57 .sdiv = (_s), \ 82 .sdiv = (_s), \
58 .kdiv = (_k), \ 83 .kdiv = (_k), \
59 } 84 }
60 85
61#define PLL_45XX_RATE(_rate, _m, _p, _s, _afc) \ 86#define PLL_4508_RATE(_fin, _rate, _m, _p, _s, _afc) \
62 { \ 87 { \
63 .rate = (_rate), \ 88 .rate = PLL_VALID_RATE(_fin, _rate, \
89 _m, _p, _s - 1, 0, 16), \
64 .mdiv = (_m), \ 90 .mdiv = (_m), \
65 .pdiv = (_p), \ 91 .pdiv = (_p), \
66 .sdiv = (_s), \ 92 .sdiv = (_s), \
67 .afc = (_afc), \ 93 .afc = (_afc), \
68 } 94 }
69 95
70#define PLL_4600_RATE(_rate, _m, _p, _s, _k, _vsel) \ 96#define PLL_4600_RATE(_fin, _rate, _m, _p, _s, _k, _vsel) \
71 { \ 97 { \
72 .rate = (_rate), \ 98 .rate = PLL_VALID_RATE(_fin, _rate, \
99 _m, _p, _s, _k, 16), \
73 .mdiv = (_m), \ 100 .mdiv = (_m), \
74 .pdiv = (_p), \ 101 .pdiv = (_p), \
75 .sdiv = (_s), \ 102 .sdiv = (_s), \
@@ -77,9 +104,10 @@ enum samsung_pll_type {
77 .vsel = (_vsel), \ 104 .vsel = (_vsel), \
78 } 105 }
79 106
80#define PLL_4650_RATE(_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \ 107#define PLL_4650_RATE(_fin, _rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \
81 { \ 108 { \
82 .rate = (_rate), \ 109 .rate = PLL_VALID_RATE(_fin, _rate, \
110 _m, _p, _s, _k, 10), \
83 .mdiv = (_m), \ 111 .mdiv = (_m), \
84 .pdiv = (_p), \ 112 .pdiv = (_p), \
85 .sdiv = (_s), \ 113 .sdiv = (_s), \
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index e0650c33863b..a9c887475054 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -95,7 +95,7 @@ static void __init s3c2410_clk_sleep_init(void) {}
95 95
96PNAME(fclk_p) = { "mpll", "div_slow" }; 96PNAME(fclk_p) = { "mpll", "div_slow" };
97 97
98struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { 98static struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
99 MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1), 99 MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
100}; 100};
101 101
@@ -111,12 +111,12 @@ static struct clk_div_table divslow_d[] = {
111 { /* sentinel */ }, 111 { /* sentinel */ },
112}; 112};
113 113
114struct samsung_div_clock s3c2410_common_dividers[] __initdata = { 114static struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
115 DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d), 115 DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
116 DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1), 116 DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
117}; 117};
118 118
119struct samsung_gate_clock s3c2410_common_gates[] __initdata = { 119static struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
120 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0), 120 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
121 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0), 121 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
122 GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0), 122 GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
@@ -135,7 +135,7 @@ struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
135}; 135};
136 136
137/* should be added _after_ the soc-specific clocks are created */ 137/* should be added _after_ the soc-specific clocks are created */
138struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { 138static struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
139 ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"), 139 ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
140 ALIAS(PCLK_ADC, NULL, "adc"), 140 ALIAS(PCLK_ADC, NULL, "adc"),
141 ALIAS(PCLK_RTC, NULL, "rtc"), 141 ALIAS(PCLK_RTC, NULL, "rtc"),
@@ -162,34 +162,34 @@ struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
162static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { 162static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
163 /* sorted in descending order */ 163 /* sorted in descending order */
164 /* 2410A extras */ 164 /* 2410A extras */
165 PLL_35XX_RATE(270000000, 127, 1, 1), 165 PLL_S3C2410_MPLL_RATE(12 * MHZ, 270000000, 127, 1, 1),
166 PLL_35XX_RATE(268000000, 126, 1, 1), 166 PLL_S3C2410_MPLL_RATE(12 * MHZ, 268000000, 126, 1, 1),
167 PLL_35XX_RATE(266000000, 125, 1, 1), 167 PLL_S3C2410_MPLL_RATE(12 * MHZ, 266000000, 125, 1, 1),
168 PLL_35XX_RATE(226000000, 105, 1, 1), 168 PLL_S3C2410_MPLL_RATE(12 * MHZ, 226000000, 105, 1, 1),
169 PLL_35XX_RATE(210000000, 132, 2, 1), 169 PLL_S3C2410_MPLL_RATE(12 * MHZ, 210000000, 132, 2, 1),
170 /* 2410 common */ 170 /* 2410 common */
171 PLL_35XX_RATE(203000000, 161, 3, 1), 171 PLL_S3C2410_MPLL_RATE(12 * MHZ, 202800000, 161, 3, 1),
172 PLL_35XX_RATE(192000000, 88, 1, 1), 172 PLL_S3C2410_MPLL_RATE(12 * MHZ, 192000000, 88, 1, 1),
173 PLL_35XX_RATE(186000000, 85, 1, 1), 173 PLL_S3C2410_MPLL_RATE(12 * MHZ, 186000000, 85, 1, 1),
174 PLL_35XX_RATE(180000000, 82, 1, 1), 174 PLL_S3C2410_MPLL_RATE(12 * MHZ, 180000000, 82, 1, 1),
175 PLL_35XX_RATE(170000000, 77, 1, 1), 175 PLL_S3C2410_MPLL_RATE(12 * MHZ, 170000000, 77, 1, 1),
176 PLL_35XX_RATE(158000000, 71, 1, 1), 176 PLL_S3C2410_MPLL_RATE(12 * MHZ, 158000000, 71, 1, 1),
177 PLL_35XX_RATE(152000000, 68, 1, 1), 177 PLL_S3C2410_MPLL_RATE(12 * MHZ, 152000000, 68, 1, 1),
178 PLL_35XX_RATE(147000000, 90, 2, 1), 178 PLL_S3C2410_MPLL_RATE(12 * MHZ, 147000000, 90, 2, 1),
179 PLL_35XX_RATE(135000000, 82, 2, 1), 179 PLL_S3C2410_MPLL_RATE(12 * MHZ, 135000000, 82, 2, 1),
180 PLL_35XX_RATE(124000000, 116, 1, 2), 180 PLL_S3C2410_MPLL_RATE(12 * MHZ, 124000000, 116, 1, 2),
181 PLL_35XX_RATE(118000000, 150, 2, 2), 181 PLL_S3C2410_MPLL_RATE(12 * MHZ, 118500000, 150, 2, 2),
182 PLL_35XX_RATE(113000000, 105, 1, 2), 182 PLL_S3C2410_MPLL_RATE(12 * MHZ, 113000000, 105, 1, 2),
183 PLL_35XX_RATE(101000000, 127, 2, 2), 183 PLL_S3C2410_MPLL_RATE(12 * MHZ, 101250000, 127, 2, 2),
184 PLL_35XX_RATE(90000000, 112, 2, 2), 184 PLL_S3C2410_MPLL_RATE(12 * MHZ, 90000000, 112, 2, 2),
185 PLL_35XX_RATE(85000000, 105, 2, 2), 185 PLL_S3C2410_MPLL_RATE(12 * MHZ, 84750000, 105, 2, 2),
186 PLL_35XX_RATE(79000000, 71, 1, 2), 186 PLL_S3C2410_MPLL_RATE(12 * MHZ, 79000000, 71, 1, 2),
187 PLL_35XX_RATE(68000000, 82, 2, 2), 187 PLL_S3C2410_MPLL_RATE(12 * MHZ, 67500000, 82, 2, 2),
188 PLL_35XX_RATE(56000000, 142, 2, 3), 188 PLL_S3C2410_MPLL_RATE(12 * MHZ, 56250000, 142, 2, 3),
189 PLL_35XX_RATE(48000000, 120, 2, 3), 189 PLL_S3C2410_MPLL_RATE(12 * MHZ, 48000000, 120, 2, 3),
190 PLL_35XX_RATE(51000000, 161, 3, 3), 190 PLL_S3C2410_MPLL_RATE(12 * MHZ, 50700000, 161, 3, 3),
191 PLL_35XX_RATE(45000000, 82, 1, 3), 191 PLL_S3C2410_MPLL_RATE(12 * MHZ, 45000000, 82, 1, 3),
192 PLL_35XX_RATE(34000000, 82, 2, 3), 192 PLL_S3C2410_MPLL_RATE(12 * MHZ, 33750000, 82, 2, 3),
193 { /* sentinel */ }, 193 { /* sentinel */ },
194}; 194};
195 195
@@ -200,11 +200,11 @@ static struct samsung_pll_clock s3c2410_plls[] __initdata = {
200 LOCKTIME, UPLLCON, NULL), 200 LOCKTIME, UPLLCON, NULL),
201}; 201};
202 202
203struct samsung_div_clock s3c2410_dividers[] __initdata = { 203static struct samsung_div_clock s3c2410_dividers[] __initdata = {
204 DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1), 204 DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
205}; 205};
206 206
207struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = { 207static struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
208 /* 208 /*
209 * armclk is directly supplied by the fclk, without 209 * armclk is directly supplied by the fclk, without
210 * switching possibility like on the s3c244x below. 210 * switching possibility like on the s3c244x below.
@@ -215,7 +215,7 @@ struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
215 FFACTOR(UCLK, "uclk", "upll", 1, 1, 0), 215 FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
216}; 216};
217 217
218struct samsung_clock_alias s3c2410_aliases[] __initdata = { 218static struct samsung_clock_alias s3c2410_aliases[] __initdata = {
219 ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"), 219 ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
220 ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"), 220 ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
221 ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"), 221 ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
@@ -229,33 +229,33 @@ struct samsung_clock_alias s3c2410_aliases[] __initdata = {
229 229
230static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = { 230static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
231 /* sorted in descending order */ 231 /* sorted in descending order */
232 PLL_35XX_RATE(400000000, 0x5c, 1, 1), 232 PLL_S3C2440_MPLL_RATE(12 * MHZ, 400000000, 0x5c, 1, 1),
233 PLL_35XX_RATE(390000000, 0x7a, 2, 1), 233 PLL_S3C2440_MPLL_RATE(12 * MHZ, 390000000, 0x7a, 2, 1),
234 PLL_35XX_RATE(380000000, 0x57, 1, 1), 234 PLL_S3C2440_MPLL_RATE(12 * MHZ, 380000000, 0x57, 1, 1),
235 PLL_35XX_RATE(370000000, 0xb1, 4, 1), 235 PLL_S3C2440_MPLL_RATE(12 * MHZ, 370000000, 0xb1, 4, 1),
236 PLL_35XX_RATE(360000000, 0x70, 2, 1), 236 PLL_S3C2440_MPLL_RATE(12 * MHZ, 360000000, 0x70, 2, 1),
237 PLL_35XX_RATE(350000000, 0xa7, 4, 1), 237 PLL_S3C2440_MPLL_RATE(12 * MHZ, 350000000, 0xa7, 4, 1),
238 PLL_35XX_RATE(340000000, 0x4d, 1, 1), 238 PLL_S3C2440_MPLL_RATE(12 * MHZ, 340000000, 0x4d, 1, 1),
239 PLL_35XX_RATE(330000000, 0x66, 2, 1), 239 PLL_S3C2440_MPLL_RATE(12 * MHZ, 330000000, 0x66, 2, 1),
240 PLL_35XX_RATE(320000000, 0x98, 4, 1), 240 PLL_S3C2440_MPLL_RATE(12 * MHZ, 320000000, 0x98, 4, 1),
241 PLL_35XX_RATE(310000000, 0x93, 4, 1), 241 PLL_S3C2440_MPLL_RATE(12 * MHZ, 310000000, 0x93, 4, 1),
242 PLL_35XX_RATE(300000000, 0x75, 3, 1), 242 PLL_S3C2440_MPLL_RATE(12 * MHZ, 300000000, 0x75, 3, 1),
243 PLL_35XX_RATE(240000000, 0x70, 1, 2), 243 PLL_S3C2440_MPLL_RATE(12 * MHZ, 240000000, 0x70, 1, 2),
244 PLL_35XX_RATE(230000000, 0x6b, 1, 2), 244 PLL_S3C2440_MPLL_RATE(12 * MHZ, 230000000, 0x6b, 1, 2),
245 PLL_35XX_RATE(220000000, 0x66, 1, 2), 245 PLL_S3C2440_MPLL_RATE(12 * MHZ, 220000000, 0x66, 1, 2),
246 PLL_35XX_RATE(210000000, 0x84, 2, 2), 246 PLL_S3C2440_MPLL_RATE(12 * MHZ, 210000000, 0x84, 2, 2),
247 PLL_35XX_RATE(200000000, 0x5c, 1, 2), 247 PLL_S3C2440_MPLL_RATE(12 * MHZ, 200000000, 0x5c, 1, 2),
248 PLL_35XX_RATE(190000000, 0x57, 1, 2), 248 PLL_S3C2440_MPLL_RATE(12 * MHZ, 190000000, 0x57, 1, 2),
249 PLL_35XX_RATE(180000000, 0x70, 2, 2), 249 PLL_S3C2440_MPLL_RATE(12 * MHZ, 180000000, 0x70, 2, 2),
250 PLL_35XX_RATE(170000000, 0x4d, 1, 2), 250 PLL_S3C2440_MPLL_RATE(12 * MHZ, 170000000, 0x4d, 1, 2),
251 PLL_35XX_RATE(160000000, 0x98, 4, 2), 251 PLL_S3C2440_MPLL_RATE(12 * MHZ, 160000000, 0x98, 4, 2),
252 PLL_35XX_RATE(150000000, 0x75, 3, 2), 252 PLL_S3C2440_MPLL_RATE(12 * MHZ, 150000000, 0x75, 3, 2),
253 PLL_35XX_RATE(120000000, 0x70, 1, 3), 253 PLL_S3C2440_MPLL_RATE(12 * MHZ, 120000000, 0x70, 1, 3),
254 PLL_35XX_RATE(110000000, 0x66, 1, 3), 254 PLL_S3C2440_MPLL_RATE(12 * MHZ, 110000000, 0x66, 1, 3),
255 PLL_35XX_RATE(100000000, 0x5c, 1, 3), 255 PLL_S3C2440_MPLL_RATE(12 * MHZ, 100000000, 0x5c, 1, 3),
256 PLL_35XX_RATE(90000000, 0x70, 2, 3), 256 PLL_S3C2440_MPLL_RATE(12 * MHZ, 90000000, 0x70, 2, 3),
257 PLL_35XX_RATE(80000000, 0x98, 4, 3), 257 PLL_S3C2440_MPLL_RATE(12 * MHZ, 80000000, 0x98, 4, 3),
258 PLL_35XX_RATE(75000000, 0x75, 3, 3), 258 PLL_S3C2440_MPLL_RATE(12 * MHZ, 75000000, 0x75, 3, 3),
259 { /* sentinel */ }, 259 { /* sentinel */ },
260}; 260};
261 261
@@ -269,12 +269,12 @@ static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
269PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; 269PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
270PNAME(armclk_p) = { "fclk", "hclk" }; 270PNAME(armclk_p) = { "fclk", "hclk" };
271 271
272struct samsung_mux_clock s3c244x_common_muxes[] __initdata = { 272static struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
273 MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2), 273 MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
274 MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1), 274 MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
275}; 275};
276 276
277struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = { 277static struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
278 FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0), 278 FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
279 FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT), 279 FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
280}; 280};
@@ -291,7 +291,7 @@ static struct clk_div_table div_hclk_3_d[] = {
291 { /* sentinel */ }, 291 { /* sentinel */ },
292}; 292};
293 293
294struct samsung_div_clock s3c244x_common_dividers[] __initdata = { 294static struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
295 DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1), 295 DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
296 DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1), 296 DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
297 DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d), 297 DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
@@ -299,11 +299,11 @@ struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
299 DIV(0, "div_cam", "upll", CAMDIVN, 0, 3), 299 DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
300}; 300};
301 301
302struct samsung_gate_clock s3c244x_common_gates[] __initdata = { 302static struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
303 GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0), 303 GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
304}; 304};
305 305
306struct samsung_clock_alias s3c244x_common_aliases[] __initdata = { 306static struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
307 ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"), 307 ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
308 ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"), 308 ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
309 ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"), 309 ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
@@ -318,23 +318,23 @@ struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
318 318
319PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; 319PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
320 320
321struct samsung_mux_clock s3c2440_muxes[] __initdata = { 321static struct samsung_mux_clock s3c2440_muxes[] __initdata = {
322 MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1), 322 MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
323}; 323};
324 324
325struct samsung_gate_clock s3c2440_gates[] __initdata = { 325static struct samsung_gate_clock s3c2440_gates[] __initdata = {
326 GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0), 326 GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
327}; 327};
328 328
329/* S3C2442 specific clocks */ 329/* S3C2442 specific clocks */
330 330
331struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = { 331static struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
332 FFACTOR(0, "upll_3", "upll", 1, 3, 0), 332 FFACTOR(0, "upll_3", "upll", 1, 3, 0),
333}; 333};
334 334
335PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; 335PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
336 336
337struct samsung_mux_clock s3c2442_muxes[] __initdata = { 337static struct samsung_mux_clock s3c2442_muxes[] __initdata = {
338 MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2), 338 MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
339}; 339};
340 340
@@ -343,7 +343,7 @@ struct samsung_mux_clock s3c2442_muxes[] __initdata = {
343 * Only necessary until the devicetree-move is complete 343 * Only necessary until the devicetree-move is complete
344 */ 344 */
345#define XTI 1 345#define XTI 1
346struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { 346static struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
347 FRATE(XTI, "xti", NULL, 0, 0), 347 FRATE(XTI, "xti", NULL, 0, 0),
348}; 348};
349 349
@@ -468,18 +468,18 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
468 468
469static void __init s3c2410_clk_init(struct device_node *np) 469static void __init s3c2410_clk_init(struct device_node *np)
470{ 470{
471 s3c2410_common_clk_init(np, 0, S3C2410, 0); 471 s3c2410_common_clk_init(np, 0, S3C2410, NULL);
472} 472}
473CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); 473CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
474 474
475static void __init s3c2440_clk_init(struct device_node *np) 475static void __init s3c2440_clk_init(struct device_node *np)
476{ 476{
477 s3c2410_common_clk_init(np, 0, S3C2440, 0); 477 s3c2410_common_clk_init(np, 0, S3C2440, NULL);
478} 478}
479CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); 479CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
480 480
481static void __init s3c2442_clk_init(struct device_node *np) 481static void __init s3c2442_clk_init(struct device_node *np)
482{ 482{
483 s3c2410_common_clk_init(np, 0, S3C2442, 0); 483 s3c2410_common_clk_init(np, 0, S3C2442, NULL);
484} 484}
485CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init); 485CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index b8340a49921b..6bc94d3aff78 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -27,11 +27,6 @@
27#define CLKSRC 0x1c 27#define CLKSRC 0x1c
28#define SWRST 0x30 28#define SWRST 0x30
29 29
30/* list of PLLs to be registered */
31enum s3c2412_plls {
32 mpll, upll,
33};
34
35static void __iomem *reg_base; 30static void __iomem *reg_base;
36 31
37#ifdef CONFIG_PM_SLEEP 32#ifdef CONFIG_PM_SLEEP
@@ -98,7 +93,7 @@ static struct clk_div_table divxti_d[] = {
98 { /* sentinel */ }, 93 { /* sentinel */ },
99}; 94};
100 95
101struct samsung_div_clock s3c2412_dividers[] __initdata = { 96static struct samsung_div_clock s3c2412_dividers[] __initdata = {
102 DIV_T(0, "div_xti", "xti", CLKSRC, 0, 3, divxti_d), 97 DIV_T(0, "div_xti", "xti", CLKSRC, 0, 3, divxti_d),
103 DIV(0, "div_cam", "mux_cam", CLKDIVN, 16, 4), 98 DIV(0, "div_cam", "mux_cam", CLKDIVN, 16, 4),
104 DIV(0, "div_i2s", "mux_i2s", CLKDIVN, 12, 4), 99 DIV(0, "div_i2s", "mux_i2s", CLKDIVN, 12, 4),
@@ -110,7 +105,7 @@ struct samsung_div_clock s3c2412_dividers[] __initdata = {
110 DIV(HCLK, "hclk", "armdiv", CLKDIVN, 0, 2), 105 DIV(HCLK, "hclk", "armdiv", CLKDIVN, 0, 2),
111}; 106};
112 107
113struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = { 108static struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = {
114 FFACTOR(0, "ff_hclk", "hclk", 2, 1, CLK_SET_RATE_PARENT), 109 FFACTOR(0, "ff_hclk", "hclk", 2, 1, CLK_SET_RATE_PARENT),
115}; 110};
116 111
@@ -130,7 +125,7 @@ PNAME(msysclk_p) = { "mdivclk", "mpll" };
130PNAME(mdivclk_p) = { "xti", "div_xti" }; 125PNAME(mdivclk_p) = { "xti", "div_xti" };
131PNAME(armclk_p) = { "armdiv", "hclk" }; 126PNAME(armclk_p) = { "armdiv", "hclk" };
132 127
133struct samsung_mux_clock s3c2412_muxes[] __initdata = { 128static struct samsung_mux_clock s3c2412_muxes[] __initdata = {
134 MUX(0, "erefclk", erefclk_p, CLKSRC, 14, 2), 129 MUX(0, "erefclk", erefclk_p, CLKSRC, 14, 2),
135 MUX(0, "urefclk", urefclk_p, CLKSRC, 12, 2), 130 MUX(0, "urefclk", urefclk_p, CLKSRC, 12, 2),
136 MUX(0, "mux_cam", camclk_p, CLKSRC, 11, 1), 131 MUX(0, "mux_cam", camclk_p, CLKSRC, 11, 1),
@@ -144,13 +139,11 @@ struct samsung_mux_clock s3c2412_muxes[] __initdata = {
144}; 139};
145 140
146static struct samsung_pll_clock s3c2412_plls[] __initdata = { 141static struct samsung_pll_clock s3c2412_plls[] __initdata = {
147 [mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti", 142 PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti", LOCKTIME, MPLLCON, NULL),
148 LOCKTIME, MPLLCON, NULL), 143 PLL(pll_s3c2410_upll, UPLL, "upll", "urefclk", LOCKTIME, UPLLCON, NULL),
149 [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "urefclk",
150 LOCKTIME, UPLLCON, NULL),
151}; 144};
152 145
153struct samsung_gate_clock s3c2412_gates[] __initdata = { 146static struct samsung_gate_clock s3c2412_gates[] __initdata = {
154 GATE(PCLK_WDT, "wdt", "pclk", CLKCON, 28, 0, 0), 147 GATE(PCLK_WDT, "wdt", "pclk", CLKCON, 28, 0, 0),
155 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 27, 0, 0), 148 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 27, 0, 0),
156 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 26, 0, 0), 149 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 26, 0, 0),
@@ -181,7 +174,7 @@ struct samsung_gate_clock s3c2412_gates[] __initdata = {
181 GATE(HCLK_DMA0, "dma0", "hclk", CLKCON, 0, CLK_IGNORE_UNUSED, 0), 174 GATE(HCLK_DMA0, "dma0", "hclk", CLKCON, 0, CLK_IGNORE_UNUSED, 0),
182}; 175};
183 176
184struct samsung_clock_alias s3c2412_aliases[] __initdata = { 177static struct samsung_clock_alias s3c2412_aliases[] __initdata = {
185 ALIAS(PCLK_UART0, "s3c2412-uart.0", "uart"), 178 ALIAS(PCLK_UART0, "s3c2412-uart.0", "uart"),
186 ALIAS(PCLK_UART1, "s3c2412-uart.1", "uart"), 179 ALIAS(PCLK_UART1, "s3c2412-uart.1", "uart"),
187 ALIAS(PCLK_UART2, "s3c2412-uart.2", "uart"), 180 ALIAS(PCLK_UART2, "s3c2412-uart.2", "uart"),
@@ -231,7 +224,7 @@ static struct notifier_block s3c2412_restart_handler = {
231 * Only necessary until the devicetree-move is complete 224 * Only necessary until the devicetree-move is complete
232 */ 225 */
233#define XTI 1 226#define XTI 1
234struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { 227static struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = {
235 FRATE(XTI, "xti", NULL, 0, 0), 228 FRATE(XTI, "xti", NULL, 0, 0),
236 FRATE(0, "ext", NULL, 0, 0), 229 FRATE(0, "ext", NULL, 0, 0),
237}; 230};
@@ -296,6 +289,6 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
296 289
297static void __init s3c2412_clk_init(struct device_node *np) 290static void __init s3c2412_clk_init(struct device_node *np)
298{ 291{
299 s3c2412_common_clk_init(np, 0, 0, 0); 292 s3c2412_common_clk_init(np, 0, 0, NULL);
300} 293}
301CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init); 294CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index d94b85a42356..c46e6d5bc9bc 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -41,11 +41,6 @@ enum supported_socs {
41 S3C2450, 41 S3C2450,
42}; 42};
43 43
44/* list of PLLs to be registered */
45enum s3c2443_plls {
46 mpll, epll,
47};
48
49static void __iomem *reg_base; 44static void __iomem *reg_base;
50 45
51#ifdef CONFIG_PM_SLEEP 46#ifdef CONFIG_PM_SLEEP
@@ -113,7 +108,7 @@ PNAME(msysclk_p) = { "mpllref", "mpll" };
113PNAME(armclk_p) = { "armdiv" , "hclk" }; 108PNAME(armclk_p) = { "armdiv" , "hclk" };
114PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; 109PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" };
115 110
116struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { 111static struct samsung_mux_clock s3c2443_common_muxes[] __initdata = {
117 MUX(0, "epllref", epllref_p, CLKSRC, 7, 2), 112 MUX(0, "epllref", epllref_p, CLKSRC, 7, 2),
118 MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1), 113 MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1),
119 MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1), 114 MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1),
@@ -141,7 +136,7 @@ static struct clk_div_table mdivclk_d[] = {
141 { /* sentinel */ }, 136 { /* sentinel */ },
142}; 137};
143 138
144struct samsung_div_clock s3c2443_common_dividers[] __initdata = { 139static struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
145 DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d), 140 DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d),
146 DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2), 141 DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2),
147 DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d), 142 DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d),
@@ -154,7 +149,7 @@ struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
154 DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2), 149 DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2),
155}; 150};
156 151
157struct samsung_gate_clock s3c2443_common_gates[] __initdata = { 152static struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
158 GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0), 153 GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0),
159 GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0), 154 GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0),
160 GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0), 155 GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0),
@@ -188,7 +183,7 @@ struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
188 GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0), 183 GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0),
189}; 184};
190 185
191struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { 186static struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
192 ALIAS(MSYSCLK, NULL, "msysclk"), 187 ALIAS(MSYSCLK, NULL, "msysclk"),
193 ALIAS(ARMCLK, NULL, "armclk"), 188 ALIAS(ARMCLK, NULL, "armclk"),
194 ALIAS(MPLL, NULL, "mpll"), 189 ALIAS(MPLL, NULL, "mpll"),
@@ -225,10 +220,8 @@ struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
225/* S3C2416 specific clocks */ 220/* S3C2416 specific clocks */
226 221
227static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { 222static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = {
228 [mpll] = PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref", 223 PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL),
229 LOCKCON0, MPLLCON, NULL), 224 PLL(pll_6553, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL),
230 [epll] = PLL(pll_6553, EPLL, "epll", "epllref",
231 LOCKCON1, EPLLCON, NULL),
232}; 225};
233 226
234PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; 227PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" };
@@ -245,19 +238,19 @@ static struct clk_div_table armdiv_s3c2416_d[] = {
245 { /* sentinel */ }, 238 { /* sentinel */ },
246}; 239};
247 240
248struct samsung_div_clock s3c2416_dividers[] __initdata = { 241static struct samsung_div_clock s3c2416_dividers[] __initdata = {
249 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d), 242 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d),
250 DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4), 243 DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4),
251 DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2), 244 DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2),
252}; 245};
253 246
254struct samsung_mux_clock s3c2416_muxes[] __initdata = { 247static struct samsung_mux_clock s3c2416_muxes[] __initdata = {
255 MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1), 248 MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1),
256 MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1), 249 MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1),
257 MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1), 250 MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1),
258}; 251};
259 252
260struct samsung_gate_clock s3c2416_gates[] __initdata = { 253static struct samsung_gate_clock s3c2416_gates[] __initdata = {
261 GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0), 254 GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0),
262 GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 255 GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
263 GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0), 256 GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0),
@@ -267,7 +260,7 @@ struct samsung_gate_clock s3c2416_gates[] __initdata = {
267 GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0), 260 GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0),
268}; 261};
269 262
270struct samsung_clock_alias s3c2416_aliases[] __initdata = { 263static struct samsung_clock_alias s3c2416_aliases[] __initdata = {
271 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), 264 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
272 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), 265 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
273 ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"), 266 ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"),
@@ -279,10 +272,8 @@ struct samsung_clock_alias s3c2416_aliases[] __initdata = {
279/* S3C2443 specific clocks */ 272/* S3C2443 specific clocks */
280 273
281static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { 274static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = {
282 [mpll] = PLL(pll_3000, MPLL, "mpll", "mpllref", 275 PLL(pll_3000, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL),
283 LOCKCON0, MPLLCON, NULL), 276 PLL(pll_2126, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL),
284 [epll] = PLL(pll_2126, EPLL, "epll", "epllref",
285 LOCKCON1, EPLLCON, NULL),
286}; 277};
287 278
288static struct clk_div_table armdiv_s3c2443_d[] = { 279static struct clk_div_table armdiv_s3c2443_d[] = {
@@ -297,12 +288,12 @@ static struct clk_div_table armdiv_s3c2443_d[] = {
297 { /* sentinel */ }, 288 { /* sentinel */ },
298}; 289};
299 290
300struct samsung_div_clock s3c2443_dividers[] __initdata = { 291static struct samsung_div_clock s3c2443_dividers[] __initdata = {
301 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d), 292 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d),
302 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 293 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
303}; 294};
304 295
305struct samsung_gate_clock s3c2443_gates[] __initdata = { 296static struct samsung_gate_clock s3c2443_gates[] __initdata = {
306 GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 297 GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
307 GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0), 298 GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0),
308 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0), 299 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0),
@@ -311,7 +302,7 @@ struct samsung_gate_clock s3c2443_gates[] __initdata = {
311 GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0), 302 GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0),
312}; 303};
313 304
314struct samsung_clock_alias s3c2443_aliases[] __initdata = { 305static struct samsung_clock_alias s3c2443_aliases[] __initdata = {
315 ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 306 ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
316 ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 307 ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
317 ALIAS(SCLK_CAM, NULL, "camif-upll"), 308 ALIAS(SCLK_CAM, NULL, "camif-upll"),
@@ -327,20 +318,20 @@ PNAME(s3c2450_cam_p) = { "div_cam", "hclk" };
327PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; 318PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" };
328PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; 319PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" };
329 320
330struct samsung_div_clock s3c2450_dividers[] __initdata = { 321static struct samsung_div_clock s3c2450_dividers[] __initdata = {
331 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 322 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
332 DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2), 323 DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2),
333 DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4), 324 DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4),
334 DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4), 325 DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4),
335}; 326};
336 327
337struct samsung_mux_clock s3c2450_muxes[] __initdata = { 328static struct samsung_mux_clock s3c2450_muxes[] __initdata = {
338 MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1), 329 MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1),
339 MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1), 330 MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1),
340 MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2), 331 MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2),
341}; 332};
342 333
343struct samsung_gate_clock s3c2450_gates[] __initdata = { 334static struct samsung_gate_clock s3c2450_gates[] __initdata = {
344 GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0), 335 GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0),
345 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0), 336 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0),
346 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 337 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
@@ -351,7 +342,7 @@ struct samsung_gate_clock s3c2450_gates[] __initdata = {
351 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0), 342 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0),
352}; 343};
353 344
354struct samsung_clock_alias s3c2450_aliases[] __initdata = { 345static struct samsung_clock_alias s3c2450_aliases[] __initdata = {
355 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"), 346 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"),
356 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"), 347 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"),
357 ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"), 348 ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"),
@@ -374,7 +365,7 @@ static struct notifier_block s3c2443_restart_handler = {
374 * fixed rate clocks generated outside the soc 365 * fixed rate clocks generated outside the soc
375 * Only necessary until the devicetree-move is complete 366 * Only necessary until the devicetree-move is complete
376 */ 367 */
377struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { 368static struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = {
378 FRATE(0, "xti", NULL, 0, 0), 369 FRATE(0, "xti", NULL, 0, 0),
379 FRATE(0, "ext", NULL, 0, 0), 370 FRATE(0, "ext", NULL, 0, 0),
380 FRATE(0, "ext_i2s", NULL, 0, 0), 371 FRATE(0, "ext_i2s", NULL, 0, 0),
@@ -470,18 +461,18 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
470 461
471static void __init s3c2416_clk_init(struct device_node *np) 462static void __init s3c2416_clk_init(struct device_node *np)
472{ 463{
473 s3c2443_common_clk_init(np, 0, S3C2416, 0); 464 s3c2443_common_clk_init(np, 0, S3C2416, NULL);
474} 465}
475CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); 466CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init);
476 467
477static void __init s3c2443_clk_init(struct device_node *np) 468static void __init s3c2443_clk_init(struct device_node *np)
478{ 469{
479 s3c2443_common_clk_init(np, 0, S3C2443, 0); 470 s3c2443_common_clk_init(np, 0, S3C2443, NULL);
480} 471}
481CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); 472CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init);
482 473
483static void __init s3c2450_clk_init(struct device_node *np) 474static void __init s3c2450_clk_init(struct device_node *np)
484{ 475{
485 s3c2443_common_clk_init(np, 0, S3C2450, 0); 476 s3c2443_common_clk_init(np, 0, S3C2450, NULL);
486} 477}
487CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init); 478CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index 7306867a0ab8..6db01cf5ab83 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -56,11 +56,6 @@
56#define GATE_ON(_id, cname, pname, o, b) \ 56#define GATE_ON(_id, cname, pname, o, b) \
57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0) 57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
58 58
59/* list of PLLs to be registered */
60enum s3c64xx_plls {
61 apll, mpll, epll,
62};
63
64static void __iomem *reg_base; 59static void __iomem *reg_base;
65static bool is_s3c6400; 60static bool is_s3c6400;
66 61
@@ -364,12 +359,12 @@ GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
364 359
365/* List of PLL clocks. */ 360/* List of PLL clocks. */
366static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = { 361static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = {
367 [apll] = PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll", 362 PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll",
368 APLL_LOCK, APLL_CON, NULL), 363 APLL_LOCK, APLL_CON, NULL),
369 [mpll] = PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll", 364 PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll",
370 MPLL_LOCK, MPLL_CON, NULL), 365 MPLL_LOCK, MPLL_CON, NULL),
371 [epll] = PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll", 366 PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll",
372 EPLL_LOCK, EPLL_CON0, NULL), 367 EPLL_LOCK, EPLL_CON0, NULL),
373}; 368};
374 369
375/* Aliases for common s3c64xx clocks. */ 370/* Aliases for common s3c64xx clocks. */
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 11a5066e5c27..5234acd30e89 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -515,7 +515,7 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
515 515
516 init.name = "emc"; 516 init.name = "emc";
517 init.ops = &tegra_clk_emc_ops; 517 init.ops = &tegra_clk_emc_ops;
518 init.flags = 0; 518 init.flags = CLK_IS_CRITICAL;
519 init.parent_names = emc_parent_clk_names; 519 init.parent_names = emc_parent_clk_names;
520 init.num_parents = ARRAY_SIZE(emc_parent_clk_names); 520 init.num_parents = ARRAY_SIZE(emc_parent_clk_names);
521 521
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 7c369e21c91c..830d1c87fa7c 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1151,6 +1151,8 @@ static const struct clk_ops tegra_clk_pllu_ops = {
1151 .enable = clk_pllu_enable, 1151 .enable = clk_pllu_enable,
1152 .disable = clk_pll_disable, 1152 .disable = clk_pll_disable,
1153 .recalc_rate = clk_pll_recalc_rate, 1153 .recalc_rate = clk_pll_recalc_rate,
1154 .round_rate = clk_pll_round_rate,
1155 .set_rate = clk_pll_set_rate,
1154}; 1156};
1155 1157
1156static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, 1158static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index c02711927d79..2acba2986bc6 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -830,7 +830,7 @@ static struct tegra_periph_init_data gate_clks[] = {
830 GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), 830 GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0),
831 GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), 831 GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0),
832 GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), 832 GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0),
833 GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), 833 GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IS_CRITICAL),
834 GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), 834 GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0),
835 GATE("ispa", "isp", 23, 0, tegra_clk_ispa, 0), 835 GATE("ispa", "isp", 23, 0, tegra_clk_ispa, 0),
836 GATE("ispb", "isp", 3, 0, tegra_clk_ispb, 0), 836 GATE("ispb", "isp", 3, 0, tegra_clk_ispb, 0),
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index 10047107c1dc..89d6b47a27a8 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -125,7 +125,8 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
125 /* SCLK */ 125 /* SCLK */
126 dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); 126 dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks);
127 if (dt_clk) { 127 if (dt_clk) {
128 clk = clk_register_divider(NULL, "sclk", "sclk_mux", 0, 128 clk = clk_register_divider(NULL, "sclk", "sclk_mux",
129 CLK_IS_CRITICAL,
129 clk_base + SCLK_DIVIDER, 0, 8, 130 clk_base + SCLK_DIVIDER, 0, 8,
130 0, &sysrate_lock); 131 0, &sysrate_lock);
131 *dt_clk = clk; 132 *dt_clk = clk;
@@ -137,7 +138,8 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
137 clk = tegra_clk_register_super_mux("sclk", 138 clk = tegra_clk_register_super_mux("sclk",
138 gen_info->sclk_parents, 139 gen_info->sclk_parents,
139 gen_info->num_sclk_parents, 140 gen_info->num_sclk_parents,
140 CLK_SET_RATE_PARENT, 141 CLK_SET_RATE_PARENT |
142 CLK_IS_CRITICAL,
141 clk_base + SCLK_BURST_POLICY, 143 clk_base + SCLK_BURST_POLICY,
142 0, 4, 0, 0, NULL); 144 0, 4, 0, 0, NULL);
143 *dt_clk = clk; 145 *dt_clk = clk;
@@ -151,7 +153,7 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
151 clk_base + SYSTEM_CLK_RATE, 4, 2, 0, 153 clk_base + SYSTEM_CLK_RATE, 4, 2, 0,
152 &sysrate_lock); 154 &sysrate_lock);
153 clk = clk_register_gate(NULL, "hclk", "hclk_div", 155 clk = clk_register_gate(NULL, "hclk", "hclk_div",
154 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 156 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
155 clk_base + SYSTEM_CLK_RATE, 157 clk_base + SYSTEM_CLK_RATE,
156 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); 158 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
157 *dt_clk = clk; 159 *dt_clk = clk;
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 63087d17c3e2..5d5a22d529f5 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -955,8 +955,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
955 955
956 /* PLLM */ 956 /* PLLM */
957 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, 957 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
958 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 958 CLK_SET_RATE_GATE, &pll_m_params, NULL);
959 &pll_m_params, NULL);
960 clks[TEGRA114_CLK_PLL_M] = clk; 959 clks[TEGRA114_CLK_PLL_M] = clk;
961 960
962 /* PLLM_OUT1 */ 961 /* PLLM_OUT1 */
@@ -1190,6 +1189,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1190 { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 }, 1189 { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 },
1191 { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 }, 1190 { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 },
1192 { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 }, 1191 { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 },
1192 { TEGRA114_CLK_VDE, TEGRA114_CLK_CLK_MAX, 600000000, 0 },
1193 /* must be the last entry */ 1193 /* must be the last entry */
1194 { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 }, 1194 { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 },
1195}; 1195};
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index e81ea5b11577..50088e976611 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1089,8 +1089,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
1089 1089
1090 /* PLLM */ 1090 /* PLLM */
1091 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, 1091 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
1092 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 1092 CLK_SET_RATE_GATE, &pll_m_params, NULL);
1093 &pll_m_params, NULL);
1094 clk_register_clkdev(clk, "pll_m", NULL); 1093 clk_register_clkdev(clk, "pll_m", NULL);
1095 clks[TEGRA124_CLK_PLL_M] = clk; 1094 clks[TEGRA124_CLK_PLL_M] = clk;
1096 1095
@@ -1099,7 +1098,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
1099 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 1098 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
1100 8, 8, 1, NULL); 1099 8, 8, 1, NULL);
1101 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 1100 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
1102 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 1101 clk_base + PLLM_OUT, 1, 0,
1103 CLK_SET_RATE_PARENT, 0, NULL); 1102 CLK_SET_RATE_PARENT, 0, NULL);
1104 clk_register_clkdev(clk, "pll_m_out1", NULL); 1103 clk_register_clkdev(clk, "pll_m_out1", NULL);
1105 clks[TEGRA124_CLK_PLL_M_OUT1] = clk; 1104 clks[TEGRA124_CLK_PLL_M_OUT1] = clk;
@@ -1268,11 +1267,11 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
1268 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1267 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1269 { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1268 { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1270 { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1269 { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1271 { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0 }, 1270 { TEGRA124_CLK_VDE, TEGRA124_CLK_CLK_MAX, 600000000, 0 },
1272 { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, 1271 { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 },
1273 { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, 1272 { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 },
1274 { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, 1273 { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 },
1275 { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1 }, 1274 { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 0 },
1276 { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 }, 1275 { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 },
1277 { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 }, 1276 { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 },
1278 { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 }, 1277 { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 },
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index cbd5a2e5c569..0ee56dd04cec 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -576,6 +576,7 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, 576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true },
577 [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true }, 577 [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true },
578 [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true }, 578 [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true },
579 [tegra_clk_emc] = { .dt_id = TEGRA20_CLK_EMC, .present = true },
579}; 580};
580 581
581static unsigned long tegra20_clk_measure_input_freq(void) 582static unsigned long tegra20_clk_measure_input_freq(void)
@@ -651,8 +652,7 @@ static void tegra20_pll_init(void)
651 652
652 /* PLLM */ 653 /* PLLM */
653 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, 654 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL,
654 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 655 CLK_SET_RATE_GATE, &pll_m_params, NULL);
655 &pll_m_params, NULL);
656 clks[TEGRA20_CLK_PLL_M] = clk; 656 clks[TEGRA20_CLK_PLL_M] = clk;
657 657
658 /* PLLM_OUT1 */ 658 /* PLLM_OUT1 */
@@ -660,7 +660,7 @@ static void tegra20_pll_init(void)
660 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 660 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
661 8, 8, 1, NULL); 661 8, 8, 1, NULL);
662 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 662 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
663 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 663 clk_base + PLLM_OUT, 1, 0,
664 CLK_SET_RATE_PARENT, 0, NULL); 664 CLK_SET_RATE_PARENT, 0, NULL);
665 clks[TEGRA20_CLK_PLL_M_OUT1] = clk; 665 clks[TEGRA20_CLK_PLL_M_OUT1] = clk;
666 666
@@ -723,7 +723,8 @@ static void tegra20_super_clk_init(void)
723 723
724 /* SCLK */ 724 /* SCLK */
725 clk = tegra_clk_register_super_mux("sclk", sclk_parents, 725 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
726 ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, 726 ARRAY_SIZE(sclk_parents),
727 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
727 clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); 728 clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
728 clks[TEGRA20_CLK_SCLK] = clk; 729 clks[TEGRA20_CLK_SCLK] = clk;
729 730
@@ -814,9 +815,6 @@ static void __init tegra20_periph_clk_init(void)
814 CLK_SET_RATE_NO_REPARENT, 815 CLK_SET_RATE_NO_REPARENT,
815 clk_base + CLK_SOURCE_EMC, 816 clk_base + CLK_SOURCE_EMC,
816 30, 2, 0, &emc_lock); 817 30, 2, 0, &emc_lock);
817 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
818 57, periph_clk_enb_refcnt);
819 clks[TEGRA20_CLK_EMC] = clk;
820 818
821 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 819 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
822 &emc_lock); 820 &emc_lock);
@@ -1019,13 +1017,12 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1019 { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 }, 1017 { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 },
1020 { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 }, 1018 { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 },
1021 { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 }, 1019 { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 },
1022 { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1 }, 1020 { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 0 },
1023 { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 216000000, 1 }, 1021 { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 240000000, 0 },
1024 { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1 }, 1022 { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 240000000, 0 },
1025 { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1023 { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 240000000, 0 },
1026 { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1 }, 1024 { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 0 },
1027 { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1025 { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 },
1028 { TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1 },
1029 { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1026 { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 },
1030 { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 }, 1027 { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 },
1031 { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 }, 1028 { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 },
@@ -1051,6 +1048,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1051 { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 }, 1048 { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 },
1052 { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 }, 1049 { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1053 { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 }, 1050 { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1051 { TEGRA20_CLK_VDE, TEGRA20_CLK_CLK_MAX, 300000000, 0 },
1054 /* must be the last entry */ 1052 /* must be the last entry */
1055 { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 }, 1053 { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
1056}; 1054};
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 9e6260869eb9..9fb5d51ccce4 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -22,10 +22,12 @@
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/mutex.h>
25#include <linux/clk/tegra.h> 26#include <linux/clk/tegra.h>
26#include <dt-bindings/clock/tegra210-car.h> 27#include <dt-bindings/clock/tegra210-car.h>
27#include <dt-bindings/reset/tegra210-car.h> 28#include <dt-bindings/reset/tegra210-car.h>
28#include <linux/iopoll.h> 29#include <linux/iopoll.h>
30#include <soc/tegra/pmc.h>
29 31
30#include "clk.h" 32#include "clk.h"
31#include "clk-id.h" 33#include "clk-id.h"
@@ -41,6 +43,7 @@
41#define CLK_SOURCE_CSITE 0x1d4 43#define CLK_SOURCE_CSITE 0x1d4
42#define CLK_SOURCE_EMC 0x19c 44#define CLK_SOURCE_EMC 0x19c
43#define CLK_SOURCE_SOR1 0x410 45#define CLK_SOURCE_SOR1 0x410
46#define CLK_SOURCE_LA 0x1f8
44 47
45#define PLLC_BASE 0x80 48#define PLLC_BASE 0x80
46#define PLLC_OUT 0x84 49#define PLLC_OUT 0x84
@@ -231,6 +234,30 @@
231#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 234#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
232#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac 235#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
233 236
237#define LVL2_CLK_GATE_OVRA 0xf8
238#define LVL2_CLK_GATE_OVRC 0x3a0
239#define LVL2_CLK_GATE_OVRD 0x3a4
240#define LVL2_CLK_GATE_OVRE 0x554
241
242/* I2S registers to handle during APE MBIST WAR */
243#define TEGRA210_I2S_BASE 0x1000
244#define TEGRA210_I2S_SIZE 0x100
245#define TEGRA210_I2S_CTRLS 5
246#define TEGRA210_I2S_CG 0x88
247#define TEGRA210_I2S_CTRL 0xa0
248
249/* DISPA registers to handle during MBIST WAR */
250#define DC_CMD_DISPLAY_COMMAND 0xc8
251#define DC_COM_DSC_TOP_CTL 0xcf8
252
253/* VIC register to handle during MBIST WAR */
254#define NV_PVIC_THI_SLCG_OVERRIDE_LOW 0x8c
255
256/* APE, DISPA and VIC base addesses needed for MBIST WAR */
257#define TEGRA210_AHUB_BASE 0x702d0000
258#define TEGRA210_DISPA_BASE 0x54200000
259#define TEGRA210_VIC_BASE 0x54340000
260
234/* 261/*
235 * SDM fractional divisor is 16-bit 2's complement signed number within 262 * SDM fractional divisor is 16-bit 2's complement signed number within
236 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned 263 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned
@@ -255,8 +282,22 @@ static struct cpu_clk_suspend_context {
255} tegra210_cpu_clk_sctx; 282} tegra210_cpu_clk_sctx;
256#endif 283#endif
257 284
285struct tegra210_domain_mbist_war {
286 void (*handle_lvl2_ovr)(struct tegra210_domain_mbist_war *mbist);
287 const u32 lvl2_offset;
288 const u32 lvl2_mask;
289 const unsigned int num_clks;
290 const unsigned int *clk_init_data;
291 struct clk_bulk_data *clks;
292};
293
294static struct clk **clks;
295
258static void __iomem *clk_base; 296static void __iomem *clk_base;
259static void __iomem *pmc_base; 297static void __iomem *pmc_base;
298static void __iomem *ahub_base;
299static void __iomem *dispa_base;
300static void __iomem *vic_base;
260 301
261static unsigned long osc_freq; 302static unsigned long osc_freq;
262static unsigned long pll_ref_freq; 303static unsigned long pll_ref_freq;
@@ -267,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock);
267static DEFINE_SPINLOCK(pll_u_lock); 308static DEFINE_SPINLOCK(pll_u_lock);
268static DEFINE_SPINLOCK(sor1_lock); 309static DEFINE_SPINLOCK(sor1_lock);
269static DEFINE_SPINLOCK(emc_lock); 310static DEFINE_SPINLOCK(emc_lock);
311static DEFINE_MUTEX(lvl2_ovr_lock);
270 312
271/* possible OSC frequencies in Hz */ 313/* possible OSC frequencies in Hz */
272static unsigned long tegra210_input_freq[] = { 314static unsigned long tegra210_input_freq[] = {
@@ -310,6 +352,8 @@ static const char *mux_pllmcp_clkm[] = {
310#define PLLA_MISC2_WRITE_MASK 0x06ffffff 352#define PLLA_MISC2_WRITE_MASK 0x06ffffff
311 353
312/* PLLD */ 354/* PLLD */
355#define PLLD_BASE_CSI_CLKSOURCE (1 << 23)
356
313#define PLLD_MISC0_EN_SDM (1 << 16) 357#define PLLD_MISC0_EN_SDM (1 << 16)
314#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) 358#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
315#define PLLD_MISC0_LOCK_ENABLE (1 << 18) 359#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
@@ -513,6 +557,115 @@ void tegra210_set_sata_pll_seq_sw(bool state)
513} 557}
514EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); 558EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
515 559
560static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
561{
562 u32 val;
563
564 val = readl_relaxed(clk_base + mbist->lvl2_offset);
565 writel_relaxed(val | mbist->lvl2_mask, clk_base + mbist->lvl2_offset);
566 fence_udelay(1, clk_base);
567 writel_relaxed(val, clk_base + mbist->lvl2_offset);
568 fence_udelay(1, clk_base);
569}
570
571static void tegra210_venc_mbist_war(struct tegra210_domain_mbist_war *mbist)
572{
573 u32 csi_src, ovra, ovre;
574 unsigned long flags = 0;
575
576 spin_lock_irqsave(&pll_d_lock, flags);
577
578 csi_src = readl_relaxed(clk_base + PLLD_BASE);
579 writel_relaxed(csi_src | PLLD_BASE_CSI_CLKSOURCE, clk_base + PLLD_BASE);
580 fence_udelay(1, clk_base);
581
582 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
583 writel_relaxed(ovra | BIT(15), clk_base + LVL2_CLK_GATE_OVRA);
584 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
585 writel_relaxed(ovre | BIT(3), clk_base + LVL2_CLK_GATE_OVRE);
586 fence_udelay(1, clk_base);
587
588 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
589 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
590 writel_relaxed(csi_src, clk_base + PLLD_BASE);
591 fence_udelay(1, clk_base);
592
593 spin_unlock_irqrestore(&pll_d_lock, flags);
594}
595
596static void tegra210_disp_mbist_war(struct tegra210_domain_mbist_war *mbist)
597{
598 u32 ovra, dsc_top_ctrl;
599
600 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
601 writel_relaxed(ovra | BIT(1), clk_base + LVL2_CLK_GATE_OVRA);
602 fence_udelay(1, clk_base);
603
604 dsc_top_ctrl = readl_relaxed(dispa_base + DC_COM_DSC_TOP_CTL);
605 writel_relaxed(dsc_top_ctrl | BIT(2), dispa_base + DC_COM_DSC_TOP_CTL);
606 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
607 writel_relaxed(dsc_top_ctrl, dispa_base + DC_COM_DSC_TOP_CTL);
608 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
609
610 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
611 fence_udelay(1, clk_base);
612}
613
614static void tegra210_vic_mbist_war(struct tegra210_domain_mbist_war *mbist)
615{
616 u32 ovre, val;
617
618 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
619 writel_relaxed(ovre | BIT(5), clk_base + LVL2_CLK_GATE_OVRE);
620 fence_udelay(1, clk_base);
621
622 val = readl_relaxed(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
623 writel_relaxed(val | BIT(0) | GENMASK(7, 2) | BIT(24),
624 vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
625 fence_udelay(1, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
626
627 writel_relaxed(val, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
628 readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
629
630 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
631 fence_udelay(1, clk_base);
632}
633
634static void tegra210_ape_mbist_war(struct tegra210_domain_mbist_war *mbist)
635{
636 void __iomem *i2s_base;
637 unsigned int i;
638 u32 ovrc, ovre;
639
640 ovrc = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRC);
641 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
642 writel_relaxed(ovrc | BIT(1), clk_base + LVL2_CLK_GATE_OVRC);
643 writel_relaxed(ovre | BIT(10) | BIT(11),
644 clk_base + LVL2_CLK_GATE_OVRE);
645 fence_udelay(1, clk_base);
646
647 i2s_base = ahub_base + TEGRA210_I2S_BASE;
648
649 for (i = 0; i < TEGRA210_I2S_CTRLS; i++) {
650 u32 i2s_ctrl;
651
652 i2s_ctrl = readl_relaxed(i2s_base + TEGRA210_I2S_CTRL);
653 writel_relaxed(i2s_ctrl | BIT(10),
654 i2s_base + TEGRA210_I2S_CTRL);
655 writel_relaxed(0, i2s_base + TEGRA210_I2S_CG);
656 readl(i2s_base + TEGRA210_I2S_CG);
657 writel_relaxed(1, i2s_base + TEGRA210_I2S_CG);
658 writel_relaxed(i2s_ctrl, i2s_base + TEGRA210_I2S_CTRL);
659 readl(i2s_base + TEGRA210_I2S_CTRL);
660
661 i2s_base += TEGRA210_I2S_SIZE;
662 }
663
664 writel_relaxed(ovrc, clk_base + LVL2_CLK_GATE_OVRC);
665 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
666 fence_udelay(1, clk_base);
667}
668
516static inline void _pll_misc_chk_default(void __iomem *base, 669static inline void _pll_misc_chk_default(void __iomem *base,
517 struct tegra_clk_pll_params *params, 670 struct tegra_clk_pll_params *params,
518 u8 misc_num, u32 default_val, u32 mask) 671 u8 misc_num, u32 default_val, u32 mask)
@@ -2411,13 +2564,150 @@ static struct tegra_audio_clk_info tegra210_audio_plls[] = {
2411 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, 2564 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" },
2412}; 2565};
2413 2566
2414static struct clk **clks;
2415
2416static const char * const aclk_parents[] = { 2567static const char * const aclk_parents[] = {
2417 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3", 2568 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3",
2418 "clk_m" 2569 "clk_m"
2419}; 2570};
2420 2571
2572static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC };
2573static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG };
2574static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X,
2575 TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 };
2576static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA,
2577 TEGRA210_CLK_HOST1X};
2578static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2579 TEGRA210_CLK_XUSB_DEV };
2580static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2581 TEGRA210_CLK_XUSB_SS };
2582static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV,
2583 TEGRA210_CLK_XUSB_SS };
2584static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X,
2585 TEGRA210_CLK_PLL_D };
2586static const unsigned int ape_slcg_clkids[] = { TEGRA210_CLK_ACLK,
2587 TEGRA210_CLK_I2S0, TEGRA210_CLK_I2S1, TEGRA210_CLK_I2S2,
2588 TEGRA210_CLK_I2S3, TEGRA210_CLK_I2S4, TEGRA210_CLK_SPDIF_OUT,
2589 TEGRA210_CLK_D_AUDIO };
2590static const unsigned int vic_slcg_clkids[] = { TEGRA210_CLK_HOST1X };
2591
2592static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = {
2593 [TEGRA_POWERGATE_VENC] = {
2594 .handle_lvl2_ovr = tegra210_venc_mbist_war,
2595 .num_clks = ARRAY_SIZE(venc_slcg_clkids),
2596 .clk_init_data = venc_slcg_clkids,
2597 },
2598 [TEGRA_POWERGATE_SATA] = {
2599 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2600 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2601 .lvl2_mask = BIT(0) | BIT(17) | BIT(19),
2602 },
2603 [TEGRA_POWERGATE_MPE] = {
2604 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2605 .lvl2_offset = LVL2_CLK_GATE_OVRE,
2606 .lvl2_mask = BIT(2),
2607 },
2608 [TEGRA_POWERGATE_SOR] = {
2609 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2610 .num_clks = ARRAY_SIZE(sor_slcg_clkids),
2611 .clk_init_data = sor_slcg_clkids,
2612 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2613 .lvl2_mask = BIT(1) | BIT(2),
2614 },
2615 [TEGRA_POWERGATE_DIS] = {
2616 .handle_lvl2_ovr = tegra210_disp_mbist_war,
2617 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2618 .clk_init_data = disp_slcg_clkids,
2619 },
2620 [TEGRA_POWERGATE_DISB] = {
2621 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2622 .clk_init_data = disp_slcg_clkids,
2623 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2624 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2625 .lvl2_mask = BIT(2),
2626 },
2627 [TEGRA_POWERGATE_XUSBA] = {
2628 .num_clks = ARRAY_SIZE(xusba_slcg_clkids),
2629 .clk_init_data = xusba_slcg_clkids,
2630 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2631 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2632 .lvl2_mask = BIT(30) | BIT(31),
2633 },
2634 [TEGRA_POWERGATE_XUSBB] = {
2635 .num_clks = ARRAY_SIZE(xusbb_slcg_clkids),
2636 .clk_init_data = xusbb_slcg_clkids,
2637 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2638 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2639 .lvl2_mask = BIT(30) | BIT(31),
2640 },
2641 [TEGRA_POWERGATE_XUSBC] = {
2642 .num_clks = ARRAY_SIZE(xusbc_slcg_clkids),
2643 .clk_init_data = xusbc_slcg_clkids,
2644 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2645 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2646 .lvl2_mask = BIT(30) | BIT(31),
2647 },
2648 [TEGRA_POWERGATE_VIC] = {
2649 .num_clks = ARRAY_SIZE(vic_slcg_clkids),
2650 .clk_init_data = vic_slcg_clkids,
2651 .handle_lvl2_ovr = tegra210_vic_mbist_war,
2652 },
2653 [TEGRA_POWERGATE_NVDEC] = {
2654 .num_clks = ARRAY_SIZE(nvdec_slcg_clkids),
2655 .clk_init_data = nvdec_slcg_clkids,
2656 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2657 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2658 .lvl2_mask = BIT(9) | BIT(31),
2659 },
2660 [TEGRA_POWERGATE_NVJPG] = {
2661 .num_clks = ARRAY_SIZE(nvjpg_slcg_clkids),
2662 .clk_init_data = nvjpg_slcg_clkids,
2663 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2664 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2665 .lvl2_mask = BIT(9) | BIT(31),
2666 },
2667 [TEGRA_POWERGATE_AUD] = {
2668 .num_clks = ARRAY_SIZE(ape_slcg_clkids),
2669 .clk_init_data = ape_slcg_clkids,
2670 .handle_lvl2_ovr = tegra210_ape_mbist_war,
2671 },
2672 [TEGRA_POWERGATE_VE2] = {
2673 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2674 .lvl2_offset = LVL2_CLK_GATE_OVRD,
2675 .lvl2_mask = BIT(22),
2676 },
2677};
2678
2679int tegra210_clk_handle_mbist_war(unsigned int id)
2680{
2681 int err;
2682 struct tegra210_domain_mbist_war *mbist_war;
2683
2684 if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) {
2685 WARN(1, "unknown domain id in MBIST WAR handler\n");
2686 return -EINVAL;
2687 }
2688
2689 mbist_war = &tegra210_pg_mbist_war[id];
2690 if (!mbist_war->handle_lvl2_ovr)
2691 return 0;
2692
2693 if (mbist_war->num_clks && !mbist_war->clks)
2694 return -ENODEV;
2695
2696 err = clk_bulk_prepare_enable(mbist_war->num_clks, mbist_war->clks);
2697 if (err < 0)
2698 return err;
2699
2700 mutex_lock(&lvl2_ovr_lock);
2701
2702 mbist_war->handle_lvl2_ovr(mbist_war);
2703
2704 mutex_unlock(&lvl2_ovr_lock);
2705
2706 clk_bulk_disable_unprepare(mbist_war->num_clks, mbist_war->clks);
2707
2708 return 0;
2709}
2710
2421void tegra210_put_utmipll_in_iddq(void) 2711void tegra210_put_utmipll_in_iddq(void)
2422{ 2712{
2423 u32 reg; 2713 u32 reg;
@@ -2654,6 +2944,13 @@ static struct tegra_periph_init_data tegra210_periph[] = {
2654 sor1_parents_idx, 0, &sor1_lock), 2944 sor1_parents_idx, 0, &sor1_lock),
2655}; 2945};
2656 2946
2947static const char * const la_parents[] = {
2948 "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_re_out1", "pll_a1", "clk_m", "pll_c4_out0"
2949};
2950
2951static struct tegra_clk_periph tegra210_la =
2952 TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0);
2953
2657static __init void tegra210_periph_clk_init(void __iomem *clk_base, 2954static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2658 void __iomem *pmc_base) 2955 void __iomem *pmc_base)
2659{ 2956{
@@ -2700,6 +2997,12 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2700 periph_clk_enb_refcnt); 2997 periph_clk_enb_refcnt);
2701 clks[TEGRA210_CLK_DSIB] = clk; 2998 clks[TEGRA210_CLK_DSIB] = clk;
2702 2999
3000 /* la */
3001 clk = tegra_clk_register_periph("la", la_parents,
3002 ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
3003 CLK_SOURCE_LA, 0);
3004 clks[TEGRA210_CLK_LA] = clk;
3005
2703 /* emc mux */ 3006 /* emc mux */
2704 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 3007 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
2705 ARRAY_SIZE(mux_pllmcp_clkm), 0, 3008 ARRAY_SIZE(mux_pllmcp_clkm), 0,
@@ -3025,7 +3328,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3025 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, 3328 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
3026 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 }, 3329 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 },
3027 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 }, 3330 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 },
3028 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, 3331 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 0 },
3029 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3332 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 },
3030 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3333 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 },
3031 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, 3334 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 },
@@ -3040,7 +3343,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3040 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, 3343 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 },
3041 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 }, 3344 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 },
3042 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 }, 3345 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 },
3043 { TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1 },
3044 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3346 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 },
3045 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3347 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 },
3046 /* TODO find a way to enable this on-demand */ 3348 /* TODO find a way to enable this on-demand */
@@ -3149,6 +3451,37 @@ static int tegra210_reset_deassert(unsigned long id)
3149 return 0; 3451 return 0;
3150} 3452}
3151 3453
3454static void tegra210_mbist_clk_init(void)
3455{
3456 unsigned int i, j;
3457
3458 for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
3459 unsigned int num_clks = tegra210_pg_mbist_war[i].num_clks;
3460 struct clk_bulk_data *clk_data;
3461
3462 if (!num_clks)
3463 continue;
3464
3465 clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
3466 GFP_KERNEL);
3467 if (WARN_ON(!clk_data))
3468 return;
3469
3470 tegra210_pg_mbist_war[i].clks = clk_data;
3471 for (j = 0; j < num_clks; j++) {
3472 int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
3473 struct clk *clk = clks[clk_id];
3474
3475 if (WARN(IS_ERR(clk), "clk_id: %d\n", clk_id)) {
3476 kfree(clk_data);
3477 tegra210_pg_mbist_war[i].clks = NULL;
3478 break;
3479 }
3480 clk_data[j].clk = clk;
3481 }
3482 }
3483}
3484
3152/** 3485/**
3153 * tegra210_clock_init - Tegra210-specific clock initialization 3486 * tegra210_clock_init - Tegra210-specific clock initialization
3154 * @np: struct device_node * of the DT node for the SoC CAR IP block 3487 * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -3183,6 +3516,24 @@ static void __init tegra210_clock_init(struct device_node *np)
3183 return; 3516 return;
3184 } 3517 }
3185 3518
3519 ahub_base = ioremap(TEGRA210_AHUB_BASE, SZ_64K);
3520 if (!ahub_base) {
3521 pr_err("ioremap tegra210 APE failed\n");
3522 return;
3523 }
3524
3525 dispa_base = ioremap(TEGRA210_DISPA_BASE, SZ_256K);
3526 if (!dispa_base) {
3527 pr_err("ioremap tegra210 DISPA failed\n");
3528 return;
3529 }
3530
3531 vic_base = ioremap(TEGRA210_VIC_BASE, SZ_256K);
3532 if (!vic_base) {
3533 pr_err("ioremap tegra210 VIC failed\n");
3534 return;
3535 }
3536
3186 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, 3537 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
3187 TEGRA210_CAR_BANK_COUNT); 3538 TEGRA210_CAR_BANK_COUNT);
3188 if (!clks) 3539 if (!clks)
@@ -3219,6 +3570,8 @@ static void __init tegra210_clock_init(struct device_node *np)
3219 tegra_add_of_provider(np); 3570 tegra_add_of_provider(np);
3220 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 3571 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
3221 3572
3573 tegra210_mbist_clk_init();
3574
3222 tegra_cpu_car_ops = &tegra210_cpu_car_ops; 3575 tegra_cpu_car_ops = &tegra210_cpu_car_ops;
3223} 3576}
3224CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); 3577CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index bee84c554932..b316dfb6f6c7 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -819,6 +819,7 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
819 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, 819 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true },
820 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, 820 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true },
821 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, 821 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true },
822 [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true },
822}; 823};
823 824
824static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; 825static const char *pll_e_parents[] = { "pll_ref", "pll_p" };
@@ -843,8 +844,7 @@ static void __init tegra30_pll_init(void)
843 844
844 /* PLLM */ 845 /* PLLM */
845 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, 846 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
846 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 847 CLK_SET_RATE_GATE, &pll_m_params, NULL);
847 &pll_m_params, NULL);
848 clks[TEGRA30_CLK_PLL_M] = clk; 848 clks[TEGRA30_CLK_PLL_M] = clk;
849 849
850 /* PLLM_OUT1 */ 850 /* PLLM_OUT1 */
@@ -852,7 +852,7 @@ static void __init tegra30_pll_init(void)
852 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 852 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
853 8, 8, 1, NULL); 853 8, 8, 1, NULL);
854 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 854 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
855 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 855 clk_base + PLLM_OUT, 1, 0,
856 CLK_SET_RATE_PARENT, 0, NULL); 856 CLK_SET_RATE_PARENT, 0, NULL);
857 clks[TEGRA30_CLK_PLL_M_OUT1] = clk; 857 clks[TEGRA30_CLK_PLL_M_OUT1] = clk;
858 858
@@ -990,7 +990,7 @@ static void __init tegra30_super_clk_init(void)
990 /* SCLK */ 990 /* SCLK */
991 clk = tegra_clk_register_super_mux("sclk", sclk_parents, 991 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
992 ARRAY_SIZE(sclk_parents), 992 ARRAY_SIZE(sclk_parents),
993 CLK_SET_RATE_PARENT, 993 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
994 clk_base + SCLK_BURST_POLICY, 994 clk_base + SCLK_BURST_POLICY,
995 0, 4, 0, 0, NULL); 995 0, 4, 0, 0, NULL);
996 clks[TEGRA30_CLK_SCLK] = clk; 996 clks[TEGRA30_CLK_SCLK] = clk;
@@ -1060,9 +1060,6 @@ static void __init tegra30_periph_clk_init(void)
1060 CLK_SET_RATE_NO_REPARENT, 1060 CLK_SET_RATE_NO_REPARENT,
1061 clk_base + CLK_SOURCE_EMC, 1061 clk_base + CLK_SOURCE_EMC,
1062 30, 2, 0, &emc_lock); 1062 30, 2, 0, &emc_lock);
1063 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
1064 57, periph_clk_enb_refcnt);
1065 clks[TEGRA30_CLK_EMC] = clk;
1066 1063
1067 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 1064 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
1068 &emc_lock); 1065 &emc_lock);
@@ -1252,10 +1249,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1252 { TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1249 { TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 },
1253 { TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1250 { TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 },
1254 { TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1251 { TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 },
1255 { TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1 },
1256 { TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1 },
1257 { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 }, 1252 { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 },
1258 { TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1 },
1259 { TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1 }, 1253 { TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1 },
1260 { TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1254 { TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0 },
1261 { TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1255 { TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0 },
@@ -1272,6 +1266,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1272 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1266 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
1273 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1267 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
1274 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, 1268 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
1269 { TEGRA30_CLK_VDE, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
1275 /* must be the last entry */ 1270 /* must be the last entry */
1276 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, 1271 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
1277}; 1272};
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 3b2763df51c2..ba7e20e6a82b 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -812,4 +812,11 @@ int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
812u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); 812u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
813int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); 813int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
814 814
815/* Combined read fence with delay */
816#define fence_udelay(delay, reg) \
817 do { \
818 readl(reg); \
819 udelay(delay); \
820 } while (0)
821
815#endif /* TEGRA_CLK_H */ 822#endif /* TEGRA_CLK_H */
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c
index b6a436594a19..caf45cf7aa8e 100644
--- a/drivers/soc/samsung/pm_domains.c
+++ b/drivers/soc/samsung/pm_domains.c
@@ -147,6 +147,12 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
147 return kstrdup_const(name, GFP_KERNEL); 147 return kstrdup_const(name, GFP_KERNEL);
148} 148}
149 149
150static const char *soc_force_no_clk[] = {
151 "samsung,exynos5250-clock",
152 "samsung,exynos5420-clock",
153 "samsung,exynos5800-clock",
154};
155
150static __init int exynos4_pm_init_power_domain(void) 156static __init int exynos4_pm_init_power_domain(void)
151{ 157{
152 struct device_node *np; 158 struct device_node *np;
@@ -183,6 +189,11 @@ static __init int exynos4_pm_init_power_domain(void)
183 pd->pd.power_on = exynos_pd_power_on; 189 pd->pd.power_on = exynos_pd_power_on;
184 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; 190 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
185 191
192 for (i = 0; i < ARRAY_SIZE(soc_force_no_clk); i++)
193 if (of_find_compatible_node(NULL, NULL,
194 soc_force_no_clk[i]))
195 goto no_clk;
196
186 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { 197 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
187 char clk_name[8]; 198 char clk_name[8];
188 199
diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index 941ac70e7f30..555937a25504 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -67,5 +67,6 @@
67#define CLKID_AO_I2C 58 67#define CLKID_AO_I2C 58
68#define CLKID_SD_EMMC_B_CLK0 59 68#define CLKID_SD_EMMC_B_CLK0 59
69#define CLKID_SD_EMMC_C_CLK0 60 69#define CLKID_SD_EMMC_C_CLK0 60
70#define CLKID_HIFI_PLL 69
70 71
71#endif /* __AXG_CLKC_H */ 72#endif /* __AXG_CLKC_H */
diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
index 6422314e46eb..6b77e721f6b1 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -95,7 +95,7 @@
95#define TEGRA210_CLK_CSITE 73 95#define TEGRA210_CLK_CSITE 73
96/* 74 */ 96/* 74 */
97/* 75 */ 97/* 75 */
98/* 76 */ 98#define TEGRA210_CLK_LA 76
99/* 77 */ 99/* 77 */
100#define TEGRA210_CLK_SOC_THERM 78 100#define TEGRA210_CLK_SOC_THERM 78
101#define TEGRA210_CLK_DTV 79 101#define TEGRA210_CLK_DTV 79
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index f711be6e8c44..210a890008f9 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -399,6 +399,7 @@ struct clk_divider {
399 spinlock_t *lock; 399 spinlock_t *lock;
400}; 400};
401 401
402#define clk_div_mask(width) ((1 << (width)) - 1)
402#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) 403#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
403 404
404#define CLK_DIVIDER_ONE_BASED BIT(0) 405#define CLK_DIVIDER_ONE_BASED BIT(0)
@@ -419,6 +420,10 @@ long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
419 unsigned long rate, unsigned long *prate, 420 unsigned long rate, unsigned long *prate,
420 const struct clk_div_table *table, 421 const struct clk_div_table *table,
421 u8 width, unsigned long flags); 422 u8 width, unsigned long flags);
423long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
424 unsigned long rate, unsigned long *prate,
425 const struct clk_div_table *table, u8 width,
426 unsigned long flags, unsigned int val);
422int divider_get_val(unsigned long rate, unsigned long parent_rate, 427int divider_get_val(unsigned long rate, unsigned long parent_rate,
423 const struct clk_div_table *table, u8 width, 428 const struct clk_div_table *table, u8 width,
424 unsigned long flags); 429 unsigned long flags);
@@ -449,8 +454,9 @@ void clk_hw_unregister_divider(struct clk_hw *hw);
449 * 454 *
450 * @hw: handle between common and hardware-specific interfaces 455 * @hw: handle between common and hardware-specific interfaces
451 * @reg: register controlling multiplexer 456 * @reg: register controlling multiplexer
457 * @table: array of register values corresponding to the parent index
452 * @shift: shift to multiplexer bit field 458 * @shift: shift to multiplexer bit field
453 * @width: width of mutliplexer bit field 459 * @mask: mask of mutliplexer bit field
454 * @flags: hardware-specific flags 460 * @flags: hardware-specific flags
455 * @lock: register lock 461 * @lock: register lock
456 * 462 *
@@ -510,6 +516,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
510 void __iomem *reg, u8 shift, u32 mask, 516 void __iomem *reg, u8 shift, u32 mask,
511 u8 clk_mux_flags, u32 *table, spinlock_t *lock); 517 u8 clk_mux_flags, u32 *table, spinlock_t *lock);
512 518
519int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
520 unsigned int val);
521unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index);
522
513void clk_unregister_mux(struct clk *clk); 523void clk_unregister_mux(struct clk *clk);
514void clk_hw_unregister_mux(struct clk_hw *hw); 524void clk_hw_unregister_mux(struct clk_hw *hw);
515 525
@@ -774,6 +784,17 @@ static inline long divider_round_rate(struct clk_hw *hw, unsigned long rate,
774 rate, prate, table, width, flags); 784 rate, prate, table, width, flags);
775} 785}
776 786
787static inline long divider_ro_round_rate(struct clk_hw *hw, unsigned long rate,
788 unsigned long *prate,
789 const struct clk_div_table *table,
790 u8 width, unsigned long flags,
791 unsigned int val)
792{
793 return divider_ro_round_rate_parent(hw, clk_hw_get_parent(hw),
794 rate, prate, table, width, flags,
795 val);
796}
797
777/* 798/*
778 * FIXME clock api without lock protection 799 * FIXME clock api without lock protection
779 */ 800 */
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index d23c9cf26993..afb9edfa5d58 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -128,5 +128,6 @@ extern void tegra210_sata_pll_hw_sequence_start(void);
128extern void tegra210_set_sata_pll_seq_sw(bool state); 128extern void tegra210_set_sata_pll_seq_sw(bool state);
129extern void tegra210_put_utmipll_in_iddq(void); 129extern void tegra210_put_utmipll_in_iddq(void);
130extern void tegra210_put_utmipll_out_iddq(void); 130extern void tegra210_put_utmipll_out_iddq(void);
131extern int tegra210_clk_handle_mbist_war(unsigned int id);
131 132
132#endif /* __LINUX_CLK_TEGRA_H_ */ 133#endif /* __LINUX_CLK_TEGRA_H_ */