1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * Copyright (c) 2016, NVIDIA CORPORATION. 5 * Copyright (c) 2018, Theobroma Systems Design und Consulting GmbH 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <clk.h> 12 #include <clk-uclass.h> 13 #include <dm.h> 14 #include <dm/device-internal.h> 15 #include <dm/read.h> 16 #include <dt-structs.h> 17 #include <errno.h> 18 19 static inline const struct clk_ops *clk_dev_ops(struct udevice *dev) 20 { 21 return (const struct clk_ops *)dev->driver->ops; 22 } 23 24 #if CONFIG_IS_ENABLED(OF_CONTROL) 25 # if CONFIG_IS_ENABLED(OF_PLATDATA) 26 int clk_get_by_index_platdata(struct udevice *dev, int index, 27 struct phandle_1_arg *cells, struct clk *clk) 28 { 29 int ret; 30 31 if (index != 0) 32 return -ENOSYS; 33 ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev); 34 if (ret) 35 return ret; 36 clk->id = cells[0].arg[0]; 37 38 return 0; 39 } 40 # else 41 static int clk_of_xlate_default(struct clk *clk, 42 struct ofnode_phandle_args *args) 43 { 44 debug("%s(clk=%p)\n", __func__, clk); 45 46 if (args->args_count > 1) { 47 debug("Invaild args_count: %d\n", args->args_count); 48 return -EINVAL; 49 } 50 51 if (args->args_count) 52 clk->id = args->args[0]; 53 else 54 clk->id = 0; 55 56 return 0; 57 } 58 59 static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name, 60 int index, struct clk *clk) 61 { 62 int ret; 63 struct ofnode_phandle_args args; 64 struct udevice *dev_clk; 65 const struct clk_ops *ops; 66 67 debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk); 68 69 assert(clk); 70 clk->dev = NULL; 71 72 ret = dev_read_phandle_with_args(dev, prop_name, "#clock-cells", 0, 73 index, &args); 74 if (ret) { 75 debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n", 76 __func__, ret); 77 return ret; 78 } 79 80 ret = uclass_get_device_by_ofnode(UCLASS_CLK, args.node, &dev_clk); 81 if (ret) { 82 debug("%s: uclass_get_device_by_of_offset failed: err=%d\n", 83 __func__, ret); 84 return ret; 85 } 86 87 clk->dev = dev_clk; 88 89 ops = clk_dev_ops(dev_clk); 90 91 if (ops->of_xlate) 92 ret = ops->of_xlate(clk, &args); 93 else 94 ret = clk_of_xlate_default(clk, &args); 95 if (ret) { 96 debug("of_xlate() failed: %d\n", ret); 97 return ret; 98 } 99 100 return clk_request(dev_clk, clk); 101 } 102 103 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) 104 { 105 return clk_get_by_indexed_prop(dev, "clocks", index, clk); 106 } 107 108 int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) 109 { 110 int i, ret, err, count; 111 112 bulk->count = 0; 113 114 count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); 115 if (!count) 116 return 0; 117 118 bulk->clks = devm_kcalloc(dev, count, sizeof(struct clk), GFP_KERNEL); 119 if (!bulk->clks) 120 return -ENOMEM; 121 122 for (i = 0; i < count; i++) { 123 ret = clk_get_by_index(dev, i, &bulk->clks[i]); 124 if (ret < 0) 125 goto bulk_get_err; 126 127 ++bulk->count; 128 } 129 130 return 0; 131 132 bulk_get_err: 133 err = clk_release_all(bulk->clks, bulk->count); 134 if (err) 135 debug("%s: could release all clocks for %p\n", 136 __func__, dev); 137 138 return ret; 139 } 140 141 static int clk_set_default_parents(struct udevice *dev) 142 { 143 struct clk clk, parent_clk; 144 int index; 145 int num_parents; 146 int ret; 147 148 num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents", 149 "#clock-cells"); 150 if (num_parents < 0) { 151 debug("%s: could not read assigned-clock-parents for %p\n", 152 __func__, dev); 153 return 0; 154 } 155 156 for (index = 0; index < num_parents; index++) { 157 ret = clk_get_by_indexed_prop(dev, "assigned-clock-parents", 158 index, &parent_clk); 159 if (ret) { 160 debug("%s: could not get parent clock %d for %s\n", 161 __func__, index, dev_read_name(dev)); 162 return ret; 163 } 164 165 ret = clk_get_by_indexed_prop(dev, "assigned-clocks", 166 index, &clk); 167 if (ret) { 168 debug("%s: could not get assigned clock %d for %s\n", 169 __func__, index, dev_read_name(dev)); 170 return ret; 171 } 172 173 ret = clk_set_parent(&clk, &parent_clk); 174 175 /* 176 * Not all drivers may support clock-reparenting (as of now). 177 * Ignore errors due to this. 178 */ 179 if (ret == -ENOSYS) 180 continue; 181 182 if (ret) { 183 debug("%s: failed to reparent clock %d for %s\n", 184 __func__, index, dev_read_name(dev)); 185 return ret; 186 } 187 } 188 189 return 0; 190 } 191 192 static int clk_set_default_rates(struct udevice *dev) 193 { 194 struct clk clk; 195 int index; 196 int num_rates; 197 int size; 198 int ret = 0; 199 u32 *rates = NULL; 200 201 size = dev_read_size(dev, "assigned-clock-rates"); 202 if (size < 0) 203 return 0; 204 205 num_rates = size / sizeof(u32); 206 rates = calloc(num_rates, sizeof(u32)); 207 if (!rates) 208 return -ENOMEM; 209 210 ret = dev_read_u32_array(dev, "assigned-clock-rates", rates, num_rates); 211 if (ret) 212 goto fail; 213 214 for (index = 0; index < num_rates; index++) { 215 ret = clk_get_by_indexed_prop(dev, "assigned-clocks", 216 index, &clk); 217 if (ret) { 218 debug("%s: could not get assigned clock %d for %s\n", 219 __func__, index, dev_read_name(dev)); 220 continue; 221 } 222 223 ret = clk_set_rate(&clk, rates[index]); 224 if (ret < 0) { 225 debug("%s: failed to set rate on clock %d for %s\n", 226 __func__, index, dev_read_name(dev)); 227 continue; 228 } 229 } 230 231 fail: 232 free(rates); 233 return ret; 234 } 235 236 int clk_set_defaults(struct udevice *dev) 237 { 238 int ret; 239 240 #ifndef CONFIG_SPL_BUILD 241 /* If this is running pre-reloc state, don't take any action. */ 242 if (!(gd->flags & GD_FLG_RELOC)) 243 return 0; 244 #endif 245 debug("%s(%s)\n", __func__, dev_read_name(dev)); 246 247 ret = clk_set_default_parents(dev); 248 if (ret) 249 return ret; 250 251 ret = clk_set_default_rates(dev); 252 if (ret < 0) 253 return ret; 254 255 return 0; 256 } 257 # endif /* OF_PLATDATA */ 258 259 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk) 260 { 261 int index; 262 263 debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk); 264 clk->dev = NULL; 265 266 index = dev_read_stringlist_search(dev, "clock-names", name); 267 if (index < 0) { 268 debug("fdt_stringlist_search() failed: %d\n", index); 269 return index; 270 } 271 272 return clk_get_by_index(dev, index, clk); 273 } 274 275 int clk_release_all(struct clk *clk, int count) 276 { 277 int i, ret; 278 279 for (i = 0; i < count; i++) { 280 debug("%s(clk[%d]=%p)\n", __func__, i, &clk[i]); 281 282 /* check if clock has been previously requested */ 283 if (!clk[i].dev) 284 continue; 285 286 ret = clk_disable(&clk[i]); 287 if (ret && ret != -ENOSYS) 288 return ret; 289 290 ret = clk_free(&clk[i]); 291 if (ret && ret != -ENOSYS) 292 return ret; 293 } 294 295 return 0; 296 } 297 298 #endif /* OF_CONTROL */ 299 300 int clk_request(struct udevice *dev, struct clk *clk) 301 { 302 const struct clk_ops *ops = clk_dev_ops(dev); 303 304 debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk); 305 306 clk->dev = dev; 307 308 if (!ops->request) 309 return 0; 310 311 return ops->request(clk); 312 } 313 314 int clk_free(struct clk *clk) 315 { 316 const struct clk_ops *ops = clk_dev_ops(clk->dev); 317 318 debug("%s(clk=%p)\n", __func__, clk); 319 320 if (!ops->free) 321 return 0; 322 323 return ops->free(clk); 324 } 325 326 ulong clk_get_rate(struct clk *clk) 327 { 328 const struct clk_ops *ops = clk_dev_ops(clk->dev); 329 330 debug("%s(clk=%p)\n", __func__, clk); 331 332 if (!ops->get_rate) 333 return -ENOSYS; 334 335 return ops->get_rate(clk); 336 } 337 338 ulong clk_set_rate(struct clk *clk, ulong rate) 339 { 340 const struct clk_ops *ops = clk_dev_ops(clk->dev); 341 342 debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); 343 344 if (!ops->set_rate) 345 return -ENOSYS; 346 347 return ops->set_rate(clk, rate); 348 } 349 350 int clk_get_phase(struct clk *clk) 351 { 352 const struct clk_ops *ops = clk_dev_ops(clk->dev); 353 354 if (!ops->get_phase) 355 return -ENOSYS; 356 357 return ops->get_phase(clk); 358 } 359 360 int clk_set_phase(struct clk *clk, int degrees) 361 { 362 const struct clk_ops *ops = clk_dev_ops(clk->dev); 363 364 if (!ops->set_phase) 365 return -ENOSYS; 366 367 return ops->set_phase(clk, degrees); 368 } 369 370 int clk_set_parent(struct clk *clk, struct clk *parent) 371 { 372 const struct clk_ops *ops = clk_dev_ops(clk->dev); 373 374 debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); 375 376 if (!ops->set_parent) 377 return -ENOSYS; 378 379 return ops->set_parent(clk, parent); 380 } 381 382 int clk_enable(struct clk *clk) 383 { 384 const struct clk_ops *ops = clk_dev_ops(clk->dev); 385 386 debug("%s(clk=%p)\n", __func__, clk); 387 388 if (!ops->enable) 389 return -ENOSYS; 390 391 return ops->enable(clk); 392 } 393 394 int clk_enable_bulk(struct clk_bulk *bulk) 395 { 396 int i, ret; 397 398 for (i = 0; i < bulk->count; i++) { 399 ret = clk_enable(&bulk->clks[i]); 400 if (ret < 0 && ret != -ENOSYS) 401 return ret; 402 } 403 404 return 0; 405 } 406 407 int clk_disable(struct clk *clk) 408 { 409 const struct clk_ops *ops = clk_dev_ops(clk->dev); 410 411 debug("%s(clk=%p)\n", __func__, clk); 412 413 if (!ops->disable) 414 return -ENOSYS; 415 416 return ops->disable(clk); 417 } 418 419 int clk_disable_bulk(struct clk_bulk *bulk) 420 { 421 int i, ret; 422 423 for (i = 0; i < bulk->count; i++) { 424 ret = clk_disable(&bulk->clks[i]); 425 if (ret < 0 && ret != -ENOSYS) 426 return ret; 427 } 428 429 return 0; 430 } 431 432 int clks_probe(void) 433 { 434 struct udevice *dev; 435 struct uclass *uc; 436 int ret; 437 438 ret = uclass_get(UCLASS_CLK, &uc); 439 if (ret) 440 return ret; 441 442 uclass_foreach_dev(dev, uc) { 443 ret = device_probe(dev); 444 if (ret) 445 printf("%s - probe failed: %d\n", dev->name, ret); 446 } 447 448 return 0; 449 } 450 451 UCLASS_DRIVER(clk) = { 452 .id = UCLASS_CLK, 453 .name = "clk", 454 }; 455