diff options
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> | |||
12189 | M: Chanwoo Choi <cw00.choi@samsung.com> | 12189 | M: Chanwoo Choi <cw00.choi@samsung.com> |
12190 | S: Supported | 12190 | S: Supported |
12191 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 12191 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
12192 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git | ||
12192 | F: drivers/clk/samsung/ | 12193 | F: drivers/clk/samsung/ |
12193 | F: include/dt-bindings/clock/exynos*.h | 12194 | F: include/dt-bindings/clock/exynos*.h |
12194 | F: Documentation/devicetree/bindings/clock/exynos*.txt | 12195 | F: 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 | |||
33 | static unsigned int _get_table_maxdiv(const struct clk_div_table *table, | 31 | static 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 | ||
68 | static unsigned int _get_table_div(const struct clk_div_table *table, | 66 | static 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 | } |
345 | EXPORT_SYMBOL_GPL(divider_round_rate_parent); | 343 | EXPORT_SYMBOL_GPL(divider_round_rate_parent); |
346 | 344 | ||
345 | long 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 | } | ||
364 | EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent); | ||
365 | |||
366 | |||
347 | static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, | 367 | static 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 | } |
381 | EXPORT_SYMBOL_GPL(divider_get_val); | 403 | EXPORT_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 | ||
29 | static u8 clk_mux_get_parent(struct clk_hw *hw) | 29 | int 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 | } |
54 | EXPORT_SYMBOL_GPL(clk_mux_val_to_index); | ||
65 | 55 | ||
66 | static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | 56 | unsigned 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 | } | ||
72 | EXPORT_SYMBOL_GPL(clk_mux_index_to_val); | ||
73 | |||
74 | static 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 | |||
85 | static 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); |
3014 | out: | 3021 | out: |
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 | ||
6 | config COMMON_CLK_REGMAP_MESON | ||
7 | bool | ||
8 | select REGMAP | ||
9 | |||
6 | config COMMON_CLK_MESON8B | 10 | config 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 | ||
5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o | 5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o |
6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o | 6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o |
7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o | 7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o |
8 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o | 8 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o |
9 | obj-$(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 | ||
22 | static DEFINE_SPINLOCK(meson_clk_lock); | 24 | static DEFINE_SPINLOCK(meson_clk_lock); |
23 | 25 | ||
24 | static const struct pll_rate_table sys_pll_rate_table[] = { | 26 | static 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 | |||
116 | static 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 | ||
141 | static struct meson_clk_pll axg_sys_pll = { | 67 | static 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 | ||
260 | static struct pll_params_table axg_gp0_params_table[] = { | 195 | static 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 | ||
269 | static struct meson_clk_pll axg_gp0_pll = { | 204 | static 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 | ||
248 | static 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 | |||
257 | static 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 | ||
303 | static struct clk_fixed_factor axg_fclk_div2 = { | 302 | static 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 | ||
314 | static struct clk_fixed_factor axg_fclk_div3 = { | 313 | static 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 | |||
326 | static 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 | ||
325 | static struct clk_fixed_factor axg_fclk_div4 = { | 337 | static 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 | |||
350 | static 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 | ||
336 | static struct clk_fixed_factor axg_fclk_div5 = { | 361 | static 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 | |||
374 | static 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 | ||
347 | static struct clk_fixed_factor axg_fclk_div7 = { | 385 | static 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 | |||
398 | static 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 | ||
358 | static struct meson_clk_mpll axg_mpll0 = { | 409 | static 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, | 422 | static 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, | 436 | static 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 | ||
393 | static struct meson_clk_mpll axg_mpll1 = { | 473 | static 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, | 487 | static 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 | ||
423 | static struct meson_clk_mpll axg_mpll2 = { | 519 | static 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, | 533 | static 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 | ||
453 | static struct meson_clk_mpll axg_mpll3 = { | 565 | static 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 | |||
579 | static 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, | 611 | static 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 | */ | ||
488 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; | 625 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; |
489 | static const char * const clk81_parent_names[] = { | 626 | static 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 | ||
494 | static struct clk_mux axg_mpeg_clk_sel = { | 631 | static 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 | ||
509 | static struct clk_divider axg_mpeg_clk_div = { | 646 | static 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 | ||
523 | static struct clk_gate axg_clk81 = { | 661 | static 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 */ |
548 | static struct clk_mux axg_sd_emmc_b_clk0_sel = { | 687 | static 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 | ||
562 | static struct clk_divider axg_sd_emmc_b_clk0_div = { | 702 | static 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 | ||
577 | static struct clk_gate axg_sd_emmc_b_clk0 = { | 718 | static 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 */ |
591 | static struct clk_mux axg_sd_emmc_c_clk0_sel = { | 733 | static 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 | ||
605 | static struct clk_divider axg_sd_emmc_c_clk0_div = { | 748 | static 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 | ||
620 | static struct clk_gate axg_sd_emmc_c_clk0 = { | 764 | static 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 | 915 | static struct clk_regmap *const axg_clk_regmaps[] = { | |
760 | static struct meson_clk_pll *const axg_clk_plls[] = { | ||
761 | &axg_fixed_pll, | ||
762 | &axg_sys_pll, | ||
763 | &axg_gp0_pll, | ||
764 | }; | ||
765 | |||
766 | static struct meson_clk_mpll *const axg_clk_mplls[] = { | ||
767 | &axg_mpll0, | ||
768 | &axg_mpll1, | ||
769 | &axg_mpll2, | ||
770 | &axg_mpll3, | ||
771 | }; | ||
772 | |||
773 | static 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 | |||
823 | static 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 | |||
829 | static 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, | |
835 | struct 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, | |
849 | static 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 | ||
863 | static const struct of_device_id clkc_match_table[] = { | 989 | static 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 | ||
994 | static const struct regmap_config clkc_regmap_config = { | ||
995 | .reg_bits = 32, | ||
996 | .val_bits = 32, | ||
997 | .reg_stride = 4, | ||
998 | }; | ||
999 | |||
868 | static int axg_clkc_probe(struct platform_device *pdev) | 1000 | static 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 | ||
930 | static struct platform_driver axg_driver = { | 1059 | static 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, \ | 31 | static inline struct meson_clk_audio_div_data * |
32 | struct meson_clk_audio_divider, hw) | 32 | meson_clk_audio_div_data(struct clk_regmap *clk) |
33 | { | ||
34 | return (struct meson_clk_audio_div_data *)clk->data; | ||
35 | } | ||
33 | 36 | ||
34 | static int _div_round(unsigned long parent_rate, unsigned long rate, | 37 | static 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 | ||
48 | static int _valid_divider(struct clk_hw *hw, int divider) | 51 | static 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) | |||
61 | static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, | 58 | static 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 | |||
57 | static 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 | |||
66 | static 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 | |||
93 | static 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 */ | ||
116 | static 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 */ | ||
138 | static 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 | */ | ||
159 | int 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 | |||
174 | const 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) | 71 | static inline struct meson_clk_mpll_data * |
72 | meson_clk_mpll_data(struct clk_regmap *clk) | ||
73 | { | ||
74 | return (struct meson_clk_mpll_data *)clk->data; | ||
75 | } | ||
72 | 76 | ||
73 | static long rate_from_params(unsigned long parent_rate, | 77 | static 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 | ||
85 | static void params_from_rate(unsigned long requested_rate, | 89 | static 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, | |||
105 | static unsigned long mpll_recalc_rate(struct clk_hw *hw, | 109 | static 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 | ||
128 | static long mpll_round_rate(struct clk_hw *hw, | 124 | static 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 | ||
184 | static 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 | |||
208 | static 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 | ||
215 | static void mpll_disable(struct clk_hw *hw) | ||
216 | { | ||
217 | mpll_enable_core(hw, 0); | ||
218 | } | ||
219 | |||
220 | static 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 | |||
234 | const struct clk_ops meson_clk_mpll_ro_ops = { | 173 | const 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 | ||
240 | const struct clk_ops meson_clk_mpll_ops = { | 178 | const 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) | 48 | static inline struct meson_clk_pll_data * |
45 | #define MESON_PLL_LOCK BIT(31) | 49 | meson_clk_pll_data(struct clk_regmap *clk) |
46 | |||
47 | #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) | ||
48 | |||
49 | static 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 | ||
90 | static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | 54 | static 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 | ||
106 | static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll, | 72 | static 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 */ | 99 | static u16 __pll_params_with_frac(unsigned long rate, |
120 | static 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 | |||
119 | static const struct pll_rate_table * | ||
120 | meson_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 | ||
143 | static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, | 144 | static 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) { | 169 | static 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 | ||
159 | static void meson_clk_pll_init_params(struct meson_clk_pll *pll) | 186 | static 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 | ||
168 | static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 199 | static 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 | ||
246 | const struct clk_ops meson_clk_pll_ops = { | 253 | const 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 | |||
7 | static 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 | |||
19 | static int clk_regmap_gate_enable(struct clk_hw *hw) | ||
20 | { | ||
21 | return clk_regmap_gate_endisable(hw, 1); | ||
22 | } | ||
23 | |||
24 | static void clk_regmap_gate_disable(struct clk_hw *hw) | ||
25 | { | ||
26 | clk_regmap_gate_endisable(hw, 0); | ||
27 | } | ||
28 | |||
29 | static 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 | |||
44 | const 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 | }; | ||
49 | EXPORT_SYMBOL_GPL(clk_regmap_gate_ops); | ||
50 | |||
51 | static 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 | |||
70 | static 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 | |||
96 | static 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 | |||
116 | const 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 | }; | ||
121 | EXPORT_SYMBOL_GPL(clk_regmap_divider_ops); | ||
122 | |||
123 | const 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 | }; | ||
127 | EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops); | ||
128 | |||
129 | static 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 | |||
145 | static 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 | |||
156 | const 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 | }; | ||
161 | EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); | ||
162 | |||
163 | const struct clk_ops clk_regmap_mux_ro_ops = { | ||
164 | .get_parent = clk_regmap_mux_get_parent, | ||
165 | }; | ||
166 | EXPORT_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 | */ | ||
21 | struct 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 | */ | ||
39 | struct clk_regmap_gate_data { | ||
40 | unsigned int offset; | ||
41 | u8 bit_idx; | ||
42 | u8 flags; | ||
43 | }; | ||
44 | |||
45 | static inline struct clk_regmap_gate_data * | ||
46 | clk_get_regmap_gate_data(struct clk_regmap *clk) | ||
47 | { | ||
48 | return (struct clk_regmap_gate_data *)clk->data; | ||
49 | } | ||
50 | |||
51 | extern 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 | */ | ||
64 | struct 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 | |||
72 | static inline struct clk_regmap_div_data * | ||
73 | clk_get_regmap_div_data(struct clk_regmap *clk) | ||
74 | { | ||
75 | return (struct clk_regmap_div_data *)clk->data; | ||
76 | } | ||
77 | |||
78 | extern const struct clk_ops clk_regmap_divider_ops; | ||
79 | extern 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 | */ | ||
94 | struct clk_regmap_mux_data { | ||
95 | unsigned int offset; | ||
96 | u32 *table; | ||
97 | u32 mask; | ||
98 | u8 shift; | ||
99 | u8 flags; | ||
100 | }; | ||
101 | |||
102 | static inline struct clk_regmap_mux_data * | ||
103 | clk_get_regmap_mux_data(struct clk_regmap *clk) | ||
104 | { | ||
105 | return (struct clk_regmap_mux_data *)clk->data; | ||
106 | } | ||
107 | |||
108 | extern const struct clk_ops clk_regmap_mux_ops; | ||
109 | extern 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 | ||
41 | static 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 | |||
49 | static 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 | |||
38 | struct pll_rate_table { | 57 | struct 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 | |||
65 | struct 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 | ||
76 | struct 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 | ||
87 | struct meson_clk_pll { | 76 | struct 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 | ||
103 | struct meson_clk_cpu { | 93 | struct 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 | |||
111 | int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event, | ||
112 | void *data); | ||
113 | |||
114 | struct 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 | ||
125 | struct meson_clk_audio_divider { | 102 | struct 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) \ |
134 | struct clk_gate _name = { \ | 108 | struct 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 | |||
13 | static 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 | |||
21 | static 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 | |||
29 | static 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 | |||
42 | const 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 | ||
67 | static DEFINE_SPINLOCK(gxbb_aoclk_lock); | ||
68 | |||
69 | struct gxbb_aoclk_reset_controller { | 68 | struct 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) \ |
90 | static struct aoclk_gate_regmap _name##_ao = { \ | 89 | static 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); | |||
107 | GXBB_AO_GATE(ir_blaster, 6); | 108 | GXBB_AO_GATE(ir_blaster, 6); |
108 | 109 | ||
109 | static struct aoclk_cec_32k cec_32k_ao = { | 110 | static 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 | ||
129 | static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { | 129 | static 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 | ||
20 | struct 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 | |||
30 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; | 20 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; |
31 | 21 | ||
32 | struct aoclk_cec_32k { | 22 | struct 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 | ||
30 | static DEFINE_SPINLOCK(meson_clk_lock); | 33 | static DEFINE_SPINLOCK(meson_clk_lock); |
31 | 34 | ||
32 | static 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 | |||
124 | static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { | 35 | static 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 | ||
281 | static struct meson_clk_pll gxbb_fixed_pll = { | 192 | static 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 | ||
307 | static struct meson_clk_pll gxbb_hdmi_pll = { | 234 | static 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, | 245 | static 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, | 297 | static 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 | ||
343 | static struct meson_clk_pll gxbb_sys_pll = { | 355 | static 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 | ||
371 | struct pll_params_table gxbb_gp0_params_table[] = { | 392 | static 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 | ||
378 | static struct meson_clk_pll gxbb_gp0_pll = { | 399 | static 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 | ||
412 | struct pll_params_table gxl_gp0_params_table[] = { | 439 | static 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 | ||
421 | static struct meson_clk_pll gxl_gp0_pll = { | 448 | static 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 | ||
455 | static struct clk_fixed_factor gxbb_fclk_div2 = { | 493 | static 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 | ||
466 | static struct clk_fixed_factor gxbb_fclk_div3 = { | 504 | static 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 | |||
517 | static 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 | ||
477 | static struct clk_fixed_factor gxbb_fclk_div4 = { | 528 | static 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 | |||
541 | static 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 | ||
488 | static struct clk_fixed_factor gxbb_fclk_div5 = { | 552 | static 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 | |||
565 | static 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 | ||
499 | static struct clk_fixed_factor gxbb_fclk_div7 = { | 576 | static 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 | |||
589 | static 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 | ||
510 | static struct meson_clk_mpll gxbb_mpll0 = { | 600 | static 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, | 613 | static 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, | 627 | static 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 | ||
545 | static struct meson_clk_mpll gxbb_mpll1 = { | 659 | static 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, | 673 | static 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 | ||
575 | static struct meson_clk_mpll gxbb_mpll2 = { | 700 | static 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, | 714 | static 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 | /* | 741 | static 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 | ||
611 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; | 755 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; |
612 | static const char * const clk81_parent_names[] = { | 756 | static 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 | ||
617 | static struct clk_mux gxbb_mpeg_clk_sel = { | 761 | static 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 | ||
638 | static struct clk_divider gxbb_mpeg_clk_div = { | 781 | static 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 */ |
653 | static struct clk_gate gxbb_clk81 = { | 796 | static 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 | ||
666 | static struct clk_mux gxbb_sar_adc_clk_sel = { | 810 | static 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 | ||
680 | static struct clk_divider gxbb_sar_adc_clk_div = { | 825 | static 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 | ||
693 | static struct clk_gate gxbb_sar_adc_clk = { | 839 | static 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 | ||
711 | static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
712 | static const char * const gxbb_mali_0_1_parent_names[] = { | 858 | static 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 | ||
717 | static struct clk_mux gxbb_mali_0_sel = { | 863 | static 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 | ||
737 | static struct clk_divider gxbb_mali_0_div = { | 883 | static 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 | ||
751 | static struct clk_gate gxbb_mali_0 = { | 898 | static 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 | ||
764 | static struct clk_mux gxbb_mali_1_sel = { | 912 | static 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 | ||
784 | static struct clk_divider gxbb_mali_1_div = { | 932 | static 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 | ||
798 | static struct clk_gate gxbb_mali_1 = { | 947 | static 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 | ||
811 | static u32 mux_table_mali[] = {0, 1}; | ||
812 | static const char * const gxbb_mali_parent_names[] = { | 961 | static const char * const gxbb_mali_parent_names[] = { |
813 | "mali_0", "mali_1" | 962 | "mali_0", "mali_1" |
814 | }; | 963 | }; |
815 | 964 | ||
816 | static struct clk_mux gxbb_mali = { | 965 | static 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 | ||
831 | static struct clk_mux gxbb_cts_amclk_sel = { | 980 | static 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 | ||
847 | static struct meson_clk_audio_divider gxbb_cts_amclk_div = { | 996 | static 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 | ||
864 | static struct clk_gate gxbb_cts_amclk = { | 1014 | static 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 | ||
877 | static struct clk_mux gxbb_cts_mclk_i958_sel = { | 1028 | static 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 | ||
893 | static struct clk_divider gxbb_cts_mclk_i958_div = { | 1044 | static 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 | ||
908 | static struct clk_gate gxbb_cts_mclk_i958 = { | 1060 | static 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 | ||
921 | static struct clk_mux gxbb_cts_i958 = { | 1074 | static 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 | ||
939 | static struct clk_divider gxbb_32k_clk_div = { | 1093 | static 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 | ||
953 | static struct clk_gate gxbb_32k_clk = { | 1108 | static 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 | ||
970 | static struct clk_mux gxbb_32k_clk_sel = { | 1126 | static 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 */ |
996 | static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { | 1153 | static 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 | ||
1010 | static struct clk_divider gxbb_sd_emmc_a_clk0_div = { | 1168 | static 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 | ||
1025 | static struct clk_gate gxbb_sd_emmc_a_clk0 = { | 1184 | static 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 */ |
1039 | static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { | 1199 | static 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 | ||
1053 | static struct clk_divider gxbb_sd_emmc_b_clk0_div = { | 1214 | static 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 | ||
1068 | static struct clk_gate gxbb_sd_emmc_b_clk0 = { | 1230 | static 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 */ |
1082 | static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { | 1245 | static 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 | ||
1096 | static struct clk_divider gxbb_sd_emmc_c_clk0_div = { | 1260 | static 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 | ||
1111 | static struct clk_gate gxbb_sd_emmc_c_clk0 = { | 1276 | static 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 | ||
1126 | static u32 mux_table_vpu[] = {0, 1, 2, 3}; | ||
1127 | static const char * const gxbb_vpu_parent_names[] = { | 1292 | static 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 | ||
1131 | static struct clk_mux gxbb_vpu_0_sel = { | 1296 | static 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 | ||
1150 | static struct clk_divider gxbb_vpu_0_div = { | 1315 | static 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 | ||
1164 | static struct clk_gate gxbb_vpu_0 = { | 1330 | static 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 | ||
1177 | static struct clk_mux gxbb_vpu_1_sel = { | 1344 | static 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 | ||
1196 | static struct clk_divider gxbb_vpu_1_div = { | 1363 | static 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 | ||
1210 | static struct clk_gate gxbb_vpu_1 = { | 1378 | static 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 | ||
1223 | static struct clk_mux gxbb_vpu = { | 1392 | static 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 | ||
1243 | static u32 mux_table_vapb[] = {0, 1, 2, 3}; | ||
1244 | static const char * const gxbb_vapb_parent_names[] = { | 1413 | static 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 | ||
1248 | static struct clk_mux gxbb_vapb_0_sel = { | 1417 | static 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 | ||
1267 | static struct clk_divider gxbb_vapb_0_div = { | 1436 | static 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 | ||
1281 | static struct clk_gate gxbb_vapb_0 = { | 1451 | static 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 | ||
1294 | static struct clk_mux gxbb_vapb_1_sel = { | 1465 | static 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 | ||
1313 | static struct clk_divider gxbb_vapb_1_div = { | 1484 | static 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 | ||
1327 | static struct clk_gate gxbb_vapb_1 = { | 1499 | static 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 | ||
1340 | static struct clk_mux gxbb_vapb_sel = { | 1513 | static 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 | ||
1358 | static struct clk_gate gxbb_vapb = { | 1532 | static 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 = { | |||
1609 | static struct clk_hw_onecell_data gxl_hw_onecell_data = { | 1794 | static 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 */ | 1950 | static struct clk_regmap *const gxbb_clk_regmaps[] = { |
1757 | |||
1758 | static 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 | |||
1765 | static 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 | ||
1772 | static struct meson_clk_mpll *const gxbb_clk_mplls[] = { | 1955 | static 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 | ||
1778 | static struct clk_gate *const gxbb_clk_gates[] = { | 1960 | static 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, | |
1877 | static 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, | |
1898 | static 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 | |||
1914 | static 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 | ||
1918 | struct clkc_data { | 2105 | struct 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 | ||
1934 | static const struct clkc_data gxbb_clkc_data = { | 2111 | static 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 | ||
1950 | static const struct clkc_data gxl_clkc_data = { | 2117 | static 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 | ||
2129 | static const struct regmap_config clkc_regmap_config = { | ||
2130 | .reg_bits = 32, | ||
2131 | .val_bits = 32, | ||
2132 | .reg_stride = 4, | ||
2133 | }; | ||
2134 | |||
1972 | static int gxbb_clkc_probe(struct platform_device *pdev) | 2135 | static 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 | |||
2034 | iounmap: | ||
2035 | iounmap(clk_base); | ||
2036 | return ret; | ||
2037 | } | 2202 | } |
2038 | 2203 | ||
2039 | static struct platform_driver gxbb_driver = { | 2204 | static 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 | ||
35 | static DEFINE_SPINLOCK(meson_clk_lock); | 37 | static 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 | ||
100 | static 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 | |||
114 | static struct clk_fixed_rate meson8b_xtal = { | 102 | static 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 | ||
123 | static struct meson_clk_pll meson8b_fixed_pll = { | 111 | static 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 | ||
149 | static struct meson_clk_pll meson8b_vid_pll = { | 153 | static 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 | ||
175 | static struct meson_clk_pll meson8b_sys_pll = { | 190 | static 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 | ||
203 | static struct clk_fixed_factor meson8b_fclk_div2 = { | 228 | static 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 | ||
214 | static struct clk_fixed_factor meson8b_fclk_div3 = { | 239 | static 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 | |||
252 | static 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 | ||
225 | static struct clk_fixed_factor meson8b_fclk_div4 = { | 263 | static 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 | |||
276 | static 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 | ||
236 | static struct clk_fixed_factor meson8b_fclk_div5 = { | 287 | static 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 | |||
300 | static 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 | ||
247 | static struct clk_fixed_factor meson8b_fclk_div7 = { | 311 | static 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 | |||
324 | static 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 | ||
258 | static struct meson_clk_mpll meson8b_mpll0 = { | 335 | static 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, | 348 | static 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, | 362 | static 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 | ||
293 | static struct meson_clk_mpll meson8b_mpll1 = { | 394 | static 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, | 408 | static 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 | ||
323 | static struct meson_clk_mpll meson8b_mpll2 = { | 435 | static 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, | 449 | static 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 | /* | 476 | static 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 | }, |
358 | static 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 | ||
370 | static u32 mux_table_clk81[] = { 6, 5, 7 }; | 490 | static u32 mux_table_clk81[] = { 6, 5, 7 }; |
371 | 491 | static struct clk_regmap meson8b_mpeg_clk_sel = { | |
372 | struct 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 | ||
394 | struct clk_divider meson8b_mpeg_clk_div = { | 512 | static 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 | ||
408 | struct clk_gate meson8b_clk81 = { | 526 | static 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 | |||
540 | static 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 | |||
556 | static 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 | |||
568 | static 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 | |||
580 | static 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 | |||
591 | static 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 | |||
608 | static 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 | |||
626 | static 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 | ||
607 | static struct meson_clk_pll *const meson8b_clk_plls[] = { | 842 | static struct clk_regmap *const meson8b_clk_regmaps[] = { |
608 | &meson8b_fixed_pll, | ||
609 | &meson8b_vid_pll, | ||
610 | &meson8b_sys_pll, | ||
611 | }; | ||
612 | |||
613 | static struct meson_clk_mpll *const meson8b_clk_mplls[] = { | ||
614 | &meson8b_mpll0, | ||
615 | &meson8b_mpll1, | ||
616 | &meson8b_mpll2, | ||
617 | }; | ||
618 | |||
619 | static 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 | |||
700 | static struct clk_mux *const meson8b_clk_muxes[] = { | ||
701 | &meson8b_mpeg_clk_sel, | ||
702 | }; | ||
703 | |||
704 | static 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 | ||
708 | static const struct meson8b_clk_reset_line { | 944 | static 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 | ||
1043 | static const struct regmap_config clkc_regmap_config = { | ||
1044 | .reg_bits = 32, | ||
1045 | .val_bits = 32, | ||
1046 | .reg_stride = 4, | ||
1047 | }; | ||
1048 | |||
807 | static int meson8b_clkc_probe(struct platform_device *pdev) | 1049 | static 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 | ||
885 | static const struct of_device_id meson8b_clkc_match_table[] = { | 1084 | static 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 = ÷r->clkr; | 30 | struct clk_regmap *clkr = ÷r->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 | ||
49 | static long div_round_rate(struct clk_hw *hw, unsigned long rate, | 41 | static 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 | |||
8 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o | 8 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o |
9 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o | 9 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o |
10 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o | 10 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o |
11 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o | ||
11 | obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o | 12 | obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o |
12 | obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o | 13 | obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o |
13 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o | 14 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o |
15 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o | ||
14 | obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o | 16 | obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o |
15 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o | 17 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o |
16 | obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o | 18 | obj-$(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 */ |
672 | static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = { | 672 | static 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 */ |
694 | static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = { | 694 | static 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 */ |
713 | static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = { | 713 | static 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 */ |
1268 | static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = { | 1268 | static 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 | ||
1281 | static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = { | 1281 | static 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 | ||
1292 | static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = { | 1292 | static 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 | ||
1301 | static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = { | 1301 | static 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 | ||
1321 | static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = { | 1321 | static 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 | ||
1332 | static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = { | 1333 | static 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 | |||
15 | static struct samsung_clk_provider *ctx; | ||
16 | static const struct exynos5_subcmu_info *cmu; | ||
17 | static int nr_cmus; | ||
18 | |||
19 | static 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 | |||
30 | static 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 | |||
39 | static 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 | */ | ||
57 | void 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 | |||
72 | static 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 | |||
85 | static 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 | |||
98 | static 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 | |||
117 | static 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 | |||
124 | static 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 | |||
133 | static 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 | |||
150 | static 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 | |||
167 | static 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 | |||
174 | static 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 | |||
183 | static 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 | } | ||
189 | core_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 | |||
6 | struct exynos5_subcmu_reg_dump { | ||
7 | u32 offset; | ||
8 | u32 value; | ||
9 | u32 mask; | ||
10 | u32 save; | ||
11 | }; | ||
12 | |||
13 | struct 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 | |||
23 | void 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 | ||
693 | static 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 | |||
711 | static 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 | |||
717 | static 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 | |||
701 | static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { | 725 | static 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 | ||
710 | static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = { | 734 | static 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 | ||
724 | static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = { | 748 | static 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 | ||
745 | static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { | 769 | static 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 | } |
868 | CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); | 893 | CLK_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 | */ |
25 | static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = { | 25 | static 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 | */ |
58 | static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = { | 58 | static 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 | ||
228 | static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = { | 228 | static 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 | ||
241 | static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { | 241 | static 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 | |||
1240 | static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = { | ||
1241 | DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2), | ||
1242 | }; | ||
1243 | |||
1244 | static 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 | |||
1258 | static 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 | |||
1266 | static 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 | |||
1271 | static 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 | |||
1280 | static 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 | |||
1287 | static 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 | |||
1291 | static 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), | 1297 | static 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 | |||
1303 | static 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 | ||
1265 | static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = { | 1331 | static 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 | ||
1287 | static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { | 1353 | static 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 | ||
1302 | static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { | 1371 | static 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 | } |
1483 | CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); | 1554 | CLK_OF_DECLARE_DRIVER(exynos5420_clk, "samsung,exynos5420-clock", |
1555 | exynos5420_clk_init); | ||
1484 | 1556 | ||
1485 | static void __init exynos5800_clk_init(struct device_node *np) | 1557 | static 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 | } |
1489 | CLK_OF_DECLARE(exynos5800_clk, "samsung,exynos5800-clock", exynos5800_clk_init); | 1561 | CLK_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 | */ |
705 | static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = { | 705 | static 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 */ |
758 | static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = { | 758 | static 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 | ||
142 | static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = { | 142 | static 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 | ||
96 | PNAME(fclk_p) = { "mpll", "div_slow" }; | 96 | PNAME(fclk_p) = { "mpll", "div_slow" }; |
97 | 97 | ||
98 | struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { | 98 | static 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 | ||
114 | struct samsung_div_clock s3c2410_common_dividers[] __initdata = { | 114 | static 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 | ||
119 | struct samsung_gate_clock s3c2410_common_gates[] __initdata = { | 119 | static 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 */ |
138 | struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { | 138 | static 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 = { | |||
162 | static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { | 162 | static 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 | ||
203 | struct samsung_div_clock s3c2410_dividers[] __initdata = { | 203 | static 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 | ||
207 | struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = { | 207 | static 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 | ||
218 | struct samsung_clock_alias s3c2410_aliases[] __initdata = { | 218 | static 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 | ||
230 | static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = { | 230 | static 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 = { | |||
269 | PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; | 269 | PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; |
270 | PNAME(armclk_p) = { "fclk", "hclk" }; | 270 | PNAME(armclk_p) = { "fclk", "hclk" }; |
271 | 271 | ||
272 | struct samsung_mux_clock s3c244x_common_muxes[] __initdata = { | 272 | static 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 | ||
277 | struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = { | 277 | static 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 | ||
294 | struct samsung_div_clock s3c244x_common_dividers[] __initdata = { | 294 | static 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 | ||
302 | struct samsung_gate_clock s3c244x_common_gates[] __initdata = { | 302 | static 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 | ||
306 | struct samsung_clock_alias s3c244x_common_aliases[] __initdata = { | 306 | static 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 | ||
319 | PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; | 319 | PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; |
320 | 320 | ||
321 | struct samsung_mux_clock s3c2440_muxes[] __initdata = { | 321 | static 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 | ||
325 | struct samsung_gate_clock s3c2440_gates[] __initdata = { | 325 | static 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 | ||
331 | struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = { | 331 | static 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 | ||
335 | PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; | 335 | PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; |
336 | 336 | ||
337 | struct samsung_mux_clock s3c2442_muxes[] __initdata = { | 337 | static 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 |
346 | struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { | 346 | static 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 | ||
469 | static void __init s3c2410_clk_init(struct device_node *np) | 469 | static 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 | } |
473 | CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); | 473 | CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); |
474 | 474 | ||
475 | static void __init s3c2440_clk_init(struct device_node *np) | 475 | static 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 | } |
479 | CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); | 479 | CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); |
480 | 480 | ||
481 | static void __init s3c2442_clk_init(struct device_node *np) | 481 | static 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 | } |
485 | CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init); | 485 | CLK_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 */ | ||
31 | enum s3c2412_plls { | ||
32 | mpll, upll, | ||
33 | }; | ||
34 | |||
35 | static void __iomem *reg_base; | 30 | static 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 | ||
101 | struct samsung_div_clock s3c2412_dividers[] __initdata = { | 96 | static 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 | ||
113 | struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = { | 108 | static 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" }; | |||
130 | PNAME(mdivclk_p) = { "xti", "div_xti" }; | 125 | PNAME(mdivclk_p) = { "xti", "div_xti" }; |
131 | PNAME(armclk_p) = { "armdiv", "hclk" }; | 126 | PNAME(armclk_p) = { "armdiv", "hclk" }; |
132 | 127 | ||
133 | struct samsung_mux_clock s3c2412_muxes[] __initdata = { | 128 | static 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 | ||
146 | static struct samsung_pll_clock s3c2412_plls[] __initdata = { | 141 | static 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 | ||
153 | struct samsung_gate_clock s3c2412_gates[] __initdata = { | 146 | static 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 | ||
184 | struct samsung_clock_alias s3c2412_aliases[] __initdata = { | 177 | static 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 |
234 | struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { | 227 | static 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 | ||
297 | static void __init s3c2412_clk_init(struct device_node *np) | 290 | static 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 | } |
301 | CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init); | 294 | CLK_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 */ | ||
45 | enum s3c2443_plls { | ||
46 | mpll, epll, | ||
47 | }; | ||
48 | |||
49 | static void __iomem *reg_base; | 44 | static 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" }; | |||
113 | PNAME(armclk_p) = { "armdiv" , "hclk" }; | 108 | PNAME(armclk_p) = { "armdiv" , "hclk" }; |
114 | PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; | 109 | PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; |
115 | 110 | ||
116 | struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { | 111 | static 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 | ||
144 | struct samsung_div_clock s3c2443_common_dividers[] __initdata = { | 139 | static 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 | ||
157 | struct samsung_gate_clock s3c2443_common_gates[] __initdata = { | 152 | static 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 | ||
191 | struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { | 186 | static 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 | ||
227 | static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { | 222 | static 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 | ||
234 | PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; | 227 | PNAME(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 | ||
248 | struct samsung_div_clock s3c2416_dividers[] __initdata = { | 241 | static 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 | ||
254 | struct samsung_mux_clock s3c2416_muxes[] __initdata = { | 247 | static 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 | ||
260 | struct samsung_gate_clock s3c2416_gates[] __initdata = { | 253 | static 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 | ||
270 | struct samsung_clock_alias s3c2416_aliases[] __initdata = { | 263 | static 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 | ||
281 | static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { | 274 | static 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 | ||
288 | static struct clk_div_table armdiv_s3c2443_d[] = { | 279 | static 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 | ||
300 | struct samsung_div_clock s3c2443_dividers[] __initdata = { | 291 | static 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 | ||
305 | struct samsung_gate_clock s3c2443_gates[] __initdata = { | 296 | static 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 | ||
314 | struct samsung_clock_alias s3c2443_aliases[] __initdata = { | 305 | static 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" }; | |||
327 | PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; | 318 | PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; |
328 | PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; | 319 | PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; |
329 | 320 | ||
330 | struct samsung_div_clock s3c2450_dividers[] __initdata = { | 321 | static 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 | ||
337 | struct samsung_mux_clock s3c2450_muxes[] __initdata = { | 328 | static 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 | ||
343 | struct samsung_gate_clock s3c2450_gates[] __initdata = { | 334 | static 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 | ||
354 | struct samsung_clock_alias s3c2450_aliases[] __initdata = { | 345 | static 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 | */ |
377 | struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { | 368 | static 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 | ||
471 | static void __init s3c2416_clk_init(struct device_node *np) | 462 | static 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 | } |
475 | CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); | 466 | CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); |
476 | 467 | ||
477 | static void __init s3c2443_clk_init(struct device_node *np) | 468 | static 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 | } |
481 | CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); | 472 | CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); |
482 | 473 | ||
483 | static void __init s3c2450_clk_init(struct device_node *np) | 474 | static 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 | } |
487 | CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init); | 478 | CLK_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 */ | ||
60 | enum s3c64xx_plls { | ||
61 | apll, mpll, epll, | ||
62 | }; | ||
63 | |||
64 | static void __iomem *reg_base; | 59 | static void __iomem *reg_base; |
65 | static bool is_s3c6400; | 60 | static 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. */ |
366 | static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = { | 361 | static 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 | ||
1156 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | 1158 | static 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 | ||
581 | static unsigned long tegra20_clk_measure_input_freq(void) | 582 | static 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 | ||
285 | struct 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 | |||
294 | static struct clk **clks; | ||
295 | |||
258 | static void __iomem *clk_base; | 296 | static void __iomem *clk_base; |
259 | static void __iomem *pmc_base; | 297 | static void __iomem *pmc_base; |
298 | static void __iomem *ahub_base; | ||
299 | static void __iomem *dispa_base; | ||
300 | static void __iomem *vic_base; | ||
260 | 301 | ||
261 | static unsigned long osc_freq; | 302 | static unsigned long osc_freq; |
262 | static unsigned long pll_ref_freq; | 303 | static unsigned long pll_ref_freq; |
@@ -267,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock); | |||
267 | static DEFINE_SPINLOCK(pll_u_lock); | 308 | static DEFINE_SPINLOCK(pll_u_lock); |
268 | static DEFINE_SPINLOCK(sor1_lock); | 309 | static DEFINE_SPINLOCK(sor1_lock); |
269 | static DEFINE_SPINLOCK(emc_lock); | 310 | static DEFINE_SPINLOCK(emc_lock); |
311 | static DEFINE_MUTEX(lvl2_ovr_lock); | ||
270 | 312 | ||
271 | /* possible OSC frequencies in Hz */ | 313 | /* possible OSC frequencies in Hz */ |
272 | static unsigned long tegra210_input_freq[] = { | 314 | static 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 | } |
514 | EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); | 558 | EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); |
515 | 559 | ||
560 | static 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 | |||
571 | static 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 | |||
596 | static 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 | |||
614 | static 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 | |||
634 | static 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 | |||
516 | static inline void _pll_misc_chk_default(void __iomem *base, | 669 | static 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 | ||
2414 | static struct clk **clks; | ||
2415 | |||
2416 | static const char * const aclk_parents[] = { | 2567 | static 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 | ||
2572 | static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC }; | ||
2573 | static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG }; | ||
2574 | static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X, | ||
2575 | TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 }; | ||
2576 | static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA, | ||
2577 | TEGRA210_CLK_HOST1X}; | ||
2578 | static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, | ||
2579 | TEGRA210_CLK_XUSB_DEV }; | ||
2580 | static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, | ||
2581 | TEGRA210_CLK_XUSB_SS }; | ||
2582 | static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV, | ||
2583 | TEGRA210_CLK_XUSB_SS }; | ||
2584 | static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X, | ||
2585 | TEGRA210_CLK_PLL_D }; | ||
2586 | static 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 }; | ||
2590 | static const unsigned int vic_slcg_clkids[] = { TEGRA210_CLK_HOST1X }; | ||
2591 | |||
2592 | static 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 | |||
2679 | int 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 | |||
2421 | void tegra210_put_utmipll_in_iddq(void) | 2711 | void 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 | ||
2947 | static 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 | |||
2951 | static 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 | |||
2657 | static __init void tegra210_periph_clk_init(void __iomem *clk_base, | 2954 | static __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 | ||
3454 | static 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 | } |
3224 | CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); | 3577 | CLK_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 | ||
824 | static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; | 825 | static 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); | |||
812 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); | 812 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); |
813 | int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); | 813 | int 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 | ||
150 | static const char *soc_force_no_clk[] = { | ||
151 | "samsung,exynos5250-clock", | ||
152 | "samsung,exynos5420-clock", | ||
153 | "samsung,exynos5800-clock", | ||
154 | }; | ||
155 | |||
150 | static __init int exynos4_pm_init_power_domain(void) | 156 | static __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); |
423 | long 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); | ||
422 | int divider_get_val(unsigned long rate, unsigned long parent_rate, | 427 | int 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 | ||
519 | int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, | ||
520 | unsigned int val); | ||
521 | unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index); | ||
522 | |||
513 | void clk_unregister_mux(struct clk *clk); | 523 | void clk_unregister_mux(struct clk *clk); |
514 | void clk_hw_unregister_mux(struct clk_hw *hw); | 524 | void 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 | ||
787 | static 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); | |||
128 | extern void tegra210_set_sata_pll_seq_sw(bool state); | 128 | extern void tegra210_set_sata_pll_seq_sw(bool state); |
129 | extern void tegra210_put_utmipll_in_iddq(void); | 129 | extern void tegra210_put_utmipll_in_iddq(void); |
130 | extern void tegra210_put_utmipll_out_iddq(void); | 130 | extern void tegra210_put_utmipll_out_iddq(void); |
131 | extern int tegra210_clk_handle_mbist_war(unsigned int id); | ||
131 | 132 | ||
132 | #endif /* __LINUX_CLK_TEGRA_H_ */ | 133 | #endif /* __LINUX_CLK_TEGRA_H_ */ |