mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
clock patches for u-boot/next
The main thing in here is Igor's conversion of soc_clk_dump to a clk_ops member. There's also a write-protect feature for nuvoton clocks. Signed-off-by: Sean Anderson <seanga2@gmail.com> -----BEGIN PGP SIGNATURE----- iQGTBAABCgB9FiEEkGEdW86NSNID6GAoPuiP7LShEG4FAmV8uvhfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDkw NjExRDVCQ0U4RDQ4RDIwM0U4NjAyODNFRTg4RkVDQjRBMTEwNkUACgkQPuiP7LSh EG5TtQf+N5BIVCRDFgFT7rM1lGYVtJEOm+oj58zQfM4MUAp2LKCHbHv7c8ZMUmdu SJPJiDW4I2xQqAaawxcSub4L5d0G22SopotIVOcQXXTFFeW8rdpcRjhPhyIuHN8w 6dOo8T9U+BMjoNgtY48nNAhkzDGUDVJRZ/uBt8F1U6hKjk5OisSFyBfPZMtuvr/D EBG8QqzXOMujrm9HGSVipvnSbgGX+QqtST4mVoatvQJ3DWYXxq8O5BPJFer1DL3F BcI9yNaOG/L6MXAA3wkjh3nYLXoiRUgo2DRag++XMHnXYQ/xFzekraNAFHGDQslQ Gnjz+5xp/z4ywOEkHSuI3mZIICBJ1Q== =z+Sl -----END PGP SIGNATURE----- Merge tag 'clk-2024.01-next' of https://source.denx.de/u-boot/custodians/u-boot-clk into next clock patches for u-boot/next The main thing in here is Igor's conversion of soc_clk_dump to a clk_ops member. There's also a write-protect feature for nuvoton clocks. Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
commit
8bb3cd7fe7
18 changed files with 288 additions and 277 deletions
|
@ -13,20 +13,6 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const char * const clk_names[clk_max] = {
|
||||
"armpll", "ddrpll", "iopll",
|
||||
"cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
|
||||
"ddr2x", "ddr3x", "dci",
|
||||
"lqspi", "smc", "pcap", "gem0", "gem1",
|
||||
"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
|
||||
"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma",
|
||||
"usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper",
|
||||
"sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper",
|
||||
"can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
|
||||
"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper",
|
||||
"smc_aper", "swdt", "dbg_trc", "dbg_apb"
|
||||
};
|
||||
|
||||
/**
|
||||
* set_cpu_clk_info() - Setup clock information
|
||||
*
|
||||
|
@ -65,46 +51,3 @@ int set_cpu_clk_info(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* soc_clk_dump() - Print clock frequencies
|
||||
* Returns zero on success
|
||||
*
|
||||
* Implementation for the clk dump command.
|
||||
*/
|
||||
int soc_clk_dump(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int i, ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_DRIVER_GET(zynq_clk), &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printf("clk\t\tfrequency\n");
|
||||
for (i = 0; i < clk_max; i++) {
|
||||
const char *name = clk_names[i];
|
||||
if (name) {
|
||||
struct clk clk;
|
||||
unsigned long rate;
|
||||
|
||||
clk.id = i;
|
||||
ret = clk_request(dev, &clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rate = clk_get_rate(&clk);
|
||||
|
||||
clk_free(&clk);
|
||||
|
||||
if ((rate == (unsigned long)-ENOSYS) ||
|
||||
(rate == (unsigned long)-ENXIO))
|
||||
printf("%10s%20s\n", name, "unknown");
|
||||
else
|
||||
printf("%10s%20lu\n", name, rate);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -143,26 +143,3 @@ const char *get_core_name(void)
|
|||
return str;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_CMD_CLK
|
||||
|
||||
int soc_clk_dump(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("PLL Speed: %lu MHz\n",
|
||||
CLK_MHZ(rate(PLLCLK)));
|
||||
|
||||
printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK)));
|
||||
|
||||
printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL)));
|
||||
|
||||
for (i = PB1CLK; i <= PB7CLK; i++)
|
||||
printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1,
|
||||
CLK_MHZ(rate(i)));
|
||||
|
||||
for (i = REF1CLK; i <= REF5CLK; i++)
|
||||
printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1,
|
||||
CLK_MHZ(rate(i)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
13
cmd/clk.c
13
cmd/clk.c
|
@ -59,9 +59,10 @@ static void show_clks(struct udevice *dev, int depth, int last_flag)
|
|||
}
|
||||
}
|
||||
|
||||
int __weak soc_clk_dump(void)
|
||||
static int soc_clk_dump(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
const struct clk_ops *ops;
|
||||
|
||||
printf(" Rate Usecnt Name\n");
|
||||
printf("------------------------------------------\n");
|
||||
|
@ -69,10 +70,18 @@ int __weak soc_clk_dump(void)
|
|||
uclass_foreach_dev_probe(UCLASS_CLK, dev)
|
||||
show_clks(dev, -1, 0);
|
||||
|
||||
uclass_foreach_dev_probe(UCLASS_CLK, dev) {
|
||||
ops = dev_get_driver_ops(dev);
|
||||
if (ops && ops->dump) {
|
||||
printf("\n%s %s:\n", dev->driver->name, dev->name);
|
||||
ops->dump(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int __weak soc_clk_dump(void)
|
||||
static int soc_clk_dump(void)
|
||||
{
|
||||
puts("Not implemented\n");
|
||||
return 1;
|
||||
|
|
|
@ -1104,46 +1104,12 @@ static int ast2600_clk_enable(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct clk_ops ast2600_clk_ops = {
|
||||
.get_rate = ast2600_clk_get_rate,
|
||||
.set_rate = ast2600_clk_set_rate,
|
||||
.enable = ast2600_clk_enable,
|
||||
};
|
||||
|
||||
static int ast2600_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct ast2600_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->scu = devfdt_get_addr_ptr(dev);
|
||||
if (IS_ERR(priv->scu))
|
||||
return PTR_ERR(priv->scu);
|
||||
|
||||
ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
|
||||
ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
|
||||
ast2600_configure_mac12_clk(priv->scu);
|
||||
ast2600_configure_mac34_clk(priv->scu);
|
||||
ast2600_configure_rsa_ecc_clk(priv->scu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ast2600_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No reset driver: ret=%d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct aspeed_clks {
|
||||
ulong id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static struct aspeed_clks aspeed_clk_names[] = {
|
||||
{ ASPEED_CLK_HPLL, "hpll" },
|
||||
{ ASPEED_CLK_MPLL, "mpll" },
|
||||
|
@ -1158,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = {
|
|||
{ ASPEED_CLK_HUARTX, "huxclk" },
|
||||
};
|
||||
|
||||
int soc_clk_dump(void)
|
||||
static void ast2600_clk_dump(struct udevice *dev)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct clk clk;
|
||||
unsigned long rate;
|
||||
int i, ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu),
|
||||
&dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printf("Clk\t\tHz\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) {
|
||||
|
@ -1202,6 +1162,45 @@ int soc_clk_dump(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct clk_ops ast2600_clk_ops = {
|
||||
.get_rate = ast2600_clk_get_rate,
|
||||
.set_rate = ast2600_clk_set_rate,
|
||||
.enable = ast2600_clk_enable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = ast2600_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int ast2600_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct ast2600_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->scu = devfdt_get_addr_ptr(dev);
|
||||
if (IS_ERR(priv->scu))
|
||||
return PTR_ERR(priv->scu);
|
||||
|
||||
ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
|
||||
ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
|
||||
ast2600_configure_mac12_clk(priv->scu);
|
||||
ast2600_configure_mac34_clk(priv->scu);
|
||||
ast2600_configure_rsa_ecc_clk(priv->scu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ast2600_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No reset driver: ret=%d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id ast2600_clk_ids[] = {
|
||||
{ .compatible = "aspeed,ast2600-scu", },
|
||||
|
|
|
@ -1239,52 +1239,6 @@ static int k210_clk_request(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops k210_clk_ops = {
|
||||
.request = k210_clk_request,
|
||||
.set_rate = k210_clk_set_rate,
|
||||
.get_rate = k210_clk_get_rate,
|
||||
.set_parent = k210_clk_set_parent,
|
||||
.enable = k210_clk_enable,
|
||||
.disable = k210_clk_disable,
|
||||
};
|
||||
|
||||
static int k210_clk_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct k210_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev_get_parent(dev));
|
||||
if (!priv->base)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->in0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Force setting defaults, even before relocation. This is so we can
|
||||
* set the clock rate for PLL1 before we relocate into aisram.
|
||||
*/
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id k210_clk_ids[] = {
|
||||
{ .compatible = "canaan,k210-clk" },
|
||||
{ },
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(k210_clk) = {
|
||||
.name = "k210_clk",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = k210_clk_ids,
|
||||
.ops = &k210_clk_ops,
|
||||
.probe = k210_clk_probe,
|
||||
.priv_auto = sizeof(struct k210_clk_priv),
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static char show_enabled(struct k210_clk_priv *priv, int id)
|
||||
{
|
||||
|
@ -1323,16 +1277,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth)
|
|||
}
|
||||
}
|
||||
|
||||
int soc_clk_dump(void)
|
||||
static void k210_clk_dump(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *dev;
|
||||
struct k210_clk_priv *priv;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk),
|
||||
&dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
priv = dev_get_priv(dev);
|
||||
|
||||
puts(" Rate Enabled Name\n");
|
||||
|
@ -1340,6 +1288,54 @@ int soc_clk_dump(void)
|
|||
printf(" %-9lu %-7c %*s%s\n", clk_get_rate(&priv->in0), 'y', 0, "",
|
||||
priv->in0.dev->name);
|
||||
show_clks(priv, K210_CLK_IN0, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct clk_ops k210_clk_ops = {
|
||||
.request = k210_clk_request,
|
||||
.set_rate = k210_clk_set_rate,
|
||||
.get_rate = k210_clk_get_rate,
|
||||
.set_parent = k210_clk_set_parent,
|
||||
.enable = k210_clk_enable,
|
||||
.disable = k210_clk_disable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = k210_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int k210_clk_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct k210_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev_get_parent(dev));
|
||||
if (!priv->base)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->in0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Force setting defaults, even before relocation. This is so we can
|
||||
* set the clock rate for PLL1 before we relocate into aisram.
|
||||
*/
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id k210_clk_ids[] = {
|
||||
{ .compatible = "canaan,k210-clk" },
|
||||
{ },
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(k210_clk) = {
|
||||
.name = "k210_clk",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = k210_clk_ids,
|
||||
.ops = &k210_clk_ops,
|
||||
.probe = k210_clk_probe,
|
||||
.priv_auto = sizeof(struct k210_clk_priv),
|
||||
};
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CLK_MHZ(x) ((x) / 1000000)
|
||||
|
||||
/* Primary oscillator */
|
||||
#define SYS_POSC_CLK_HZ 24000000
|
||||
|
||||
|
@ -385,9 +387,44 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate)
|
|||
return rate;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static void pic32_dump(struct udevice *dev)
|
||||
{
|
||||
int i;
|
||||
struct clk clk;
|
||||
|
||||
clk.dev = dev;
|
||||
|
||||
clk.id = PLLCLK;
|
||||
printf("PLL Speed: %lu MHz\n",
|
||||
CLK_MHZ(pic32_get_rate(&clk)));
|
||||
|
||||
clk.id = PB7CLK;
|
||||
printf("CPU Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&clk)));
|
||||
|
||||
clk.id = MPLL;
|
||||
printf("MPLL Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&clk)));
|
||||
|
||||
for (i = PB1CLK; i <= PB7CLK; i++) {
|
||||
clk.id = i;
|
||||
printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1,
|
||||
CLK_MHZ(pic32_get_rate(&clk)));
|
||||
}
|
||||
|
||||
for (i = REF1CLK; i <= REF5CLK; i++) {
|
||||
clk.id = i;
|
||||
printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1,
|
||||
CLK_MHZ(pic32_get_rate(&clk)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct clk_ops pic32_pic32_clk_ops = {
|
||||
.set_rate = pic32_set_rate,
|
||||
.get_rate = pic32_get_rate,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = pic32_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int pic32_clk_probe(struct udevice *dev)
|
||||
|
|
|
@ -555,7 +555,8 @@ static int versal_clock_get_rate(u32 clk_id, u64 *clk_rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int soc_clk_dump(void)
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static void versal_clk_dump(struct udevice __always_unused *dev)
|
||||
{
|
||||
u64 clk_rate = 0;
|
||||
u32 type, ret, i = 0;
|
||||
|
@ -575,9 +576,8 @@ int soc_clk_dump(void)
|
|||
printf("clk: %s freq:%lld\n",
|
||||
clock[i].clk_name, clk_rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void versal_get_clock_info(void)
|
||||
{
|
||||
|
@ -769,6 +769,9 @@ static struct clk_ops versal_clk_ops = {
|
|||
.set_rate = versal_clk_set_rate,
|
||||
.get_rate = versal_clk_get_rate,
|
||||
.enable = versal_clk_enable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = versal_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct udevice_id versal_clk_ids[] = {
|
||||
|
|
|
@ -454,12 +454,64 @@ static int dummy_enable(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static const char * const clk_names[clk_max] = {
|
||||
"armpll", "ddrpll", "iopll",
|
||||
"cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
|
||||
"ddr2x", "ddr3x", "dci",
|
||||
"lqspi", "smc", "pcap", "gem0", "gem1",
|
||||
"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
|
||||
"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma",
|
||||
"usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper",
|
||||
"sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper",
|
||||
"can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
|
||||
"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper",
|
||||
"smc_aper", "swdt", "dbg_trc", "dbg_apb"
|
||||
};
|
||||
|
||||
static void zynq_clk_dump(struct udevice *dev)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
printf("clk\t\tfrequency\n");
|
||||
for (i = 0; i < clk_max; i++) {
|
||||
const char *name = clk_names[i];
|
||||
|
||||
if (name) {
|
||||
struct clk clk;
|
||||
unsigned long rate;
|
||||
|
||||
clk.id = i;
|
||||
ret = clk_request(dev, &clk);
|
||||
if (ret < 0) {
|
||||
printf("%s clk_request() failed: %d\n",
|
||||
__func__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
rate = clk_get_rate(&clk);
|
||||
|
||||
clk_free(&clk);
|
||||
|
||||
if ((rate == (unsigned long)-ENOSYS) ||
|
||||
(rate == (unsigned long)-ENXIO))
|
||||
printf("%10s%20s\n", name, "unknown");
|
||||
else
|
||||
printf("%10s%20lu\n", name, rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct clk_ops zynq_clk_ops = {
|
||||
.get_rate = zynq_clk_get_rate,
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
.set_rate = zynq_clk_set_rate,
|
||||
#endif
|
||||
.enable = dummy_enable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = zynq_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int zynq_clk_probe(struct udevice *dev)
|
||||
|
|
|
@ -735,16 +735,11 @@ static ulong zynqmp_clk_set_rate(struct clk *clk, ulong rate)
|
|||
}
|
||||
}
|
||||
|
||||
int soc_clk_dump(void)
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static void zynqmp_clk_dump(struct udevice *dev)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int i, ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_DRIVER_GET(zynqmp_clk), &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printf("clk\t\tfrequency\n");
|
||||
for (i = 0; i < clk_max; i++) {
|
||||
const char *name = clk_names[i];
|
||||
|
@ -754,8 +749,11 @@ int soc_clk_dump(void)
|
|||
|
||||
clk.id = i;
|
||||
ret = clk_request(dev, &clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < 0) {
|
||||
printf("%s clk_request() failed: %d\n",
|
||||
__func__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
rate = clk_get_rate(&clk);
|
||||
|
||||
|
@ -769,9 +767,8 @@ int soc_clk_dump(void)
|
|||
printf("%10s%20lu\n", name, rate);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int zynqmp_get_freq_by_name(char *name, struct udevice *dev, ulong *freq)
|
||||
{
|
||||
|
@ -872,6 +869,9 @@ static struct clk_ops zynqmp_clk_ops = {
|
|||
.set_rate = zynqmp_clk_set_rate,
|
||||
.get_rate = zynqmp_clk_get_rate,
|
||||
.enable = zynqmp_clk_enable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = zynqmp_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct udevice_id zynqmp_clk_ids[] = {
|
||||
|
|
|
@ -43,18 +43,12 @@ static int imx8_clk_enable(struct clk *clk)
|
|||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
int soc_clk_dump(void)
|
||||
static void imx8_clk_dump(struct udevice *dev)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct clk clk;
|
||||
unsigned long rate;
|
||||
int i, ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_DRIVER_GET(imx8_clk), &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printf("Clk\t\tHz\n");
|
||||
|
||||
for (i = 0; i < num_clks; i++) {
|
||||
|
@ -84,8 +78,6 @@ int soc_clk_dump(void)
|
|||
printf("%s(%3lu):\t%lu\n",
|
||||
imx8_clk_names[i].name, imx8_clk_names[i].id, rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -94,6 +86,9 @@ static struct clk_ops imx8_clk_ops = {
|
|||
.get_rate = imx8_clk_get_rate,
|
||||
.enable = imx8_clk_enable,
|
||||
.disable = imx8_clk_disable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = imx8_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int imx8_clk_probe(struct udevice *dev)
|
||||
|
|
|
@ -607,14 +607,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk)
|
|||
return meson_mux_set_parent_by_id(clk, parent_clk->id);
|
||||
}
|
||||
|
||||
static struct clk_ops meson_clk_ops = {
|
||||
.disable = meson_clk_disable,
|
||||
.enable = meson_clk_enable,
|
||||
.get_rate = meson_clk_get_rate,
|
||||
.set_rate = meson_clk_set_rate,
|
||||
.set_parent = meson_clk_set_parent,
|
||||
};
|
||||
|
||||
static int meson_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct meson_clk *priv = dev_get_priv(dev);
|
||||
|
@ -644,15 +636,7 @@ static const struct udevice_id meson_clk_ids[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(meson_clk) = {
|
||||
.name = "meson-clk-a1",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = meson_clk_ids,
|
||||
.priv_auto = sizeof(struct meson_clk),
|
||||
.ops = &meson_clk_ops,
|
||||
.probe = meson_clk_probe,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
static const char *meson_clk_get_name(struct clk *clk, int id)
|
||||
{
|
||||
const struct meson_clk_info *info;
|
||||
|
@ -662,7 +646,7 @@ static const char *meson_clk_get_name(struct clk *clk, int id)
|
|||
return IS_ERR(info) ? "unknown" : info->name;
|
||||
}
|
||||
|
||||
static int meson_clk_dump(struct clk *clk)
|
||||
static int meson_clk_dump_single(struct clk *clk)
|
||||
{
|
||||
const struct meson_clk_info *info;
|
||||
struct meson_clk *priv;
|
||||
|
@ -697,7 +681,7 @@ static int meson_clk_dump(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_dump_dev(struct udevice *dev)
|
||||
static void meson_clk_dump(struct udevice *dev)
|
||||
{
|
||||
int i;
|
||||
struct meson_clk_data *data;
|
||||
|
@ -710,26 +694,30 @@ static int meson_clk_dump_dev(struct udevice *dev)
|
|||
|
||||
data = (struct meson_clk_data *)dev_get_driver_data(dev);
|
||||
for (i = 0; i < data->num_clocks; i++) {
|
||||
meson_clk_dump(&(struct clk){
|
||||
meson_clk_dump_single(&(struct clk){
|
||||
.dev = dev,
|
||||
.id = i
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int soc_clk_dump(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int i = 0;
|
||||
static struct clk_ops meson_clk_ops = {
|
||||
.disable = meson_clk_disable,
|
||||
.enable = meson_clk_enable,
|
||||
.get_rate = meson_clk_get_rate,
|
||||
.set_rate = meson_clk_set_rate,
|
||||
.set_parent = meson_clk_set_parent,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = meson_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
while (!uclass_get_device(UCLASS_CLK, i++, &dev)) {
|
||||
if (dev->driver == DM_DRIVER_GET(meson_clk)) {
|
||||
meson_clk_dump_dev(dev);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
U_BOOT_DRIVER(meson_clk) = {
|
||||
.name = "meson-clk-a1",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = meson_clk_ids,
|
||||
.priv_auto = sizeof(struct meson_clk),
|
||||
.ops = &meson_clk_ops,
|
||||
.probe = meson_clk_probe,
|
||||
};
|
||||
|
|
|
@ -488,33 +488,36 @@ static int armada_37xx_periph_clk_dump(struct udevice *dev)
|
|||
static int clk_dump(const char *name, int (*func)(struct udevice *))
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
if (uclass_get_device_by_name(UCLASS_CLK, name, &dev)) {
|
||||
printf("Cannot find device %s\n", name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return func(dev);
|
||||
ret = func(dev);
|
||||
if (ret)
|
||||
printf("Dump failed for %s: %d\n", name, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int armada_37xx_tbg_clk_dump(struct udevice *);
|
||||
|
||||
int soc_clk_dump(void)
|
||||
static void armada37xx_clk_dump(struct udevice __always_unused *dev)
|
||||
{
|
||||
printf(" xtal at %u000000 Hz\n\n", get_ref_clk());
|
||||
|
||||
if (clk_dump("tbg@13200", armada_37xx_tbg_clk_dump))
|
||||
return 1;
|
||||
return;
|
||||
|
||||
if (clk_dump("nb-periph-clk@13000",
|
||||
armada_37xx_periph_clk_dump))
|
||||
return 1;
|
||||
return;
|
||||
|
||||
if (clk_dump("sb-periph-clk@18000",
|
||||
armada_37xx_periph_clk_dump))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -605,6 +608,9 @@ static const struct clk_ops armada_37xx_periph_clk_ops = {
|
|||
.set_parent = armada_37xx_periph_clk_set_parent,
|
||||
.enable = armada_37xx_periph_clk_enable,
|
||||
.disable = armada_37xx_periph_clk_disable,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
.dump = armada37xx_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct udevice_id armada_37xx_periph_clk_ids[] = {
|
||||
|
|
|
@ -135,7 +135,7 @@ static u32 npcm_clk_get_div(struct clk *clk)
|
|||
return div;
|
||||
}
|
||||
|
||||
static u32 npcm_clk_set_div(struct clk *clk, u32 div)
|
||||
static int npcm_clk_set_div(struct clk *clk, u32 div)
|
||||
{
|
||||
struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
struct npcm_clk_div *divider;
|
||||
|
@ -145,6 +145,9 @@ static u32 npcm_clk_set_div(struct clk *clk, u32 div)
|
|||
if (!divider)
|
||||
return -EINVAL;
|
||||
|
||||
if (divider->flags & DIV_RO)
|
||||
return 0;
|
||||
|
||||
if (divider->flags & PRE_DIV2)
|
||||
div = div >> 1;
|
||||
|
||||
|
@ -153,6 +156,12 @@ static u32 npcm_clk_set_div(struct clk *clk, u32 div)
|
|||
else
|
||||
clkdiv = ilog2(div);
|
||||
|
||||
if (clkdiv > (divider->mask >> (ffs(divider->mask) - 1))) {
|
||||
printf("clkdiv(%d) for clk(%ld) is over limit\n",
|
||||
clkdiv, clk->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = readl(priv->base + divider->reg);
|
||||
val &= ~divider->mask;
|
||||
val |= (clkdiv << (ffs(divider->mask) - 1)) & divider->mask;
|
||||
|
@ -253,8 +262,8 @@ static ulong npcm_clk_set_rate(struct clk *clk, ulong rate)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
debug("%s: rate %lu, new rate (%lu / %u)\n", __func__, rate, parent_rate, div);
|
||||
return (parent_rate / div);
|
||||
debug("%s: rate %lu, new rate %lu\n", __func__, rate, npcm_clk_get_rate(clk));
|
||||
return npcm_clk_get_rate(clk);
|
||||
}
|
||||
|
||||
static int npcm_clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#define PRE_DIV2 BIT(2) /* Pre divisor = 2 */
|
||||
#define POST_DIV2 BIT(3) /* Post divisor = 2 */
|
||||
#define FIXED_PARENT BIT(4) /* clock source is fixed */
|
||||
#define DIV_RO BIT(5) /* divider is read-only */
|
||||
|
||||
/* Parameters of PLL configuration */
|
||||
struct npcm_clk_pll {
|
||||
|
|
|
@ -45,12 +45,12 @@ static struct npcm_clk_select npcm8xx_clk_selectors[] = {
|
|||
};
|
||||
|
||||
static struct npcm_clk_div npcm8xx_clk_dividers[] = {
|
||||
{NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2},
|
||||
{NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2},
|
||||
{NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2},
|
||||
{NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1},
|
||||
{NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1},
|
||||
{NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1},
|
||||
{NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2 | DIV_RO},
|
||||
{NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2 | DIV_RO},
|
||||
{NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2 | DIV_RO},
|
||||
{NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1 | DIV_RO},
|
||||
{NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1 | DIV_RO},
|
||||
{NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1 | DIV_RO},
|
||||
{NPCM8XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1},
|
||||
{NPCM8XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1},
|
||||
{NPCM8XX_CLK_UART2, CLKDIV3, UARTDIV2, DIV_TYPE1},
|
||||
|
|
|
@ -2225,10 +2225,13 @@ static void stm32mp1_osc_init(struct udevice *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void __maybe_unused stm32mp1_clk_dump(struct stm32mp1_clk_priv *priv)
|
||||
static void __maybe_unused stm32mp1_clk_dump(struct udevice *dev)
|
||||
{
|
||||
char buf[32];
|
||||
int i, s, p;
|
||||
struct stm32mp1_clk_priv *priv;
|
||||
|
||||
priv = dev_get_priv(dev);
|
||||
|
||||
printf("Clocks:\n");
|
||||
for (i = 0; i < _PARENT_NB; i++) {
|
||||
|
@ -2252,27 +2255,6 @@ static void __maybe_unused stm32mp1_clk_dump(struct stm32mp1_clk_priv *priv)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_CLK
|
||||
int soc_clk_dump(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct stm32mp1_clk_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_DRIVER_GET(stm32mp1_clock),
|
||||
&dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv = dev_get_priv(dev);
|
||||
|
||||
stm32mp1_clk_dump(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stm32mp1_clk_probe(struct udevice *dev)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -2302,7 +2284,7 @@ static int stm32mp1_clk_probe(struct udevice *dev)
|
|||
#if defined(VERBOSE_DEBUG)
|
||||
/* display debug information for probe after relocation */
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
stm32mp1_clk_dump(priv);
|
||||
stm32mp1_clk_dump(dev);
|
||||
#endif
|
||||
|
||||
gd->cpu_clk = stm32mp1_clk_get(priv, _CK_MPU);
|
||||
|
@ -2333,6 +2315,9 @@ static const struct clk_ops stm32mp1_clk_ops = {
|
|||
.disable = stm32mp1_clk_disable,
|
||||
.get_rate = stm32mp1_clk_get_rate,
|
||||
.set_rate = stm32mp1_clk_set_rate,
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK) && !IS_ENABLED(CONFIG_SPL_BUILD)
|
||||
.dump = stm32mp1_clk_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(stm32mp1_clock) = {
|
||||
|
|
|
@ -25,6 +25,7 @@ struct ofnode_phandle_args;
|
|||
* @set_parent: Set current clock parent
|
||||
* @enable: Enable a clock.
|
||||
* @disable: Disable a clock.
|
||||
* @dump: Print clock information.
|
||||
*
|
||||
* The individual methods are described more fully below.
|
||||
*/
|
||||
|
@ -39,6 +40,9 @@ struct clk_ops {
|
|||
int (*set_parent)(struct clk *clk, struct clk *parent);
|
||||
int (*enable)(struct clk *clk);
|
||||
int (*disable)(struct clk *clk);
|
||||
#if IS_ENABLED(CONFIG_CMD_CLK)
|
||||
void (*dump)(struct udevice *dev);
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0 /* For documentation only */
|
||||
|
@ -135,6 +139,15 @@ int enable(struct clk *clk);
|
|||
* Return: zero on success, or -ve error code.
|
||||
*/
|
||||
int disable(struct clk *clk);
|
||||
|
||||
/**
|
||||
* dump() - Print clock information.
|
||||
* @dev: The clock device to dump.
|
||||
*
|
||||
* If present, this function is called by "clk dump" command for each
|
||||
* bound device.
|
||||
*/
|
||||
void dump(struct udevice *dev);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -676,8 +676,6 @@ static inline bool clk_valid(struct clk *clk)
|
|||
return clk && !!clk->dev;
|
||||
}
|
||||
|
||||
int soc_clk_dump(void);
|
||||
|
||||
#endif
|
||||
|
||||
#define clk_prepare_enable(clk) clk_enable(clk)
|
||||
|
|
Loading…
Reference in a new issue