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 static unsigned long ti_composite_recalc_rate(struct clk_hw
*hw
,
32 unsigned long parent_rate
)
34 return ti_clk_divider_ops
.recalc_rate(hw
, parent_rate
);
37 static long ti_composite_round_rate(struct clk_hw
*hw
, unsigned long rate
,
43 static int ti_composite_set_rate(struct clk_hw
*hw
, unsigned long rate
,
44 unsigned long parent_rate
)
49 static const struct clk_ops ti_composite_divider_ops
= {
50 .recalc_rate
= &ti_composite_recalc_rate
,
51 .round_rate
= &ti_composite_round_rate
,
52 .set_rate
= &ti_composite_set_rate
,
55 static const struct clk_ops ti_composite_gate_ops
= {
56 .enable
= &omap2_dflt_clk_enable
,
57 .disable
= &omap2_dflt_clk_disable
,
58 .is_enabled
= &omap2_dflt_clk_is_enabled
,
61 struct component_clk
{
63 const char **parent_names
;
64 struct device_node
*node
;
67 struct list_head link
;
70 static const char * const component_clk_types
[] __initconst
= {
71 "gate", "divider", "mux"
74 static LIST_HEAD(component_clks
);
76 static struct device_node
*_get_component_node(struct device_node
*node
, int i
)
79 struct of_phandle_args clkspec
;
81 rc
= of_parse_phandle_with_args(node
, "clocks", "#clock-cells", i
,
89 static struct component_clk
*_lookup_component(struct device_node
*node
)
91 struct component_clk
*comp
;
93 list_for_each_entry(comp
, &component_clks
, link
) {
94 if (comp
->node
== node
)
100 struct clk_hw_omap_comp
{
102 struct device_node
*comp_nodes
[CLK_COMPONENT_TYPE_MAX
];
103 struct component_clk
*comp_clks
[CLK_COMPONENT_TYPE_MAX
];
106 static inline struct clk_hw
*_get_hw(struct clk_hw_omap_comp
*clk
, int idx
)
111 if (!clk
->comp_clks
[idx
])
114 return clk
->comp_clks
[idx
]->hw
;
117 #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw)
119 static void __init
_register_composite(void *user
,
120 struct device_node
*node
)
122 struct clk_hw
*hw
= user
;
124 struct clk_hw_omap_comp
*cclk
= to_clk_hw_comp(hw
);
125 struct component_clk
*comp
;
127 const char **parent_names
= NULL
;
131 /* Check for presence of each component clock */
132 for (i
= 0; i
< CLK_COMPONENT_TYPE_MAX
; i
++) {
133 if (!cclk
->comp_nodes
[i
])
136 comp
= _lookup_component(cclk
->comp_nodes
[i
]);
138 pr_debug("component %s not ready for %pOFn, retry\n",
139 cclk
->comp_nodes
[i
]->name
, node
);
140 if (!ti_clk_retry_init(node
, hw
,
141 _register_composite
))
146 if (cclk
->comp_clks
[comp
->type
] != NULL
) {
147 pr_err("duplicate component types for %pOFn (%s)!\n",
148 node
, component_clk_types
[comp
->type
]);
152 cclk
->comp_clks
[comp
->type
] = comp
;
154 /* Mark this node as found */
155 cclk
->comp_nodes
[i
] = NULL
;
158 /* All components exists, proceed with registration */
159 for (i
= CLK_COMPONENT_TYPE_MAX
- 1; i
>= 0; i
--) {
160 comp
= cclk
->comp_clks
[i
];
163 if (comp
->num_parents
) {
164 num_parents
= comp
->num_parents
;
165 parent_names
= comp
->parent_names
;
171 pr_err("%s: no parents found for %pOFn!\n", __func__
, node
);
175 clk
= clk_register_composite(NULL
, node
->name
,
176 parent_names
, num_parents
,
177 _get_hw(cclk
, CLK_COMPONENT_TYPE_MUX
),
179 _get_hw(cclk
, CLK_COMPONENT_TYPE_DIVIDER
),
180 &ti_composite_divider_ops
,
181 _get_hw(cclk
, CLK_COMPONENT_TYPE_GATE
),
182 &ti_composite_gate_ops
, 0);
185 ret
= ti_clk_add_alias(NULL
, clk
, node
->name
);
190 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
194 /* Free component clock list entries */
195 for (i
= 0; i
< CLK_COMPONENT_TYPE_MAX
; i
++) {
196 if (!cclk
->comp_clks
[i
])
198 list_del(&cclk
->comp_clks
[i
]->link
);
199 kfree(cclk
->comp_clks
[i
]);
205 static void __init
of_ti_composite_clk_setup(struct device_node
*node
)
207 unsigned int num_clks
;
209 struct clk_hw_omap_comp
*cclk
;
211 /* Number of component clocks to be put inside this clock */
212 num_clks
= of_clk_get_parent_count(node
);
215 pr_err("composite clk %pOFn must have component(s)\n", node
);
219 cclk
= kzalloc(sizeof(*cclk
), GFP_KERNEL
);
223 /* Get device node pointers for each component clock */
224 for (i
= 0; i
< num_clks
; i
++)
225 cclk
->comp_nodes
[i
] = _get_component_node(node
, i
);
227 _register_composite(&cclk
->hw
, node
);
229 CLK_OF_DECLARE(ti_composite_clock
, "ti,composite-clock",
230 of_ti_composite_clk_setup
);
233 * ti_clk_add_component - add a component clock to the pool
234 * @node: device node of the component clock
235 * @hw: hardware clock definition for the component clock
236 * @type: type of the component clock
238 * Adds a component clock to the list of available components, so that
239 * it can be registered by a composite clock.
241 int __init
ti_clk_add_component(struct device_node
*node
, struct clk_hw
*hw
,
244 unsigned int num_parents
;
245 const char **parent_names
;
246 struct component_clk
*clk
;
248 num_parents
= of_clk_get_parent_count(node
);
251 pr_err("component-clock %pOFn must have parent(s)\n", node
);
255 parent_names
= kzalloc((sizeof(char *) * num_parents
), GFP_KERNEL
);
259 of_clk_parent_fill(node
, parent_names
, num_parents
);
261 clk
= kzalloc(sizeof(*clk
), GFP_KERNEL
);
267 clk
->num_parents
= num_parents
;
268 clk
->parent_names
= parent_names
;
272 list_add(&clk
->link
, &component_clks
);