2 * Copyright 2013 Freescale Semiconductor, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * clock driver for Freescale PowerPC corenet SoCs.
10 #include <linux/clk-provider.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/of_platform.h>
16 #include <linux/slab.h>
24 #define PLL_KILL BIT(31)
25 #define CLKSEL_SHIFT 27
26 #define CLKSEL_ADJUST BIT(0)
27 #define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
29 static void __iomem
*base
;
30 static unsigned int clocks_per_pll
;
32 static int cmux_set_parent(struct clk_hw
*hw
, u8 idx
)
34 struct cmux_clk
*clk
= to_cmux_clk(hw
);
37 clksel
= ((idx
/ clocks_per_pll
) << 2) + idx
% clocks_per_pll
;
38 if (clk
->flags
& CLKSEL_ADJUST
)
40 clksel
= (clksel
& 0xf) << CLKSEL_SHIFT
;
41 iowrite32be(clksel
, clk
->reg
);
46 static u8
cmux_get_parent(struct clk_hw
*hw
)
48 struct cmux_clk
*clk
= to_cmux_clk(hw
);
51 clksel
= ioread32be(clk
->reg
);
52 clksel
= (clksel
>> CLKSEL_SHIFT
) & 0xf;
53 if (clk
->flags
& CLKSEL_ADJUST
)
55 clksel
= (clksel
>> 2) * clocks_per_pll
+ clksel
% 4;
60 const struct clk_ops cmux_ops
= {
61 .get_parent
= cmux_get_parent
,
62 .set_parent
= cmux_set_parent
,
65 static void __init
core_mux_init(struct device_node
*np
)
68 struct clk_init_data init
;
69 struct cmux_clk
*cmux_clk
;
70 struct device_node
*node
;
74 const char **parent_names
;
76 rc
= of_property_read_u32(np
, "reg", &offset
);
78 pr_err("%s: could not get reg property\n", np
->name
);
82 /* get the input clock source count */
83 count
= of_property_count_strings(np
, "clock-names");
85 pr_err("%s: get clock count error\n", np
->name
);
88 parent_names
= kzalloc((sizeof(char *) * count
), GFP_KERNEL
);
90 pr_err("%s: could not allocate parent_names\n", __func__
);
94 for (i
= 0; i
< count
; i
++)
95 parent_names
[i
] = of_clk_get_parent_name(np
, i
);
97 cmux_clk
= kzalloc(sizeof(struct cmux_clk
), GFP_KERNEL
);
99 pr_err("%s: could not allocate cmux_clk\n", __func__
);
102 cmux_clk
->reg
= base
+ offset
;
104 node
= of_find_compatible_node(NULL
, NULL
, "fsl,p4080-clockgen");
105 if (node
&& (offset
>= 0x80))
106 cmux_clk
->flags
= CLKSEL_ADJUST
;
108 rc
= of_property_read_string_index(np
, "clock-output-names",
111 pr_err("%s: read clock names error\n", np
->name
);
115 init
.name
= clk_name
;
116 init
.ops
= &cmux_ops
;
117 init
.parent_names
= parent_names
;
118 init
.num_parents
= count
;
120 cmux_clk
->hw
.init
= &init
;
122 clk
= clk_register(NULL
, &cmux_clk
->hw
);
124 pr_err("%s: could not register clock\n", clk_name
);
128 rc
= of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
130 pr_err("Could not register clock provider for node:%s\n",
139 /* free *_names because they are reallocated when registered */
143 static void __init
core_pll_init(struct device_node
*np
)
147 const char *clk_name
, *parent_name
;
148 struct clk_onecell_data
*onecell_data
;
149 struct clk
**subclks
;
151 rc
= of_property_read_u32(np
, "reg", &offset
);
153 pr_err("%s: could not get reg property\n", np
->name
);
157 /* get the multiple of PLL */
158 mult
= ioread32be(base
+ offset
);
160 /* check if this PLL is disabled */
161 if (mult
& PLL_KILL
) {
162 pr_debug("PLL:%s is disabled\n", np
->name
);
165 mult
= (mult
>> 1) & 0x3f;
167 parent_name
= of_clk_get_parent_name(np
, 0);
169 pr_err("PLL: %s must have a parent\n", np
->name
);
173 count
= of_property_count_strings(np
, "clock-output-names");
174 if (count
< 0 || count
> 4) {
175 pr_err("%s: clock is not supported\n", np
->name
);
179 /* output clock number per PLL */
180 clocks_per_pll
= count
;
182 subclks
= kzalloc(sizeof(struct clk
*) * count
, GFP_KERNEL
);
184 pr_err("%s: could not allocate subclks\n", __func__
);
188 onecell_data
= kzalloc(sizeof(struct clk_onecell_data
), GFP_KERNEL
);
190 pr_err("%s: could not allocate onecell_data\n", __func__
);
194 for (i
= 0; i
< count
; i
++) {
195 rc
= of_property_read_string_index(np
, "clock-output-names",
198 pr_err("%s: could not get clock names\n", np
->name
);
203 * when count == 4, there are 4 output clocks:
204 * /1, /2, /3, /4 respectively
205 * when count < 4, there are at least 2 output clocks:
206 * /1, /2, (/4, if count == 3) respectively.
209 subclks
[i
] = clk_register_fixed_factor(NULL
, clk_name
,
210 parent_name
, 0, mult
, 1 + i
);
213 subclks
[i
] = clk_register_fixed_factor(NULL
, clk_name
,
214 parent_name
, 0, mult
, 1 << i
);
216 if (IS_ERR(subclks
[i
])) {
217 pr_err("%s: could not register clock\n", clk_name
);
222 onecell_data
->clks
= subclks
;
223 onecell_data
->clk_num
= count
;
225 rc
= of_clk_add_provider(np
, of_clk_src_onecell_get
, onecell_data
);
227 pr_err("Could not register clk provider for node:%s\n",
239 static const struct of_device_id clk_match
[] __initconst
= {
240 { .compatible
= "fixed-clock", .data
= of_fixed_clk_setup
, },
241 { .compatible
= "fsl,core-pll-clock", .data
= core_pll_init
, },
242 { .compatible
= "fsl,core-mux-clock", .data
= core_mux_init
, },
246 static int __init
ppc_corenet_clk_probe(struct platform_device
*pdev
)
248 struct device_node
*np
;
250 np
= pdev
->dev
.of_node
;
251 base
= of_iomap(np
, 0);
253 dev_err(&pdev
->dev
, "iomap error\n");
256 of_clk_init(clk_match
);
261 static const struct of_device_id ppc_clk_ids
[] __initconst
= {
262 { .compatible
= "fsl,qoriq-clockgen-1.0", },
263 { .compatible
= "fsl,qoriq-clockgen-2.0", },
267 static struct platform_driver ppc_corenet_clk_driver
= {
269 .name
= "ppc_corenet_clock",
270 .owner
= THIS_MODULE
,
271 .of_match_table
= ppc_clk_ids
,
273 .probe
= ppc_corenet_clk_probe
,
276 static int __init
ppc_corenet_clk_init(void)
278 return platform_driver_register(&ppc_corenet_clk_driver
);
280 subsys_initcall(ppc_corenet_clk_init
);