aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Armstrong <narmstrong@baylibre.com>2019-03-04 08:11:29 -0500
committerNeil Armstrong <narmstrong@baylibre.com>2019-04-01 04:45:11 -0400
commit370294e2667fa1648eb05aab6c4657419634ff83 (patch)
tree3311a34764422bfdca967965cc927260e9b85d57
parent77a725ff7a640ab24ff9cf9450e6eae072c49f16 (diff)
clk: meson: g12a: add cpu clocks
Add the Amlogic G12A Family CPU Clock tree in read/only for now. The CPU clock can either use the SYS_PLL for > 1GHz frequencies or use a couple of div+mux from 1GHz/667MHz/24MHz source with 2 non-glitch muxes. Proper DVFS support will come in a second time. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Acked-by: Jerome Brunet <jbrunet@baylibre.com> [narmstrong: fixed cpu clocks namings] Link: https://lkml.kernel.org/r/20190304131129.7762-3-narmstrong@baylibre.com
-rw-r--r--drivers/clk/meson/g12a.c350
-rw-r--r--drivers/clk/meson/g12a.h22
2 files changed, 371 insertions, 1 deletions
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 0e1ce8c03259..10ba8bc4646d 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -150,6 +150,318 @@ static struct clk_regmap g12a_sys_pll = {
150 }, 150 },
151}; 151};
152 152
153static struct clk_regmap g12a_sys_pll_div16_en = {
154 .data = &(struct clk_regmap_gate_data){
155 .offset = HHI_SYS_CPU_CLK_CNTL1,
156 .bit_idx = 24,
157 },
158 .hw.init = &(struct clk_init_data) {
159 .name = "sys_pll_div16_en",
160 .ops = &clk_regmap_gate_ro_ops,
161 .parent_names = (const char *[]){ "sys_pll" },
162 .num_parents = 1,
163 /*
164 * This clock is used to debug the sys_pll range
165 * Linux should not change it at runtime
166 */
167 },
168};
169
170static struct clk_fixed_factor g12a_sys_pll_div16 = {
171 .mult = 1,
172 .div = 16,
173 .hw.init = &(struct clk_init_data){
174 .name = "sys_pll_div16",
175 .ops = &clk_fixed_factor_ops,
176 .parent_names = (const char *[]){ "sys_pll_div16_en" },
177 .num_parents = 1,
178 },
179};
180
181/* Datasheet names this field as "premux0" */
182static struct clk_regmap g12a_cpu_clk_premux0 = {
183 .data = &(struct clk_regmap_mux_data){
184 .offset = HHI_SYS_CPU_CLK_CNTL0,
185 .mask = 0x3,
186 .shift = 0,
187 },
188 .hw.init = &(struct clk_init_data){
189 .name = "cpu_clk_dyn0_sel",
190 .ops = &clk_regmap_mux_ro_ops,
191 .parent_names = (const char *[]){ IN_PREFIX "xtal",
192 "fclk_div2",
193 "fclk_div3" },
194 .num_parents = 3,
195 },
196};
197
198/* Datasheet names this field as "mux0_divn_tcnt" */
199static struct clk_regmap g12a_cpu_clk_mux0_div = {
200 .data = &(struct clk_regmap_div_data){
201 .offset = HHI_SYS_CPU_CLK_CNTL0,
202 .shift = 4,
203 .width = 6,
204 },
205 .hw.init = &(struct clk_init_data){
206 .name = "cpu_clk_dyn0_div",
207 .ops = &clk_regmap_divider_ro_ops,
208 .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
209 .num_parents = 1,
210 },
211};
212
213/* Datasheet names this field as "postmux0" */
214static struct clk_regmap g12a_cpu_clk_postmux0 = {
215 .data = &(struct clk_regmap_mux_data){
216 .offset = HHI_SYS_CPU_CLK_CNTL0,
217 .mask = 0x1,
218 .shift = 2,
219 },
220 .hw.init = &(struct clk_init_data){
221 .name = "cpu_clk_dyn0",
222 .ops = &clk_regmap_mux_ro_ops,
223 .parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
224 "cpu_clk_dyn0_div" },
225 .num_parents = 2,
226 },
227};
228
229/* Datasheet names this field as "premux1" */
230static struct clk_regmap g12a_cpu_clk_premux1 = {
231 .data = &(struct clk_regmap_mux_data){
232 .offset = HHI_SYS_CPU_CLK_CNTL0,
233 .mask = 0x3,
234 .shift = 16,
235 },
236 .hw.init = &(struct clk_init_data){
237 .name = "cpu_clk_dyn1_sel",
238 .ops = &clk_regmap_mux_ro_ops,
239 .parent_names = (const char *[]){ IN_PREFIX "xtal",
240 "fclk_div2",
241 "fclk_div3" },
242 .num_parents = 3,
243 },
244};
245
246/* Datasheet names this field as "Mux1_divn_tcnt" */
247static struct clk_regmap g12a_cpu_clk_mux1_div = {
248 .data = &(struct clk_regmap_div_data){
249 .offset = HHI_SYS_CPU_CLK_CNTL0,
250 .shift = 20,
251 .width = 6,
252 },
253 .hw.init = &(struct clk_init_data){
254 .name = "cpu_clk_dyn1_div",
255 .ops = &clk_regmap_divider_ro_ops,
256 .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" },
257 .num_parents = 1,
258 },
259};
260
261/* Datasheet names this field as "postmux1" */
262static struct clk_regmap g12a_cpu_clk_postmux1 = {
263 .data = &(struct clk_regmap_mux_data){
264 .offset = HHI_SYS_CPU_CLK_CNTL0,
265 .mask = 0x1,
266 .shift = 18,
267 },
268 .hw.init = &(struct clk_init_data){
269 .name = "cpu_clk_dyn1",
270 .ops = &clk_regmap_mux_ro_ops,
271 .parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
272 "cpu_clk_dyn1_div" },
273 .num_parents = 2,
274 },
275};
276
277/* Datasheet names this field as "Final_dyn_mux_sel" */
278static struct clk_regmap g12a_cpu_clk_dyn = {
279 .data = &(struct clk_regmap_mux_data){
280 .offset = HHI_SYS_CPU_CLK_CNTL0,
281 .mask = 0x1,
282 .shift = 10,
283 },
284 .hw.init = &(struct clk_init_data){
285 .name = "cpu_clk_dyn",
286 .ops = &clk_regmap_mux_ro_ops,
287 .parent_names = (const char *[]){ "cpu_clk_dyn0",
288 "cpu_clk_dyn1" },
289 .num_parents = 2,
290 },
291};
292
293/* Datasheet names this field as "Final_mux_sel" */
294static struct clk_regmap g12a_cpu_clk = {
295 .data = &(struct clk_regmap_mux_data){
296 .offset = HHI_SYS_CPU_CLK_CNTL0,
297 .mask = 0x1,
298 .shift = 11,
299 },
300 .hw.init = &(struct clk_init_data){
301 .name = "cpu_clk",
302 .ops = &clk_regmap_mux_ro_ops,
303 .parent_names = (const char *[]){ "cpu_clk_dyn",
304 "sys_pll" },
305 .num_parents = 2,
306 },
307};
308
309static struct clk_regmap g12a_cpu_clk_div16_en = {
310 .data = &(struct clk_regmap_gate_data){
311 .offset = HHI_SYS_CPU_CLK_CNTL1,
312 .bit_idx = 1,
313 },
314 .hw.init = &(struct clk_init_data) {
315 .name = "cpu_clk_div16_en",
316 .ops = &clk_regmap_gate_ro_ops,
317 .parent_names = (const char *[]){ "cpu_clk" },
318 .num_parents = 1,
319 /*
320 * This clock is used to debug the cpu_clk range
321 * Linux should not change it at runtime
322 */
323 },
324};
325
326static struct clk_fixed_factor g12a_cpu_clk_div16 = {
327 .mult = 1,
328 .div = 16,
329 .hw.init = &(struct clk_init_data){
330 .name = "cpu_clk_div16",
331 .ops = &clk_fixed_factor_ops,
332 .parent_names = (const char *[]){ "cpu_clk_div16_en" },
333 .num_parents = 1,
334 },
335};
336
337static struct clk_regmap g12a_cpu_clk_apb_div = {
338 .data = &(struct clk_regmap_div_data){
339 .offset = HHI_SYS_CPU_CLK_CNTL1,
340 .shift = 3,
341 .width = 3,
342 .flags = CLK_DIVIDER_POWER_OF_TWO,
343 },
344 .hw.init = &(struct clk_init_data){
345 .name = "cpu_clk_apb_div",
346 .ops = &clk_regmap_divider_ro_ops,
347 .parent_names = (const char *[]){ "cpu_clk" },
348 .num_parents = 1,
349 },
350};
351
352static struct clk_regmap g12a_cpu_clk_apb = {
353 .data = &(struct clk_regmap_gate_data){
354 .offset = HHI_SYS_CPU_CLK_CNTL1,
355 .bit_idx = 1,
356 },
357 .hw.init = &(struct clk_init_data) {
358 .name = "cpu_clk_apb",
359 .ops = &clk_regmap_gate_ro_ops,
360 .parent_names = (const char *[]){ "cpu_clk_apb_div" },
361 .num_parents = 1,
362 /*
363 * This clock is set by the ROM monitor code,
364 * Linux should not change it at runtime
365 */
366 },
367};
368
369static struct clk_regmap g12a_cpu_clk_atb_div = {
370 .data = &(struct clk_regmap_div_data){
371 .offset = HHI_SYS_CPU_CLK_CNTL1,
372 .shift = 6,
373 .width = 3,
374 .flags = CLK_DIVIDER_POWER_OF_TWO,
375 },
376 .hw.init = &(struct clk_init_data){
377 .name = "cpu_clk_atb_div",
378 .ops = &clk_regmap_divider_ro_ops,
379 .parent_names = (const char *[]){ "cpu_clk" },
380 .num_parents = 1,
381 },
382};
383
384static struct clk_regmap g12a_cpu_clk_atb = {
385 .data = &(struct clk_regmap_gate_data){
386 .offset = HHI_SYS_CPU_CLK_CNTL1,
387 .bit_idx = 17,
388 },
389 .hw.init = &(struct clk_init_data) {
390 .name = "cpu_clk_atb",
391 .ops = &clk_regmap_gate_ro_ops,
392 .parent_names = (const char *[]){ "cpu_clk_atb_div" },
393 .num_parents = 1,
394 /*
395 * This clock is set by the ROM monitor code,
396 * Linux should not change it at runtime
397 */
398 },
399};
400
401static struct clk_regmap g12a_cpu_clk_axi_div = {
402 .data = &(struct clk_regmap_div_data){
403 .offset = HHI_SYS_CPU_CLK_CNTL1,
404 .shift = 9,
405 .width = 3,
406 .flags = CLK_DIVIDER_POWER_OF_TWO,
407 },
408 .hw.init = &(struct clk_init_data){
409 .name = "cpu_clk_axi_div",
410 .ops = &clk_regmap_divider_ro_ops,
411 .parent_names = (const char *[]){ "cpu_clk" },
412 .num_parents = 1,
413 },
414};
415
416static struct clk_regmap g12a_cpu_clk_axi = {
417 .data = &(struct clk_regmap_gate_data){
418 .offset = HHI_SYS_CPU_CLK_CNTL1,
419 .bit_idx = 18,
420 },
421 .hw.init = &(struct clk_init_data) {
422 .name = "cpu_clk_axi",
423 .ops = &clk_regmap_gate_ro_ops,
424 .parent_names = (const char *[]){ "cpu_clk_axi_div" },
425 .num_parents = 1,
426 /*
427 * This clock is set by the ROM monitor code,
428 * Linux should not change it at runtime
429 */
430 },
431};
432
433static struct clk_regmap g12a_cpu_clk_trace_div = {
434 .data = &(struct clk_regmap_div_data){
435 .offset = HHI_SYS_CPU_CLK_CNTL1,
436 .shift = 20,
437 .width = 3,
438 .flags = CLK_DIVIDER_POWER_OF_TWO,
439 },
440 .hw.init = &(struct clk_init_data){
441 .name = "cpu_clk_trace_div",
442 .ops = &clk_regmap_divider_ro_ops,
443 .parent_names = (const char *[]){ "cpu_clk" },
444 .num_parents = 1,
445 },
446};
447
448static struct clk_regmap g12a_cpu_clk_trace = {
449 .data = &(struct clk_regmap_gate_data){
450 .offset = HHI_SYS_CPU_CLK_CNTL1,
451 .bit_idx = 23,
452 },
453 .hw.init = &(struct clk_init_data) {
454 .name = "cpu_clk_trace",
455 .ops = &clk_regmap_gate_ro_ops,
456 .parent_names = (const char *[]){ "cpu_clk_trace_div" },
457 .num_parents = 1,
458 /*
459 * This clock is set by the ROM monitor code,
460 * Linux should not change it at runtime
461 */
462 },
463};
464
153static const struct pll_mult_range g12a_gp0_pll_mult_range = { 465static const struct pll_mult_range g12a_gp0_pll_mult_range = {
154 .min = 55, 466 .min = 55,
155 .max = 255, 467 .max = 255,
@@ -2167,6 +2479,26 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = {
2167 [CLKID_MALI] = &g12a_mali.hw, 2479 [CLKID_MALI] = &g12a_mali.hw,
2168 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw, 2480 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw,
2169 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw, 2481 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw,
2482 [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw,
2483 [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw,
2484 [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw,
2485 [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw,
2486 [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw,
2487 [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw,
2488 [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw,
2489 [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw,
2490 [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw,
2491 [CLKID_CPU_CLK] = &g12a_cpu_clk.hw,
2492 [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw,
2493 [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw,
2494 [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw,
2495 [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw,
2496 [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw,
2497 [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw,
2498 [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw,
2499 [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw,
2500 [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw,
2501 [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw,
2170 [NR_CLKS] = NULL, 2502 [NR_CLKS] = NULL,
2171 }, 2503 },
2172 .num = NR_CLKS, 2504 .num = NR_CLKS,
@@ -2335,6 +2667,24 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
2335 &g12a_mali_1, 2667 &g12a_mali_1,
2336 &g12a_mali, 2668 &g12a_mali,
2337 &g12a_mpll_50m, 2669 &g12a_mpll_50m,
2670 &g12a_sys_pll_div16_en,
2671 &g12a_cpu_clk_premux0,
2672 &g12a_cpu_clk_mux0_div,
2673 &g12a_cpu_clk_postmux0,
2674 &g12a_cpu_clk_premux1,
2675 &g12a_cpu_clk_mux1_div,
2676 &g12a_cpu_clk_postmux1,
2677 &g12a_cpu_clk_dyn,
2678 &g12a_cpu_clk,
2679 &g12a_cpu_clk_div16_en,
2680 &g12a_cpu_clk_apb_div,
2681 &g12a_cpu_clk_apb,
2682 &g12a_cpu_clk_atb_div,
2683 &g12a_cpu_clk_atb,
2684 &g12a_cpu_clk_axi_div,
2685 &g12a_cpu_clk_axi,
2686 &g12a_cpu_clk_trace_div,
2687 &g12a_cpu_clk_trace,
2338}; 2688};
2339 2689
2340static const struct meson_eeclkc_data g12a_clkc_data = { 2690static const struct meson_eeclkc_data g12a_clkc_data = {
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h
index f399dfe1401c..70aa469ca1cf 100644
--- a/drivers/clk/meson/g12a.h
+++ b/drivers/clk/meson/g12a.h
@@ -50,6 +50,7 @@
50#define HHI_GCLK_MPEG2 0x148 50#define HHI_GCLK_MPEG2 0x148
51#define HHI_GCLK_OTHER 0x150 51#define HHI_GCLK_OTHER 0x150
52#define HHI_GCLK_OTHER2 0x154 52#define HHI_GCLK_OTHER2 0x154
53#define HHI_SYS_CPU_CLK_CNTL1 0x15c
53#define HHI_VID_CLK_DIV 0x164 54#define HHI_VID_CLK_DIV 0x164
54#define HHI_MPEG_CLK_CNTL 0x174 55#define HHI_MPEG_CLK_CNTL 0x174
55#define HHI_AUD_CLK_CNTL 0x178 56#define HHI_AUD_CLK_CNTL 0x178
@@ -166,8 +167,27 @@
166#define CLKID_MALI_0_DIV 170 167#define CLKID_MALI_0_DIV 170
167#define CLKID_MALI_1_DIV 173 168#define CLKID_MALI_1_DIV 173
168#define CLKID_MPLL_5OM_DIV 176 169#define CLKID_MPLL_5OM_DIV 176
170#define CLKID_SYS_PLL_DIV16_EN 178
171#define CLKID_SYS_PLL_DIV16 179
172#define CLKID_CPU_CLK_DYN0_SEL 180
173#define CLKID_CPU_CLK_DYN0_DIV 181
174#define CLKID_CPU_CLK_DYN0 182
175#define CLKID_CPU_CLK_DYN1_SEL 183
176#define CLKID_CPU_CLK_DYN1_DIV 184
177#define CLKID_CPU_CLK_DYN1 185
178#define CLKID_CPU_CLK_DYN 186
179#define CLKID_CPU_CLK_DIV16_EN 188
180#define CLKID_CPU_CLK_DIV16 189
181#define CLKID_CPU_CLK_APB_DIV 190
182#define CLKID_CPU_CLK_APB 191
183#define CLKID_CPU_CLK_ATB_DIV 192
184#define CLKID_CPU_CLK_ATB 193
185#define CLKID_CPU_CLK_AXI_DIV 194
186#define CLKID_CPU_CLK_AXI 195
187#define CLKID_CPU_CLK_TRACE_DIV 196
188#define CLKID_CPU_CLK_TRACE 197
169 189
170#define NR_CLKS 178 190#define NR_CLKS 198
171 191
172/* include the CLKIDs that have been made part of the DT binding */ 192/* include the CLKIDs that have been made part of the DT binding */
173#include <dt-bindings/clock/g12a-clkc.h> 193#include <dt-bindings/clock/g12a-clkc.h>