183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass * Copyright (C) 2013 Xilinx, Inc.
42e192b24SSimon Glass */
52e192b24SSimon Glass #include <common.h>
62e192b24SSimon Glass #include <command.h>
72e192b24SSimon Glass #include <clk.h>
8*ff8eee03SMarek Vasut #if defined(CONFIG_DM) && defined(CONFIG_CLK)
9*ff8eee03SMarek Vasut #include <dm.h>
10*ff8eee03SMarek Vasut #include <dm/device-internal.h>
11*ff8eee03SMarek Vasut #endif
122e192b24SSimon Glass
soc_clk_dump(void)132e192b24SSimon Glass int __weak soc_clk_dump(void)
142e192b24SSimon Glass {
15*ff8eee03SMarek Vasut #if defined(CONFIG_DM) && defined(CONFIG_CLK)
16*ff8eee03SMarek Vasut struct udevice *dev;
17*ff8eee03SMarek Vasut struct uclass *uc;
18*ff8eee03SMarek Vasut struct clk clk;
19*ff8eee03SMarek Vasut int ret;
20*ff8eee03SMarek Vasut
21*ff8eee03SMarek Vasut /* Device addresses start at 1 */
22*ff8eee03SMarek Vasut ret = uclass_get(UCLASS_CLK, &uc);
23*ff8eee03SMarek Vasut if (ret)
24*ff8eee03SMarek Vasut return ret;
25*ff8eee03SMarek Vasut
26*ff8eee03SMarek Vasut uclass_foreach_dev(dev, uc) {
27*ff8eee03SMarek Vasut memset(&clk, 0, sizeof(clk));
28*ff8eee03SMarek Vasut ret = device_probe(dev);
29*ff8eee03SMarek Vasut if (ret) {
30*ff8eee03SMarek Vasut printf("%-30.30s : ? Hz\n", dev->name);
31*ff8eee03SMarek Vasut continue;
32*ff8eee03SMarek Vasut }
33*ff8eee03SMarek Vasut
34*ff8eee03SMarek Vasut ret = clk_request(dev, &clk);
35*ff8eee03SMarek Vasut if (ret) {
36*ff8eee03SMarek Vasut printf("%-30.30s : ? Hz\n", dev->name);
37*ff8eee03SMarek Vasut continue;
38*ff8eee03SMarek Vasut }
39*ff8eee03SMarek Vasut
40*ff8eee03SMarek Vasut printf("%-30.30s : %lu Hz\n", dev->name, clk_get_rate(&clk));
41*ff8eee03SMarek Vasut
42*ff8eee03SMarek Vasut clk_free(&clk);
43*ff8eee03SMarek Vasut }
44*ff8eee03SMarek Vasut
45*ff8eee03SMarek Vasut return 0;
46*ff8eee03SMarek Vasut #else
472e192b24SSimon Glass puts("Not implemented\n");
482e192b24SSimon Glass return 1;
49*ff8eee03SMarek Vasut #endif
502e192b24SSimon Glass }
512e192b24SSimon Glass
do_clk_dump(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])522e192b24SSimon Glass static int do_clk_dump(cmd_tbl_t *cmdtp, int flag, int argc,
532e192b24SSimon Glass char *const argv[])
542e192b24SSimon Glass {
55ebc675b9SMichal Simek int ret;
56ebc675b9SMichal Simek
57ebc675b9SMichal Simek ret = soc_clk_dump();
58ebc675b9SMichal Simek if (ret < 0) {
59ebc675b9SMichal Simek printf("Clock dump error %d\n", ret);
60ebc675b9SMichal Simek ret = CMD_RET_FAILURE;
61ebc675b9SMichal Simek }
62ebc675b9SMichal Simek
63ebc675b9SMichal Simek return ret;
642e192b24SSimon Glass }
652e192b24SSimon Glass
662e192b24SSimon Glass static cmd_tbl_t cmd_clk_sub[] = {
672e192b24SSimon Glass U_BOOT_CMD_MKENT(dump, 1, 1, do_clk_dump, "", ""),
682e192b24SSimon Glass };
692e192b24SSimon Glass
do_clk(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])702e192b24SSimon Glass static int do_clk(cmd_tbl_t *cmdtp, int flag, int argc,
712e192b24SSimon Glass char *const argv[])
722e192b24SSimon Glass {
732e192b24SSimon Glass cmd_tbl_t *c;
742e192b24SSimon Glass
752e192b24SSimon Glass if (argc < 2)
762e192b24SSimon Glass return CMD_RET_USAGE;
772e192b24SSimon Glass
782e192b24SSimon Glass /* Strip off leading 'clk' command argument */
792e192b24SSimon Glass argc--;
802e192b24SSimon Glass argv++;
812e192b24SSimon Glass
822e192b24SSimon Glass c = find_cmd_tbl(argv[0], &cmd_clk_sub[0], ARRAY_SIZE(cmd_clk_sub));
832e192b24SSimon Glass
842e192b24SSimon Glass if (c)
852e192b24SSimon Glass return c->cmd(cmdtp, flag, argc, argv);
862e192b24SSimon Glass else
872e192b24SSimon Glass return CMD_RET_USAGE;
882e192b24SSimon Glass }
892e192b24SSimon Glass
902e192b24SSimon Glass #ifdef CONFIG_SYS_LONGHELP
912e192b24SSimon Glass static char clk_help_text[] =
922e192b24SSimon Glass "dump - Print clock frequencies";
932e192b24SSimon Glass #endif
942e192b24SSimon Glass
952e192b24SSimon Glass U_BOOT_CMD(clk, 2, 1, do_clk, "CLK sub-system", clk_help_text);
96