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 static int clk_set_default_parents(struct udevice *dev) 109 { 110 struct clk clk, parent_clk; 111 int index; 112 int num_parents; 113 int ret; 114 115 num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents", 116 "#clock-cells"); 117 if (num_parents < 0) { 118 debug("%s: could not read assigned-clock-parents for %p\n", 119 __func__, dev); 120 return 0; 121 } 122 123 for (index = 0; index < num_parents; index++) { 124 ret = clk_get_by_indexed_prop(dev, "assigned-clock-parents", 125 index, &parent_clk); 126 if (ret) { 127 debug("%s: could not get parent clock %d for %s\n", 128 __func__, index, dev_read_name(dev)); 129 return ret; 130 } 131 132 ret = clk_get_by_indexed_prop(dev, "assigned-clocks", 133 index, &clk); 134 if (ret) { 135 debug("%s: could not get assigned clock %d for %s\n", 136 __func__, index, dev_read_name(dev)); 137 return ret; 138 } 139 140 ret = clk_set_parent(&clk, &parent_clk); 141 142 /* 143 * Not all drivers may support clock-reparenting (as of now). 144 * Ignore errors due to this. 145 */ 146 if (ret == -ENOSYS) 147 continue; 148 149 if (ret) { 150 debug("%s: failed to reparent clock %d for %s\n", 151 __func__, index, dev_read_name(dev)); 152 return ret; 153 } 154 } 155 156 return 0; 157 } 158 159 static int clk_set_default_rates(struct udevice *dev) 160 { 161 struct clk clk; 162 int index; 163 int num_rates; 164 int size; 165 int ret = 0; 166 u32 *rates = NULL; 167 168 size = dev_read_size(dev, "assigned-clock-rates"); 169 if (size < 0) 170 return 0; 171 172 num_rates = size / sizeof(u32); 173 rates = calloc(num_rates, sizeof(u32)); 174 if (!rates) 175 return -ENOMEM; 176 177 ret = dev_read_u32_array(dev, "assigned-clock-rates", rates, num_rates); 178 if (ret) 179 goto fail; 180 181 for (index = 0; index < num_rates; index++) { 182 ret = clk_get_by_indexed_prop(dev, "assigned-clocks", 183 index, &clk); 184 if (ret) { 185 debug("%s: could not get assigned clock %d for %s\n", 186 __func__, index, dev_read_name(dev)); 187 continue; 188 } 189 190 ret = clk_set_rate(&clk, rates[index]); 191 if (ret < 0) { 192 debug("%s: failed to set rate on clock %d for %s\n", 193 __func__, index, dev_read_name(dev)); 194 continue; 195 } 196 } 197 198 fail: 199 free(rates); 200 return ret; 201 } 202 203 int clk_set_defaults(struct udevice *dev) 204 { 205 int ret; 206 207 /* If this is running pre-reloc state, don't take any action. */ 208 if (!(gd->flags & GD_FLG_RELOC)) 209 return 0; 210 211 debug("%s(%s)\n", __func__, dev_read_name(dev)); 212 213 ret = clk_set_default_parents(dev); 214 if (ret) 215 return ret; 216 217 ret = clk_set_default_rates(dev); 218 if (ret < 0) 219 return ret; 220 221 return 0; 222 } 223 # endif /* OF_PLATDATA */ 224 225 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk) 226 { 227 int index; 228 229 debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk); 230 clk->dev = NULL; 231 232 index = dev_read_stringlist_search(dev, "clock-names", name); 233 if (index < 0) { 234 debug("fdt_stringlist_search() failed: %d\n", index); 235 return index; 236 } 237 238 return clk_get_by_index(dev, index, clk); 239 } 240 241 int clk_release_all(struct clk *clk, int count) 242 { 243 int i, ret; 244 245 for (i = 0; i < count; i++) { 246 debug("%s(clk[%d]=%p)\n", __func__, i, &clk[i]); 247 248 /* check if clock has been previously requested */ 249 if (!clk[i].dev) 250 continue; 251 252 ret = clk_disable(&clk[i]); 253 if (ret && ret != -ENOSYS) 254 return ret; 255 256 ret = clk_free(&clk[i]); 257 if (ret && ret != -ENOSYS) 258 return ret; 259 } 260 261 return 0; 262 } 263 264 #endif /* OF_CONTROL */ 265 266 int clk_request(struct udevice *dev, struct clk *clk) 267 { 268 const struct clk_ops *ops = clk_dev_ops(dev); 269 270 debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk); 271 272 clk->dev = dev; 273 274 if (!ops->request) 275 return 0; 276 277 return ops->request(clk); 278 } 279 280 int clk_free(struct clk *clk) 281 { 282 const struct clk_ops *ops = clk_dev_ops(clk->dev); 283 284 debug("%s(clk=%p)\n", __func__, clk); 285 286 if (!ops->free) 287 return 0; 288 289 return ops->free(clk); 290 } 291 292 ulong clk_get_rate(struct clk *clk) 293 { 294 const struct clk_ops *ops = clk_dev_ops(clk->dev); 295 296 debug("%s(clk=%p)\n", __func__, clk); 297 298 if (!ops->get_rate) 299 return -ENOSYS; 300 301 return ops->get_rate(clk); 302 } 303 304 ulong clk_set_rate(struct clk *clk, ulong rate) 305 { 306 const struct clk_ops *ops = clk_dev_ops(clk->dev); 307 308 debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); 309 310 if (!ops->set_rate) 311 return -ENOSYS; 312 313 return ops->set_rate(clk, rate); 314 } 315 316 int clk_get_phase(struct clk *clk) 317 { 318 const struct clk_ops *ops = clk_dev_ops(clk->dev); 319 320 if (!ops->get_phase) 321 return -ENOSYS; 322 323 return ops->get_phase(clk); 324 } 325 326 int clk_set_phase(struct clk *clk, int degrees) 327 { 328 const struct clk_ops *ops = clk_dev_ops(clk->dev); 329 330 if (!ops->set_phase) 331 return -ENOSYS; 332 333 return ops->set_phase(clk, degrees); 334 } 335 336 int clk_set_parent(struct clk *clk, struct clk *parent) 337 { 338 const struct clk_ops *ops = clk_dev_ops(clk->dev); 339 340 debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); 341 342 if (!ops->set_parent) 343 return -ENOSYS; 344 345 return ops->set_parent(clk, parent); 346 } 347 348 int clk_enable(struct clk *clk) 349 { 350 const struct clk_ops *ops = clk_dev_ops(clk->dev); 351 352 debug("%s(clk=%p)\n", __func__, clk); 353 354 if (!ops->enable) 355 return -ENOSYS; 356 357 return ops->enable(clk); 358 } 359 360 int clk_disable(struct clk *clk) 361 { 362 const struct clk_ops *ops = clk_dev_ops(clk->dev); 363 364 debug("%s(clk=%p)\n", __func__, clk); 365 366 if (!ops->disable) 367 return -ENOSYS; 368 369 return ops->disable(clk); 370 } 371 372 int clks_probe(void) 373 { 374 struct udevice *dev; 375 struct uclass *uc; 376 int ret; 377 378 ret = uclass_get(UCLASS_CLK, &uc); 379 if (ret) 380 return ret; 381 382 uclass_foreach_dev(dev, uc) { 383 ret = device_probe(dev); 384 if (ret) 385 printf("%s - probe failed: %d\n", dev->name, ret); 386 } 387 388 return 0; 389 } 390 391 UCLASS_DRIVER(clk) = { 392 .id = UCLASS_CLK, 393 .name = "clk", 394 }; 395