2 * TI composite clock support
4 * Copyright (C) 2013 Texas Instruments, Inc.
6 * Tero Kristo <t-kristo@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/clk-provider.h>
19 #include <linux/slab.h>
22 #include <linux/of_address.h>
23 #include <linux/clk/ti.h>
24 #include <linux/list.h>
29 #define pr_fmt(fmt) "%s: " fmt, __func__
31 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
33 static unsigned long ti_composite_recalc_rate(struct clk_hw
*hw
,
34 unsigned long parent_rate
)
36 return ti_clk_divider_ops
.recalc_rate(hw
, parent_rate
);
39 static long ti_composite_round_rate(struct clk_hw
*hw
, unsigned long rate
,
45 static int ti_composite_set_rate(struct clk_hw
*hw
, unsigned long rate
,
46 unsigned long parent_rate
)
51 static const struct clk_ops ti_composite_divider_ops
= {
52 .recalc_rate
= &ti_composite_recalc_rate
,
53 .round_rate
= &ti_composite_round_rate
,
54 .set_rate
= &ti_composite_set_rate
,
57 static const struct clk_ops ti_composite_gate_ops
= {
58 .enable
= &omap2_dflt_clk_enable
,
59 .disable
= &omap2_dflt_clk_disable
,
60 .is_enabled
= &omap2_dflt_clk_is_enabled
,
63 struct component_clk
{
65 const char **parent_names
;
66 struct device_node
*node
;
69 struct list_head link
;
72 static const char * const component_clk_types
[] __initconst
= {
73 "gate", "divider", "mux"
76 static LIST_HEAD(component_clks
);
78 static struct device_node
*_get_component_node(struct device_node
*node
, int i
)
81 struct of_phandle_args clkspec
;
83 rc
= of_parse_phandle_with_args(node
, "clocks", "#clock-cells", i
,
91 static struct component_clk
*_lookup_component(struct device_node
*node
)
93 struct component_clk
*comp
;
95 list_for_each_entry(comp
, &component_clks
, link
) {
96 if (comp
->node
== node
)
102 struct clk_hw_omap_comp
{
104 struct device_node
*comp_nodes
[CLK_COMPONENT_TYPE_MAX
];
105 struct component_clk
*comp_clks
[CLK_COMPONENT_TYPE_MAX
];
108 static inline struct clk_hw
*_get_hw(struct clk_hw_omap_comp
*clk
, int idx
)
113 if (!clk
->comp_clks
[idx
])
116 return clk
->comp_clks
[idx
]->hw
;
119 #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw)
121 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
122 struct clk
*ti_clk_register_composite(struct ti_clk
*setup
)
124 struct ti_clk_composite
*comp
;
129 const char **parent_names
= NULL
;
134 div
= ti_clk_build_component_div(comp
->divider
);
135 gate
= ti_clk_build_component_gate(comp
->gate
);
136 mux
= ti_clk_build_component_mux(comp
->mux
);
139 parent_names
= &comp
->divider
->parent
;
142 parent_names
= &comp
->gate
->parent
;
145 num_parents
= comp
->mux
->num_parents
;
146 parent_names
= comp
->mux
->parents
;
149 clk
= clk_register_composite(NULL
, setup
->name
,
150 parent_names
, num_parents
, mux
,
151 &ti_clk_mux_ops
, div
,
152 &ti_composite_divider_ops
, gate
,
153 &ti_composite_gate_ops
, 0);
159 static void __init
_register_composite(struct clk_hw
*hw
,
160 struct device_node
*node
)
163 struct clk_hw_omap_comp
*cclk
= to_clk_hw_comp(hw
);
164 struct component_clk
*comp
;
166 const char **parent_names
= NULL
;
169 /* Check for presence of each component clock */
170 for (i
= 0; i
< CLK_COMPONENT_TYPE_MAX
; i
++) {
171 if (!cclk
->comp_nodes
[i
])
174 comp
= _lookup_component(cclk
->comp_nodes
[i
]);
176 pr_debug("component %s not ready for %s, retry\n",
177 cclk
->comp_nodes
[i
]->name
, node
->name
);
178 if (!ti_clk_retry_init(node
, hw
,
179 _register_composite
))
184 if (cclk
->comp_clks
[comp
->type
] != NULL
) {
185 pr_err("duplicate component types for %s (%s)!\n",
186 node
->name
, component_clk_types
[comp
->type
]);
190 cclk
->comp_clks
[comp
->type
] = comp
;
192 /* Mark this node as found */
193 cclk
->comp_nodes
[i
] = NULL
;
196 /* All components exists, proceed with registration */
197 for (i
= CLK_COMPONENT_TYPE_MAX
- 1; i
>= 0; i
--) {
198 comp
= cclk
->comp_clks
[i
];
201 if (comp
->num_parents
) {
202 num_parents
= comp
->num_parents
;
203 parent_names
= comp
->parent_names
;
209 pr_err("%s: no parents found for %s!\n", __func__
, node
->name
);
213 clk
= clk_register_composite(NULL
, node
->name
,
214 parent_names
, num_parents
,
215 _get_hw(cclk
, CLK_COMPONENT_TYPE_MUX
),
217 _get_hw(cclk
, CLK_COMPONENT_TYPE_DIVIDER
),
218 &ti_composite_divider_ops
,
219 _get_hw(cclk
, CLK_COMPONENT_TYPE_GATE
),
220 &ti_composite_gate_ops
, 0);
223 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
226 /* Free component clock list entries */
227 for (i
= 0; i
< CLK_COMPONENT_TYPE_MAX
; i
++) {
228 if (!cclk
->comp_clks
[i
])
230 list_del(&cclk
->comp_clks
[i
]->link
);
231 kfree(cclk
->comp_clks
[i
]);
237 static void __init
of_ti_composite_clk_setup(struct device_node
*node
)
241 struct clk_hw_omap_comp
*cclk
;
243 /* Number of component clocks to be put inside this clock */
244 num_clks
= of_clk_get_parent_count(node
);
247 pr_err("composite clk %s must have component(s)\n", node
->name
);
251 cclk
= kzalloc(sizeof(*cclk
), GFP_KERNEL
);
255 /* Get device node pointers for each component clock */
256 for (i
= 0; i
< num_clks
; i
++)
257 cclk
->comp_nodes
[i
] = _get_component_node(node
, i
);
259 _register_composite(&cclk
->hw
, node
);
261 CLK_OF_DECLARE(ti_composite_clock
, "ti,composite-clock",
262 of_ti_composite_clk_setup
);
265 * ti_clk_add_component - add a component clock to the pool
266 * @node: device node of the component clock
267 * @hw: hardware clock definition for the component clock
268 * @type: type of the component clock
270 * Adds a component clock to the list of available components, so that
271 * it can be registered by a composite clock.
273 int __init
ti_clk_add_component(struct device_node
*node
, struct clk_hw
*hw
,
277 const char **parent_names
;
278 struct component_clk
*clk
;
280 num_parents
= of_clk_get_parent_count(node
);
282 if (num_parents
< 1) {
283 pr_err("component-clock %s must have parent(s)\n", node
->name
);
287 parent_names
= kzalloc((sizeof(char *) * num_parents
), GFP_KERNEL
);
291 of_clk_parent_fill(node
, parent_names
, num_parents
);
293 clk
= kzalloc(sizeof(*clk
), GFP_KERNEL
);
299 clk
->num_parents
= num_parents
;
300 clk
->parent_names
= parent_names
;
304 list_add(&clk
->link
, &component_clks
);