10107f240SMasahiro Yamada /*
20107f240SMasahiro Yamada * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
30107f240SMasahiro Yamada * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
40107f240SMasahiro Yamada *
50107f240SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+
60107f240SMasahiro Yamada */
7*781745bdSStefan Herbrechtsmeier #include <clk.h>
80107f240SMasahiro Yamada #include <common.h>
9*781745bdSStefan Herbrechtsmeier #include <dm.h>
100107f240SMasahiro Yamada #include <asm/arch/clk.h>
110107f240SMasahiro Yamada
120107f240SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
130107f240SMasahiro Yamada
14e18c0f66SStefan Herbrechtsmeier static const char * const clk_names[clk_max] = {
15e18c0f66SStefan Herbrechtsmeier "armpll", "ddrpll", "iopll",
16e18c0f66SStefan Herbrechtsmeier "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
17e18c0f66SStefan Herbrechtsmeier "ddr2x", "ddr3x", "dci",
18e18c0f66SStefan Herbrechtsmeier "lqspi", "smc", "pcap", "gem0", "gem1",
19e18c0f66SStefan Herbrechtsmeier "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
20e18c0f66SStefan Herbrechtsmeier "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma",
21e18c0f66SStefan Herbrechtsmeier "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper",
22e18c0f66SStefan Herbrechtsmeier "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper",
23e18c0f66SStefan Herbrechtsmeier "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
24e18c0f66SStefan Herbrechtsmeier "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper",
25e18c0f66SStefan Herbrechtsmeier "smc_aper", "swdt", "dbg_trc", "dbg_apb"
26e18c0f66SStefan Herbrechtsmeier };
27e18c0f66SStefan Herbrechtsmeier
280107f240SMasahiro Yamada /**
29*781745bdSStefan Herbrechtsmeier * set_cpu_clk_info() - Setup clock information
300107f240SMasahiro Yamada *
310107f240SMasahiro Yamada * This function is called from common code after relocation and sets up the
32*781745bdSStefan Herbrechtsmeier * clock information.
330107f240SMasahiro Yamada */
set_cpu_clk_info(void)340107f240SMasahiro Yamada int set_cpu_clk_info(void)
350107f240SMasahiro Yamada {
36*781745bdSStefan Herbrechtsmeier struct clk clk;
37*781745bdSStefan Herbrechtsmeier struct udevice *dev;
38*781745bdSStefan Herbrechtsmeier ulong rate;
39*781745bdSStefan Herbrechtsmeier int i, ret;
400107f240SMasahiro Yamada
41*781745bdSStefan Herbrechtsmeier ret = uclass_get_device_by_driver(UCLASS_CLK,
42*781745bdSStefan Herbrechtsmeier DM_GET_DRIVER(zynq_clk), &dev);
43*781745bdSStefan Herbrechtsmeier if (ret)
44*781745bdSStefan Herbrechtsmeier return ret;
450107f240SMasahiro Yamada
46*781745bdSStefan Herbrechtsmeier for (i = 0; i < 2; i++) {
47*781745bdSStefan Herbrechtsmeier clk.id = i ? ddr3x_clk : cpu_6or4x_clk;
48*781745bdSStefan Herbrechtsmeier ret = clk_request(dev, &clk);
49*781745bdSStefan Herbrechtsmeier if (ret < 0)
50*781745bdSStefan Herbrechtsmeier return ret;
51*781745bdSStefan Herbrechtsmeier
52*781745bdSStefan Herbrechtsmeier rate = clk_get_rate(&clk) / 1000000;
53*781745bdSStefan Herbrechtsmeier if (i)
54*781745bdSStefan Herbrechtsmeier gd->bd->bi_ddr_freq = rate;
55*781745bdSStefan Herbrechtsmeier else
56*781745bdSStefan Herbrechtsmeier gd->bd->bi_arm_freq = rate;
57*781745bdSStefan Herbrechtsmeier
58*781745bdSStefan Herbrechtsmeier clk_free(&clk);
59*781745bdSStefan Herbrechtsmeier }
600107f240SMasahiro Yamada gd->bd->bi_dsp_freq = 0;
610107f240SMasahiro Yamada
620107f240SMasahiro Yamada return 0;
630107f240SMasahiro Yamada }
640107f240SMasahiro Yamada
650107f240SMasahiro Yamada /**
660107f240SMasahiro Yamada * soc_clk_dump() - Print clock frequencies
670107f240SMasahiro Yamada * Returns zero on success
680107f240SMasahiro Yamada *
690107f240SMasahiro Yamada * Implementation for the clk dump command.
700107f240SMasahiro Yamada */
soc_clk_dump(void)710107f240SMasahiro Yamada int soc_clk_dump(void)
720107f240SMasahiro Yamada {
73*781745bdSStefan Herbrechtsmeier struct udevice *dev;
74*781745bdSStefan Herbrechtsmeier int i, ret;
75*781745bdSStefan Herbrechtsmeier
76*781745bdSStefan Herbrechtsmeier ret = uclass_get_device_by_driver(UCLASS_CLK,
77*781745bdSStefan Herbrechtsmeier DM_GET_DRIVER(zynq_clk), &dev);
78*781745bdSStefan Herbrechtsmeier if (ret)
79*781745bdSStefan Herbrechtsmeier return ret;
800107f240SMasahiro Yamada
810107f240SMasahiro Yamada printf("clk\t\tfrequency\n");
820107f240SMasahiro Yamada for (i = 0; i < clk_max; i++) {
83f96fccbaSStefan Herbrechtsmeier const char *name = clk_names[i];
84*781745bdSStefan Herbrechtsmeier if (name) {
85*781745bdSStefan Herbrechtsmeier struct clk clk;
86*781745bdSStefan Herbrechtsmeier unsigned long rate;
87*781745bdSStefan Herbrechtsmeier
88*781745bdSStefan Herbrechtsmeier clk.id = i;
89*781745bdSStefan Herbrechtsmeier ret = clk_request(dev, &clk);
90*781745bdSStefan Herbrechtsmeier if (ret < 0)
91*781745bdSStefan Herbrechtsmeier return ret;
92*781745bdSStefan Herbrechtsmeier
93*781745bdSStefan Herbrechtsmeier rate = clk_get_rate(&clk);
94*781745bdSStefan Herbrechtsmeier
95*781745bdSStefan Herbrechtsmeier clk_free(&clk);
96*781745bdSStefan Herbrechtsmeier
97*781745bdSStefan Herbrechtsmeier if (rate == (unsigned long)-ENOSYS)
98*781745bdSStefan Herbrechtsmeier printf("%10s%20s\n", name, "unknown");
99*781745bdSStefan Herbrechtsmeier else
100*781745bdSStefan Herbrechtsmeier printf("%10s%20lu\n", name, rate);
101*781745bdSStefan Herbrechtsmeier }
1020107f240SMasahiro Yamada }
1030107f240SMasahiro Yamada
1040107f240SMasahiro Yamada return 0;
1050107f240SMasahiro Yamada }
106