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.h> 19 #include <linux/clk-provider.h> 20 #include <linux/clkdev.h> 21 #include <linux/clk/ti.h> 22 #include <linux/of.h> 23 #include <linux/of_address.h> 24 #include <linux/list.h> 25 #include <linux/regmap.h> 26 #include <linux/bootmem.h> 27 28 #include "clock.h" 29 30 #undef pr_fmt 31 #define pr_fmt(fmt) "%s: " fmt, __func__ 32 33 struct ti_clk_ll_ops *ti_clk_ll_ops; 34 static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; 35 36 static struct ti_clk_features ti_clk_features; 37 38 struct clk_iomap { 39 struct regmap *regmap; 40 void __iomem *mem; 41 }; 42 43 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS]; 44 45 static void clk_memmap_writel(u32 val, void __iomem *reg) 46 { 47 struct clk_omap_reg *r = (struct clk_omap_reg *)® 48 struct clk_iomap *io = clk_memmaps[r->index]; 49 50 if (io->regmap) 51 regmap_write(io->regmap, r->offset, val); 52 else 53 writel_relaxed(val, io->mem + r->offset); 54 } 55 56 static u32 clk_memmap_readl(void __iomem *reg) 57 { 58 u32 val; 59 struct clk_omap_reg *r = (struct clk_omap_reg *)® 60 struct clk_iomap *io = clk_memmaps[r->index]; 61 62 if (io->regmap) 63 regmap_read(io->regmap, r->offset, &val); 64 else 65 val = readl_relaxed(io->mem + r->offset); 66 67 return val; 68 } 69 70 /** 71 * ti_clk_setup_ll_ops - setup low level clock operations 72 * @ops: low level clock ops descriptor 73 * 74 * Sets up low level clock operations for TI clock driver. This is used 75 * to provide various callbacks for the clock driver towards platform 76 * specific code. Returns 0 on success, -EBUSY if ll_ops have been 77 * registered already. 78 */ 79 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops) 80 { 81 if (ti_clk_ll_ops) { 82 pr_err("Attempt to register ll_ops multiple times.\n"); 83 return -EBUSY; 84 } 85 86 ti_clk_ll_ops = ops; 87 ops->clk_readl = clk_memmap_readl; 88 ops->clk_writel = clk_memmap_writel; 89 90 return 0; 91 } 92 93 /** 94 * ti_dt_clocks_register - register DT alias clocks during boot 95 * @oclks: list of clocks to register 96 * 97 * Register alias or non-standard DT clock entries during boot. By 98 * default, DT clocks are found based on their node name. If any 99 * additional con-id / dev-id -> clock mapping is required, use this 100 * function to list these. 101 */ 102 void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) 103 { 104 struct ti_dt_clk *c; 105 struct device_node *node; 106 struct clk *clk; 107 struct of_phandle_args clkspec; 108 109 for (c = oclks; c->node_name != NULL; c++) { 110 node = of_find_node_by_name(NULL, c->node_name); 111 clkspec.np = node; 112 clk = of_clk_get_from_provider(&clkspec); 113 114 if (!IS_ERR(clk)) { 115 c->lk.clk = clk; 116 clkdev_add(&c->lk); 117 } else { 118 pr_warn("failed to lookup clock node %s\n", 119 c->node_name); 120 } 121 } 122 } 123 124 struct clk_init_item { 125 struct device_node *node; 126 struct clk_hw *hw; 127 ti_of_clk_init_cb_t func; 128 struct list_head link; 129 }; 130 131 static LIST_HEAD(retry_list); 132 133 /** 134 * ti_clk_retry_init - retries a failed clock init at later phase 135 * @node: device not for the clock 136 * @hw: partially initialized clk_hw struct for the clock 137 * @func: init function to be called for the clock 138 * 139 * Adds a failed clock init to the retry list. The retry list is parsed 140 * once all the other clocks have been initialized. 141 */ 142 int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, 143 ti_of_clk_init_cb_t func) 144 { 145 struct clk_init_item *retry; 146 147 pr_debug("%s: adding to retry list...\n", node->name); 148 retry = kzalloc(sizeof(*retry), GFP_KERNEL); 149 if (!retry) 150 return -ENOMEM; 151 152 retry->node = node; 153 retry->func = func; 154 retry->hw = hw; 155 list_add(&retry->link, &retry_list); 156 157 return 0; 158 } 159 160 /** 161 * ti_clk_get_reg_addr - get register address for a clock register 162 * @node: device node for the clock 163 * @index: register index from the clock node 164 * 165 * Builds clock register address from device tree information. This 166 * is a struct of type clk_omap_reg. Returns a pointer to the register 167 * address, or a pointer error value in failure. 168 */ 169 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index) 170 { 171 struct clk_omap_reg *reg; 172 u32 val; 173 u32 tmp; 174 int i; 175 176 reg = (struct clk_omap_reg *)&tmp; 177 178 for (i = 0; i < CLK_MAX_MEMMAPS; i++) { 179 if (clocks_node_ptr[i] == node->parent) 180 break; 181 } 182 183 if (i == CLK_MAX_MEMMAPS) { 184 pr_err("clk-provider not found for %s!\n", node->name); 185 return IOMEM_ERR_PTR(-ENOENT); 186 } 187 188 reg->index = i; 189 190 if (of_property_read_u32_index(node, "reg", index, &val)) { 191 pr_err("%s must have reg[%d]!\n", node->name, index); 192 return IOMEM_ERR_PTR(-EINVAL); 193 } 194 195 reg->offset = val; 196 197 return (__force void __iomem *)tmp; 198 } 199 200 /** 201 * omap2_clk_provider_init - init master clock provider 202 * @parent: master node 203 * @index: internal index for clk_reg_ops 204 * @syscon: syscon regmap pointer for accessing clock registers 205 * @mem: iomem pointer for the clock provider memory area, only used if 206 * syscon is not provided 207 * 208 * Initializes a master clock IP block. This basically sets up the 209 * mapping from clocks node to the memory map index. All the clocks 210 * are then initialized through the common of_clk_init call, and the 211 * clocks will access their memory maps based on the node layout. 212 * Returns 0 in success. 213 */ 214 int __init omap2_clk_provider_init(struct device_node *parent, int index, 215 struct regmap *syscon, void __iomem *mem) 216 { 217 struct device_node *clocks; 218 struct clk_iomap *io; 219 220 /* get clocks for this parent */ 221 clocks = of_get_child_by_name(parent, "clocks"); 222 if (!clocks) { 223 pr_err("%s missing 'clocks' child node.\n", parent->name); 224 return -EINVAL; 225 } 226 227 /* add clocks node info */ 228 clocks_node_ptr[index] = clocks; 229 230 io = kzalloc(sizeof(*io), GFP_KERNEL); 231 if (!io) 232 return -ENOMEM; 233 234 io->regmap = syscon; 235 io->mem = mem; 236 237 clk_memmaps[index] = io; 238 239 return 0; 240 } 241 242 /** 243 * omap2_clk_legacy_provider_init - initialize a legacy clock provider 244 * @index: index for the clock provider 245 * @mem: iomem pointer for the clock provider memory area 246 * 247 * Initializes a legacy clock provider memory mapping. 248 */ 249 void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem) 250 { 251 struct clk_iomap *io; 252 253 io = memblock_virt_alloc(sizeof(*io), 0); 254 255 io->mem = mem; 256 257 clk_memmaps[index] = io; 258 } 259 260 /** 261 * ti_dt_clk_init_retry_clks - init clocks from the retry list 262 * 263 * Initializes any clocks that have failed to initialize before, 264 * reasons being missing parent node(s) during earlier init. This 265 * typically happens only for DPLLs which need to have both of their 266 * parent clocks ready during init. 267 */ 268 void ti_dt_clk_init_retry_clks(void) 269 { 270 struct clk_init_item *retry; 271 struct clk_init_item *tmp; 272 int retries = 5; 273 274 while (!list_empty(&retry_list) && retries) { 275 list_for_each_entry_safe(retry, tmp, &retry_list, link) { 276 pr_debug("retry-init: %s\n", retry->node->name); 277 retry->func(retry->hw, retry->node); 278 list_del(&retry->link); 279 kfree(retry); 280 } 281 retries--; 282 } 283 } 284 285 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS) 286 void __init ti_clk_patch_legacy_clks(struct ti_clk **patch) 287 { 288 while (*patch) { 289 memcpy((*patch)->patch, *patch, sizeof(**patch)); 290 patch++; 291 } 292 } 293 294 struct clk __init *ti_clk_register_clk(struct ti_clk *setup) 295 { 296 struct clk *clk; 297 struct ti_clk_fixed *fixed; 298 struct ti_clk_fixed_factor *fixed_factor; 299 struct clk_hw *clk_hw; 300 301 if (setup->clk) 302 return setup->clk; 303 304 switch (setup->type) { 305 case TI_CLK_FIXED: 306 fixed = setup->data; 307 308 clk = clk_register_fixed_rate(NULL, setup->name, NULL, 309 CLK_IS_ROOT, fixed->frequency); 310 break; 311 case TI_CLK_MUX: 312 clk = ti_clk_register_mux(setup); 313 break; 314 case TI_CLK_DIVIDER: 315 clk = ti_clk_register_divider(setup); 316 break; 317 case TI_CLK_COMPOSITE: 318 clk = ti_clk_register_composite(setup); 319 break; 320 case TI_CLK_FIXED_FACTOR: 321 fixed_factor = setup->data; 322 323 clk = clk_register_fixed_factor(NULL, setup->name, 324 fixed_factor->parent, 325 0, fixed_factor->mult, 326 fixed_factor->div); 327 break; 328 case TI_CLK_GATE: 329 clk = ti_clk_register_gate(setup); 330 break; 331 case TI_CLK_DPLL: 332 clk = ti_clk_register_dpll(setup); 333 break; 334 default: 335 pr_err("bad type for %s!\n", setup->name); 336 clk = ERR_PTR(-EINVAL); 337 } 338 339 if (!IS_ERR(clk)) { 340 setup->clk = clk; 341 if (setup->clkdm_name) { 342 clk_hw = __clk_get_hw(clk); 343 if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) { 344 pr_warn("can't setup clkdm for basic clk %s\n", 345 setup->name); 346 } else { 347 to_clk_hw_omap(clk_hw)->clkdm_name = 348 setup->clkdm_name; 349 omap2_init_clk_clkdm(clk_hw); 350 } 351 } 352 } 353 354 return clk; 355 } 356 357 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks) 358 { 359 struct clk *clk; 360 bool retry; 361 struct ti_clk_alias *retry_clk; 362 struct ti_clk_alias *tmp; 363 364 while (clks->clk) { 365 clk = ti_clk_register_clk(clks->clk); 366 if (IS_ERR(clk)) { 367 if (PTR_ERR(clk) == -EAGAIN) { 368 list_add(&clks->link, &retry_list); 369 } else { 370 pr_err("register for %s failed: %ld\n", 371 clks->clk->name, PTR_ERR(clk)); 372 return PTR_ERR(clk); 373 } 374 } else { 375 clks->lk.clk = clk; 376 clkdev_add(&clks->lk); 377 } 378 clks++; 379 } 380 381 retry = true; 382 383 while (!list_empty(&retry_list) && retry) { 384 retry = false; 385 list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) { 386 pr_debug("retry-init: %s\n", retry_clk->clk->name); 387 clk = ti_clk_register_clk(retry_clk->clk); 388 if (IS_ERR(clk)) { 389 if (PTR_ERR(clk) == -EAGAIN) { 390 continue; 391 } else { 392 pr_err("register for %s failed: %ld\n", 393 retry_clk->clk->name, 394 PTR_ERR(clk)); 395 return PTR_ERR(clk); 396 } 397 } else { 398 retry = true; 399 retry_clk->lk.clk = clk; 400 clkdev_add(&retry_clk->lk); 401 list_del(&retry_clk->link); 402 } 403 } 404 } 405 406 return 0; 407 } 408 #endif 409 410 /** 411 * ti_clk_setup_features - setup clock features flags 412 * @features: features definition to use 413 * 414 * Initializes the clock driver features flags based on platform 415 * provided data. No return value. 416 */ 417 void __init ti_clk_setup_features(struct ti_clk_features *features) 418 { 419 memcpy(&ti_clk_features, features, sizeof(*features)); 420 } 421 422 /** 423 * ti_clk_get_features - get clock driver features flags 424 * 425 * Get TI clock driver features description. Returns a pointer 426 * to the current feature setup. 427 */ 428 const struct ti_clk_features *ti_clk_get_features(void) 429 { 430 return &ti_clk_features; 431 } 432 433 /** 434 * omap2_clk_enable_init_clocks - prepare & enable a list of clocks 435 * @clk_names: ptr to an array of strings of clock names to enable 436 * @num_clocks: number of clock names in @clk_names 437 * 438 * Prepare and enable a list of clocks, named by @clk_names. No 439 * return value. XXX Deprecated; only needed until these clocks are 440 * properly claimed and enabled by the drivers or core code that uses 441 * them. XXX What code disables & calls clk_put on these clocks? 442 */ 443 void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks) 444 { 445 struct clk *init_clk; 446 int i; 447 448 for (i = 0; i < num_clocks; i++) { 449 init_clk = clk_get(NULL, clk_names[i]); 450 if (WARN(IS_ERR(init_clk), "could not find init clock %s\n", 451 clk_names[i])) 452 continue; 453 clk_prepare_enable(init_clk); 454 } 455 } 456