xref: /rk3399_rockchip-uboot/drivers/clk/clk-uclass.c (revision a4b10c088c4f6ef2e2bba33e8cfea369bcbbce44)
1f26c8a8eSSimon Glass /*
2f26c8a8eSSimon Glass  * Copyright (C) 2015 Google, Inc
3f26c8a8eSSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4f26c8a8eSSimon Glass  *
5f26c8a8eSSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6f26c8a8eSSimon Glass  */
7f26c8a8eSSimon Glass 
8f26c8a8eSSimon Glass #include <common.h>
9f26c8a8eSSimon Glass #include <clk.h>
10f26c8a8eSSimon Glass #include <dm.h>
11f26c8a8eSSimon Glass #include <errno.h>
12f26c8a8eSSimon Glass #include <dm/lists.h>
13f26c8a8eSSimon Glass #include <dm/root.h>
14f26c8a8eSSimon Glass 
15e70cc438SSimon Glass DECLARE_GLOBAL_DATA_PTR;
16e70cc438SSimon Glass 
17f26c8a8eSSimon Glass ulong clk_get_rate(struct udevice *dev)
18f26c8a8eSSimon Glass {
19f26c8a8eSSimon Glass 	struct clk_ops *ops = clk_get_ops(dev);
20f26c8a8eSSimon Glass 
21f26c8a8eSSimon Glass 	if (!ops->get_rate)
22f26c8a8eSSimon Glass 		return -ENOSYS;
23f26c8a8eSSimon Glass 
24f26c8a8eSSimon Glass 	return ops->get_rate(dev);
25f26c8a8eSSimon Glass }
26f26c8a8eSSimon Glass 
27f26c8a8eSSimon Glass ulong clk_set_rate(struct udevice *dev, ulong rate)
28f26c8a8eSSimon Glass {
29f26c8a8eSSimon Glass 	struct clk_ops *ops = clk_get_ops(dev);
30f26c8a8eSSimon Glass 
31f26c8a8eSSimon Glass 	if (!ops->set_rate)
32f26c8a8eSSimon Glass 		return -ENOSYS;
33f26c8a8eSSimon Glass 
34f26c8a8eSSimon Glass 	return ops->set_rate(dev, rate);
35f26c8a8eSSimon Glass }
36f26c8a8eSSimon Glass 
37f0e07516SMasahiro Yamada int clk_enable(struct udevice *dev, int periph)
38f0e07516SMasahiro Yamada {
39f0e07516SMasahiro Yamada 	struct clk_ops *ops = clk_get_ops(dev);
40f0e07516SMasahiro Yamada 
41f0e07516SMasahiro Yamada 	if (!ops->enable)
42f0e07516SMasahiro Yamada 		return -ENOSYS;
43f0e07516SMasahiro Yamada 
44f0e07516SMasahiro Yamada 	return ops->enable(dev, periph);
45f0e07516SMasahiro Yamada }
46f0e07516SMasahiro Yamada 
47f26c8a8eSSimon Glass ulong clk_get_periph_rate(struct udevice *dev, int periph)
48f26c8a8eSSimon Glass {
49f26c8a8eSSimon Glass 	struct clk_ops *ops = clk_get_ops(dev);
50f26c8a8eSSimon Glass 
51f26c8a8eSSimon Glass 	if (!ops->get_periph_rate)
52f26c8a8eSSimon Glass 		return -ENOSYS;
53f26c8a8eSSimon Glass 
54f26c8a8eSSimon Glass 	return ops->get_periph_rate(dev, periph);
55f26c8a8eSSimon Glass }
56f26c8a8eSSimon Glass 
57f26c8a8eSSimon Glass ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate)
58f26c8a8eSSimon Glass {
59f26c8a8eSSimon Glass 	struct clk_ops *ops = clk_get_ops(dev);
60f26c8a8eSSimon Glass 
61f26c8a8eSSimon Glass 	if (!ops->set_periph_rate)
62f26c8a8eSSimon Glass 		return -ENOSYS;
63f26c8a8eSSimon Glass 
64f26c8a8eSSimon Glass 	return ops->set_periph_rate(dev, periph, rate);
65f26c8a8eSSimon Glass }
66f26c8a8eSSimon Glass 
67e70cc438SSimon Glass #if CONFIG_IS_ENABLED(OF_CONTROL)
68e70cc438SSimon Glass int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp)
69e70cc438SSimon Glass {
70e70cc438SSimon Glass 	int ret;
71*a4b10c08SSimon Glass #ifdef CONFIG_SPL_BUILD
72*a4b10c08SSimon Glass 	u32 cell[2];
73*a4b10c08SSimon Glass 
74*a4b10c08SSimon Glass 	if (index != 0)
75*a4b10c08SSimon Glass 		return -ENOSYS;
76*a4b10c08SSimon Glass 	assert(*clk_devp);
77*a4b10c08SSimon Glass 	ret = uclass_get_device(UCLASS_CLK, 0, clk_devp);
78*a4b10c08SSimon Glass 	if (ret)
79*a4b10c08SSimon Glass 		return ret;
80*a4b10c08SSimon Glass 	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
81*a4b10c08SSimon Glass 				   cell, 2);
82*a4b10c08SSimon Glass 	if (ret)
83*a4b10c08SSimon Glass 		return ret;
84*a4b10c08SSimon Glass 	return cell[1];
85*a4b10c08SSimon Glass #else
86*a4b10c08SSimon Glass 	struct fdtdec_phandle_args args;
87e70cc438SSimon Glass 
88e70cc438SSimon Glass 	assert(*clk_devp);
89e70cc438SSimon Glass 	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
90e70cc438SSimon Glass 					     "clocks", "#clock-cells", 0, index,
91e70cc438SSimon Glass 					     &args);
92e70cc438SSimon Glass 	if (ret) {
93e70cc438SSimon Glass 		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
94e70cc438SSimon Glass 		      __func__, ret);
95e70cc438SSimon Glass 		return ret;
96e70cc438SSimon Glass 	}
97e70cc438SSimon Glass 
98e70cc438SSimon Glass 	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, clk_devp);
99e70cc438SSimon Glass 	if (ret) {
100e70cc438SSimon Glass 		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
101e70cc438SSimon Glass 		      __func__, ret);
102e70cc438SSimon Glass 		return ret;
103e70cc438SSimon Glass 	}
104e70cc438SSimon Glass 	return args.args_count > 0 ? args.args[0] : 0;
105*a4b10c08SSimon Glass #endif
106e70cc438SSimon Glass }
107e70cc438SSimon Glass #endif
108e70cc438SSimon Glass 
109f26c8a8eSSimon Glass UCLASS_DRIVER(clk) = {
110f26c8a8eSSimon Glass 	.id		= UCLASS_CLK,
111f26c8a8eSSimon Glass 	.name		= "clk",
112f26c8a8eSSimon Glass };
113