1 /* 2 * TI clock support 3 * 4 * Copyright (C) 2013 Texas Instruments, Inc. 5 * 6 * Tero Kristo <t-kristo@ti.com> 7 * 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. 11 * 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. 16 */ 17 18 #include <linux/clk-provider.h> 19 #include <linux/clkdev.h> 20 #include <linux/clk/ti.h> 21 #include <linux/of.h> 22 #include <linux/of_address.h> 23 #include <linux/list.h> 24 25 #include "clock.h" 26 27 #undef pr_fmt 28 #define pr_fmt(fmt) "%s: " fmt, __func__ 29 30 struct ti_clk_ll_ops *ti_clk_ll_ops; 31 static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; 32 33 /** 34 * ti_dt_clocks_register - register DT alias clocks during boot 35 * @oclks: list of clocks to register 36 * 37 * Register alias or non-standard DT clock entries during boot. By 38 * default, DT clocks are found based on their node name. If any 39 * additional con-id / dev-id -> clock mapping is required, use this 40 * function to list these. 41 */ 42 void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) 43 { 44 struct ti_dt_clk *c; 45 struct device_node *node; 46 struct clk *clk; 47 struct of_phandle_args clkspec; 48 49 for (c = oclks; c->node_name != NULL; c++) { 50 node = of_find_node_by_name(NULL, c->node_name); 51 clkspec.np = node; 52 clk = of_clk_get_from_provider(&clkspec); 53 54 if (!IS_ERR(clk)) { 55 c->lk.clk = clk; 56 clkdev_add(&c->lk); 57 } else { 58 pr_warn("failed to lookup clock node %s\n", 59 c->node_name); 60 } 61 } 62 } 63 64 struct clk_init_item { 65 struct device_node *node; 66 struct clk_hw *hw; 67 ti_of_clk_init_cb_t func; 68 struct list_head link; 69 }; 70 71 static LIST_HEAD(retry_list); 72 73 /** 74 * ti_clk_retry_init - retries a failed clock init at later phase 75 * @node: device not for the clock 76 * @hw: partially initialized clk_hw struct for the clock 77 * @func: init function to be called for the clock 78 * 79 * Adds a failed clock init to the retry list. The retry list is parsed 80 * once all the other clocks have been initialized. 81 */ 82 int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, 83 ti_of_clk_init_cb_t func) 84 { 85 struct clk_init_item *retry; 86 87 pr_debug("%s: adding to retry list...\n", node->name); 88 retry = kzalloc(sizeof(*retry), GFP_KERNEL); 89 if (!retry) 90 return -ENOMEM; 91 92 retry->node = node; 93 retry->func = func; 94 retry->hw = hw; 95 list_add(&retry->link, &retry_list); 96 97 return 0; 98 } 99 100 /** 101 * ti_clk_get_reg_addr - get register address for a clock register 102 * @node: device node for the clock 103 * @index: register index from the clock node 104 * 105 * Builds clock register address from device tree information. This 106 * is a struct of type clk_omap_reg. 107 */ 108 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index) 109 { 110 struct clk_omap_reg *reg; 111 u32 val; 112 u32 tmp; 113 int i; 114 115 reg = (struct clk_omap_reg *)&tmp; 116 117 for (i = 0; i < CLK_MAX_MEMMAPS; i++) { 118 if (clocks_node_ptr[i] == node->parent) 119 break; 120 } 121 122 if (i == CLK_MAX_MEMMAPS) { 123 pr_err("clk-provider not found for %s!\n", node->name); 124 return NULL; 125 } 126 127 reg->index = i; 128 129 if (of_property_read_u32_index(node, "reg", index, &val)) { 130 pr_err("%s must have reg[%d]!\n", node->name, index); 131 return NULL; 132 } 133 134 reg->offset = val; 135 136 return (void __iomem *)tmp; 137 } 138 139 /** 140 * ti_dt_clk_init_provider - init master clock provider 141 * @parent: master node 142 * @index: internal index for clk_reg_ops 143 * 144 * Initializes a master clock IP block. This basically sets up the 145 * mapping from clocks node to the memory map index. All the clocks 146 * are then initialized through the common of_clk_init call, and the 147 * clocks will access their memory maps based on the node layout. 148 */ 149 void ti_dt_clk_init_provider(struct device_node *parent, int index) 150 { 151 struct device_node *clocks; 152 153 /* get clocks for this parent */ 154 clocks = of_get_child_by_name(parent, "clocks"); 155 if (!clocks) { 156 pr_err("%s missing 'clocks' child node.\n", parent->name); 157 return; 158 } 159 160 /* add clocks node info */ 161 clocks_node_ptr[index] = clocks; 162 } 163 164 /** 165 * ti_dt_clk_init_retry_clks - init clocks from the retry list 166 * 167 * Initializes any clocks that have failed to initialize before, 168 * reasons being missing parent node(s) during earlier init. This 169 * typically happens only for DPLLs which need to have both of their 170 * parent clocks ready during init. 171 */ 172 void ti_dt_clk_init_retry_clks(void) 173 { 174 struct clk_init_item *retry; 175 struct clk_init_item *tmp; 176 int retries = 5; 177 178 while (!list_empty(&retry_list) && retries) { 179 list_for_each_entry_safe(retry, tmp, &retry_list, link) { 180 pr_debug("retry-init: %s\n", retry->node->name); 181 retry->func(retry->hw, retry->node); 182 list_del(&retry->link); 183 kfree(retry); 184 } 185 retries--; 186 } 187 } 188 189 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS) 190 void __init ti_clk_patch_legacy_clks(struct ti_clk **patch) 191 { 192 while (*patch) { 193 memcpy((*patch)->patch, *patch, sizeof(**patch)); 194 patch++; 195 } 196 } 197 198 struct clk __init *ti_clk_register_clk(struct ti_clk *setup) 199 { 200 struct clk *clk; 201 struct ti_clk_fixed *fixed; 202 struct ti_clk_fixed_factor *fixed_factor; 203 struct clk_hw *clk_hw; 204 205 if (setup->clk) 206 return setup->clk; 207 208 switch (setup->type) { 209 case TI_CLK_FIXED: 210 fixed = setup->data; 211 212 clk = clk_register_fixed_rate(NULL, setup->name, NULL, 213 CLK_IS_ROOT, fixed->frequency); 214 break; 215 case TI_CLK_MUX: 216 clk = ti_clk_register_mux(setup); 217 break; 218 case TI_CLK_DIVIDER: 219 clk = ti_clk_register_divider(setup); 220 break; 221 case TI_CLK_COMPOSITE: 222 clk = ti_clk_register_composite(setup); 223 break; 224 case TI_CLK_FIXED_FACTOR: 225 fixed_factor = setup->data; 226 227 clk = clk_register_fixed_factor(NULL, setup->name, 228 fixed_factor->parent, 229 0, fixed_factor->mult, 230 fixed_factor->div); 231 break; 232 case TI_CLK_GATE: 233 clk = ti_clk_register_gate(setup); 234 break; 235 case TI_CLK_DPLL: 236 clk = ti_clk_register_dpll(setup); 237 break; 238 default: 239 pr_err("bad type for %s!\n", setup->name); 240 clk = ERR_PTR(-EINVAL); 241 } 242 243 if (!IS_ERR(clk)) { 244 setup->clk = clk; 245 if (setup->clkdm_name) { 246 if (__clk_get_flags(clk) & CLK_IS_BASIC) { 247 pr_warn("can't setup clkdm for basic clk %s\n", 248 setup->name); 249 } else { 250 clk_hw = __clk_get_hw(clk); 251 to_clk_hw_omap(clk_hw)->clkdm_name = 252 setup->clkdm_name; 253 omap2_init_clk_clkdm(clk_hw); 254 } 255 } 256 } 257 258 return clk; 259 } 260 261 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks) 262 { 263 struct clk *clk; 264 bool retry; 265 struct ti_clk_alias *retry_clk; 266 struct ti_clk_alias *tmp; 267 268 while (clks->clk) { 269 clk = ti_clk_register_clk(clks->clk); 270 if (IS_ERR(clk)) { 271 if (PTR_ERR(clk) == -EAGAIN) { 272 list_add(&clks->link, &retry_list); 273 } else { 274 pr_err("register for %s failed: %ld\n", 275 clks->clk->name, PTR_ERR(clk)); 276 return PTR_ERR(clk); 277 } 278 } else { 279 clks->lk.clk = clk; 280 clkdev_add(&clks->lk); 281 } 282 clks++; 283 } 284 285 retry = true; 286 287 while (!list_empty(&retry_list) && retry) { 288 retry = false; 289 list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) { 290 pr_debug("retry-init: %s\n", retry_clk->clk->name); 291 clk = ti_clk_register_clk(retry_clk->clk); 292 if (IS_ERR(clk)) { 293 if (PTR_ERR(clk) == -EAGAIN) { 294 continue; 295 } else { 296 pr_err("register for %s failed: %ld\n", 297 retry_clk->clk->name, 298 PTR_ERR(clk)); 299 return PTR_ERR(clk); 300 } 301 } else { 302 retry = true; 303 retry_clk->lk.clk = clk; 304 clkdev_add(&retry_clk->lk); 305 list_del(&retry_clk->link); 306 } 307 } 308 } 309 310 return 0; 311 } 312 #endif 313