2 * Copyright 2013 Emilio López
4 * Emilio López <emilio@elopez.com.ar>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/clk-provider.h>
18 #include <linux/clkdev.h>
19 #include <linux/clk/sunxi.h>
21 #include <linux/of_address.h>
23 #include "clk-factors.h"
25 static DEFINE_SPINLOCK(clk_lock
);
28 * sunxi_osc_clk_setup() - Setup function for gatable oscillator
31 #define SUNXI_OSC24M_GATE 0
33 static void __init
sunxi_osc_clk_setup(struct device_node
*node
)
36 struct clk_fixed_rate
*fixed
;
37 struct clk_gate
*gate
;
38 const char *clk_name
= node
->name
;
41 /* allocate fixed-rate and gate clock structs */
42 fixed
= kzalloc(sizeof(struct clk_fixed_rate
), GFP_KERNEL
);
45 gate
= kzalloc(sizeof(struct clk_gate
), GFP_KERNEL
);
51 if (of_property_read_u32(node
, "clock-frequency", &rate
))
54 /* set up gate and fixed rate properties */
55 gate
->reg
= of_iomap(node
, 0);
56 gate
->bit_idx
= SUNXI_OSC24M_GATE
;
57 gate
->lock
= &clk_lock
;
58 fixed
->fixed_rate
= rate
;
60 clk
= clk_register_composite(NULL
, clk_name
,
63 &fixed
->hw
, &clk_fixed_rate_ops
,
64 &gate
->hw
, &clk_gate_ops
,
68 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
69 clk_register_clkdev(clk
, clk_name
, NULL
);
76 * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1
77 * PLL1 rate is calculated as follows
78 * rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
79 * parent_rate is always 24Mhz
82 static void sunxi_get_pll1_factors(u32
*freq
, u32 parent_rate
,
83 u8
*n
, u8
*k
, u8
*m
, u8
*p
)
87 /* Normalize value to a 6M multiple */
88 div
= *freq
/ 6000000;
89 *freq
= 6000000 * div
;
91 /* we were called to round the frequency, we can now return */
95 /* m is always zero for pll1 */
98 /* k is 1 only on these cases */
99 if (*freq
>= 768000000 || *freq
== 42000000 || *freq
== 54000000)
104 /* p will be 3 for divs under 10 */
108 /* p will be 2 for divs between 10 - 20 and odd divs under 32 */
109 else if (div
< 20 || (div
< 32 && (div
& 1)))
112 /* p will be 1 for even divs under 32, divs under 40 and odd pairs
113 * of divs between 40-62 */
114 else if (div
< 40 || (div
< 64 && (div
& 2)))
117 /* any other entries have p = 0 */
121 /* calculate a suitable n based on k and p */
130 * sunxi_get_apb1_factors() - calculates m, p factors for APB1
131 * APB1 rate is calculated as follows
132 * rate = (parent_rate >> p) / (m + 1);
135 static void sunxi_get_apb1_factors(u32
*freq
, u32 parent_rate
,
136 u8
*n
, u8
*k
, u8
*m
, u8
*p
)
140 if (parent_rate
< *freq
)
143 parent_rate
= (parent_rate
+ (*freq
- 1)) / *freq
;
146 if (parent_rate
> 32)
149 if (parent_rate
<= 4)
151 else if (parent_rate
<= 8)
153 else if (parent_rate
<= 16)
158 calcm
= (parent_rate
>> calcp
) - 1;
160 *freq
= (parent_rate
>> calcp
) / (calcm
+ 1);
162 /* we were called to round the frequency, we can now return */
173 * sunxi_factors_clk_setup() - Setup function for factor clocks
176 struct factors_data
{
177 struct clk_factors_config
*table
;
178 void (*getter
) (u32
*rate
, u32 parent_rate
, u8
*n
, u8
*k
, u8
*m
, u8
*p
);
181 static struct clk_factors_config pll1_config
= {
192 static struct clk_factors_config apb1_config
= {
199 static const __initconst
struct factors_data pll1_data
= {
200 .table
= &pll1_config
,
201 .getter
= sunxi_get_pll1_factors
,
204 static const __initconst
struct factors_data apb1_data
= {
205 .table
= &apb1_config
,
206 .getter
= sunxi_get_apb1_factors
,
209 static void __init
sunxi_factors_clk_setup(struct device_node
*node
,
210 struct factors_data
*data
)
213 const char *clk_name
= node
->name
;
217 reg
= of_iomap(node
, 0);
219 parent
= of_clk_get_parent_name(node
, 0);
221 clk
= clk_register_factors(NULL
, clk_name
, parent
, 0, reg
,
222 data
->table
, data
->getter
, &clk_lock
);
225 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
226 clk_register_clkdev(clk
, clk_name
, NULL
);
233 * sunxi_mux_clk_setup() - Setup function for muxes
236 #define SUNXI_MUX_GATE_WIDTH 2
242 static const __initconst
struct mux_data cpu_mux_data
= {
246 static const __initconst
struct mux_data apb1_mux_data
= {
250 static void __init
sunxi_mux_clk_setup(struct device_node
*node
,
251 struct mux_data
*data
)
254 const char *clk_name
= node
->name
;
255 const char *parents
[5];
259 reg
= of_iomap(node
, 0);
261 while (i
< 5 && (parents
[i
] = of_clk_get_parent_name(node
, i
)) != NULL
)
264 clk
= clk_register_mux(NULL
, clk_name
, parents
, i
, 0, reg
,
265 data
->shift
, SUNXI_MUX_GATE_WIDTH
,
269 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
270 clk_register_clkdev(clk
, clk_name
, NULL
);
277 * sunxi_divider_clk_setup() - Setup function for simple divider clocks
280 #define SUNXI_DIVISOR_WIDTH 2
287 static const __initconst
struct div_data axi_data
= {
292 static const __initconst
struct div_data ahb_data
= {
297 static const __initconst
struct div_data apb0_data
= {
302 static void __init
sunxi_divider_clk_setup(struct device_node
*node
,
303 struct div_data
*data
)
306 const char *clk_name
= node
->name
;
307 const char *clk_parent
;
310 reg
= of_iomap(node
, 0);
312 clk_parent
= of_clk_get_parent_name(node
, 0);
314 clk
= clk_register_divider(NULL
, clk_name
, clk_parent
, 0,
315 reg
, data
->shift
, SUNXI_DIVISOR_WIDTH
,
316 data
->pow
? CLK_DIVIDER_POWER_OF_TWO
: 0,
319 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
320 clk_register_clkdev(clk
, clk_name
, NULL
);
327 * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
330 #define SUNXI_GATES_MAX_SIZE 64
333 DECLARE_BITMAP(mask
, SUNXI_GATES_MAX_SIZE
);
336 static const __initconst
struct gates_data sun4i_axi_gates_data
= {
340 static const __initconst
struct gates_data sun4i_ahb_gates_data
= {
341 .mask
= {0x7F77FFF, 0x14FB3F},
344 static const __initconst
struct gates_data sun5i_a13_ahb_gates_data
= {
345 .mask
= {0x107067e7, 0x185111},
348 static const __initconst
struct gates_data sun4i_apb0_gates_data
= {
352 static const __initconst
struct gates_data sun5i_a13_apb0_gates_data
= {
356 static const __initconst
struct gates_data sun4i_apb1_gates_data
= {
360 static const __initconst
struct gates_data sun5i_a13_apb1_gates_data
= {
364 static void __init
sunxi_gates_clk_setup(struct device_node
*node
,
365 struct gates_data
*data
)
367 struct clk_onecell_data
*clk_data
;
368 const char *clk_parent
;
369 const char *clk_name
;
376 reg
= of_iomap(node
, 0);
378 clk_parent
= of_clk_get_parent_name(node
, 0);
380 /* Worst-case size approximation and memory allocation */
381 qty
= find_last_bit(data
->mask
, SUNXI_GATES_MAX_SIZE
);
382 clk_data
= kmalloc(sizeof(struct clk_onecell_data
), GFP_KERNEL
);
385 clk_data
->clks
= kzalloc((qty
+1) * sizeof(struct clk
*), GFP_KERNEL
);
386 if (!clk_data
->clks
) {
391 for_each_set_bit(i
, data
->mask
, SUNXI_GATES_MAX_SIZE
) {
392 of_property_read_string_index(node
, "clock-output-names",
395 /* No driver claims this clock, but it should remain gated */
396 ignore
= !strcmp("ahb_sdram", clk_name
) ? CLK_IGNORE_UNUSED
: 0;
398 clk_data
->clks
[i
] = clk_register_gate(NULL
, clk_name
,
400 reg
+ 4 * (i
/32), i
% 32,
402 WARN_ON(IS_ERR(clk_data
->clks
[i
]));
407 /* Adjust to the real max */
408 clk_data
->clk_num
= i
;
410 of_clk_add_provider(node
, of_clk_src_onecell_get
, clk_data
);
413 /* Matches for of_clk_init */
414 static const __initconst
struct of_device_id clk_match
[] = {
415 {.compatible
= "allwinner,sun4i-osc-clk", .data
= sunxi_osc_clk_setup
,},
419 /* Matches for factors clocks */
420 static const __initconst
struct of_device_id clk_factors_match
[] = {
421 {.compatible
= "allwinner,sun4i-pll1-clk", .data
= &pll1_data
,},
422 {.compatible
= "allwinner,sun4i-apb1-clk", .data
= &apb1_data
,},
426 /* Matches for divider clocks */
427 static const __initconst
struct of_device_id clk_div_match
[] = {
428 {.compatible
= "allwinner,sun4i-axi-clk", .data
= &axi_data
,},
429 {.compatible
= "allwinner,sun4i-ahb-clk", .data
= &ahb_data
,},
430 {.compatible
= "allwinner,sun4i-apb0-clk", .data
= &apb0_data
,},
434 /* Matches for mux clocks */
435 static const __initconst
struct of_device_id clk_mux_match
[] = {
436 {.compatible
= "allwinner,sun4i-cpu-clk", .data
= &cpu_mux_data
,},
437 {.compatible
= "allwinner,sun4i-apb1-mux-clk", .data
= &apb1_mux_data
,},
441 /* Matches for gate clocks */
442 static const __initconst
struct of_device_id clk_gates_match
[] = {
443 {.compatible
= "allwinner,sun4i-axi-gates-clk", .data
= &sun4i_axi_gates_data
,},
444 {.compatible
= "allwinner,sun4i-ahb-gates-clk", .data
= &sun4i_ahb_gates_data
,},
445 {.compatible
= "allwinner,sun5i-a13-ahb-gates-clk", .data
= &sun5i_a13_ahb_gates_data
,},
446 {.compatible
= "allwinner,sun4i-apb0-gates-clk", .data
= &sun4i_apb0_gates_data
,},
447 {.compatible
= "allwinner,sun5i-a13-apb0-gates-clk", .data
= &sun5i_a13_apb0_gates_data
,},
448 {.compatible
= "allwinner,sun4i-apb1-gates-clk", .data
= &sun4i_apb1_gates_data
,},
449 {.compatible
= "allwinner,sun5i-a13-apb1-gates-clk", .data
= &sun5i_a13_apb1_gates_data
,},
453 static void __init
of_sunxi_table_clock_setup(const struct of_device_id
*clk_match
,
456 struct device_node
*np
;
457 const struct div_data
*data
;
458 const struct of_device_id
*match
;
459 void (*setup_function
)(struct device_node
*, const void *) = function
;
461 for_each_matching_node(np
, clk_match
) {
462 match
= of_match_node(clk_match
, np
);
464 setup_function(np
, data
);
468 void __init
sunxi_init_clocks(void)
470 /* Register all the simple sunxi clocks on DT */
471 of_clk_init(clk_match
);
473 /* Register factor clocks */
474 of_sunxi_table_clock_setup(clk_factors_match
, sunxi_factors_clk_setup
);
476 /* Register divider clocks */
477 of_sunxi_table_clock_setup(clk_div_match
, sunxi_divider_clk_setup
);
479 /* Register mux clocks */
480 of_sunxi_table_clock_setup(clk_mux_match
, sunxi_mux_clk_setup
);
482 /* Register gate clocks */
483 of_sunxi_table_clock_setup(clk_gates_match
, sunxi_gates_clk_setup
);