"Das U-Boot" Source Tree
at master 153 lines 3.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2013 Xilinx, Inc. 4 */ 5#include <command.h> 6#include <clk.h> 7#include <dm.h> 8#include <dm/device.h> 9#include <dm/root.h> 10#include <dm/device-internal.h> 11#include <linux/clk-provider.h> 12 13static void show_clks(struct udevice *dev, int depth, int last_flag) 14{ 15 int i, is_last; 16 struct udevice *child; 17 struct clk *clkp, *parent; 18 u32 rate; 19 20 clkp = dev_get_clk_ptr(dev); 21 if (clkp) { 22 parent = clk_get_parent(clkp); 23 if (!IS_ERR(parent) && depth == -1) 24 return; 25 depth++; 26 rate = clk_get_rate(clkp); 27 28 printf(" %-12u %8d ", rate, clkp->enable_count); 29 30 for (i = depth; i >= 0; i--) { 31 is_last = (last_flag >> i) & 1; 32 if (i) { 33 if (is_last) 34 printf(" "); 35 else 36 printf("| "); 37 } else { 38 if (is_last) 39 printf("`-- "); 40 else 41 printf("|-- "); 42 } 43 } 44 45 printf("%s\n", dev->name); 46 } 47 48 device_foreach_child_probe(child, dev) { 49 if (device_get_uclass_id(child) != UCLASS_CLK) 50 continue; 51 if (child == dev) 52 continue; 53 is_last = list_is_last(&child->sibling_node, &dev->child_head); 54 show_clks(child, depth, (last_flag << 1) | is_last); 55 } 56} 57 58static int soc_clk_dump(void) 59{ 60 struct udevice *dev; 61 const struct clk_ops *ops; 62 63 printf(" Rate Usecnt Name\n"); 64 printf("------------------------------------------\n"); 65 66 uclass_foreach_dev_probe(UCLASS_CLK, dev) 67 show_clks(dev, -1, 0); 68 69 uclass_foreach_dev_probe(UCLASS_CLK, dev) { 70 ops = dev_get_driver_ops(dev); 71 if (ops && ops->dump) { 72 printf("\n%s %s:\n", dev->driver->name, dev->name); 73 ops->dump(dev); 74 } 75 } 76 77 return 0; 78} 79 80static int do_clk_dump(struct cmd_tbl *cmdtp, int flag, int argc, 81 char *const argv[]) 82{ 83 int ret; 84 85 ret = soc_clk_dump(); 86 if (ret < 0) { 87 printf("Clock dump error %d\n", ret); 88 ret = CMD_RET_FAILURE; 89 } 90 91 return ret; 92} 93 94static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc, 95 char *const argv[]) 96{ 97 struct clk *clk = NULL; 98 s32 freq; 99 struct udevice *dev; 100 101 if (argc != 3) 102 return CMD_RET_USAGE; 103 104 freq = dectoul(argv[2], NULL); 105 106 if (!uclass_get_device_by_name(UCLASS_CLK, argv[1], &dev)) 107 clk = dev_get_clk_ptr(dev); 108 109 if (!clk) { 110 printf("clock '%s' not found.\n", argv[1]); 111 return CMD_RET_FAILURE; 112 } 113 114 freq = clk_set_rate(clk, freq); 115 if (freq < 0) { 116 printf("set_rate failed: %d\n", freq); 117 return CMD_RET_FAILURE; 118 } 119 120 printf("set_rate returns %u\n", freq); 121 return 0; 122} 123 124static struct cmd_tbl cmd_clk_sub[] = { 125 U_BOOT_CMD_MKENT(dump, 1, 1, do_clk_dump, "", ""), 126 U_BOOT_CMD_MKENT(setfreq, 3, 1, do_clk_setfreq, "", ""), 127}; 128 129static int do_clk(struct cmd_tbl *cmdtp, int flag, int argc, 130 char *const argv[]) 131{ 132 struct cmd_tbl *c; 133 134 if (argc < 2) 135 return CMD_RET_USAGE; 136 137 /* Strip off leading 'clk' command argument */ 138 argc--; 139 argv++; 140 141 c = find_cmd_tbl(argv[0], &cmd_clk_sub[0], ARRAY_SIZE(cmd_clk_sub)); 142 143 if (c) 144 return c->cmd(cmdtp, flag, argc, argv); 145 else 146 return CMD_RET_USAGE; 147} 148 149U_BOOT_LONGHELP(clk, 150 "dump - Print clock frequencies\n" 151 "clk setfreq [clk] [freq] - Set clock frequency"); 152 153U_BOOT_CMD(clk, 4, 1, do_clk, "CLK sub-system", clk_help_text);