diff options
24 files changed, 926 insertions, 761 deletions
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h deleted file mode 100644 index 42ed4f2f5ce4..000000000000 --- a/arch/arm/mach-davinci/include/mach/clock.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-davinci/include/mach/clock.h | ||
3 | * | ||
4 | * Clock control driver for DaVinci - header file | ||
5 | * | ||
6 | * Authors: Vladimir Barinov <source@mvista.com> | ||
7 | * | ||
8 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | #ifndef __ASM_ARCH_DAVINCI_CLOCK_H | ||
14 | #define __ASM_ARCH_DAVINCI_CLOCK_H | ||
15 | |||
16 | struct clk; | ||
17 | |||
18 | int davinci_clk_reset_assert(struct clk *c); | ||
19 | int davinci_clk_reset_deassert(struct clk *c); | ||
20 | |||
21 | #endif | ||
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index fffbed5e263b..5b69e24a224f 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c | |||
@@ -303,24 +303,6 @@ static int davinci_lpsc_clk_reset(struct clk *clk, bool reset) | |||
303 | return 0; | 303 | return 0; |
304 | } | 304 | } |
305 | 305 | ||
306 | /* | ||
307 | * REVISIT: These exported functions can be removed after a non-DT lookup is | ||
308 | * added to the reset controller framework and the davinci-rproc driver is | ||
309 | * updated to use the generic reset controller framework. | ||
310 | */ | ||
311 | |||
312 | int davinci_clk_reset_assert(struct clk *clk) | ||
313 | { | ||
314 | return davinci_lpsc_clk_reset(clk, true); | ||
315 | } | ||
316 | EXPORT_SYMBOL(davinci_clk_reset_assert); | ||
317 | |||
318 | int davinci_clk_reset_deassert(struct clk *clk) | ||
319 | { | ||
320 | return davinci_lpsc_clk_reset(clk, false); | ||
321 | } | ||
322 | EXPORT_SYMBOL(davinci_clk_reset_deassert); | ||
323 | |||
324 | static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev, | 306 | static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev, |
325 | unsigned long id) | 307 | unsigned long id) |
326 | { | 308 | { |
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index a0ed41e73bde..5f6c860aa122 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c | |||
@@ -101,10 +101,16 @@ static const char * const mst_mux_parent_names[] = { | |||
101 | "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", | 101 | "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", |
102 | }; | 102 | }; |
103 | 103 | ||
104 | #define AXG_MST_MCLK_MUX(_name, _reg) \ | 104 | #define AXG_MST_MUX(_name, _reg, _flag) \ |
105 | AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \ | 105 | AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ |
106 | mst_mux_parent_names, CLK_SET_RATE_PARENT) | 106 | mst_mux_parent_names, CLK_SET_RATE_PARENT) |
107 | 107 | ||
108 | #define AXG_MST_MCLK_MUX(_name, _reg) \ | ||
109 | AXG_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) | ||
110 | |||
111 | #define AXG_MST_SYS_MUX(_name, _reg) \ | ||
112 | AXG_MST_MUX(_name, _reg, 0) | ||
113 | |||
108 | static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); | 114 | static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); |
109 | static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); | 115 | static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); |
110 | static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); | 116 | static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); |
@@ -112,13 +118,19 @@ static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); | |||
112 | static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); | 118 | static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); |
113 | static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); | 119 | static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); |
114 | static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); | 120 | static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); |
115 | static AXG_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); | ||
116 | static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); | 121 | static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); |
117 | static AXG_MST_MCLK_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | 122 | static AXG_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); |
123 | static AXG_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | ||
124 | |||
125 | #define AXG_MST_DIV(_name, _reg, _flag) \ | ||
126 | AXG_AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ | ||
127 | "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ | ||
128 | |||
129 | #define AXG_MST_MCLK_DIV(_name, _reg) \ | ||
130 | AXG_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) | ||
118 | 131 | ||
119 | #define AXG_MST_MCLK_DIV(_name, _reg) \ | 132 | #define AXG_MST_SYS_DIV(_name, _reg) \ |
120 | AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \ | 133 | AXG_MST_DIV(_name, _reg, 0) |
121 | "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ | ||
122 | 134 | ||
123 | static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); | 135 | static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); |
124 | static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); | 136 | static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); |
@@ -127,12 +139,12 @@ static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); | |||
127 | static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); | 139 | static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); |
128 | static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); | 140 | static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); |
129 | static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); | 141 | static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); |
130 | static AXG_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); | ||
131 | static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); | 142 | static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); |
132 | static AXG_MST_MCLK_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | 143 | static AXG_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); |
144 | static AXG_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | ||
133 | 145 | ||
134 | #define AXG_MST_MCLK_GATE(_name, _reg) \ | 146 | #define AXG_MST_MCLK_GATE(_name, _reg) \ |
135 | AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ | 147 | AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ |
136 | CLK_SET_RATE_PARENT) | 148 | CLK_SET_RATE_PARENT) |
137 | 149 | ||
138 | static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); | 150 | static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); |
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 00ce62ad6416..c981159b02c0 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c | |||
@@ -22,8 +22,13 @@ | |||
22 | 22 | ||
23 | static DEFINE_SPINLOCK(meson_clk_lock); | 23 | static DEFINE_SPINLOCK(meson_clk_lock); |
24 | 24 | ||
25 | static struct clk_regmap axg_fixed_pll = { | 25 | static struct clk_regmap axg_fixed_pll_dco = { |
26 | .data = &(struct meson_clk_pll_data){ | 26 | .data = &(struct meson_clk_pll_data){ |
27 | .en = { | ||
28 | .reg_off = HHI_MPLL_CNTL, | ||
29 | .shift = 30, | ||
30 | .width = 1, | ||
31 | }, | ||
27 | .m = { | 32 | .m = { |
28 | .reg_off = HHI_MPLL_CNTL, | 33 | .reg_off = HHI_MPLL_CNTL, |
29 | .shift = 0, | 34 | .shift = 0, |
@@ -34,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = { | |||
34 | .shift = 9, | 39 | .shift = 9, |
35 | .width = 5, | 40 | .width = 5, |
36 | }, | 41 | }, |
37 | .od = { | ||
38 | .reg_off = HHI_MPLL_CNTL, | ||
39 | .shift = 16, | ||
40 | .width = 2, | ||
41 | }, | ||
42 | .frac = { | 42 | .frac = { |
43 | .reg_off = HHI_MPLL_CNTL2, | 43 | .reg_off = HHI_MPLL_CNTL2, |
44 | .shift = 0, | 44 | .shift = 0, |
@@ -56,15 +56,39 @@ static struct clk_regmap axg_fixed_pll = { | |||
56 | }, | 56 | }, |
57 | }, | 57 | }, |
58 | .hw.init = &(struct clk_init_data){ | 58 | .hw.init = &(struct clk_init_data){ |
59 | .name = "fixed_pll", | 59 | .name = "fixed_pll_dco", |
60 | .ops = &meson_clk_pll_ro_ops, | 60 | .ops = &meson_clk_pll_ro_ops, |
61 | .parent_names = (const char *[]){ "xtal" }, | 61 | .parent_names = (const char *[]){ "xtal" }, |
62 | .num_parents = 1, | 62 | .num_parents = 1, |
63 | }, | 63 | }, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static struct clk_regmap axg_sys_pll = { | 66 | static struct clk_regmap axg_fixed_pll = { |
67 | .data = &(struct clk_regmap_div_data){ | ||
68 | .offset = HHI_MPLL_CNTL, | ||
69 | .shift = 16, | ||
70 | .width = 2, | ||
71 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
72 | }, | ||
73 | .hw.init = &(struct clk_init_data){ | ||
74 | .name = "fixed_pll", | ||
75 | .ops = &clk_regmap_divider_ro_ops, | ||
76 | .parent_names = (const char *[]){ "fixed_pll_dco" }, | ||
77 | .num_parents = 1, | ||
78 | /* | ||
79 | * This clock won't ever change at runtime so | ||
80 | * CLK_SET_RATE_PARENT is not required | ||
81 | */ | ||
82 | }, | ||
83 | }; | ||
84 | |||
85 | static struct clk_regmap axg_sys_pll_dco = { | ||
67 | .data = &(struct meson_clk_pll_data){ | 86 | .data = &(struct meson_clk_pll_data){ |
87 | .en = { | ||
88 | .reg_off = HHI_SYS_PLL_CNTL, | ||
89 | .shift = 30, | ||
90 | .width = 1, | ||
91 | }, | ||
68 | .m = { | 92 | .m = { |
69 | .reg_off = HHI_SYS_PLL_CNTL, | 93 | .reg_off = HHI_SYS_PLL_CNTL, |
70 | .shift = 0, | 94 | .shift = 0, |
@@ -75,11 +99,6 @@ static struct clk_regmap axg_sys_pll = { | |||
75 | .shift = 9, | 99 | .shift = 9, |
76 | .width = 5, | 100 | .width = 5, |
77 | }, | 101 | }, |
78 | .od = { | ||
79 | .reg_off = HHI_SYS_PLL_CNTL, | ||
80 | .shift = 16, | ||
81 | .width = 2, | ||
82 | }, | ||
83 | .l = { | 102 | .l = { |
84 | .reg_off = HHI_SYS_PLL_CNTL, | 103 | .reg_off = HHI_SYS_PLL_CNTL, |
85 | .shift = 31, | 104 | .shift = 31, |
@@ -92,102 +111,59 @@ static struct clk_regmap axg_sys_pll = { | |||
92 | }, | 111 | }, |
93 | }, | 112 | }, |
94 | .hw.init = &(struct clk_init_data){ | 113 | .hw.init = &(struct clk_init_data){ |
95 | .name = "sys_pll", | 114 | .name = "sys_pll_dco", |
96 | .ops = &meson_clk_pll_ro_ops, | 115 | .ops = &meson_clk_pll_ro_ops, |
97 | .parent_names = (const char *[]){ "xtal" }, | 116 | .parent_names = (const char *[]){ "xtal" }, |
98 | .num_parents = 1, | 117 | .num_parents = 1, |
99 | .flags = CLK_GET_RATE_NOCACHE, | ||
100 | }, | 118 | }, |
101 | }; | 119 | }; |
102 | 120 | ||
103 | static const struct pll_rate_table axg_gp0_pll_rate_table[] = { | 121 | static struct clk_regmap axg_sys_pll = { |
104 | PLL_RATE(240000000, 40, 1, 2), | 122 | .data = &(struct clk_regmap_div_data){ |
105 | PLL_RATE(246000000, 41, 1, 2), | 123 | .offset = HHI_SYS_PLL_CNTL, |
106 | PLL_RATE(252000000, 42, 1, 2), | 124 | .shift = 16, |
107 | PLL_RATE(258000000, 43, 1, 2), | 125 | .width = 2, |
108 | PLL_RATE(264000000, 44, 1, 2), | 126 | .flags = CLK_DIVIDER_POWER_OF_TWO, |
109 | PLL_RATE(270000000, 45, 1, 2), | 127 | }, |
110 | PLL_RATE(276000000, 46, 1, 2), | 128 | .hw.init = &(struct clk_init_data){ |
111 | PLL_RATE(282000000, 47, 1, 2), | 129 | .name = "sys_pll", |
112 | PLL_RATE(288000000, 48, 1, 2), | 130 | .ops = &clk_regmap_divider_ro_ops, |
113 | PLL_RATE(294000000, 49, 1, 2), | 131 | .parent_names = (const char *[]){ "sys_pll_dco" }, |
114 | PLL_RATE(300000000, 50, 1, 2), | 132 | .num_parents = 1, |
115 | PLL_RATE(306000000, 51, 1, 2), | 133 | .flags = CLK_SET_RATE_PARENT, |
116 | PLL_RATE(312000000, 52, 1, 2), | 134 | }, |
117 | PLL_RATE(318000000, 53, 1, 2), | 135 | }; |
118 | PLL_RATE(324000000, 54, 1, 2), | 136 | |
119 | PLL_RATE(330000000, 55, 1, 2), | 137 | static const struct pll_params_table axg_gp0_pll_params_table[] = { |
120 | PLL_RATE(336000000, 56, 1, 2), | 138 | PLL_PARAMS(40, 1), |
121 | PLL_RATE(342000000, 57, 1, 2), | 139 | PLL_PARAMS(41, 1), |
122 | PLL_RATE(348000000, 58, 1, 2), | 140 | PLL_PARAMS(42, 1), |
123 | PLL_RATE(354000000, 59, 1, 2), | 141 | PLL_PARAMS(43, 1), |
124 | PLL_RATE(360000000, 60, 1, 2), | 142 | PLL_PARAMS(44, 1), |
125 | PLL_RATE(366000000, 61, 1, 2), | 143 | PLL_PARAMS(45, 1), |
126 | PLL_RATE(372000000, 62, 1, 2), | 144 | PLL_PARAMS(46, 1), |
127 | PLL_RATE(378000000, 63, 1, 2), | 145 | PLL_PARAMS(47, 1), |
128 | PLL_RATE(384000000, 64, 1, 2), | 146 | PLL_PARAMS(48, 1), |
129 | PLL_RATE(390000000, 65, 1, 3), | 147 | PLL_PARAMS(49, 1), |
130 | PLL_RATE(396000000, 66, 1, 3), | 148 | PLL_PARAMS(50, 1), |
131 | PLL_RATE(402000000, 67, 1, 3), | 149 | PLL_PARAMS(51, 1), |
132 | PLL_RATE(408000000, 68, 1, 3), | 150 | PLL_PARAMS(52, 1), |
133 | PLL_RATE(480000000, 40, 1, 1), | 151 | PLL_PARAMS(53, 1), |
134 | PLL_RATE(492000000, 41, 1, 1), | 152 | PLL_PARAMS(54, 1), |
135 | PLL_RATE(504000000, 42, 1, 1), | 153 | PLL_PARAMS(55, 1), |
136 | PLL_RATE(516000000, 43, 1, 1), | 154 | PLL_PARAMS(56, 1), |
137 | PLL_RATE(528000000, 44, 1, 1), | 155 | PLL_PARAMS(57, 1), |
138 | PLL_RATE(540000000, 45, 1, 1), | 156 | PLL_PARAMS(58, 1), |
139 | PLL_RATE(552000000, 46, 1, 1), | 157 | PLL_PARAMS(59, 1), |
140 | PLL_RATE(564000000, 47, 1, 1), | 158 | PLL_PARAMS(60, 1), |
141 | PLL_RATE(576000000, 48, 1, 1), | 159 | PLL_PARAMS(61, 1), |
142 | PLL_RATE(588000000, 49, 1, 1), | 160 | PLL_PARAMS(62, 1), |
143 | PLL_RATE(600000000, 50, 1, 1), | 161 | PLL_PARAMS(63, 1), |
144 | PLL_RATE(612000000, 51, 1, 1), | 162 | PLL_PARAMS(64, 1), |
145 | PLL_RATE(624000000, 52, 1, 1), | 163 | PLL_PARAMS(65, 1), |
146 | PLL_RATE(636000000, 53, 1, 1), | 164 | PLL_PARAMS(66, 1), |
147 | PLL_RATE(648000000, 54, 1, 1), | 165 | PLL_PARAMS(67, 1), |
148 | PLL_RATE(660000000, 55, 1, 1), | 166 | PLL_PARAMS(68, 1), |
149 | PLL_RATE(672000000, 56, 1, 1), | ||
150 | PLL_RATE(684000000, 57, 1, 1), | ||
151 | PLL_RATE(696000000, 58, 1, 1), | ||
152 | PLL_RATE(708000000, 59, 1, 1), | ||
153 | PLL_RATE(720000000, 60, 1, 1), | ||
154 | PLL_RATE(732000000, 61, 1, 1), | ||
155 | PLL_RATE(744000000, 62, 1, 1), | ||
156 | PLL_RATE(756000000, 63, 1, 1), | ||
157 | PLL_RATE(768000000, 64, 1, 1), | ||
158 | PLL_RATE(780000000, 65, 1, 1), | ||
159 | PLL_RATE(792000000, 66, 1, 1), | ||
160 | PLL_RATE(804000000, 67, 1, 1), | ||
161 | PLL_RATE(816000000, 68, 1, 1), | ||
162 | PLL_RATE(960000000, 40, 1, 0), | ||
163 | PLL_RATE(984000000, 41, 1, 0), | ||
164 | PLL_RATE(1008000000, 42, 1, 0), | ||
165 | PLL_RATE(1032000000, 43, 1, 0), | ||
166 | PLL_RATE(1056000000, 44, 1, 0), | ||
167 | PLL_RATE(1080000000, 45, 1, 0), | ||
168 | PLL_RATE(1104000000, 46, 1, 0), | ||
169 | PLL_RATE(1128000000, 47, 1, 0), | ||
170 | PLL_RATE(1152000000, 48, 1, 0), | ||
171 | PLL_RATE(1176000000, 49, 1, 0), | ||
172 | PLL_RATE(1200000000, 50, 1, 0), | ||
173 | PLL_RATE(1224000000, 51, 1, 0), | ||
174 | PLL_RATE(1248000000, 52, 1, 0), | ||
175 | PLL_RATE(1272000000, 53, 1, 0), | ||
176 | PLL_RATE(1296000000, 54, 1, 0), | ||
177 | PLL_RATE(1320000000, 55, 1, 0), | ||
178 | PLL_RATE(1344000000, 56, 1, 0), | ||
179 | PLL_RATE(1368000000, 57, 1, 0), | ||
180 | PLL_RATE(1392000000, 58, 1, 0), | ||
181 | PLL_RATE(1416000000, 59, 1, 0), | ||
182 | PLL_RATE(1440000000, 60, 1, 0), | ||
183 | PLL_RATE(1464000000, 61, 1, 0), | ||
184 | PLL_RATE(1488000000, 62, 1, 0), | ||
185 | PLL_RATE(1512000000, 63, 1, 0), | ||
186 | PLL_RATE(1536000000, 64, 1, 0), | ||
187 | PLL_RATE(1560000000, 65, 1, 0), | ||
188 | PLL_RATE(1584000000, 66, 1, 0), | ||
189 | PLL_RATE(1608000000, 67, 1, 0), | ||
190 | PLL_RATE(1632000000, 68, 1, 0), | ||
191 | { /* sentinel */ }, | 167 | { /* sentinel */ }, |
192 | }; | 168 | }; |
193 | 169 | ||
@@ -197,11 +173,15 @@ static const struct reg_sequence axg_gp0_init_regs[] = { | |||
197 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, | 173 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, |
198 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, | 174 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, |
199 | { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, | 175 | { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, |
200 | { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 }, | ||
201 | }; | 176 | }; |
202 | 177 | ||
203 | static struct clk_regmap axg_gp0_pll = { | 178 | static struct clk_regmap axg_gp0_pll_dco = { |
204 | .data = &(struct meson_clk_pll_data){ | 179 | .data = &(struct meson_clk_pll_data){ |
180 | .en = { | ||
181 | .reg_off = HHI_GP0_PLL_CNTL, | ||
182 | .shift = 30, | ||
183 | .width = 1, | ||
184 | }, | ||
205 | .m = { | 185 | .m = { |
206 | .reg_off = HHI_GP0_PLL_CNTL, | 186 | .reg_off = HHI_GP0_PLL_CNTL, |
207 | .shift = 0, | 187 | .shift = 0, |
@@ -212,11 +192,6 @@ static struct clk_regmap axg_gp0_pll = { | |||
212 | .shift = 9, | 192 | .shift = 9, |
213 | .width = 5, | 193 | .width = 5, |
214 | }, | 194 | }, |
215 | .od = { | ||
216 | .reg_off = HHI_GP0_PLL_CNTL, | ||
217 | .shift = 16, | ||
218 | .width = 2, | ||
219 | }, | ||
220 | .frac = { | 195 | .frac = { |
221 | .reg_off = HHI_GP0_PLL_CNTL1, | 196 | .reg_off = HHI_GP0_PLL_CNTL1, |
222 | .shift = 0, | 197 | .shift = 0, |
@@ -232,29 +207,49 @@ static struct clk_regmap axg_gp0_pll = { | |||
232 | .shift = 29, | 207 | .shift = 29, |
233 | .width = 1, | 208 | .width = 1, |
234 | }, | 209 | }, |
235 | .table = axg_gp0_pll_rate_table, | 210 | .table = axg_gp0_pll_params_table, |
236 | .init_regs = axg_gp0_init_regs, | 211 | .init_regs = axg_gp0_init_regs, |
237 | .init_count = ARRAY_SIZE(axg_gp0_init_regs), | 212 | .init_count = ARRAY_SIZE(axg_gp0_init_regs), |
238 | }, | 213 | }, |
239 | .hw.init = &(struct clk_init_data){ | 214 | .hw.init = &(struct clk_init_data){ |
240 | .name = "gp0_pll", | 215 | .name = "gp0_pll_dco", |
241 | .ops = &meson_clk_pll_ops, | 216 | .ops = &meson_clk_pll_ops, |
242 | .parent_names = (const char *[]){ "xtal" }, | 217 | .parent_names = (const char *[]){ "xtal" }, |
243 | .num_parents = 1, | 218 | .num_parents = 1, |
244 | }, | 219 | }, |
245 | }; | 220 | }; |
246 | 221 | ||
222 | static struct clk_regmap axg_gp0_pll = { | ||
223 | .data = &(struct clk_regmap_div_data){ | ||
224 | .offset = HHI_GP0_PLL_CNTL, | ||
225 | .shift = 16, | ||
226 | .width = 2, | ||
227 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
228 | }, | ||
229 | .hw.init = &(struct clk_init_data){ | ||
230 | .name = "gp0_pll", | ||
231 | .ops = &clk_regmap_divider_ops, | ||
232 | .parent_names = (const char *[]){ "gp0_pll_dco" }, | ||
233 | .num_parents = 1, | ||
234 | .flags = CLK_SET_RATE_PARENT, | ||
235 | }, | ||
236 | }; | ||
237 | |||
247 | static const struct reg_sequence axg_hifi_init_regs[] = { | 238 | static const struct reg_sequence axg_hifi_init_regs[] = { |
248 | { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, | 239 | { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, |
249 | { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, | 240 | { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, |
250 | { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 }, | 241 | { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 }, |
251 | { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d }, | 242 | { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d }, |
252 | { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, | 243 | { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, |
253 | { .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 }, | ||
254 | }; | 244 | }; |
255 | 245 | ||
256 | static struct clk_regmap axg_hifi_pll = { | 246 | static struct clk_regmap axg_hifi_pll_dco = { |
257 | .data = &(struct meson_clk_pll_data){ | 247 | .data = &(struct meson_clk_pll_data){ |
248 | .en = { | ||
249 | .reg_off = HHI_HIFI_PLL_CNTL, | ||
250 | .shift = 30, | ||
251 | .width = 1, | ||
252 | }, | ||
258 | .m = { | 253 | .m = { |
259 | .reg_off = HHI_HIFI_PLL_CNTL, | 254 | .reg_off = HHI_HIFI_PLL_CNTL, |
260 | .shift = 0, | 255 | .shift = 0, |
@@ -265,11 +260,6 @@ static struct clk_regmap axg_hifi_pll = { | |||
265 | .shift = 9, | 260 | .shift = 9, |
266 | .width = 5, | 261 | .width = 5, |
267 | }, | 262 | }, |
268 | .od = { | ||
269 | .reg_off = HHI_HIFI_PLL_CNTL, | ||
270 | .shift = 16, | ||
271 | .width = 2, | ||
272 | }, | ||
273 | .frac = { | 263 | .frac = { |
274 | .reg_off = HHI_HIFI_PLL_CNTL5, | 264 | .reg_off = HHI_HIFI_PLL_CNTL5, |
275 | .shift = 0, | 265 | .shift = 0, |
@@ -285,19 +275,35 @@ static struct clk_regmap axg_hifi_pll = { | |||
285 | .shift = 29, | 275 | .shift = 29, |
286 | .width = 1, | 276 | .width = 1, |
287 | }, | 277 | }, |
288 | .table = axg_gp0_pll_rate_table, | 278 | .table = axg_gp0_pll_params_table, |
289 | .init_regs = axg_hifi_init_regs, | 279 | .init_regs = axg_hifi_init_regs, |
290 | .init_count = ARRAY_SIZE(axg_hifi_init_regs), | 280 | .init_count = ARRAY_SIZE(axg_hifi_init_regs), |
291 | .flags = CLK_MESON_PLL_ROUND_CLOSEST, | 281 | .flags = CLK_MESON_PLL_ROUND_CLOSEST, |
292 | }, | 282 | }, |
293 | .hw.init = &(struct clk_init_data){ | 283 | .hw.init = &(struct clk_init_data){ |
294 | .name = "hifi_pll", | 284 | .name = "hifi_pll_dco", |
295 | .ops = &meson_clk_pll_ops, | 285 | .ops = &meson_clk_pll_ops, |
296 | .parent_names = (const char *[]){ "xtal" }, | 286 | .parent_names = (const char *[]){ "xtal" }, |
297 | .num_parents = 1, | 287 | .num_parents = 1, |
298 | }, | 288 | }, |
299 | }; | 289 | }; |
300 | 290 | ||
291 | static struct clk_regmap axg_hifi_pll = { | ||
292 | .data = &(struct clk_regmap_div_data){ | ||
293 | .offset = HHI_HIFI_PLL_CNTL, | ||
294 | .shift = 16, | ||
295 | .width = 2, | ||
296 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
297 | }, | ||
298 | .hw.init = &(struct clk_init_data){ | ||
299 | .name = "hifi_pll", | ||
300 | .ops = &clk_regmap_divider_ops, | ||
301 | .parent_names = (const char *[]){ "hifi_pll_dco" }, | ||
302 | .num_parents = 1, | ||
303 | .flags = CLK_SET_RATE_PARENT, | ||
304 | }, | ||
305 | }; | ||
306 | |||
301 | static struct clk_fixed_factor axg_fclk_div2_div = { | 307 | static struct clk_fixed_factor axg_fclk_div2_div = { |
302 | .mult = 1, | 308 | .mult = 1, |
303 | .div = 2, | 309 | .div = 2, |
@@ -625,29 +631,31 @@ static struct clk_regmap axg_mpll3 = { | |||
625 | }, | 631 | }, |
626 | }; | 632 | }; |
627 | 633 | ||
628 | static const struct pll_rate_table axg_pcie_pll_rate_table[] = { | 634 | static const struct pll_params_table axg_pcie_pll_params_table[] = { |
629 | { | 635 | { |
630 | .rate = 100000000, | 636 | .m = 200, |
631 | .m = 200, | 637 | .n = 3, |
632 | .n = 3, | ||
633 | .od = 1, | ||
634 | .od2 = 3, | ||
635 | }, | 638 | }, |
636 | { /* sentinel */ }, | 639 | { /* sentinel */ }, |
637 | }; | 640 | }; |
638 | 641 | ||
639 | static const struct reg_sequence axg_pcie_init_regs[] = { | 642 | static const struct reg_sequence axg_pcie_init_regs[] = { |
640 | { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, | ||
641 | { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, | 643 | { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, |
642 | { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, | 644 | { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, |
643 | { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, | 645 | { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, |
644 | { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, | 646 | { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, |
645 | { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, | 647 | { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, |
646 | { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, | 648 | { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, |
649 | { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, | ||
647 | }; | 650 | }; |
648 | 651 | ||
649 | static struct clk_regmap axg_pcie_pll = { | 652 | static struct clk_regmap axg_pcie_pll_dco = { |
650 | .data = &(struct meson_clk_pll_data){ | 653 | .data = &(struct meson_clk_pll_data){ |
654 | .en = { | ||
655 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
656 | .shift = 30, | ||
657 | .width = 1, | ||
658 | }, | ||
651 | .m = { | 659 | .m = { |
652 | .reg_off = HHI_PCIE_PLL_CNTL, | 660 | .reg_off = HHI_PCIE_PLL_CNTL, |
653 | .shift = 0, | 661 | .shift = 0, |
@@ -658,16 +666,6 @@ static struct clk_regmap axg_pcie_pll = { | |||
658 | .shift = 9, | 666 | .shift = 9, |
659 | .width = 5, | 667 | .width = 5, |
660 | }, | 668 | }, |
661 | .od = { | ||
662 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
663 | .shift = 16, | ||
664 | .width = 2, | ||
665 | }, | ||
666 | .od2 = { | ||
667 | .reg_off = HHI_PCIE_PLL_CNTL6, | ||
668 | .shift = 6, | ||
669 | .width = 2, | ||
670 | }, | ||
671 | .frac = { | 669 | .frac = { |
672 | .reg_off = HHI_PCIE_PLL_CNTL1, | 670 | .reg_off = HHI_PCIE_PLL_CNTL1, |
673 | .shift = 0, | 671 | .shift = 0, |
@@ -683,29 +681,63 @@ static struct clk_regmap axg_pcie_pll = { | |||
683 | .shift = 29, | 681 | .shift = 29, |
684 | .width = 1, | 682 | .width = 1, |
685 | }, | 683 | }, |
686 | .table = axg_pcie_pll_rate_table, | 684 | .table = axg_pcie_pll_params_table, |
687 | .init_regs = axg_pcie_init_regs, | 685 | .init_regs = axg_pcie_init_regs, |
688 | .init_count = ARRAY_SIZE(axg_pcie_init_regs), | 686 | .init_count = ARRAY_SIZE(axg_pcie_init_regs), |
689 | }, | 687 | }, |
690 | .hw.init = &(struct clk_init_data){ | 688 | .hw.init = &(struct clk_init_data){ |
691 | .name = "pcie_pll", | 689 | .name = "pcie_pll_dco", |
692 | .ops = &meson_clk_pll_ops, | 690 | .ops = &meson_clk_pll_ops, |
693 | .parent_names = (const char *[]){ "xtal" }, | 691 | .parent_names = (const char *[]){ "xtal" }, |
694 | .num_parents = 1, | 692 | .num_parents = 1, |
695 | }, | 693 | }, |
696 | }; | 694 | }; |
697 | 695 | ||
696 | static struct clk_regmap axg_pcie_pll_od = { | ||
697 | .data = &(struct clk_regmap_div_data){ | ||
698 | .offset = HHI_PCIE_PLL_CNTL, | ||
699 | .shift = 16, | ||
700 | .width = 2, | ||
701 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
702 | }, | ||
703 | .hw.init = &(struct clk_init_data){ | ||
704 | .name = "pcie_pll_od", | ||
705 | .ops = &clk_regmap_divider_ops, | ||
706 | .parent_names = (const char *[]){ "pcie_pll_dco" }, | ||
707 | .num_parents = 1, | ||
708 | .flags = CLK_SET_RATE_PARENT, | ||
709 | }, | ||
710 | }; | ||
711 | |||
712 | static struct clk_regmap axg_pcie_pll = { | ||
713 | .data = &(struct clk_regmap_div_data){ | ||
714 | .offset = HHI_PCIE_PLL_CNTL6, | ||
715 | .shift = 6, | ||
716 | .width = 2, | ||
717 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
718 | }, | ||
719 | .hw.init = &(struct clk_init_data){ | ||
720 | .name = "pcie_pll", | ||
721 | .ops = &clk_regmap_divider_ops, | ||
722 | .parent_names = (const char *[]){ "pcie_pll_od" }, | ||
723 | .num_parents = 1, | ||
724 | .flags = CLK_SET_RATE_PARENT, | ||
725 | }, | ||
726 | }; | ||
727 | |||
698 | static struct clk_regmap axg_pcie_mux = { | 728 | static struct clk_regmap axg_pcie_mux = { |
699 | .data = &(struct clk_regmap_mux_data){ | 729 | .data = &(struct clk_regmap_mux_data){ |
700 | .offset = HHI_PCIE_PLL_CNTL6, | 730 | .offset = HHI_PCIE_PLL_CNTL6, |
701 | .mask = 0x1, | 731 | .mask = 0x1, |
702 | .shift = 2, | 732 | .shift = 2, |
733 | /* skip the parent mpll3, reserved for debug */ | ||
734 | .table = (u32[]){ 1 }, | ||
703 | }, | 735 | }, |
704 | .hw.init = &(struct clk_init_data){ | 736 | .hw.init = &(struct clk_init_data){ |
705 | .name = "pcie_mux", | 737 | .name = "pcie_mux", |
706 | .ops = &clk_regmap_mux_ops, | 738 | .ops = &clk_regmap_mux_ops, |
707 | .parent_names = (const char *[]){ "mpll3", "pcie_pll" }, | 739 | .parent_names = (const char *[]){ "pcie_pll" }, |
708 | .num_parents = 2, | 740 | .num_parents = 1, |
709 | .flags = CLK_SET_RATE_PARENT, | 741 | .flags = CLK_SET_RATE_PARENT, |
710 | }, | 742 | }, |
711 | }; | 743 | }; |
@@ -1107,6 +1139,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { | |||
1107 | [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, | 1139 | [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, |
1108 | [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, | 1140 | [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, |
1109 | [CLKID_GEN_CLK] = &axg_gen_clk.hw, | 1141 | [CLKID_GEN_CLK] = &axg_gen_clk.hw, |
1142 | [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, | ||
1143 | [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, | ||
1144 | [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, | ||
1145 | [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, | ||
1146 | [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, | ||
1147 | [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, | ||
1110 | [NR_CLKS] = NULL, | 1148 | [NR_CLKS] = NULL, |
1111 | }, | 1149 | }, |
1112 | .num = NR_CLKS, | 1150 | .num = NR_CLKS, |
@@ -1185,6 +1223,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = { | |||
1185 | &axg_fclk_div4, | 1223 | &axg_fclk_div4, |
1186 | &axg_fclk_div5, | 1224 | &axg_fclk_div5, |
1187 | &axg_fclk_div7, | 1225 | &axg_fclk_div7, |
1226 | &axg_pcie_pll_dco, | ||
1227 | &axg_pcie_pll_od, | ||
1188 | &axg_pcie_pll, | 1228 | &axg_pcie_pll, |
1189 | &axg_pcie_mux, | 1229 | &axg_pcie_mux, |
1190 | &axg_pcie_ref, | 1230 | &axg_pcie_ref, |
@@ -1194,6 +1234,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = { | |||
1194 | &axg_gen_clk_sel, | 1234 | &axg_gen_clk_sel, |
1195 | &axg_gen_clk_div, | 1235 | &axg_gen_clk_div, |
1196 | &axg_gen_clk, | 1236 | &axg_gen_clk, |
1237 | &axg_fixed_pll_dco, | ||
1238 | &axg_sys_pll_dco, | ||
1239 | &axg_gp0_pll_dco, | ||
1240 | &axg_hifi_pll_dco, | ||
1241 | &axg_pcie_pll_dco, | ||
1242 | &axg_pcie_pll_od, | ||
1197 | }; | 1243 | }; |
1198 | 1244 | ||
1199 | static const struct of_device_id clkc_match_table[] = { | 1245 | static const struct of_device_id clkc_match_table[] = { |
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h index 1d04144a1b2c..0431dabac629 100644 --- a/drivers/clk/meson/axg.h +++ b/drivers/clk/meson/axg.h | |||
@@ -133,8 +133,14 @@ | |||
133 | #define CLKID_PCIE_REF 78 | 133 | #define CLKID_PCIE_REF 78 |
134 | #define CLKID_GEN_CLK_SEL 82 | 134 | #define CLKID_GEN_CLK_SEL 82 |
135 | #define CLKID_GEN_CLK_DIV 83 | 135 | #define CLKID_GEN_CLK_DIV 83 |
136 | #define CLKID_SYS_PLL_DCO 85 | ||
137 | #define CLKID_FIXED_PLL_DCO 86 | ||
138 | #define CLKID_GP0_PLL_DCO 87 | ||
139 | #define CLKID_HIFI_PLL_DCO 88 | ||
140 | #define CLKID_PCIE_PLL_DCO 89 | ||
141 | #define CLKID_PCIE_PLL_OD 90 | ||
136 | 142 | ||
137 | #define NR_CLKS 85 | 143 | #define NR_CLKS 91 |
138 | 144 | ||
139 | /* include the CLKIDs that have been made part of the DT binding */ | 145 | /* include the CLKIDs that have been made part of the DT binding */ |
140 | #include <dt-bindings/clock/axg-clkc.h> | 146 | #include <dt-bindings/clock/axg-clkc.h> |
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 3e04617ac47f..f5b5b3fabe3c 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c | |||
@@ -11,15 +11,19 @@ | |||
11 | * In the most basic form, a Meson PLL is composed as follows: | 11 | * In the most basic form, a Meson PLL is composed as follows: |
12 | * | 12 | * |
13 | * PLL | 13 | * PLL |
14 | * +------------------------------+ | 14 | * +--------------------------------+ |
15 | * | | | 15 | * | | |
16 | * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out | 16 | * | +--+ | |
17 | * | ^ ^ | | 17 | * in >>-----[ /N ]--->| | +-----+ | |
18 | * +------------------------------+ | 18 | * | | |------| DCO |---->> out |
19 | * | | | 19 | * | +--------->| | +--v--+ | |
20 | * FREF VCO | 20 | * | | +--+ | | |
21 | * | | | | | ||
22 | * | +--[ *(M + (F/Fmax) ]<--+ | | ||
23 | * | | | ||
24 | * +--------------------------------+ | ||
21 | * | 25 | * |
22 | * out = in * (m + frac / frac_max) / (n << sum(ods)) | 26 | * out = in * (m + frac / frac_max) / n |
23 | */ | 27 | */ |
24 | 28 | ||
25 | #include <linux/clk-provider.h> | 29 | #include <linux/clk-provider.h> |
@@ -41,12 +45,11 @@ meson_clk_pll_data(struct clk_regmap *clk) | |||
41 | } | 45 | } |
42 | 46 | ||
43 | static unsigned long __pll_params_to_rate(unsigned long parent_rate, | 47 | static unsigned long __pll_params_to_rate(unsigned long parent_rate, |
44 | const struct pll_rate_table *pllt, | 48 | const struct pll_params_table *pllt, |
45 | u16 frac, | 49 | u16 frac, |
46 | struct meson_clk_pll_data *pll) | 50 | struct meson_clk_pll_data *pll) |
47 | { | 51 | { |
48 | u64 rate = (u64)parent_rate * pllt->m; | 52 | u64 rate = (u64)parent_rate * pllt->m; |
49 | unsigned int od = pllt->od + pllt->od2 + pllt->od3; | ||
50 | 53 | ||
51 | if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { | 54 | if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { |
52 | u64 frac_rate = (u64)parent_rate * frac; | 55 | u64 frac_rate = (u64)parent_rate * frac; |
@@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, | |||
55 | (1 << pll->frac.width)); | 58 | (1 << pll->frac.width)); |
56 | } | 59 | } |
57 | 60 | ||
58 | return DIV_ROUND_UP_ULL(rate, pllt->n << od); | 61 | return DIV_ROUND_UP_ULL(rate, pllt->n); |
59 | } | 62 | } |
60 | 63 | ||
61 | static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, | 64 | static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, |
@@ -63,20 +66,11 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, | |||
63 | { | 66 | { |
64 | struct clk_regmap *clk = to_clk_regmap(hw); | 67 | struct clk_regmap *clk = to_clk_regmap(hw); |
65 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); | 68 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); |
66 | struct pll_rate_table pllt; | 69 | struct pll_params_table pllt; |
67 | u16 frac; | 70 | u16 frac; |
68 | 71 | ||
69 | pllt.n = meson_parm_read(clk->map, &pll->n); | 72 | pllt.n = meson_parm_read(clk->map, &pll->n); |
70 | pllt.m = meson_parm_read(clk->map, &pll->m); | 73 | pllt.m = meson_parm_read(clk->map, &pll->m); |
71 | pllt.od = meson_parm_read(clk->map, &pll->od); | ||
72 | |||
73 | pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ? | ||
74 | meson_parm_read(clk->map, &pll->od2) : | ||
75 | 0; | ||
76 | |||
77 | pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ? | ||
78 | meson_parm_read(clk->map, &pll->od3) : | ||
79 | 0; | ||
80 | 74 | ||
81 | frac = MESON_PARM_APPLICABLE(&pll->frac) ? | 75 | frac = MESON_PARM_APPLICABLE(&pll->frac) ? |
82 | meson_parm_read(clk->map, &pll->frac) : | 76 | meson_parm_read(clk->map, &pll->frac) : |
@@ -87,14 +81,12 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, | |||
87 | 81 | ||
88 | static u16 __pll_params_with_frac(unsigned long rate, | 82 | static u16 __pll_params_with_frac(unsigned long rate, |
89 | unsigned long parent_rate, | 83 | unsigned long parent_rate, |
90 | const struct pll_rate_table *pllt, | 84 | const struct pll_params_table *pllt, |
91 | struct meson_clk_pll_data *pll) | 85 | struct meson_clk_pll_data *pll) |
92 | { | 86 | { |
93 | u16 frac_max = (1 << pll->frac.width); | 87 | u16 frac_max = (1 << pll->frac.width); |
94 | u64 val = (u64)rate * pllt->n; | 88 | u64 val = (u64)rate * pllt->n; |
95 | 89 | ||
96 | val <<= pllt->od + pllt->od2 + pllt->od3; | ||
97 | |||
98 | if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) | 90 | if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) |
99 | val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); | 91 | val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); |
100 | else | 92 | else |
@@ -105,29 +97,50 @@ static u16 __pll_params_with_frac(unsigned long rate, | |||
105 | return min((u16)val, (u16)(frac_max - 1)); | 97 | return min((u16)val, (u16)(frac_max - 1)); |
106 | } | 98 | } |
107 | 99 | ||
108 | static const struct pll_rate_table * | 100 | static bool meson_clk_pll_is_better(unsigned long rate, |
101 | unsigned long best, | ||
102 | unsigned long now, | ||
103 | struct meson_clk_pll_data *pll) | ||
104 | { | ||
105 | if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) || | ||
106 | MESON_PARM_APPLICABLE(&pll->frac)) { | ||
107 | /* Round down */ | ||
108 | if (now < rate && best < now) | ||
109 | return true; | ||
110 | } else { | ||
111 | /* Round Closest */ | ||
112 | if (abs(now - rate) < abs(best - rate)) | ||
113 | return true; | ||
114 | } | ||
115 | |||
116 | return false; | ||
117 | } | ||
118 | |||
119 | static const struct pll_params_table * | ||
109 | meson_clk_get_pll_settings(unsigned long rate, | 120 | meson_clk_get_pll_settings(unsigned long rate, |
121 | unsigned long parent_rate, | ||
110 | struct meson_clk_pll_data *pll) | 122 | struct meson_clk_pll_data *pll) |
111 | { | 123 | { |
112 | const struct pll_rate_table *table = pll->table; | 124 | const struct pll_params_table *table = pll->table; |
113 | unsigned int i = 0; | 125 | unsigned long best = 0, now = 0; |
126 | unsigned int i, best_i = 0; | ||
114 | 127 | ||
115 | if (!table) | 128 | if (!table) |
116 | return NULL; | 129 | return NULL; |
117 | 130 | ||
118 | /* Find the first table element exceeding rate */ | 131 | for (i = 0; table[i].n; i++) { |
119 | while (table[i].rate && table[i].rate <= rate) | 132 | now = __pll_params_to_rate(parent_rate, &table[i], 0, pll); |
120 | i++; | ||
121 | 133 | ||
122 | if (i != 0) { | 134 | /* If we get an exact match, don't bother any further */ |
123 | if (MESON_PARM_APPLICABLE(&pll->frac) || | 135 | if (now == rate) { |
124 | !(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) || | 136 | return &table[i]; |
125 | (abs(rate - table[i - 1].rate) < | 137 | } else if (meson_clk_pll_is_better(rate, best, now, pll)) { |
126 | abs(rate - table[i].rate))) | 138 | best = now; |
127 | i--; | 139 | best_i = i; |
140 | } | ||
128 | } | 141 | } |
129 | 142 | ||
130 | return (struct pll_rate_table *)&table[i]; | 143 | return (struct pll_params_table *)&table[best_i]; |
131 | } | 144 | } |
132 | 145 | ||
133 | static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | 146 | static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, |
@@ -135,16 +148,18 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
135 | { | 148 | { |
136 | struct clk_regmap *clk = to_clk_regmap(hw); | 149 | struct clk_regmap *clk = to_clk_regmap(hw); |
137 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); | 150 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); |
138 | const struct pll_rate_table *pllt = | 151 | const struct pll_params_table *pllt = |
139 | meson_clk_get_pll_settings(rate, pll); | 152 | meson_clk_get_pll_settings(rate, *parent_rate, pll); |
153 | unsigned long round; | ||
140 | u16 frac; | 154 | u16 frac; |
141 | 155 | ||
142 | if (!pllt) | 156 | if (!pllt) |
143 | return meson_clk_pll_recalc_rate(hw, *parent_rate); | 157 | return meson_clk_pll_recalc_rate(hw, *parent_rate); |
144 | 158 | ||
145 | if (!MESON_PARM_APPLICABLE(&pll->frac) | 159 | round = __pll_params_to_rate(*parent_rate, pllt, 0, pll); |
146 | || rate == pllt->rate) | 160 | |
147 | return pllt->rate; | 161 | if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round) |
162 | return round; | ||
148 | 163 | ||
149 | /* | 164 | /* |
150 | * The rate provided by the setting is not an exact match, let's | 165 | * The rate provided by the setting is not an exact match, let's |
@@ -185,12 +200,45 @@ static void meson_clk_pll_init(struct clk_hw *hw) | |||
185 | } | 200 | } |
186 | } | 201 | } |
187 | 202 | ||
203 | static int meson_clk_pll_enable(struct clk_hw *hw) | ||
204 | { | ||
205 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
206 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); | ||
207 | |||
208 | /* Make sure the pll is in reset */ | ||
209 | meson_parm_write(clk->map, &pll->rst, 1); | ||
210 | |||
211 | /* Enable the pll */ | ||
212 | meson_parm_write(clk->map, &pll->en, 1); | ||
213 | |||
214 | /* Take the pll out reset */ | ||
215 | meson_parm_write(clk->map, &pll->rst, 0); | ||
216 | |||
217 | if (meson_clk_pll_wait_lock(hw)) | ||
218 | return -EIO; | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static void meson_clk_pll_disable(struct clk_hw *hw) | ||
224 | { | ||
225 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
226 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); | ||
227 | |||
228 | /* Put the pll is in reset */ | ||
229 | meson_parm_write(clk->map, &pll->rst, 1); | ||
230 | |||
231 | /* Disable the pll */ | ||
232 | meson_parm_write(clk->map, &pll->en, 0); | ||
233 | } | ||
234 | |||
188 | static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 235 | static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, |
189 | unsigned long parent_rate) | 236 | unsigned long parent_rate) |
190 | { | 237 | { |
191 | struct clk_regmap *clk = to_clk_regmap(hw); | 238 | struct clk_regmap *clk = to_clk_regmap(hw); |
192 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); | 239 | struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); |
193 | const struct pll_rate_table *pllt; | 240 | const struct pll_params_table *pllt; |
241 | unsigned int enabled; | ||
194 | unsigned long old_rate; | 242 | unsigned long old_rate; |
195 | u16 frac = 0; | 243 | u16 frac = 0; |
196 | 244 | ||
@@ -199,32 +247,28 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
199 | 247 | ||
200 | old_rate = rate; | 248 | old_rate = rate; |
201 | 249 | ||
202 | pllt = meson_clk_get_pll_settings(rate, pll); | 250 | pllt = meson_clk_get_pll_settings(rate, parent_rate, pll); |
203 | if (!pllt) | 251 | if (!pllt) |
204 | return -EINVAL; | 252 | return -EINVAL; |
205 | 253 | ||
206 | /* Put the pll in reset to write the params */ | 254 | enabled = meson_parm_read(clk->map, &pll->en); |
207 | meson_parm_write(clk->map, &pll->rst, 1); | 255 | if (enabled) |
256 | meson_clk_pll_disable(hw); | ||
208 | 257 | ||
209 | meson_parm_write(clk->map, &pll->n, pllt->n); | 258 | meson_parm_write(clk->map, &pll->n, pllt->n); |
210 | meson_parm_write(clk->map, &pll->m, pllt->m); | 259 | meson_parm_write(clk->map, &pll->m, pllt->m); |
211 | meson_parm_write(clk->map, &pll->od, pllt->od); | ||
212 | 260 | ||
213 | if (MESON_PARM_APPLICABLE(&pll->od2)) | ||
214 | meson_parm_write(clk->map, &pll->od2, pllt->od2); | ||
215 | |||
216 | if (MESON_PARM_APPLICABLE(&pll->od3)) | ||
217 | meson_parm_write(clk->map, &pll->od3, pllt->od3); | ||
218 | 261 | ||
219 | if (MESON_PARM_APPLICABLE(&pll->frac)) { | 262 | if (MESON_PARM_APPLICABLE(&pll->frac)) { |
220 | frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); | 263 | frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); |
221 | meson_parm_write(clk->map, &pll->frac, frac); | 264 | meson_parm_write(clk->map, &pll->frac, frac); |
222 | } | 265 | } |
223 | 266 | ||
224 | /* make sure the reset is cleared at this point */ | 267 | /* If the pll is stopped, bail out now */ |
225 | meson_parm_write(clk->map, &pll->rst, 0); | 268 | if (!enabled) |
269 | return 0; | ||
226 | 270 | ||
227 | if (meson_clk_pll_wait_lock(hw)) { | 271 | if (meson_clk_pll_enable(hw)) { |
228 | pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", | 272 | pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", |
229 | __func__, old_rate); | 273 | __func__, old_rate); |
230 | /* | 274 | /* |
@@ -244,6 +288,8 @@ const struct clk_ops meson_clk_pll_ops = { | |||
244 | .recalc_rate = meson_clk_pll_recalc_rate, | 288 | .recalc_rate = meson_clk_pll_recalc_rate, |
245 | .round_rate = meson_clk_pll_round_rate, | 289 | .round_rate = meson_clk_pll_round_rate, |
246 | .set_rate = meson_clk_pll_set_rate, | 290 | .set_rate = meson_clk_pll_set_rate, |
291 | .enable = meson_clk_pll_enable, | ||
292 | .disable = meson_clk_pll_disable | ||
247 | }; | 293 | }; |
248 | 294 | ||
249 | const struct clk_ops meson_clk_pll_ro_ops = { | 295 | const struct clk_ops meson_clk_pll_ro_ops = { |
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 24cec16b6038..6b96d55c047d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h | |||
@@ -43,37 +43,29 @@ static inline void meson_parm_write(struct regmap *map, struct parm *p, | |||
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | struct pll_rate_table { | 46 | struct pll_params_table { |
47 | unsigned long rate; | ||
48 | u16 m; | 47 | u16 m; |
49 | u16 n; | 48 | u16 n; |
50 | u16 od; | ||
51 | u16 od2; | ||
52 | u16 od3; | ||
53 | }; | 49 | }; |
54 | 50 | ||
55 | #define PLL_RATE(_r, _m, _n, _od) \ | 51 | #define PLL_PARAMS(_m, _n) \ |
56 | { \ | 52 | { \ |
57 | .rate = (_r), \ | ||
58 | .m = (_m), \ | 53 | .m = (_m), \ |
59 | .n = (_n), \ | 54 | .n = (_n), \ |
60 | .od = (_od), \ | ||
61 | } | 55 | } |
62 | 56 | ||
63 | #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) | 57 | #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) |
64 | 58 | ||
65 | struct meson_clk_pll_data { | 59 | struct meson_clk_pll_data { |
60 | struct parm en; | ||
66 | struct parm m; | 61 | struct parm m; |
67 | struct parm n; | 62 | struct parm n; |
68 | struct parm frac; | 63 | struct parm frac; |
69 | struct parm od; | ||
70 | struct parm od2; | ||
71 | struct parm od3; | ||
72 | struct parm l; | 64 | struct parm l; |
73 | struct parm rst; | 65 | struct parm rst; |
74 | const struct reg_sequence *init_regs; | 66 | const struct reg_sequence *init_regs; |
75 | unsigned int init_count; | 67 | unsigned int init_count; |
76 | const struct pll_rate_table *table; | 68 | const struct pll_params_table *table; |
77 | u8 flags; | 69 | u8 flags; |
78 | }; | 70 | }; |
79 | 71 | ||
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 86d3ae58e84c..9309cfaaa464 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
@@ -18,165 +18,77 @@ | |||
18 | 18 | ||
19 | static DEFINE_SPINLOCK(meson_clk_lock); | 19 | static DEFINE_SPINLOCK(meson_clk_lock); |
20 | 20 | ||
21 | static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { | 21 | static const struct pll_params_table gxbb_gp0_pll_params_table[] = { |
22 | PLL_RATE(96000000, 32, 1, 3), | 22 | PLL_PARAMS(32, 1), |
23 | PLL_RATE(99000000, 33, 1, 3), | 23 | PLL_PARAMS(33, 1), |
24 | PLL_RATE(102000000, 34, 1, 3), | 24 | PLL_PARAMS(34, 1), |
25 | PLL_RATE(105000000, 35, 1, 3), | 25 | PLL_PARAMS(35, 1), |
26 | PLL_RATE(108000000, 36, 1, 3), | 26 | PLL_PARAMS(36, 1), |
27 | PLL_RATE(111000000, 37, 1, 3), | 27 | PLL_PARAMS(37, 1), |
28 | PLL_RATE(114000000, 38, 1, 3), | 28 | PLL_PARAMS(38, 1), |
29 | PLL_RATE(117000000, 39, 1, 3), | 29 | PLL_PARAMS(39, 1), |
30 | PLL_RATE(120000000, 40, 1, 3), | 30 | PLL_PARAMS(40, 1), |
31 | PLL_RATE(123000000, 41, 1, 3), | 31 | PLL_PARAMS(41, 1), |
32 | PLL_RATE(126000000, 42, 1, 3), | 32 | PLL_PARAMS(42, 1), |
33 | PLL_RATE(129000000, 43, 1, 3), | 33 | PLL_PARAMS(43, 1), |
34 | PLL_RATE(132000000, 44, 1, 3), | 34 | PLL_PARAMS(44, 1), |
35 | PLL_RATE(135000000, 45, 1, 3), | 35 | PLL_PARAMS(45, 1), |
36 | PLL_RATE(138000000, 46, 1, 3), | 36 | PLL_PARAMS(46, 1), |
37 | PLL_RATE(141000000, 47, 1, 3), | 37 | PLL_PARAMS(47, 1), |
38 | PLL_RATE(144000000, 48, 1, 3), | 38 | PLL_PARAMS(48, 1), |
39 | PLL_RATE(147000000, 49, 1, 3), | 39 | PLL_PARAMS(49, 1), |
40 | PLL_RATE(150000000, 50, 1, 3), | 40 | PLL_PARAMS(50, 1), |
41 | PLL_RATE(153000000, 51, 1, 3), | 41 | PLL_PARAMS(51, 1), |
42 | PLL_RATE(156000000, 52, 1, 3), | 42 | PLL_PARAMS(52, 1), |
43 | PLL_RATE(159000000, 53, 1, 3), | 43 | PLL_PARAMS(53, 1), |
44 | PLL_RATE(162000000, 54, 1, 3), | 44 | PLL_PARAMS(54, 1), |
45 | PLL_RATE(165000000, 55, 1, 3), | 45 | PLL_PARAMS(55, 1), |
46 | PLL_RATE(168000000, 56, 1, 3), | 46 | PLL_PARAMS(56, 1), |
47 | PLL_RATE(171000000, 57, 1, 3), | 47 | PLL_PARAMS(57, 1), |
48 | PLL_RATE(174000000, 58, 1, 3), | 48 | PLL_PARAMS(58, 1), |
49 | PLL_RATE(177000000, 59, 1, 3), | 49 | PLL_PARAMS(59, 1), |
50 | PLL_RATE(180000000, 60, 1, 3), | 50 | PLL_PARAMS(60, 1), |
51 | PLL_RATE(183000000, 61, 1, 3), | 51 | PLL_PARAMS(61, 1), |
52 | PLL_RATE(186000000, 62, 1, 3), | 52 | PLL_PARAMS(62, 1), |
53 | PLL_RATE(192000000, 32, 1, 2), | ||
54 | PLL_RATE(198000000, 33, 1, 2), | ||
55 | PLL_RATE(204000000, 34, 1, 2), | ||
56 | PLL_RATE(210000000, 35, 1, 2), | ||
57 | PLL_RATE(216000000, 36, 1, 2), | ||
58 | PLL_RATE(222000000, 37, 1, 2), | ||
59 | PLL_RATE(228000000, 38, 1, 2), | ||
60 | PLL_RATE(234000000, 39, 1, 2), | ||
61 | PLL_RATE(240000000, 40, 1, 2), | ||
62 | PLL_RATE(246000000, 41, 1, 2), | ||
63 | PLL_RATE(252000000, 42, 1, 2), | ||
64 | PLL_RATE(258000000, 43, 1, 2), | ||
65 | PLL_RATE(264000000, 44, 1, 2), | ||
66 | PLL_RATE(270000000, 45, 1, 2), | ||
67 | PLL_RATE(276000000, 46, 1, 2), | ||
68 | PLL_RATE(282000000, 47, 1, 2), | ||
69 | PLL_RATE(288000000, 48, 1, 2), | ||
70 | PLL_RATE(294000000, 49, 1, 2), | ||
71 | PLL_RATE(300000000, 50, 1, 2), | ||
72 | PLL_RATE(306000000, 51, 1, 2), | ||
73 | PLL_RATE(312000000, 52, 1, 2), | ||
74 | PLL_RATE(318000000, 53, 1, 2), | ||
75 | PLL_RATE(324000000, 54, 1, 2), | ||
76 | PLL_RATE(330000000, 55, 1, 2), | ||
77 | PLL_RATE(336000000, 56, 1, 2), | ||
78 | PLL_RATE(342000000, 57, 1, 2), | ||
79 | PLL_RATE(348000000, 58, 1, 2), | ||
80 | PLL_RATE(354000000, 59, 1, 2), | ||
81 | PLL_RATE(360000000, 60, 1, 2), | ||
82 | PLL_RATE(366000000, 61, 1, 2), | ||
83 | PLL_RATE(372000000, 62, 1, 2), | ||
84 | PLL_RATE(384000000, 32, 1, 1), | ||
85 | PLL_RATE(396000000, 33, 1, 1), | ||
86 | PLL_RATE(408000000, 34, 1, 1), | ||
87 | PLL_RATE(420000000, 35, 1, 1), | ||
88 | PLL_RATE(432000000, 36, 1, 1), | ||
89 | PLL_RATE(444000000, 37, 1, 1), | ||
90 | PLL_RATE(456000000, 38, 1, 1), | ||
91 | PLL_RATE(468000000, 39, 1, 1), | ||
92 | PLL_RATE(480000000, 40, 1, 1), | ||
93 | PLL_RATE(492000000, 41, 1, 1), | ||
94 | PLL_RATE(504000000, 42, 1, 1), | ||
95 | PLL_RATE(516000000, 43, 1, 1), | ||
96 | PLL_RATE(528000000, 44, 1, 1), | ||
97 | PLL_RATE(540000000, 45, 1, 1), | ||
98 | PLL_RATE(552000000, 46, 1, 1), | ||
99 | PLL_RATE(564000000, 47, 1, 1), | ||
100 | PLL_RATE(576000000, 48, 1, 1), | ||
101 | PLL_RATE(588000000, 49, 1, 1), | ||
102 | PLL_RATE(600000000, 50, 1, 1), | ||
103 | PLL_RATE(612000000, 51, 1, 1), | ||
104 | PLL_RATE(624000000, 52, 1, 1), | ||
105 | PLL_RATE(636000000, 53, 1, 1), | ||
106 | PLL_RATE(648000000, 54, 1, 1), | ||
107 | PLL_RATE(660000000, 55, 1, 1), | ||
108 | PLL_RATE(672000000, 56, 1, 1), | ||
109 | PLL_RATE(684000000, 57, 1, 1), | ||
110 | PLL_RATE(696000000, 58, 1, 1), | ||
111 | PLL_RATE(708000000, 59, 1, 1), | ||
112 | PLL_RATE(720000000, 60, 1, 1), | ||
113 | PLL_RATE(732000000, 61, 1, 1), | ||
114 | PLL_RATE(744000000, 62, 1, 1), | ||
115 | PLL_RATE(768000000, 32, 1, 0), | ||
116 | PLL_RATE(792000000, 33, 1, 0), | ||
117 | PLL_RATE(816000000, 34, 1, 0), | ||
118 | PLL_RATE(840000000, 35, 1, 0), | ||
119 | PLL_RATE(864000000, 36, 1, 0), | ||
120 | PLL_RATE(888000000, 37, 1, 0), | ||
121 | PLL_RATE(912000000, 38, 1, 0), | ||
122 | PLL_RATE(936000000, 39, 1, 0), | ||
123 | PLL_RATE(960000000, 40, 1, 0), | ||
124 | PLL_RATE(984000000, 41, 1, 0), | ||
125 | PLL_RATE(1008000000, 42, 1, 0), | ||
126 | PLL_RATE(1032000000, 43, 1, 0), | ||
127 | PLL_RATE(1056000000, 44, 1, 0), | ||
128 | PLL_RATE(1080000000, 45, 1, 0), | ||
129 | PLL_RATE(1104000000, 46, 1, 0), | ||
130 | PLL_RATE(1128000000, 47, 1, 0), | ||
131 | PLL_RATE(1152000000, 48, 1, 0), | ||
132 | PLL_RATE(1176000000, 49, 1, 0), | ||
133 | PLL_RATE(1200000000, 50, 1, 0), | ||
134 | PLL_RATE(1224000000, 51, 1, 0), | ||
135 | PLL_RATE(1248000000, 52, 1, 0), | ||
136 | PLL_RATE(1272000000, 53, 1, 0), | ||
137 | PLL_RATE(1296000000, 54, 1, 0), | ||
138 | PLL_RATE(1320000000, 55, 1, 0), | ||
139 | PLL_RATE(1344000000, 56, 1, 0), | ||
140 | PLL_RATE(1368000000, 57, 1, 0), | ||
141 | PLL_RATE(1392000000, 58, 1, 0), | ||
142 | PLL_RATE(1416000000, 59, 1, 0), | ||
143 | PLL_RATE(1440000000, 60, 1, 0), | ||
144 | PLL_RATE(1464000000, 61, 1, 0), | ||
145 | PLL_RATE(1488000000, 62, 1, 0), | ||
146 | { /* sentinel */ }, | 53 | { /* sentinel */ }, |
147 | }; | 54 | }; |
148 | 55 | ||
149 | static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { | 56 | static const struct pll_params_table gxl_gp0_pll_params_table[] = { |
150 | PLL_RATE(504000000, 42, 1, 1), | 57 | PLL_PARAMS(42, 1), |
151 | PLL_RATE(516000000, 43, 1, 1), | 58 | PLL_PARAMS(43, 1), |
152 | PLL_RATE(528000000, 44, 1, 1), | 59 | PLL_PARAMS(44, 1), |
153 | PLL_RATE(540000000, 45, 1, 1), | 60 | PLL_PARAMS(45, 1), |
154 | PLL_RATE(552000000, 46, 1, 1), | 61 | PLL_PARAMS(46, 1), |
155 | PLL_RATE(564000000, 47, 1, 1), | 62 | PLL_PARAMS(47, 1), |
156 | PLL_RATE(576000000, 48, 1, 1), | 63 | PLL_PARAMS(48, 1), |
157 | PLL_RATE(588000000, 49, 1, 1), | 64 | PLL_PARAMS(49, 1), |
158 | PLL_RATE(600000000, 50, 1, 1), | 65 | PLL_PARAMS(50, 1), |
159 | PLL_RATE(612000000, 51, 1, 1), | 66 | PLL_PARAMS(51, 1), |
160 | PLL_RATE(624000000, 52, 1, 1), | 67 | PLL_PARAMS(52, 1), |
161 | PLL_RATE(636000000, 53, 1, 1), | 68 | PLL_PARAMS(53, 1), |
162 | PLL_RATE(648000000, 54, 1, 1), | 69 | PLL_PARAMS(54, 1), |
163 | PLL_RATE(660000000, 55, 1, 1), | 70 | PLL_PARAMS(55, 1), |
164 | PLL_RATE(672000000, 56, 1, 1), | 71 | PLL_PARAMS(56, 1), |
165 | PLL_RATE(684000000, 57, 1, 1), | 72 | PLL_PARAMS(57, 1), |
166 | PLL_RATE(696000000, 58, 1, 1), | 73 | PLL_PARAMS(58, 1), |
167 | PLL_RATE(708000000, 59, 1, 1), | 74 | PLL_PARAMS(59, 1), |
168 | PLL_RATE(720000000, 60, 1, 1), | 75 | PLL_PARAMS(60, 1), |
169 | PLL_RATE(732000000, 61, 1, 1), | 76 | PLL_PARAMS(61, 1), |
170 | PLL_RATE(744000000, 62, 1, 1), | 77 | PLL_PARAMS(62, 1), |
171 | PLL_RATE(756000000, 63, 1, 1), | 78 | PLL_PARAMS(63, 1), |
172 | PLL_RATE(768000000, 64, 1, 1), | 79 | PLL_PARAMS(64, 1), |
173 | PLL_RATE(780000000, 65, 1, 1), | 80 | PLL_PARAMS(65, 1), |
174 | PLL_RATE(792000000, 66, 1, 1), | 81 | PLL_PARAMS(66, 1), |
175 | { /* sentinel */ }, | 82 | { /* sentinel */ }, |
176 | }; | 83 | }; |
177 | 84 | ||
178 | static struct clk_regmap gxbb_fixed_pll = { | 85 | static struct clk_regmap gxbb_fixed_pll_dco = { |
179 | .data = &(struct meson_clk_pll_data){ | 86 | .data = &(struct meson_clk_pll_data){ |
87 | .en = { | ||
88 | .reg_off = HHI_MPLL_CNTL, | ||
89 | .shift = 30, | ||
90 | .width = 1, | ||
91 | }, | ||
180 | .m = { | 92 | .m = { |
181 | .reg_off = HHI_MPLL_CNTL, | 93 | .reg_off = HHI_MPLL_CNTL, |
182 | .shift = 0, | 94 | .shift = 0, |
@@ -187,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = { | |||
187 | .shift = 9, | 99 | .shift = 9, |
188 | .width = 5, | 100 | .width = 5, |
189 | }, | 101 | }, |
190 | .od = { | ||
191 | .reg_off = HHI_MPLL_CNTL, | ||
192 | .shift = 16, | ||
193 | .width = 2, | ||
194 | }, | ||
195 | .frac = { | 102 | .frac = { |
196 | .reg_off = HHI_MPLL_CNTL2, | 103 | .reg_off = HHI_MPLL_CNTL2, |
197 | .shift = 0, | 104 | .shift = 0, |
@@ -209,11 +116,29 @@ static struct clk_regmap gxbb_fixed_pll = { | |||
209 | }, | 116 | }, |
210 | }, | 117 | }, |
211 | .hw.init = &(struct clk_init_data){ | 118 | .hw.init = &(struct clk_init_data){ |
212 | .name = "fixed_pll", | 119 | .name = "fixed_pll_dco", |
213 | .ops = &meson_clk_pll_ro_ops, | 120 | .ops = &meson_clk_pll_ro_ops, |
214 | .parent_names = (const char *[]){ "xtal" }, | 121 | .parent_names = (const char *[]){ "xtal" }, |
215 | .num_parents = 1, | 122 | .num_parents = 1, |
216 | .flags = CLK_GET_RATE_NOCACHE, | 123 | }, |
124 | }; | ||
125 | |||
126 | static struct clk_regmap gxbb_fixed_pll = { | ||
127 | .data = &(struct clk_regmap_div_data){ | ||
128 | .offset = HHI_MPLL_CNTL, | ||
129 | .shift = 16, | ||
130 | .width = 2, | ||
131 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
132 | }, | ||
133 | .hw.init = &(struct clk_init_data){ | ||
134 | .name = "fixed_pll", | ||
135 | .ops = &clk_regmap_divider_ro_ops, | ||
136 | .parent_names = (const char *[]){ "fixed_pll_dco" }, | ||
137 | .num_parents = 1, | ||
138 | /* | ||
139 | * This clock won't ever change at runtime so | ||
140 | * CLK_SET_RATE_PARENT is not required | ||
141 | */ | ||
217 | }, | 142 | }, |
218 | }; | 143 | }; |
219 | 144 | ||
@@ -228,8 +153,13 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { | |||
228 | }, | 153 | }, |
229 | }; | 154 | }; |
230 | 155 | ||
231 | static struct clk_regmap gxbb_hdmi_pll = { | 156 | static struct clk_regmap gxbb_hdmi_pll_dco = { |
232 | .data = &(struct meson_clk_pll_data){ | 157 | .data = &(struct meson_clk_pll_data){ |
158 | .en = { | ||
159 | .reg_off = HHI_HDMI_PLL_CNTL, | ||
160 | .shift = 30, | ||
161 | .width = 1, | ||
162 | }, | ||
233 | .m = { | 163 | .m = { |
234 | .reg_off = HHI_HDMI_PLL_CNTL, | 164 | .reg_off = HHI_HDMI_PLL_CNTL, |
235 | .shift = 0, | 165 | .shift = 0, |
@@ -245,21 +175,6 @@ static struct clk_regmap gxbb_hdmi_pll = { | |||
245 | .shift = 0, | 175 | .shift = 0, |
246 | .width = 12, | 176 | .width = 12, |
247 | }, | 177 | }, |
248 | .od = { | ||
249 | .reg_off = HHI_HDMI_PLL_CNTL2, | ||
250 | .shift = 16, | ||
251 | .width = 2, | ||
252 | }, | ||
253 | .od2 = { | ||
254 | .reg_off = HHI_HDMI_PLL_CNTL2, | ||
255 | .shift = 22, | ||
256 | .width = 2, | ||
257 | }, | ||
258 | .od3 = { | ||
259 | .reg_off = HHI_HDMI_PLL_CNTL2, | ||
260 | .shift = 18, | ||
261 | .width = 2, | ||
262 | }, | ||
263 | .l = { | 178 | .l = { |
264 | .reg_off = HHI_HDMI_PLL_CNTL, | 179 | .reg_off = HHI_HDMI_PLL_CNTL, |
265 | .shift = 31, | 180 | .shift = 31, |
@@ -272,74 +187,121 @@ static struct clk_regmap gxbb_hdmi_pll = { | |||
272 | }, | 187 | }, |
273 | }, | 188 | }, |
274 | .hw.init = &(struct clk_init_data){ | 189 | .hw.init = &(struct clk_init_data){ |
275 | .name = "hdmi_pll", | 190 | .name = "hdmi_pll_dco", |
276 | .ops = &meson_clk_pll_ro_ops, | 191 | .ops = &meson_clk_pll_ro_ops, |
277 | .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, | 192 | .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, |
278 | .num_parents = 1, | 193 | .num_parents = 1, |
194 | /* | ||
195 | * Display directly handle hdmi pll registers ATM, we need | ||
196 | * NOCACHE to keep our view of the clock as accurate as possible | ||
197 | */ | ||
279 | .flags = CLK_GET_RATE_NOCACHE, | 198 | .flags = CLK_GET_RATE_NOCACHE, |
280 | }, | 199 | }, |
281 | }; | 200 | }; |
282 | 201 | ||
202 | static struct clk_regmap gxbb_hdmi_pll_od = { | ||
203 | .data = &(struct clk_regmap_div_data){ | ||
204 | .offset = HHI_HDMI_PLL_CNTL2, | ||
205 | .shift = 16, | ||
206 | .width = 2, | ||
207 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
208 | }, | ||
209 | .hw.init = &(struct clk_init_data){ | ||
210 | .name = "hdmi_pll_od", | ||
211 | .ops = &clk_regmap_divider_ro_ops, | ||
212 | .parent_names = (const char *[]){ "hdmi_pll_dco" }, | ||
213 | .num_parents = 1, | ||
214 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, | ||
215 | }, | ||
216 | }; | ||
217 | |||
218 | static struct clk_regmap gxbb_hdmi_pll_od2 = { | ||
219 | .data = &(struct clk_regmap_div_data){ | ||
220 | .offset = HHI_HDMI_PLL_CNTL2, | ||
221 | .shift = 22, | ||
222 | .width = 2, | ||
223 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
224 | }, | ||
225 | .hw.init = &(struct clk_init_data){ | ||
226 | .name = "hdmi_pll_od2", | ||
227 | .ops = &clk_regmap_divider_ro_ops, | ||
228 | .parent_names = (const char *[]){ "hdmi_pll_od" }, | ||
229 | .num_parents = 1, | ||
230 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | static struct clk_regmap gxbb_hdmi_pll = { | ||
235 | .data = &(struct clk_regmap_div_data){ | ||
236 | .offset = HHI_HDMI_PLL_CNTL2, | ||
237 | .shift = 18, | ||
238 | .width = 2, | ||
239 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
240 | }, | ||
241 | .hw.init = &(struct clk_init_data){ | ||
242 | .name = "hdmi_pll", | ||
243 | .ops = &clk_regmap_divider_ro_ops, | ||
244 | .parent_names = (const char *[]){ "hdmi_pll_od2" }, | ||
245 | .num_parents = 1, | ||
246 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | static struct clk_regmap gxl_hdmi_pll_od = { | ||
251 | .data = &(struct clk_regmap_div_data){ | ||
252 | .offset = HHI_HDMI_PLL_CNTL + 8, | ||
253 | .shift = 21, | ||
254 | .width = 2, | ||
255 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
256 | }, | ||
257 | .hw.init = &(struct clk_init_data){ | ||
258 | .name = "hdmi_pll_od", | ||
259 | .ops = &clk_regmap_divider_ro_ops, | ||
260 | .parent_names = (const char *[]){ "hdmi_pll_dco" }, | ||
261 | .num_parents = 1, | ||
262 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static struct clk_regmap gxl_hdmi_pll_od2 = { | ||
267 | .data = &(struct clk_regmap_div_data){ | ||
268 | .offset = HHI_HDMI_PLL_CNTL + 8, | ||
269 | .shift = 23, | ||
270 | .width = 2, | ||
271 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
272 | }, | ||
273 | .hw.init = &(struct clk_init_data){ | ||
274 | .name = "hdmi_pll_od2", | ||
275 | .ops = &clk_regmap_divider_ro_ops, | ||
276 | .parent_names = (const char *[]){ "hdmi_pll_od" }, | ||
277 | .num_parents = 1, | ||
278 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, | ||
279 | }, | ||
280 | }; | ||
281 | |||
283 | static struct clk_regmap gxl_hdmi_pll = { | 282 | static struct clk_regmap gxl_hdmi_pll = { |
284 | .data = &(struct meson_clk_pll_data){ | 283 | .data = &(struct clk_regmap_div_data){ |
285 | .m = { | 284 | .offset = HHI_HDMI_PLL_CNTL + 8, |
286 | .reg_off = HHI_HDMI_PLL_CNTL, | 285 | .shift = 19, |
287 | .shift = 0, | 286 | .width = 2, |
288 | .width = 9, | 287 | .flags = CLK_DIVIDER_POWER_OF_TWO, |
289 | }, | ||
290 | .n = { | ||
291 | .reg_off = HHI_HDMI_PLL_CNTL, | ||
292 | .shift = 9, | ||
293 | .width = 5, | ||
294 | }, | ||
295 | .frac = { | ||
296 | /* | ||
297 | * On gxl, there is a register shift due to | ||
298 | * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb, | ||
299 | * so we compute the register offset based on the PLL | ||
300 | * base to get it right | ||
301 | */ | ||
302 | .reg_off = HHI_HDMI_PLL_CNTL + 4, | ||
303 | .shift = 0, | ||
304 | .width = 12, | ||
305 | }, | ||
306 | .od = { | ||
307 | .reg_off = HHI_HDMI_PLL_CNTL + 8, | ||
308 | .shift = 21, | ||
309 | .width = 2, | ||
310 | }, | ||
311 | .od2 = { | ||
312 | .reg_off = HHI_HDMI_PLL_CNTL + 8, | ||
313 | .shift = 23, | ||
314 | .width = 2, | ||
315 | }, | ||
316 | .od3 = { | ||
317 | .reg_off = HHI_HDMI_PLL_CNTL + 8, | ||
318 | .shift = 19, | ||
319 | .width = 2, | ||
320 | }, | ||
321 | .l = { | ||
322 | .reg_off = HHI_HDMI_PLL_CNTL, | ||
323 | .shift = 31, | ||
324 | .width = 1, | ||
325 | }, | ||
326 | .rst = { | ||
327 | .reg_off = HHI_HDMI_PLL_CNTL, | ||
328 | .shift = 29, | ||
329 | .width = 1, | ||
330 | }, | ||
331 | }, | 288 | }, |
332 | .hw.init = &(struct clk_init_data){ | 289 | .hw.init = &(struct clk_init_data){ |
333 | .name = "hdmi_pll", | 290 | .name = "hdmi_pll", |
334 | .ops = &meson_clk_pll_ro_ops, | 291 | .ops = &clk_regmap_divider_ro_ops, |
335 | .parent_names = (const char *[]){ "xtal" }, | 292 | .parent_names = (const char *[]){ "hdmi_pll_od2" }, |
336 | .num_parents = 1, | 293 | .num_parents = 1, |
337 | .flags = CLK_GET_RATE_NOCACHE, | 294 | .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, |
338 | }, | 295 | }, |
339 | }; | 296 | }; |
340 | 297 | ||
341 | static struct clk_regmap gxbb_sys_pll = { | 298 | static struct clk_regmap gxbb_sys_pll_dco = { |
342 | .data = &(struct meson_clk_pll_data){ | 299 | .data = &(struct meson_clk_pll_data){ |
300 | .en = { | ||
301 | .reg_off = HHI_SYS_PLL_CNTL, | ||
302 | .shift = 30, | ||
303 | .width = 1, | ||
304 | }, | ||
343 | .m = { | 305 | .m = { |
344 | .reg_off = HHI_SYS_PLL_CNTL, | 306 | .reg_off = HHI_SYS_PLL_CNTL, |
345 | .shift = 0, | 307 | .shift = 0, |
@@ -350,11 +312,6 @@ static struct clk_regmap gxbb_sys_pll = { | |||
350 | .shift = 9, | 312 | .shift = 9, |
351 | .width = 5, | 313 | .width = 5, |
352 | }, | 314 | }, |
353 | .od = { | ||
354 | .reg_off = HHI_SYS_PLL_CNTL, | ||
355 | .shift = 10, | ||
356 | .width = 2, | ||
357 | }, | ||
358 | .l = { | 315 | .l = { |
359 | .reg_off = HHI_SYS_PLL_CNTL, | 316 | .reg_off = HHI_SYS_PLL_CNTL, |
360 | .shift = 31, | 317 | .shift = 31, |
@@ -367,11 +324,26 @@ static struct clk_regmap gxbb_sys_pll = { | |||
367 | }, | 324 | }, |
368 | }, | 325 | }, |
369 | .hw.init = &(struct clk_init_data){ | 326 | .hw.init = &(struct clk_init_data){ |
370 | .name = "sys_pll", | 327 | .name = "sys_pll_dco", |
371 | .ops = &meson_clk_pll_ro_ops, | 328 | .ops = &meson_clk_pll_ro_ops, |
372 | .parent_names = (const char *[]){ "xtal" }, | 329 | .parent_names = (const char *[]){ "xtal" }, |
373 | .num_parents = 1, | 330 | .num_parents = 1, |
374 | .flags = CLK_GET_RATE_NOCACHE, | 331 | }, |
332 | }; | ||
333 | |||
334 | static struct clk_regmap gxbb_sys_pll = { | ||
335 | .data = &(struct clk_regmap_div_data){ | ||
336 | .offset = HHI_SYS_PLL_CNTL, | ||
337 | .shift = 10, | ||
338 | .width = 2, | ||
339 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
340 | }, | ||
341 | .hw.init = &(struct clk_init_data){ | ||
342 | .name = "sys_pll", | ||
343 | .ops = &clk_regmap_divider_ro_ops, | ||
344 | .parent_names = (const char *[]){ "sys_pll_dco" }, | ||
345 | .num_parents = 1, | ||
346 | .flags = CLK_SET_RATE_PARENT, | ||
375 | }, | 347 | }, |
376 | }; | 348 | }; |
377 | 349 | ||
@@ -379,11 +351,15 @@ static const struct reg_sequence gxbb_gp0_init_regs[] = { | |||
379 | { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, | 351 | { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, |
380 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, | 352 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, |
381 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, | 353 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, |
382 | { .reg = HHI_GP0_PLL_CNTL, .def = 0x4a000228 }, | ||
383 | }; | 354 | }; |
384 | 355 | ||
385 | static struct clk_regmap gxbb_gp0_pll = { | 356 | static struct clk_regmap gxbb_gp0_pll_dco = { |
386 | .data = &(struct meson_clk_pll_data){ | 357 | .data = &(struct meson_clk_pll_data){ |
358 | .en = { | ||
359 | .reg_off = HHI_GP0_PLL_CNTL, | ||
360 | .shift = 30, | ||
361 | .width = 1, | ||
362 | }, | ||
387 | .m = { | 363 | .m = { |
388 | .reg_off = HHI_GP0_PLL_CNTL, | 364 | .reg_off = HHI_GP0_PLL_CNTL, |
389 | .shift = 0, | 365 | .shift = 0, |
@@ -394,11 +370,6 @@ static struct clk_regmap gxbb_gp0_pll = { | |||
394 | .shift = 9, | 370 | .shift = 9, |
395 | .width = 5, | 371 | .width = 5, |
396 | }, | 372 | }, |
397 | .od = { | ||
398 | .reg_off = HHI_GP0_PLL_CNTL, | ||
399 | .shift = 16, | ||
400 | .width = 2, | ||
401 | }, | ||
402 | .l = { | 373 | .l = { |
403 | .reg_off = HHI_GP0_PLL_CNTL, | 374 | .reg_off = HHI_GP0_PLL_CNTL, |
404 | .shift = 31, | 375 | .shift = 31, |
@@ -409,16 +380,15 @@ static struct clk_regmap gxbb_gp0_pll = { | |||
409 | .shift = 29, | 380 | .shift = 29, |
410 | .width = 1, | 381 | .width = 1, |
411 | }, | 382 | }, |
412 | .table = gxbb_gp0_pll_rate_table, | 383 | .table = gxbb_gp0_pll_params_table, |
413 | .init_regs = gxbb_gp0_init_regs, | 384 | .init_regs = gxbb_gp0_init_regs, |
414 | .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), | 385 | .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), |
415 | }, | 386 | }, |
416 | .hw.init = &(struct clk_init_data){ | 387 | .hw.init = &(struct clk_init_data){ |
417 | .name = "gp0_pll", | 388 | .name = "gp0_pll_dco", |
418 | .ops = &meson_clk_pll_ops, | 389 | .ops = &meson_clk_pll_ops, |
419 | .parent_names = (const char *[]){ "xtal" }, | 390 | .parent_names = (const char *[]){ "xtal" }, |
420 | .num_parents = 1, | 391 | .num_parents = 1, |
421 | .flags = CLK_GET_RATE_NOCACHE, | ||
422 | }, | 392 | }, |
423 | }; | 393 | }; |
424 | 394 | ||
@@ -428,11 +398,15 @@ static const struct reg_sequence gxl_gp0_init_regs[] = { | |||
428 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, | 398 | { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, |
429 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, | 399 | { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, |
430 | { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, | 400 | { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, |
431 | { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 }, | ||
432 | }; | 401 | }; |
433 | 402 | ||
434 | static struct clk_regmap gxl_gp0_pll = { | 403 | static struct clk_regmap gxl_gp0_pll_dco = { |
435 | .data = &(struct meson_clk_pll_data){ | 404 | .data = &(struct meson_clk_pll_data){ |
405 | .en = { | ||
406 | .reg_off = HHI_GP0_PLL_CNTL, | ||
407 | .shift = 30, | ||
408 | .width = 1, | ||
409 | }, | ||
436 | .m = { | 410 | .m = { |
437 | .reg_off = HHI_GP0_PLL_CNTL, | 411 | .reg_off = HHI_GP0_PLL_CNTL, |
438 | .shift = 0, | 412 | .shift = 0, |
@@ -443,11 +417,6 @@ static struct clk_regmap gxl_gp0_pll = { | |||
443 | .shift = 9, | 417 | .shift = 9, |
444 | .width = 5, | 418 | .width = 5, |
445 | }, | 419 | }, |
446 | .od = { | ||
447 | .reg_off = HHI_GP0_PLL_CNTL, | ||
448 | .shift = 16, | ||
449 | .width = 2, | ||
450 | }, | ||
451 | .frac = { | 420 | .frac = { |
452 | .reg_off = HHI_GP0_PLL_CNTL1, | 421 | .reg_off = HHI_GP0_PLL_CNTL1, |
453 | .shift = 0, | 422 | .shift = 0, |
@@ -463,16 +432,31 @@ static struct clk_regmap gxl_gp0_pll = { | |||
463 | .shift = 29, | 432 | .shift = 29, |
464 | .width = 1, | 433 | .width = 1, |
465 | }, | 434 | }, |
466 | .table = gxl_gp0_pll_rate_table, | 435 | .table = gxl_gp0_pll_params_table, |
467 | .init_regs = gxl_gp0_init_regs, | 436 | .init_regs = gxl_gp0_init_regs, |
468 | .init_count = ARRAY_SIZE(gxl_gp0_init_regs), | 437 | .init_count = ARRAY_SIZE(gxl_gp0_init_regs), |
469 | }, | 438 | }, |
470 | .hw.init = &(struct clk_init_data){ | 439 | .hw.init = &(struct clk_init_data){ |
471 | .name = "gp0_pll", | 440 | .name = "gp0_pll_dco", |
472 | .ops = &meson_clk_pll_ops, | 441 | .ops = &meson_clk_pll_ops, |
473 | .parent_names = (const char *[]){ "xtal" }, | 442 | .parent_names = (const char *[]){ "xtal" }, |
474 | .num_parents = 1, | 443 | .num_parents = 1, |
475 | .flags = CLK_GET_RATE_NOCACHE, | 444 | }, |
445 | }; | ||
446 | |||
447 | static struct clk_regmap gxbb_gp0_pll = { | ||
448 | .data = &(struct clk_regmap_div_data){ | ||
449 | .offset = HHI_GP0_PLL_CNTL, | ||
450 | .shift = 16, | ||
451 | .width = 2, | ||
452 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
453 | }, | ||
454 | .hw.init = &(struct clk_init_data){ | ||
455 | .name = "gp0_pll", | ||
456 | .ops = &clk_regmap_divider_ops, | ||
457 | .parent_names = (const char *[]){ "gp0_pll_dco" }, | ||
458 | .num_parents = 1, | ||
459 | .flags = CLK_SET_RATE_PARENT, | ||
476 | }, | 460 | }, |
477 | }; | 461 | }; |
478 | 462 | ||
@@ -1933,6 +1917,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { | |||
1933 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, | 1917 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, |
1934 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, | 1918 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, |
1935 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, | 1919 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, |
1920 | [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, | ||
1921 | [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, | ||
1922 | [CLKID_HDMI_PLL_OD] = &gxbb_hdmi_pll_od.hw, | ||
1923 | [CLKID_HDMI_PLL_OD2] = &gxbb_hdmi_pll_od2.hw, | ||
1924 | [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, | ||
1925 | [CLKID_GP0_PLL_DCO] = &gxbb_gp0_pll_dco.hw, | ||
1936 | [NR_CLKS] = NULL, | 1926 | [NR_CLKS] = NULL, |
1937 | }, | 1927 | }, |
1938 | .num = NR_CLKS, | 1928 | .num = NR_CLKS, |
@@ -1948,7 +1938,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { | |||
1948 | [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, | 1938 | [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, |
1949 | [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, | 1939 | [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, |
1950 | [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, | 1940 | [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, |
1951 | [CLKID_GP0_PLL] = &gxl_gp0_pll.hw, | 1941 | [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, |
1952 | [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, | 1942 | [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, |
1953 | [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, | 1943 | [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, |
1954 | [CLKID_CLK81] = &gxbb_clk81.hw, | 1944 | [CLKID_CLK81] = &gxbb_clk81.hw, |
@@ -2098,19 +2088,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { | |||
2098 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, | 2088 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, |
2099 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, | 2089 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, |
2100 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, | 2090 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, |
2091 | [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, | ||
2092 | [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, | ||
2093 | [CLKID_HDMI_PLL_OD] = &gxl_hdmi_pll_od.hw, | ||
2094 | [CLKID_HDMI_PLL_OD2] = &gxl_hdmi_pll_od2.hw, | ||
2095 | [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, | ||
2096 | [CLKID_GP0_PLL_DCO] = &gxl_gp0_pll_dco.hw, | ||
2101 | [NR_CLKS] = NULL, | 2097 | [NR_CLKS] = NULL, |
2102 | }, | 2098 | }, |
2103 | .num = NR_CLKS, | 2099 | .num = NR_CLKS, |
2104 | }; | 2100 | }; |
2105 | 2101 | ||
2106 | static struct clk_regmap *const gxbb_clk_regmaps[] = { | 2102 | static struct clk_regmap *const gxbb_clk_regmaps[] = { |
2107 | &gxbb_gp0_pll, | 2103 | &gxbb_gp0_pll_dco, |
2108 | &gxbb_hdmi_pll, | 2104 | &gxbb_hdmi_pll, |
2105 | &gxbb_hdmi_pll_od, | ||
2106 | &gxbb_hdmi_pll_od2, | ||
2109 | }; | 2107 | }; |
2110 | 2108 | ||
2111 | static struct clk_regmap *const gxl_clk_regmaps[] = { | 2109 | static struct clk_regmap *const gxl_clk_regmaps[] = { |
2112 | &gxl_gp0_pll, | 2110 | &gxl_gp0_pll_dco, |
2113 | &gxl_hdmi_pll, | 2111 | &gxl_hdmi_pll, |
2112 | &gxl_hdmi_pll_od, | ||
2113 | &gxl_hdmi_pll_od2, | ||
2114 | }; | 2114 | }; |
2115 | 2115 | ||
2116 | static struct clk_regmap *const gx_clk_regmaps[] = { | 2116 | static struct clk_regmap *const gx_clk_regmaps[] = { |
@@ -2265,6 +2265,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = { | |||
2265 | &gxbb_gen_clk_sel, | 2265 | &gxbb_gen_clk_sel, |
2266 | &gxbb_gen_clk_div, | 2266 | &gxbb_gen_clk_div, |
2267 | &gxbb_gen_clk, | 2267 | &gxbb_gen_clk, |
2268 | &gxbb_fixed_pll_dco, | ||
2269 | &gxbb_hdmi_pll_dco, | ||
2270 | &gxbb_sys_pll_dco, | ||
2271 | &gxbb_gp0_pll, | ||
2268 | }; | 2272 | }; |
2269 | 2273 | ||
2270 | struct clkc_data { | 2274 | struct clkc_data { |
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 20dfb1daf5b8..72bc077d9663 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h | |||
@@ -159,8 +159,14 @@ | |||
159 | #define CLKID_VDEC_HEVC_DIV 155 | 159 | #define CLKID_VDEC_HEVC_DIV 155 |
160 | #define CLKID_GEN_CLK_SEL 157 | 160 | #define CLKID_GEN_CLK_SEL 157 |
161 | #define CLKID_GEN_CLK_DIV 158 | 161 | #define CLKID_GEN_CLK_DIV 158 |
162 | 162 | #define CLKID_FIXED_PLL_DCO 160 | |
163 | #define NR_CLKS 160 | 163 | #define CLKID_HDMI_PLL_DCO 161 |
164 | #define CLKID_HDMI_PLL_OD 162 | ||
165 | #define CLKID_HDMI_PLL_OD2 163 | ||
166 | #define CLKID_SYS_PLL_DCO 164 | ||
167 | #define CLKID_GP0_PLL_DCO 165 | ||
168 | |||
169 | #define NR_CLKS 166 | ||
164 | 170 | ||
165 | /* include the CLKIDs that have been made part of the DT binding */ | 171 | /* include the CLKIDs that have been made part of the DT binding */ |
166 | #include <dt-bindings/clock/gxbb-clkc.h> | 172 | #include <dt-bindings/clock/gxbb-clkc.h> |
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 7447d96a265f..346b9e165b7a 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/clk-provider.h> | 11 | #include <linux/clk-provider.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/reset-controller.h> | 14 | #include <linux/reset-controller.h> |
16 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
17 | #include <linux/regmap.h> | 16 | #include <linux/regmap.h> |
@@ -22,66 +21,27 @@ | |||
22 | 21 | ||
23 | static DEFINE_SPINLOCK(meson_clk_lock); | 22 | static DEFINE_SPINLOCK(meson_clk_lock); |
24 | 23 | ||
25 | static void __iomem *clk_base; | ||
26 | |||
27 | struct meson8b_clk_reset { | 24 | struct meson8b_clk_reset { |
28 | struct reset_controller_dev reset; | 25 | struct reset_controller_dev reset; |
29 | void __iomem *base; | 26 | struct regmap *regmap; |
30 | }; | 27 | }; |
31 | 28 | ||
32 | static const struct pll_rate_table sys_pll_rate_table[] = { | 29 | static const struct pll_params_table sys_pll_params_table[] = { |
33 | PLL_RATE(312000000, 52, 1, 2), | 30 | PLL_PARAMS(50, 1), |
34 | PLL_RATE(336000000, 56, 1, 2), | 31 | PLL_PARAMS(51, 1), |
35 | PLL_RATE(360000000, 60, 1, 2), | 32 | PLL_PARAMS(52, 1), |
36 | PLL_RATE(384000000, 64, 1, 2), | 33 | PLL_PARAMS(53, 1), |
37 | PLL_RATE(408000000, 68, 1, 2), | 34 | PLL_PARAMS(54, 1), |
38 | PLL_RATE(432000000, 72, 1, 2), | 35 | PLL_PARAMS(55, 1), |
39 | PLL_RATE(456000000, 76, 1, 2), | 36 | PLL_PARAMS(56, 1), |
40 | PLL_RATE(480000000, 80, 1, 2), | 37 | PLL_PARAMS(57, 1), |
41 | PLL_RATE(504000000, 84, 1, 2), | 38 | PLL_PARAMS(58, 1), |
42 | PLL_RATE(528000000, 88, 1, 2), | 39 | PLL_PARAMS(59, 1), |
43 | PLL_RATE(552000000, 92, 1, 2), | 40 | PLL_PARAMS(60, 1), |
44 | PLL_RATE(576000000, 96, 1, 2), | 41 | PLL_PARAMS(61, 1), |
45 | PLL_RATE(600000000, 50, 1, 1), | 42 | PLL_PARAMS(62, 1), |
46 | PLL_RATE(624000000, 52, 1, 1), | 43 | PLL_PARAMS(63, 1), |
47 | PLL_RATE(648000000, 54, 1, 1), | 44 | PLL_PARAMS(64, 1), |
48 | PLL_RATE(672000000, 56, 1, 1), | ||
49 | PLL_RATE(696000000, 58, 1, 1), | ||
50 | PLL_RATE(720000000, 60, 1, 1), | ||
51 | PLL_RATE(744000000, 62, 1, 1), | ||
52 | PLL_RATE(768000000, 64, 1, 1), | ||
53 | PLL_RATE(792000000, 66, 1, 1), | ||
54 | PLL_RATE(816000000, 68, 1, 1), | ||
55 | PLL_RATE(840000000, 70, 1, 1), | ||
56 | PLL_RATE(864000000, 72, 1, 1), | ||
57 | PLL_RATE(888000000, 74, 1, 1), | ||
58 | PLL_RATE(912000000, 76, 1, 1), | ||
59 | PLL_RATE(936000000, 78, 1, 1), | ||
60 | PLL_RATE(960000000, 80, 1, 1), | ||
61 | PLL_RATE(984000000, 82, 1, 1), | ||
62 | PLL_RATE(1008000000, 84, 1, 1), | ||
63 | PLL_RATE(1032000000, 86, 1, 1), | ||
64 | PLL_RATE(1056000000, 88, 1, 1), | ||
65 | PLL_RATE(1080000000, 90, 1, 1), | ||
66 | PLL_RATE(1104000000, 92, 1, 1), | ||
67 | PLL_RATE(1128000000, 94, 1, 1), | ||
68 | PLL_RATE(1152000000, 96, 1, 1), | ||
69 | PLL_RATE(1176000000, 98, 1, 1), | ||
70 | PLL_RATE(1200000000, 50, 1, 0), | ||
71 | PLL_RATE(1224000000, 51, 1, 0), | ||
72 | PLL_RATE(1248000000, 52, 1, 0), | ||
73 | PLL_RATE(1272000000, 53, 1, 0), | ||
74 | PLL_RATE(1296000000, 54, 1, 0), | ||
75 | PLL_RATE(1320000000, 55, 1, 0), | ||
76 | PLL_RATE(1344000000, 56, 1, 0), | ||
77 | PLL_RATE(1368000000, 57, 1, 0), | ||
78 | PLL_RATE(1392000000, 58, 1, 0), | ||
79 | PLL_RATE(1416000000, 59, 1, 0), | ||
80 | PLL_RATE(1440000000, 60, 1, 0), | ||
81 | PLL_RATE(1464000000, 61, 1, 0), | ||
82 | PLL_RATE(1488000000, 62, 1, 0), | ||
83 | PLL_RATE(1512000000, 63, 1, 0), | ||
84 | PLL_RATE(1536000000, 64, 1, 0), | ||
85 | { /* sentinel */ }, | 45 | { /* sentinel */ }, |
86 | }; | 46 | }; |
87 | 47 | ||
@@ -94,8 +54,13 @@ static struct clk_fixed_rate meson8b_xtal = { | |||
94 | }, | 54 | }, |
95 | }; | 55 | }; |
96 | 56 | ||
97 | static struct clk_regmap meson8b_fixed_pll = { | 57 | static struct clk_regmap meson8b_fixed_pll_dco = { |
98 | .data = &(struct meson_clk_pll_data){ | 58 | .data = &(struct meson_clk_pll_data){ |
59 | .en = { | ||
60 | .reg_off = HHI_MPLL_CNTL, | ||
61 | .shift = 30, | ||
62 | .width = 1, | ||
63 | }, | ||
99 | .m = { | 64 | .m = { |
100 | .reg_off = HHI_MPLL_CNTL, | 65 | .reg_off = HHI_MPLL_CNTL, |
101 | .shift = 0, | 66 | .shift = 0, |
@@ -106,11 +71,6 @@ static struct clk_regmap meson8b_fixed_pll = { | |||
106 | .shift = 9, | 71 | .shift = 9, |
107 | .width = 5, | 72 | .width = 5, |
108 | }, | 73 | }, |
109 | .od = { | ||
110 | .reg_off = HHI_MPLL_CNTL, | ||
111 | .shift = 16, | ||
112 | .width = 2, | ||
113 | }, | ||
114 | .frac = { | 74 | .frac = { |
115 | .reg_off = HHI_MPLL_CNTL2, | 75 | .reg_off = HHI_MPLL_CNTL2, |
116 | .shift = 0, | 76 | .shift = 0, |
@@ -128,16 +88,39 @@ static struct clk_regmap meson8b_fixed_pll = { | |||
128 | }, | 88 | }, |
129 | }, | 89 | }, |
130 | .hw.init = &(struct clk_init_data){ | 90 | .hw.init = &(struct clk_init_data){ |
131 | .name = "fixed_pll", | 91 | .name = "fixed_pll_dco", |
132 | .ops = &meson_clk_pll_ro_ops, | 92 | .ops = &meson_clk_pll_ro_ops, |
133 | .parent_names = (const char *[]){ "xtal" }, | 93 | .parent_names = (const char *[]){ "xtal" }, |
134 | .num_parents = 1, | 94 | .num_parents = 1, |
135 | .flags = CLK_GET_RATE_NOCACHE, | ||
136 | }, | 95 | }, |
137 | }; | 96 | }; |
138 | 97 | ||
139 | static struct clk_regmap meson8b_vid_pll = { | 98 | static struct clk_regmap meson8b_fixed_pll = { |
99 | .data = &(struct clk_regmap_div_data){ | ||
100 | .offset = HHI_MPLL_CNTL, | ||
101 | .shift = 16, | ||
102 | .width = 2, | ||
103 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
104 | }, | ||
105 | .hw.init = &(struct clk_init_data){ | ||
106 | .name = "fixed_pll", | ||
107 | .ops = &clk_regmap_divider_ro_ops, | ||
108 | .parent_names = (const char *[]){ "fixed_pll_dco" }, | ||
109 | .num_parents = 1, | ||
110 | /* | ||
111 | * This clock won't ever change at runtime so | ||
112 | * CLK_SET_RATE_PARENT is not required | ||
113 | */ | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct clk_regmap meson8b_vid_pll_dco = { | ||
140 | .data = &(struct meson_clk_pll_data){ | 118 | .data = &(struct meson_clk_pll_data){ |
119 | .en = { | ||
120 | .reg_off = HHI_VID_PLL_CNTL, | ||
121 | .shift = 30, | ||
122 | .width = 1, | ||
123 | }, | ||
141 | .m = { | 124 | .m = { |
142 | .reg_off = HHI_VID_PLL_CNTL, | 125 | .reg_off = HHI_VID_PLL_CNTL, |
143 | .shift = 0, | 126 | .shift = 0, |
@@ -148,11 +131,6 @@ static struct clk_regmap meson8b_vid_pll = { | |||
148 | .shift = 9, | 131 | .shift = 9, |
149 | .width = 5, | 132 | .width = 5, |
150 | }, | 133 | }, |
151 | .od = { | ||
152 | .reg_off = HHI_VID_PLL_CNTL, | ||
153 | .shift = 16, | ||
154 | .width = 2, | ||
155 | }, | ||
156 | .l = { | 134 | .l = { |
157 | .reg_off = HHI_VID_PLL_CNTL, | 135 | .reg_off = HHI_VID_PLL_CNTL, |
158 | .shift = 31, | 136 | .shift = 31, |
@@ -165,16 +143,36 @@ static struct clk_regmap meson8b_vid_pll = { | |||
165 | }, | 143 | }, |
166 | }, | 144 | }, |
167 | .hw.init = &(struct clk_init_data){ | 145 | .hw.init = &(struct clk_init_data){ |
168 | .name = "vid_pll", | 146 | .name = "vid_pll_dco", |
169 | .ops = &meson_clk_pll_ro_ops, | 147 | .ops = &meson_clk_pll_ro_ops, |
170 | .parent_names = (const char *[]){ "xtal" }, | 148 | .parent_names = (const char *[]){ "xtal" }, |
171 | .num_parents = 1, | 149 | .num_parents = 1, |
172 | .flags = CLK_GET_RATE_NOCACHE, | ||
173 | }, | 150 | }, |
174 | }; | 151 | }; |
175 | 152 | ||
176 | static struct clk_regmap meson8b_sys_pll = { | 153 | static struct clk_regmap meson8b_vid_pll = { |
154 | .data = &(struct clk_regmap_div_data){ | ||
155 | .offset = HHI_VID_PLL_CNTL, | ||
156 | .shift = 16, | ||
157 | .width = 2, | ||
158 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
159 | }, | ||
160 | .hw.init = &(struct clk_init_data){ | ||
161 | .name = "vid_pll", | ||
162 | .ops = &clk_regmap_divider_ro_ops, | ||
163 | .parent_names = (const char *[]){ "vid_pll_dco" }, | ||
164 | .num_parents = 1, | ||
165 | .flags = CLK_SET_RATE_PARENT, | ||
166 | }, | ||
167 | }; | ||
168 | |||
169 | static struct clk_regmap meson8b_sys_pll_dco = { | ||
177 | .data = &(struct meson_clk_pll_data){ | 170 | .data = &(struct meson_clk_pll_data){ |
171 | .en = { | ||
172 | .reg_off = HHI_SYS_PLL_CNTL, | ||
173 | .shift = 30, | ||
174 | .width = 1, | ||
175 | }, | ||
178 | .m = { | 176 | .m = { |
179 | .reg_off = HHI_SYS_PLL_CNTL, | 177 | .reg_off = HHI_SYS_PLL_CNTL, |
180 | .shift = 0, | 178 | .shift = 0, |
@@ -185,11 +183,6 @@ static struct clk_regmap meson8b_sys_pll = { | |||
185 | .shift = 9, | 183 | .shift = 9, |
186 | .width = 5, | 184 | .width = 5, |
187 | }, | 185 | }, |
188 | .od = { | ||
189 | .reg_off = HHI_SYS_PLL_CNTL, | ||
190 | .shift = 16, | ||
191 | .width = 2, | ||
192 | }, | ||
193 | .l = { | 186 | .l = { |
194 | .reg_off = HHI_SYS_PLL_CNTL, | 187 | .reg_off = HHI_SYS_PLL_CNTL, |
195 | .shift = 31, | 188 | .shift = 31, |
@@ -200,14 +193,29 @@ static struct clk_regmap meson8b_sys_pll = { | |||
200 | .shift = 29, | 193 | .shift = 29, |
201 | .width = 1, | 194 | .width = 1, |
202 | }, | 195 | }, |
203 | .table = sys_pll_rate_table, | 196 | .table = sys_pll_params_table, |
204 | }, | 197 | }, |
205 | .hw.init = &(struct clk_init_data){ | 198 | .hw.init = &(struct clk_init_data){ |
206 | .name = "sys_pll", | 199 | .name = "sys_pll_dco", |
207 | .ops = &meson_clk_pll_ro_ops, | 200 | .ops = &meson_clk_pll_ro_ops, |
208 | .parent_names = (const char *[]){ "xtal" }, | 201 | .parent_names = (const char *[]){ "xtal" }, |
209 | .num_parents = 1, | 202 | .num_parents = 1, |
210 | .flags = CLK_GET_RATE_NOCACHE, | 203 | }, |
204 | }; | ||
205 | |||
206 | static struct clk_regmap meson8b_sys_pll = { | ||
207 | .data = &(struct clk_regmap_div_data){ | ||
208 | .offset = HHI_SYS_PLL_CNTL, | ||
209 | .shift = 16, | ||
210 | .width = 2, | ||
211 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
212 | }, | ||
213 | .hw.init = &(struct clk_init_data){ | ||
214 | .name = "sys_pll", | ||
215 | .ops = &clk_regmap_divider_ro_ops, | ||
216 | .parent_names = (const char *[]){ "sys_pll_dco" }, | ||
217 | .num_parents = 1, | ||
218 | .flags = CLK_SET_RATE_PARENT, | ||
211 | }, | 219 | }, |
212 | }; | 220 | }; |
213 | 221 | ||
@@ -879,6 +887,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { | |||
879 | [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, | 887 | [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, |
880 | [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, | 888 | [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, |
881 | [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, | 889 | [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, |
890 | [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, | ||
891 | [CLKID_PLL_VID_DCO] = &meson8b_vid_pll_dco.hw, | ||
892 | [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, | ||
882 | [CLK_NR_CLKS] = NULL, | 893 | [CLK_NR_CLKS] = NULL, |
883 | }, | 894 | }, |
884 | .num = CLK_NR_CLKS, | 895 | .num = CLK_NR_CLKS, |
@@ -987,6 +998,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { | |||
987 | &meson8b_nand_clk_sel, | 998 | &meson8b_nand_clk_sel, |
988 | &meson8b_nand_clk_div, | 999 | &meson8b_nand_clk_div, |
989 | &meson8b_nand_clk_gate, | 1000 | &meson8b_nand_clk_gate, |
1001 | &meson8b_fixed_pll_dco, | ||
1002 | &meson8b_vid_pll_dco, | ||
1003 | &meson8b_sys_pll_dco, | ||
990 | }; | 1004 | }; |
991 | 1005 | ||
992 | static const struct meson8b_clk_reset_line { | 1006 | static const struct meson8b_clk_reset_line { |
@@ -1050,7 +1064,6 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, | |||
1050 | container_of(rcdev, struct meson8b_clk_reset, reset); | 1064 | container_of(rcdev, struct meson8b_clk_reset, reset); |
1051 | unsigned long flags; | 1065 | unsigned long flags; |
1052 | const struct meson8b_clk_reset_line *reset; | 1066 | const struct meson8b_clk_reset_line *reset; |
1053 | u32 val; | ||
1054 | 1067 | ||
1055 | if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) | 1068 | if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) |
1056 | return -EINVAL; | 1069 | return -EINVAL; |
@@ -1059,12 +1072,12 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, | |||
1059 | 1072 | ||
1060 | spin_lock_irqsave(&meson_clk_lock, flags); | 1073 | spin_lock_irqsave(&meson_clk_lock, flags); |
1061 | 1074 | ||
1062 | val = readl(meson8b_clk_reset->base + reset->reg); | ||
1063 | if (assert) | 1075 | if (assert) |
1064 | val |= BIT(reset->bit_idx); | 1076 | regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, |
1077 | BIT(reset->bit_idx), BIT(reset->bit_idx)); | ||
1065 | else | 1078 | else |
1066 | val &= ~BIT(reset->bit_idx); | 1079 | regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, |
1067 | writel(val, meson8b_clk_reset->base + reset->reg); | 1080 | BIT(reset->bit_idx), 0); |
1068 | 1081 | ||
1069 | spin_unlock_irqrestore(&meson_clk_lock, flags); | 1082 | spin_unlock_irqrestore(&meson_clk_lock, flags); |
1070 | 1083 | ||
@@ -1094,62 +1107,12 @@ static const struct regmap_config clkc_regmap_config = { | |||
1094 | .reg_stride = 4, | 1107 | .reg_stride = 4, |
1095 | }; | 1108 | }; |
1096 | 1109 | ||
1097 | static int meson8b_clkc_probe(struct platform_device *pdev) | 1110 | static void __init meson8b_clkc_init(struct device_node *np) |
1098 | { | ||
1099 | int ret, i; | ||
1100 | struct device *dev = &pdev->dev; | ||
1101 | struct regmap *map; | ||
1102 | |||
1103 | if (!clk_base) | ||
1104 | return -ENXIO; | ||
1105 | |||
1106 | map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config); | ||
1107 | if (IS_ERR(map)) | ||
1108 | return PTR_ERR(map); | ||
1109 | |||
1110 | /* Populate regmap for the regmap backed clocks */ | ||
1111 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++) | ||
1112 | meson8b_clk_regmaps[i]->map = map; | ||
1113 | |||
1114 | /* | ||
1115 | * register all clks | ||
1116 | * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 | ||
1117 | */ | ||
1118 | for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { | ||
1119 | /* array might be sparse */ | ||
1120 | if (!meson8b_hw_onecell_data.hws[i]) | ||
1121 | continue; | ||
1122 | |||
1123 | ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]); | ||
1124 | if (ret) | ||
1125 | return ret; | ||
1126 | } | ||
1127 | |||
1128 | return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, | ||
1129 | &meson8b_hw_onecell_data); | ||
1130 | } | ||
1131 | |||
1132 | static const struct of_device_id meson8b_clkc_match_table[] = { | ||
1133 | { .compatible = "amlogic,meson8-clkc" }, | ||
1134 | { .compatible = "amlogic,meson8b-clkc" }, | ||
1135 | { .compatible = "amlogic,meson8m2-clkc" }, | ||
1136 | { } | ||
1137 | }; | ||
1138 | |||
1139 | static struct platform_driver meson8b_driver = { | ||
1140 | .probe = meson8b_clkc_probe, | ||
1141 | .driver = { | ||
1142 | .name = "meson8b-clkc", | ||
1143 | .of_match_table = meson8b_clkc_match_table, | ||
1144 | }, | ||
1145 | }; | ||
1146 | |||
1147 | builtin_platform_driver(meson8b_driver); | ||
1148 | |||
1149 | static void __init meson8b_clkc_reset_init(struct device_node *np) | ||
1150 | { | 1111 | { |
1151 | struct meson8b_clk_reset *rstc; | 1112 | struct meson8b_clk_reset *rstc; |
1152 | int ret; | 1113 | void __iomem *clk_base; |
1114 | struct regmap *map; | ||
1115 | int i, ret; | ||
1153 | 1116 | ||
1154 | /* Generic clocks, PLLs and some of the reset-bits */ | 1117 | /* Generic clocks, PLLs and some of the reset-bits */ |
1155 | clk_base = of_iomap(np, 1); | 1118 | clk_base = of_iomap(np, 1); |
@@ -1158,12 +1121,16 @@ static void __init meson8b_clkc_reset_init(struct device_node *np) | |||
1158 | return; | 1121 | return; |
1159 | } | 1122 | } |
1160 | 1123 | ||
1124 | map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config); | ||
1125 | if (IS_ERR(map)) | ||
1126 | return; | ||
1127 | |||
1161 | rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); | 1128 | rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); |
1162 | if (!rstc) | 1129 | if (!rstc) |
1163 | return; | 1130 | return; |
1164 | 1131 | ||
1165 | /* Reset Controller */ | 1132 | /* Reset Controller */ |
1166 | rstc->base = clk_base; | 1133 | rstc->regmap = map; |
1167 | rstc->reset.ops = &meson8b_clk_reset_ops; | 1134 | rstc->reset.ops = &meson8b_clk_reset_ops; |
1168 | rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); | 1135 | rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); |
1169 | rstc->reset.of_node = np; | 1136 | rstc->reset.of_node = np; |
@@ -1173,11 +1140,34 @@ static void __init meson8b_clkc_reset_init(struct device_node *np) | |||
1173 | __func__, ret); | 1140 | __func__, ret); |
1174 | return; | 1141 | return; |
1175 | } | 1142 | } |
1143 | |||
1144 | /* Populate regmap for the regmap backed clocks */ | ||
1145 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++) | ||
1146 | meson8b_clk_regmaps[i]->map = map; | ||
1147 | |||
1148 | /* | ||
1149 | * register all clks | ||
1150 | * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 | ||
1151 | */ | ||
1152 | for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { | ||
1153 | /* array might be sparse */ | ||
1154 | if (!meson8b_hw_onecell_data.hws[i]) | ||
1155 | continue; | ||
1156 | |||
1157 | ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]); | ||
1158 | if (ret) | ||
1159 | return; | ||
1160 | } | ||
1161 | |||
1162 | ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, | ||
1163 | &meson8b_hw_onecell_data); | ||
1164 | if (ret) | ||
1165 | pr_err("%s: failed to register clock provider\n", __func__); | ||
1176 | } | 1166 | } |
1177 | 1167 | ||
1178 | CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", | 1168 | CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", |
1179 | meson8b_clkc_reset_init); | 1169 | meson8b_clkc_init); |
1180 | CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", | 1170 | CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", |
1181 | meson8b_clkc_reset_init); | 1171 | meson8b_clkc_init); |
1182 | CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", | 1172 | CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", |
1183 | meson8b_clkc_reset_init); | 1173 | meson8b_clkc_init); |
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index 5d09412b5084..1c6fb180e6a2 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h | |||
@@ -75,8 +75,11 @@ | |||
75 | #define CLKID_FCLK_DIV7_DIV 109 | 75 | #define CLKID_FCLK_DIV7_DIV 109 |
76 | #define CLKID_NAND_SEL 110 | 76 | #define CLKID_NAND_SEL 110 |
77 | #define CLKID_NAND_DIV 111 | 77 | #define CLKID_NAND_DIV 111 |
78 | #define CLKID_PLL_FIXED_DCO 113 | ||
79 | #define CLKID_PLL_VID_DCO 114 | ||
80 | #define CLKID_PLL_SYS_DCO 115 | ||
78 | 81 | ||
79 | #define CLK_NR_CLKS 113 | 82 | #define CLK_NR_CLKS 116 |
80 | 83 | ||
81 | /* | 84 | /* |
82 | * include the CLKID and RESETID that have | 85 | * include the CLKID and RESETID that have |
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 9fbec3eb725f..ea54a874bbda 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c | |||
@@ -153,7 +153,6 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, | |||
153 | goto fail4; | 153 | goto fail4; |
154 | } | 154 | } |
155 | 155 | ||
156 | of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); | ||
157 | ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); | 156 | ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); |
158 | if (ret) | 157 | if (ret) |
159 | goto fail_clk_add; | 158 | goto fail_clk_add; |
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 499f5962c8b0..1f1cff428d78 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c | |||
@@ -56,6 +56,15 @@ | |||
56 | struct clk_periph_driver_data { | 56 | struct clk_periph_driver_data { |
57 | struct clk_hw_onecell_data *hw_data; | 57 | struct clk_hw_onecell_data *hw_data; |
58 | spinlock_t lock; | 58 | spinlock_t lock; |
59 | void __iomem *reg; | ||
60 | |||
61 | /* Storage registers for suspend/resume operations */ | ||
62 | u32 tbg_sel; | ||
63 | u32 div_sel0; | ||
64 | u32 div_sel1; | ||
65 | u32 div_sel2; | ||
66 | u32 clk_sel; | ||
67 | u32 clk_dis; | ||
59 | }; | 68 | }; |
60 | 69 | ||
61 | struct clk_double_div { | 70 | struct clk_double_div { |
@@ -672,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data, | |||
672 | return PTR_ERR_OR_ZERO(*hw); | 681 | return PTR_ERR_OR_ZERO(*hw); |
673 | } | 682 | } |
674 | 683 | ||
684 | static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev) | ||
685 | { | ||
686 | struct clk_periph_driver_data *data = dev_get_drvdata(dev); | ||
687 | |||
688 | data->tbg_sel = readl(data->reg + TBG_SEL); | ||
689 | data->div_sel0 = readl(data->reg + DIV_SEL0); | ||
690 | data->div_sel1 = readl(data->reg + DIV_SEL1); | ||
691 | data->div_sel2 = readl(data->reg + DIV_SEL2); | ||
692 | data->clk_sel = readl(data->reg + CLK_SEL); | ||
693 | data->clk_dis = readl(data->reg + CLK_DIS); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) | ||
699 | { | ||
700 | struct clk_periph_driver_data *data = dev_get_drvdata(dev); | ||
701 | |||
702 | /* Follow the same order than what the Cortex-M3 does (ATF code) */ | ||
703 | writel(data->clk_dis, data->reg + CLK_DIS); | ||
704 | writel(data->div_sel0, data->reg + DIV_SEL0); | ||
705 | writel(data->div_sel1, data->reg + DIV_SEL1); | ||
706 | writel(data->div_sel2, data->reg + DIV_SEL2); | ||
707 | writel(data->tbg_sel, data->reg + TBG_SEL); | ||
708 | writel(data->clk_sel, data->reg + CLK_SEL); | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { | ||
714 | SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, | ||
715 | armada_3700_periph_clock_resume) | ||
716 | }; | ||
717 | |||
675 | static int armada_3700_periph_clock_probe(struct platform_device *pdev) | 718 | static int armada_3700_periph_clock_probe(struct platform_device *pdev) |
676 | { | 719 | { |
677 | struct clk_periph_driver_data *driver_data; | 720 | struct clk_periph_driver_data *driver_data; |
@@ -680,7 +723,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) | |||
680 | struct device *dev = &pdev->dev; | 723 | struct device *dev = &pdev->dev; |
681 | int num_periph = 0, i, ret; | 724 | int num_periph = 0, i, ret; |
682 | struct resource *res; | 725 | struct resource *res; |
683 | void __iomem *reg; | ||
684 | 726 | ||
685 | data = of_device_get_match_data(dev); | 727 | data = of_device_get_match_data(dev); |
686 | if (!data) | 728 | if (!data) |
@@ -689,11 +731,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) | |||
689 | while (data[num_periph].name) | 731 | while (data[num_periph].name) |
690 | num_periph++; | 732 | num_periph++; |
691 | 733 | ||
692 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
693 | reg = devm_ioremap_resource(dev, res); | ||
694 | if (IS_ERR(reg)) | ||
695 | return PTR_ERR(reg); | ||
696 | |||
697 | driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); | 734 | driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); |
698 | if (!driver_data) | 735 | if (!driver_data) |
699 | return -ENOMEM; | 736 | return -ENOMEM; |
@@ -706,12 +743,16 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) | |||
706 | return -ENOMEM; | 743 | return -ENOMEM; |
707 | driver_data->hw_data->num = num_periph; | 744 | driver_data->hw_data->num = num_periph; |
708 | 745 | ||
746 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
747 | driver_data->reg = devm_ioremap_resource(dev, res); | ||
748 | if (IS_ERR(driver_data->reg)) | ||
749 | return PTR_ERR(driver_data->reg); | ||
750 | |||
709 | spin_lock_init(&driver_data->lock); | 751 | spin_lock_init(&driver_data->lock); |
710 | 752 | ||
711 | for (i = 0; i < num_periph; i++) { | 753 | for (i = 0; i < num_periph; i++) { |
712 | struct clk_hw **hw = &driver_data->hw_data->hws[i]; | 754 | struct clk_hw **hw = &driver_data->hw_data->hws[i]; |
713 | 755 | if (armada_3700_add_composite_clk(&data[i], driver_data->reg, | |
714 | if (armada_3700_add_composite_clk(&data[i], reg, | ||
715 | &driver_data->lock, dev, hw)) | 756 | &driver_data->lock, dev, hw)) |
716 | dev_err(dev, "Can't register periph clock %s\n", | 757 | dev_err(dev, "Can't register periph clock %s\n", |
717 | data[i].name); | 758 | data[i].name); |
@@ -749,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = { | |||
749 | .driver = { | 790 | .driver = { |
750 | .name = "marvell-armada-3700-periph-clock", | 791 | .name = "marvell-armada-3700-periph-clock", |
751 | .of_match_table = armada_3700_periph_clock_of_match, | 792 | .of_match_table = armada_3700_periph_clock_of_match, |
793 | .pm = &armada_3700_periph_clock_pm_ops, | ||
752 | }, | 794 | }, |
753 | }; | 795 | }; |
754 | 796 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index ee9c12cf3f08..5f80eb018014 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c | |||
@@ -64,17 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | |||
64 | BIT(28), /* lock */ | 64 | BIT(28), /* lock */ |
65 | CLK_SET_RATE_UNGATE); | 65 | CLK_SET_RATE_UNGATE); |
66 | 66 | ||
67 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", | 67 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", |
68 | "osc24M", 0x010, | 68 | "osc24M", 0x010, |
69 | 8, 7, /* N */ | 69 | 192000000, /* Minimum rate */ |
70 | 0, 4, /* M */ | 70 | 1008000000, /* Maximum rate */ |
71 | BIT(24), /* frac enable */ | 71 | 8, 7, /* N */ |
72 | BIT(25), /* frac select */ | 72 | 0, 4, /* M */ |
73 | 270000000, /* frac rate 0 */ | 73 | BIT(24), /* frac enable */ |
74 | 297000000, /* frac rate 1 */ | 74 | BIT(25), /* frac select */ |
75 | BIT(31), /* gate */ | 75 | 270000000, /* frac rate 0 */ |
76 | BIT(28), /* lock */ | 76 | 297000000, /* frac rate 1 */ |
77 | CLK_SET_RATE_UNGATE); | 77 | BIT(31), /* gate */ |
78 | BIT(28), /* lock */ | ||
79 | CLK_SET_RATE_UNGATE); | ||
78 | 80 | ||
79 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | 81 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", |
80 | "osc24M", 0x018, | 82 | "osc24M", 0x018, |
@@ -125,17 +127,19 @@ static struct ccu_nk pll_periph1_clk = { | |||
125 | }, | 127 | }, |
126 | }; | 128 | }; |
127 | 129 | ||
128 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", | 130 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", |
129 | "osc24M", 0x030, | 131 | "osc24M", 0x030, |
130 | 8, 7, /* N */ | 132 | 192000000, /* Minimum rate */ |
131 | 0, 4, /* M */ | 133 | 1008000000, /* Maximum rate */ |
132 | BIT(24), /* frac enable */ | 134 | 8, 7, /* N */ |
133 | BIT(25), /* frac select */ | 135 | 0, 4, /* M */ |
134 | 270000000, /* frac rate 0 */ | 136 | BIT(24), /* frac enable */ |
135 | 297000000, /* frac rate 1 */ | 137 | BIT(25), /* frac select */ |
136 | BIT(31), /* gate */ | 138 | 270000000, /* frac rate 0 */ |
137 | BIT(28), /* lock */ | 139 | 297000000, /* frac rate 1 */ |
138 | CLK_SET_RATE_UNGATE); | 140 | BIT(31), /* gate */ |
141 | BIT(28), /* lock */ | ||
142 | CLK_SET_RATE_UNGATE); | ||
139 | 143 | ||
140 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", | 144 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", |
141 | "osc24M", 0x038, | 145 | "osc24M", 0x038, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 061b6fbb4f95..cd415b968e8c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h | |||
@@ -27,7 +27,9 @@ | |||
27 | #define CLK_PLL_AUDIO_2X 4 | 27 | #define CLK_PLL_AUDIO_2X 4 |
28 | #define CLK_PLL_AUDIO_4X 5 | 28 | #define CLK_PLL_AUDIO_4X 5 |
29 | #define CLK_PLL_AUDIO_8X 6 | 29 | #define CLK_PLL_AUDIO_8X 6 |
30 | #define CLK_PLL_VIDEO0 7 | 30 | |
31 | /* PLL_VIDEO0 exported for HDMI PHY */ | ||
32 | |||
31 | #define CLK_PLL_VIDEO0_2X 8 | 33 | #define CLK_PLL_VIDEO0_2X 8 |
32 | #define CLK_PLL_VE 9 | 34 | #define CLK_PLL_VE 9 |
33 | #define CLK_PLL_DDR0 10 | 35 | #define CLK_PLL_DDR0 10 |
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index bdbfe78fe133..2193e1495086 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c | |||
@@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", | |||
224 | psi_ahb1_ahb2_parents, | 224 | psi_ahb1_ahb2_parents, |
225 | 0x510, | 225 | 0x510, |
226 | 0, 5, /* M */ | 226 | 0, 5, /* M */ |
227 | 16, 2, /* P */ | 227 | 8, 2, /* P */ |
228 | 24, 2, /* mux */ | 228 | 24, 2, /* mux */ |
229 | 0); | 229 | 0); |
230 | 230 | ||
@@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k", | |||
233 | "pll-periph0" }; | 233 | "pll-periph0" }; |
234 | static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, | 234 | static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, |
235 | 0, 5, /* M */ | 235 | 0, 5, /* M */ |
236 | 16, 2, /* P */ | 236 | 8, 2, /* P */ |
237 | 24, 2, /* mux */ | 237 | 24, 2, /* mux */ |
238 | 0); | 238 | 0); |
239 | 239 | ||
240 | static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, | 240 | static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, |
241 | 0, 5, /* M */ | 241 | 0, 5, /* M */ |
242 | 16, 2, /* P */ | 242 | 8, 2, /* P */ |
243 | 24, 2, /* mux */ | 243 | 24, 2, /* mux */ |
244 | 0); | 244 | 0); |
245 | 245 | ||
246 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, | 246 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, |
247 | 0, 5, /* M */ | 247 | 0, 5, /* M */ |
248 | 16, 2, /* P */ | 248 | 8, 2, /* P */ |
249 | 24, 2, /* mux */ | 249 | 24, 2, /* mux */ |
250 | 0); | 250 | 0); |
251 | 251 | ||
@@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2", | |||
352 | static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", | 352 | static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", |
353 | 0x79c, BIT(0), 0); | 353 | 0x79c, BIT(0), 0); |
354 | 354 | ||
355 | static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0); | 355 | static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0); |
356 | 356 | ||
357 | static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); | 357 | static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); |
358 | 358 | ||
@@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0); | |||
408 | 408 | ||
409 | static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x", | 409 | static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x", |
410 | "pll-periph1-2x" }; | 410 | "pll-periph1-2x" }; |
411 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830, | 411 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, |
412 | 0, 4, /* M */ | 412 | 0, 4, /* M */ |
413 | 8, 2, /* N */ | 413 | 8, 2, /* N */ |
414 | 24, 3, /* mux */ | 414 | 24, 3, /* mux */ |
415 | BIT(31),/* gate */ | 415 | BIT(31), /* gate */ |
416 | 0); | 416 | 2, /* post-div */ |
417 | 417 | 0); | |
418 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834, | 418 | |
419 | 0, 4, /* M */ | 419 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, |
420 | 8, 2, /* N */ | 420 | 0, 4, /* M */ |
421 | 24, 3, /* mux */ | 421 | 8, 2, /* N */ |
422 | BIT(31),/* gate */ | 422 | 24, 3, /* mux */ |
423 | 0); | 423 | BIT(31), /* gate */ |
424 | 424 | 2, /* post-div */ | |
425 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838, | 425 | 0); |
426 | 0, 4, /* M */ | 426 | |
427 | 8, 2, /* N */ | 427 | static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, |
428 | 24, 3, /* mux */ | 428 | 0, 4, /* M */ |
429 | BIT(31),/* gate */ | 429 | 8, 2, /* N */ |
430 | 0); | 430 | 24, 3, /* mux */ |
431 | BIT(31), /* gate */ | ||
432 | 2, /* post-div */ | ||
433 | 0); | ||
431 | 434 | ||
432 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); | 435 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); |
433 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); | 436 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index 7d08015b980d..2d6555d73170 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | |||
@@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = { | |||
108 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), | 108 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), |
109 | .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ | 109 | .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ |
110 | .p = _SUNXI_CCU_DIV(0, 2), /* output divider */ | 110 | .p = _SUNXI_CCU_DIV(0, 2), /* output divider */ |
111 | .max_rate = 3000000000UL, | ||
111 | .common = { | 112 | .common = { |
112 | .reg = 0x010, | 113 | .reg = 0x010, |
113 | .lock_reg = CCU_SUN8I_A83T_LOCK_REG, | 114 | .lock_reg = CCU_SUN8I_A83T_LOCK_REG, |
@@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = { | |||
220 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), | 221 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), |
221 | .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ | 222 | .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ |
222 | .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ | 223 | .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ |
224 | .max_rate = 3000000000UL, | ||
223 | .common = { | 225 | .common = { |
224 | .reg = 0x04c, | 226 | .reg = 0x04c, |
225 | .lock_reg = CCU_SUN8I_A83T_LOCK_REG, | 227 | .lock_reg = CCU_SUN8I_A83T_LOCK_REG, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 77ed0b0ba681..eb5c608428fa 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | |||
69 | BIT(28), /* lock */ | 69 | BIT(28), /* lock */ |
70 | CLK_SET_RATE_UNGATE); | 70 | CLK_SET_RATE_UNGATE); |
71 | 71 | ||
72 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video", | 72 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video", |
73 | "osc24M", 0x0010, | 73 | "osc24M", 0x0010, |
74 | 192000000, /* Minimum rate */ | 74 | 192000000, /* Minimum rate */ |
75 | 8, 7, /* N */ | 75 | 912000000, /* Maximum rate */ |
76 | 0, 4, /* M */ | 76 | 8, 7, /* N */ |
77 | BIT(24), /* frac enable */ | 77 | 0, 4, /* M */ |
78 | BIT(25), /* frac select */ | 78 | BIT(24), /* frac enable */ |
79 | 270000000, /* frac rate 0 */ | 79 | BIT(25), /* frac select */ |
80 | 297000000, /* frac rate 1 */ | 80 | 270000000, /* frac rate 0 */ |
81 | BIT(31), /* gate */ | 81 | 297000000, /* frac rate 1 */ |
82 | BIT(28), /* lock */ | 82 | BIT(31), /* gate */ |
83 | CLK_SET_RATE_UNGATE); | 83 | BIT(28), /* lock */ |
84 | CLK_SET_RATE_UNGATE); | ||
84 | 85 | ||
85 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | 86 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", |
86 | "osc24M", 0x0018, | 87 | "osc24M", 0x0018, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 0f388f6944d5..582ebd41d20d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c | |||
@@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | |||
65 | BIT(28), /* lock */ | 65 | BIT(28), /* lock */ |
66 | CLK_SET_RATE_UNGATE); | 66 | CLK_SET_RATE_UNGATE); |
67 | 67 | ||
68 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 68 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", |
69 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", | 69 | "osc24M", 0x0010, |
70 | "osc24M", 0x0010, | 70 | 192000000, /* Minimum rate */ |
71 | 192000000, /* Minimum rate */ | 71 | 1008000000, /* Maximum rate */ |
72 | 8, 7, /* N */ | 72 | 8, 7, /* N */ |
73 | 0, 4, /* M */ | 73 | 0, 4, /* M */ |
74 | BIT(24), /* frac enable */ | 74 | BIT(24), /* frac enable */ |
75 | BIT(25), /* frac select */ | 75 | BIT(25), /* frac select */ |
76 | 270000000, /* frac rate 0 */ | 76 | 270000000, /* frac rate 0 */ |
77 | 297000000, /* frac rate 1 */ | 77 | 297000000, /* frac rate 1 */ |
78 | BIT(31), /* gate */ | 78 | BIT(31), /* gate */ |
79 | BIT(28), /* lock */ | 79 | BIT(28), /* lock */ |
80 | CLK_SET_RATE_UNGATE); | 80 | CLK_SET_RATE_UNGATE); |
81 | 81 | ||
82 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 82 | /* TODO: The result of N/M is required to be in [8, 25] range. */ |
83 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | 83 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", |
@@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = { | |||
152 | }, | 152 | }, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 155 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", |
156 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", | 156 | "osc24M", 0x030, |
157 | "osc24M", 0x030, | 157 | 192000000, /* Minimum rate */ |
158 | 192000000, /* Minimum rate */ | 158 | 1008000000, /* Maximum rate */ |
159 | 8, 7, /* N */ | 159 | 8, 7, /* N */ |
160 | 0, 4, /* M */ | 160 | 0, 4, /* M */ |
161 | BIT(24), /* frac enable */ | 161 | BIT(24), /* frac enable */ |
162 | BIT(25), /* frac select */ | 162 | BIT(25), /* frac select */ |
163 | 270000000, /* frac rate 0 */ | 163 | 270000000, /* frac rate 0 */ |
164 | 297000000, /* frac rate 1 */ | 164 | 297000000, /* frac rate 1 */ |
165 | BIT(31), /* gate */ | 165 | BIT(31), /* gate */ |
166 | BIT(28), /* lock */ | 166 | BIT(28), /* lock */ |
167 | CLK_SET_RATE_UNGATE); | 167 | CLK_SET_RATE_UNGATE); |
168 | 168 | ||
169 | static struct ccu_nkm pll_sata_clk = { | 169 | static struct ccu_nkm pll_sata_clk = { |
170 | .enable = BIT(31), | 170 | .enable = BIT(31), |
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index ebd9436d2c7c..9b49adb20d07 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c | |||
@@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, | |||
137 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | 137 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) |
138 | rate *= nkmp->fixed_post_div; | 138 | rate *= nkmp->fixed_post_div; |
139 | 139 | ||
140 | if (nkmp->max_rate && rate > nkmp->max_rate) { | ||
141 | rate = nkmp->max_rate; | ||
142 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
143 | rate /= nkmp->fixed_post_div; | ||
144 | return rate; | ||
145 | } | ||
146 | |||
140 | _nkmp.min_n = nkmp->n.min ?: 1; | 147 | _nkmp.min_n = nkmp->n.min ?: 1; |
141 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; | 148 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; |
142 | _nkmp.min_k = nkmp->k.min ?: 1; | 149 | _nkmp.min_k = nkmp->k.min ?: 1; |
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h index 6940503e7fc4..a9f8c116a745 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.h +++ b/drivers/clk/sunxi-ng/ccu_nkmp.h | |||
@@ -35,6 +35,7 @@ struct ccu_nkmp { | |||
35 | struct ccu_div_internal p; | 35 | struct ccu_div_internal p; |
36 | 36 | ||
37 | unsigned int fixed_post_div; | 37 | unsigned int fixed_post_div; |
38 | unsigned int max_rate; | ||
38 | 39 | ||
39 | struct ccu_common common; | 40 | struct ccu_common common; |
40 | }; | 41 | }; |
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index 4e2073307f34..6fe3c14f7b2d 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c | |||
@@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, | |||
124 | return rate; | 124 | return rate; |
125 | } | 125 | } |
126 | 126 | ||
127 | if (nm->max_rate && rate > nm->max_rate) { | ||
128 | rate = nm->max_rate; | ||
129 | if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
130 | rate /= nm->fixed_post_div; | ||
131 | return rate; | ||
132 | } | ||
133 | |||
127 | if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { | 134 | if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { |
128 | if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) | 135 | if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) |
129 | rate /= nm->fixed_post_div; | 136 | rate /= nm->fixed_post_div; |
diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h index 1d8b459c50b7..de232f2199a6 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.h +++ b/drivers/clk/sunxi-ng/ccu_nm.h | |||
@@ -38,6 +38,7 @@ struct ccu_nm { | |||
38 | 38 | ||
39 | unsigned int fixed_post_div; | 39 | unsigned int fixed_post_div; |
40 | unsigned int min_rate; | 40 | unsigned int min_rate; |
41 | unsigned int max_rate; | ||
41 | 42 | ||
42 | struct ccu_common common; | 43 | struct ccu_common common; |
43 | }; | 44 | }; |
@@ -115,6 +116,35 @@ struct ccu_nm { | |||
115 | }, \ | 116 | }, \ |
116 | } | 117 | } |
117 | 118 | ||
119 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ | ||
120 | _parent, _reg, \ | ||
121 | _min_rate, _max_rate, \ | ||
122 | _nshift, _nwidth, \ | ||
123 | _mshift, _mwidth, \ | ||
124 | _frac_en, _frac_sel, \ | ||
125 | _frac_rate_0, \ | ||
126 | _frac_rate_1, \ | ||
127 | _gate, _lock, _flags) \ | ||
128 | struct ccu_nm _struct = { \ | ||
129 | .enable = _gate, \ | ||
130 | .lock = _lock, \ | ||
131 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ | ||
132 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | ||
133 | .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ | ||
134 | _frac_rate_0, \ | ||
135 | _frac_rate_1), \ | ||
136 | .min_rate = _min_rate, \ | ||
137 | .max_rate = _max_rate, \ | ||
138 | .common = { \ | ||
139 | .reg = _reg, \ | ||
140 | .features = CCU_FEATURE_FRACTIONAL, \ | ||
141 | .hw.init = CLK_HW_INIT(_name, \ | ||
142 | _parent, \ | ||
143 | &ccu_nm_ops, \ | ||
144 | _flags), \ | ||
145 | }, \ | ||
146 | } | ||
147 | |||
118 | #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ | 148 | #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ |
119 | _nshift, _nwidth, \ | 149 | _nshift, _nwidth, \ |
120 | _mshift, _mwidth, \ | 150 | _mshift, _mwidth, \ |
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h index d66432c6e675..a8ac4cfcdcbc 100644 --- a/include/dt-bindings/clock/sun50i-a64-ccu.h +++ b/include/dt-bindings/clock/sun50i-a64-ccu.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ | 43 | #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ |
44 | #define _DT_BINDINGS_CLK_SUN50I_A64_H_ | 44 | #define _DT_BINDINGS_CLK_SUN50I_A64_H_ |
45 | 45 | ||
46 | #define CLK_PLL_VIDEO0 7 | ||
46 | #define CLK_PLL_PERIPH0 11 | 47 | #define CLK_PLL_PERIPH0 11 |
47 | 48 | ||
48 | #define CLK_BUS_MIPI_DSI 28 | 49 | #define CLK_BUS_MIPI_DSI 28 |