diff --git a/arch/arm/include/asm/arch-rockchip/cru_px30.h b/arch/arm/include/asm/arch-rockchip/cru_px30.h index df5ec9b9e2..acaa204a25 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_px30.h +++ b/arch/arm/include/asm/arch-rockchip/cru_px30.h @@ -27,6 +27,12 @@ enum px30_pll_id { PLL_COUNT, }; +struct px30_clk_info { + unsigned long id; + char *name; + bool is_cru; +}; + /* Private data for the clock driver - used by rockchip_get_cru() */ struct px30_clk_priv { struct px30_cru *cru; diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c index 3b8dca8547..7fbb279247 100644 --- a/drivers/clk/rockchip/clk_px30.c +++ b/drivers/clk/rockchip/clk_px30.c @@ -40,6 +40,13 @@ enum { #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) +#define PX30_CLK_DUMP(_id, _name, _iscru) \ +{ \ + .id = _id, \ + .name = _name, \ + .is_cru = _iscru, \ +} + static struct pll_rate_table px30_pll_rates[] = { /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), @@ -49,6 +56,20 @@ static struct pll_rate_table px30_pll_rates[] = { PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), }; +static const struct px30_clk_info clks_dump[] = { + PX30_CLK_DUMP(PLL_APLL, "apll", true), + PX30_CLK_DUMP(PLL_DPLL, "dpll", true), + PX30_CLK_DUMP(PLL_CPLL, "cpll", true), + PX30_CLK_DUMP(PLL_NPLL, "npll", true), + PX30_CLK_DUMP(PLL_GPLL, "gpll", false), + PX30_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true), + PX30_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true), + PX30_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true), + PX30_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true), + PX30_CLK_DUMP(HCLK_PERI_PRE, "hclk_peri", true), + PX30_CLK_DUMP(PCLK_PMU_PRE, "pclk_pmu", false), +}; + static u8 pll_mode_shift[PLL_COUNT] = { APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT, NPLL_MODE_SHIFT, GPLL_MODE_SHIFT @@ -1281,3 +1302,69 @@ U_BOOT_DRIVER(rockchip_px30_pmucru) = { .ops = &px30_pmuclk_ops, .probe = px30_pmuclk_probe, }; + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *cru_dev, *pmucru_dev; + const struct px30_clk_info *clk_dump; + struct clk clk; + unsigned long clk_count = ARRAY_SIZE(clks_dump); + unsigned long rate; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_px30_cru), + &cru_dev); + if (ret) { + printf("%s failed to get cru device\n", __func__); + return ret; + } + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_px30_pmucru), + &pmucru_dev); + if (ret) { + printf("%s failed to get pmucru device\n", __func__); + return ret; + } + + printf("CLK:"); + for (i = 0; i < clk_count; i++) { + clk_dump = &clks_dump[i]; + if (clk_dump->name) { + clk.id = clk_dump->id; + if (clk_dump->is_cru) + ret = clk_request(cru_dev, &clk); + else + ret = clk_request(pmucru_dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + clk_free(&clk); + if (i == 0) { + if (rate < 0) + printf("%10s%20s\n", clk_dump->name, + "unknown"); + else + printf("%10s%20lu Hz\n", clk_dump->name, + rate); + } else { + if (rate < 0) + printf("%14s%20s\n", clk_dump->name, + "unknown"); + else + printf("%14s%20lu Hz\n", clk_dump->name, + rate); + } + } + } + + return 0; +}