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_address.h>
15 #include <linux/of_platform.h>
17 #include <linux/slab.h>
25 #define PLL_KILL BIT(31)
26 #define CLKSEL_SHIFT 27
27 #define CLKSEL_ADJUST BIT(0)
28 #define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
30 static void __iomem
*base
;
31 static unsigned int clocks_per_pll
;
33 static int cmux_set_parent(struct clk_hw
*hw
, u8 idx
)
35 struct cmux_clk
*clk
= to_cmux_clk(hw
);
38 clksel
= ((idx
/ clocks_per_pll
) << 2) + idx
% clocks_per_pll
;
39 if (clk
->flags
& CLKSEL_ADJUST
)
41 clksel
= (clksel
& 0xf) << CLKSEL_SHIFT
;
42 iowrite32be(clksel
, clk
->reg
);
47 static u8
cmux_get_parent(struct clk_hw
*hw
)
49 struct cmux_clk
*clk
= to_cmux_clk(hw
);
52 clksel
= ioread32be(clk
->reg
);
53 clksel
= (clksel
>> CLKSEL_SHIFT
) & 0xf;
54 if (clk
->flags
& CLKSEL_ADJUST
)
56 clksel
= (clksel
>> 2) * clocks_per_pll
+ clksel
% 4;
61 const struct clk_ops cmux_ops
= {
62 .get_parent
= cmux_get_parent
,
63 .set_parent
= cmux_set_parent
,
66 static void __init
core_mux_init(struct device_node
*np
)
69 struct clk_init_data init
;
70 struct cmux_clk
*cmux_clk
;
71 struct device_node
*node
;
75 const char **parent_names
;
77 rc
= of_property_read_u32(np
, "reg", &offset
);
79 pr_err("%s: could not get reg property\n", np
->name
);
83 /* get the input clock source count */
84 count
= of_property_count_strings(np
, "clock-names");
86 pr_err("%s: get clock count error\n", np
->name
);
89 parent_names
= kzalloc((sizeof(char *) * count
), GFP_KERNEL
);
91 pr_err("%s: could not allocate parent_names\n", __func__
);
95 for (i
= 0; i
< count
; i
++)
96 parent_names
[i
] = of_clk_get_parent_name(np
, i
);
98 cmux_clk
= kzalloc(sizeof(struct cmux_clk
), GFP_KERNEL
);
100 pr_err("%s: could not allocate cmux_clk\n", __func__
);
103 cmux_clk
->reg
= base
+ offset
;
105 node
= of_find_compatible_node(NULL
, NULL
, "fsl,p4080-clockgen");
106 if (node
&& (offset
>= 0x80))
107 cmux_clk
->flags
= CLKSEL_ADJUST
;
109 rc
= of_property_read_string_index(np
, "clock-output-names",
112 pr_err("%s: read clock names error\n", np
->name
);
116 init
.name
= clk_name
;
117 init
.ops
= &cmux_ops
;
118 init
.parent_names
= parent_names
;
119 init
.num_parents
= count
;
121 cmux_clk
->hw
.init
= &init
;
123 clk
= clk_register(NULL
, &cmux_clk
->hw
);
125 pr_err("%s: could not register clock\n", clk_name
);
129 rc
= of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
131 pr_err("Could not register clock provider for node:%s\n",
140 /* free *_names because they are reallocated when registered */
144 static void __init
core_pll_init(struct device_node
*np
)
148 const char *clk_name
, *parent_name
;
149 struct clk_onecell_data
*onecell_data
;
150 struct clk
**subclks
;
152 rc
= of_property_read_u32(np
, "reg", &offset
);
154 pr_err("%s: could not get reg property\n", np
->name
);
158 /* get the multiple of PLL */
159 mult
= ioread32be(base
+ offset
);
161 /* check if this PLL is disabled */
162 if (mult
& PLL_KILL
) {
163 pr_debug("PLL:%s is disabled\n", np
->name
);
166 mult
= (mult
>> 1) & 0x3f;
168 parent_name
= of_clk_get_parent_name(np
, 0);
170 pr_err("PLL: %s must have a parent\n", np
->name
);
174 count
= of_property_count_strings(np
, "clock-output-names");
175 if (count
< 0 || count
> 4) {
176 pr_err("%s: clock is not supported\n", np
->name
);
180 /* output clock number per PLL */
181 clocks_per_pll
= count
;
183 subclks
= kzalloc(sizeof(struct clk
*) * count
, GFP_KERNEL
);
185 pr_err("%s: could not allocate subclks\n", __func__
);
189 onecell_data
= kzalloc(sizeof(struct clk_onecell_data
), GFP_KERNEL
);
191 pr_err("%s: could not allocate onecell_data\n", __func__
);
195 for (i
= 0; i
< count
; i
++) {
196 rc
= of_property_read_string_index(np
, "clock-output-names",
199 pr_err("%s: could not get clock names\n", np
->name
);
204 * when count == 4, there are 4 output clocks:
205 * /1, /2, /3, /4 respectively
206 * when count < 4, there are at least 2 output clocks:
207 * /1, /2, (/4, if count == 3) respectively.
210 subclks
[i
] = clk_register_fixed_factor(NULL
, clk_name
,
211 parent_name
, 0, mult
, 1 + i
);
214 subclks
[i
] = clk_register_fixed_factor(NULL
, clk_name
,
215 parent_name
, 0, mult
, 1 << i
);
217 if (IS_ERR(subclks
[i
])) {
218 pr_err("%s: could not register clock\n", clk_name
);
223 onecell_data
->clks
= subclks
;
224 onecell_data
->clk_num
= count
;
226 rc
= of_clk_add_provider(np
, of_clk_src_onecell_get
, onecell_data
);
228 pr_err("Could not register clk provider for node:%s\n",
240 static const struct of_device_id clk_match
[] __initconst
= {
241 { .compatible
= "fixed-clock", .data
= of_fixed_clk_setup
, },
242 { .compatible
= "fsl,core-pll-clock", .data
= core_pll_init
, },
243 { .compatible
= "fsl,core-mux-clock", .data
= core_mux_init
, },
247 static int __init
ppc_corenet_clk_probe(struct platform_device
*pdev
)
249 struct device_node
*np
;
251 np
= pdev
->dev
.of_node
;
252 base
= of_iomap(np
, 0);
254 dev_err(&pdev
->dev
, "iomap error\n");
257 of_clk_init(clk_match
);
262 static const struct of_device_id ppc_clk_ids
[] __initconst
= {
263 { .compatible
= "fsl,qoriq-clockgen-1.0", },
264 { .compatible
= "fsl,qoriq-clockgen-2.0", },
268 static struct platform_driver ppc_corenet_clk_driver
= {
270 .name
= "ppc_corenet_clock",
271 .owner
= THIS_MODULE
,
272 .of_match_table
= ppc_clk_ids
,
274 .probe
= ppc_corenet_clk_probe
,
277 static int __init
ppc_corenet_clk_init(void)
279 return platform_driver_register(&ppc_corenet_clk_driver
);
281 subsys_initcall(ppc_corenet_clk_init
);