1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI composite clock support 4 * 5 * Copyright (C) 2013 Texas Instruments, Inc. 6 * 7 * Tero Kristo <t-kristo@ti.com> 8 */ 9 10 #include <linux/clk-provider.h> 11 #include <linux/slab.h> 12 #include <linux/io.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/clk/ti.h> 16 #include <linux/list.h> 17 18 #include "clock.h" 19 20 #undef pr_fmt 21 #define pr_fmt(fmt) "%s: " fmt, __func__ 22 23 static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, 24 unsigned long parent_rate) 25 { 26 return ti_clk_divider_ops.recalc_rate(hw, parent_rate); 27 } 28 29 static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate, 30 unsigned long *prate) 31 { 32 return -EINVAL; 33 } 34 35 static int ti_composite_set_rate(struct clk_hw *hw, unsigned long rate, 36 unsigned long parent_rate) 37 { 38 return -EINVAL; 39 } 40 41 static const struct clk_ops ti_composite_divider_ops = { 42 .recalc_rate = &ti_composite_recalc_rate, 43 .round_rate = &ti_composite_round_rate, 44 .set_rate = &ti_composite_set_rate, 45 }; 46 47 static const struct clk_ops ti_composite_gate_ops = { 48 .enable = &omap2_dflt_clk_enable, 49 .disable = &omap2_dflt_clk_disable, 50 .is_enabled = &omap2_dflt_clk_is_enabled, 51 }; 52 53 struct component_clk { 54 int num_parents; 55 const char **parent_names; 56 struct device_node *node; 57 int type; 58 struct clk_hw *hw; 59 struct list_head link; 60 }; 61 62 static const char * const component_clk_types[] __initconst = { 63 "gate", "divider", "mux" 64 }; 65 66 static LIST_HEAD(component_clks); 67 68 static struct device_node *_get_component_node(struct device_node *node, int i) 69 { 70 int rc; 71 struct of_phandle_args clkspec; 72 73 rc = of_parse_phandle_with_args(node, "clocks", "#clock-cells", i, 74 &clkspec); 75 if (rc) 76 return NULL; 77 78 return clkspec.np; 79 } 80 81 static struct component_clk *_lookup_component(struct device_node *node) 82 { 83 struct component_clk *comp; 84 85 list_for_each_entry(comp, &component_clks, link) { 86 if (comp->node == node) 87 return comp; 88 } 89 return NULL; 90 } 91 92 struct clk_hw_omap_comp { 93 struct clk_hw hw; 94 struct device_node *comp_nodes[CLK_COMPONENT_TYPE_MAX]; 95 struct component_clk *comp_clks[CLK_COMPONENT_TYPE_MAX]; 96 }; 97 98 static inline struct clk_hw *_get_hw(struct clk_hw_omap_comp *clk, int idx) 99 { 100 if (!clk) 101 return NULL; 102 103 if (!clk->comp_clks[idx]) 104 return NULL; 105 106 return clk->comp_clks[idx]->hw; 107 } 108 109 #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw) 110 111 static void __init _register_composite(void *user, 112 struct device_node *node) 113 { 114 struct clk_hw *hw = user; 115 struct clk *clk; 116 struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw); 117 struct component_clk *comp; 118 int num_parents = 0; 119 const char **parent_names = NULL; 120 const char *name; 121 int i; 122 int ret; 123 124 /* Check for presence of each component clock */ 125 for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) { 126 if (!cclk->comp_nodes[i]) 127 continue; 128 129 comp = _lookup_component(cclk->comp_nodes[i]); 130 if (!comp) { 131 pr_debug("component %s not ready for %pOFn, retry\n", 132 cclk->comp_nodes[i]->name, node); 133 if (!ti_clk_retry_init(node, hw, 134 _register_composite)) 135 return; 136 137 goto cleanup; 138 } 139 if (cclk->comp_clks[comp->type] != NULL) { 140 pr_err("duplicate component types for %pOFn (%s)!\n", 141 node, component_clk_types[comp->type]); 142 goto cleanup; 143 } 144 145 cclk->comp_clks[comp->type] = comp; 146 147 /* Mark this node as found */ 148 cclk->comp_nodes[i] = NULL; 149 } 150 151 /* All components exists, proceed with registration */ 152 for (i = CLK_COMPONENT_TYPE_MAX - 1; i >= 0; i--) { 153 comp = cclk->comp_clks[i]; 154 if (!comp) 155 continue; 156 if (comp->num_parents) { 157 num_parents = comp->num_parents; 158 parent_names = comp->parent_names; 159 break; 160 } 161 } 162 163 if (!num_parents) { 164 pr_err("%s: no parents found for %pOFn!\n", __func__, node); 165 goto cleanup; 166 } 167 168 name = ti_dt_clk_name(node); 169 clk = clk_register_composite(NULL, name, 170 parent_names, num_parents, 171 _get_hw(cclk, CLK_COMPONENT_TYPE_MUX), 172 &ti_clk_mux_ops, 173 _get_hw(cclk, CLK_COMPONENT_TYPE_DIVIDER), 174 &ti_composite_divider_ops, 175 _get_hw(cclk, CLK_COMPONENT_TYPE_GATE), 176 &ti_composite_gate_ops, 0); 177 178 if (!IS_ERR(clk)) { 179 ret = ti_clk_add_alias(NULL, clk, name); 180 if (ret) { 181 clk_unregister(clk); 182 goto cleanup; 183 } 184 of_clk_add_provider(node, of_clk_src_simple_get, clk); 185 } 186 187 cleanup: 188 /* Free component clock list entries */ 189 for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) { 190 if (!cclk->comp_clks[i]) 191 continue; 192 list_del(&cclk->comp_clks[i]->link); 193 kfree(cclk->comp_clks[i]->parent_names); 194 kfree(cclk->comp_clks[i]); 195 } 196 197 kfree(cclk); 198 } 199 200 static void __init of_ti_composite_clk_setup(struct device_node *node) 201 { 202 unsigned int num_clks; 203 int i; 204 struct clk_hw_omap_comp *cclk; 205 206 /* Number of component clocks to be put inside this clock */ 207 num_clks = of_clk_get_parent_count(node); 208 209 if (!num_clks) { 210 pr_err("composite clk %pOFn must have component(s)\n", node); 211 return; 212 } 213 214 cclk = kzalloc(sizeof(*cclk), GFP_KERNEL); 215 if (!cclk) 216 return; 217 218 /* Get device node pointers for each component clock */ 219 for (i = 0; i < num_clks; i++) 220 cclk->comp_nodes[i] = _get_component_node(node, i); 221 222 _register_composite(&cclk->hw, node); 223 } 224 CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock", 225 of_ti_composite_clk_setup); 226 227 /** 228 * ti_clk_add_component - add a component clock to the pool 229 * @node: device node of the component clock 230 * @hw: hardware clock definition for the component clock 231 * @type: type of the component clock 232 * 233 * Adds a component clock to the list of available components, so that 234 * it can be registered by a composite clock. 235 */ 236 int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, 237 int type) 238 { 239 unsigned int num_parents; 240 const char **parent_names; 241 struct component_clk *clk; 242 243 num_parents = of_clk_get_parent_count(node); 244 245 if (!num_parents) { 246 pr_err("component-clock %pOFn must have parent(s)\n", node); 247 return -EINVAL; 248 } 249 250 parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); 251 if (!parent_names) 252 return -ENOMEM; 253 254 of_clk_parent_fill(node, parent_names, num_parents); 255 256 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 257 if (!clk) { 258 kfree(parent_names); 259 return -ENOMEM; 260 } 261 262 clk->num_parents = num_parents; 263 clk->parent_names = parent_names; 264 clk->hw = hw; 265 clk->node = node; 266 clk->type = type; 267 list_add(&clk->link, &component_clks); 268 269 return 0; 270 } 271