clk.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2013 Xilinx, Inc.
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <clk.h>
  8. #if defined(CONFIG_DM) && defined(CONFIG_CLK)
  9. #include <dm.h>
  10. #include <dm/device.h>
  11. #include <dm/root.h>
  12. #include <dm/device-internal.h>
  13. #include <linux/clk-provider.h>
  14. #endif
  15. #if defined(CONFIG_DM) && defined(CONFIG_CLK)
  16. static void show_clks(struct udevice *dev, int depth, int last_flag)
  17. {
  18. int i, is_last;
  19. struct udevice *child;
  20. struct clk *clkp;
  21. u32 rate;
  22. clkp = dev_get_clk_ptr(dev);
  23. if (device_get_uclass_id(dev) == UCLASS_CLK && clkp) {
  24. rate = clk_get_rate(clkp);
  25. printf(" %-12u %8d ", rate, clkp->enable_count);
  26. for (i = depth; i >= 0; i--) {
  27. is_last = (last_flag >> i) & 1;
  28. if (i) {
  29. if (is_last)
  30. printf(" ");
  31. else
  32. printf("| ");
  33. } else {
  34. if (is_last)
  35. printf("`-- ");
  36. else
  37. printf("|-- ");
  38. }
  39. }
  40. printf("%s\n", dev->name);
  41. }
  42. list_for_each_entry(child, &dev->child_head, sibling_node) {
  43. is_last = list_is_last(&child->sibling_node, &dev->child_head);
  44. show_clks(child, depth + 1, (last_flag << 1) | is_last);
  45. }
  46. }
  47. int __weak soc_clk_dump(void)
  48. {
  49. struct udevice *root;
  50. root = dm_root();
  51. if (root) {
  52. printf(" Rate Usecnt Name\n");
  53. printf("------------------------------------------\n");
  54. show_clks(root, -1, 0);
  55. }
  56. return 0;
  57. }
  58. #else
  59. int __weak soc_clk_dump(void)
  60. {
  61. puts("Not implemented\n");
  62. return 1;
  63. }
  64. #endif
  65. static int do_clk_dump(cmd_tbl_t *cmdtp, int flag, int argc,
  66. char *const argv[])
  67. {
  68. int ret;
  69. ret = soc_clk_dump();
  70. if (ret < 0) {
  71. printf("Clock dump error %d\n", ret);
  72. ret = CMD_RET_FAILURE;
  73. }
  74. return ret;
  75. }
  76. static cmd_tbl_t cmd_clk_sub[] = {
  77. U_BOOT_CMD_MKENT(dump, 1, 1, do_clk_dump, "", ""),
  78. };
  79. static int do_clk(cmd_tbl_t *cmdtp, int flag, int argc,
  80. char *const argv[])
  81. {
  82. cmd_tbl_t *c;
  83. if (argc < 2)
  84. return CMD_RET_USAGE;
  85. /* Strip off leading 'clk' command argument */
  86. argc--;
  87. argv++;
  88. c = find_cmd_tbl(argv[0], &cmd_clk_sub[0], ARRAY_SIZE(cmd_clk_sub));
  89. if (c)
  90. return c->cmd(cmdtp, flag, argc, argv);
  91. else
  92. return CMD_RET_USAGE;
  93. }
  94. #ifdef CONFIG_SYS_LONGHELP
  95. static char clk_help_text[] =
  96. "dump - Print clock frequencies";
  97. #endif
  98. U_BOOT_CMD(clk, 2, 1, do_clk, "CLK sub-system", clk_help_text);