Commit 135aa95002646c46e89de93fa36adad1b010548f

Authored by Stephen Warren
Committed by Simon Glass
1 parent 4581b717b1

clk: convert API to match reset/mailbox style

The following changes are made to the clock API:
* The concept of "clocks" and "peripheral clocks" are unified; each clock
  provider now implements a single set of clocks. This provides a simpler
  conceptual interface to clients, and better aligns with device tree
  clock bindings.
* Clocks are now identified with a single "struct clk", rather than
  requiring clients to store the clock provider device and clock identity
  values separately. For simple clock consumers, this isolates clients
  from internal details of the clock API.
* clk.h is split so it only contains the client/consumer API, whereas
  clk-uclass.h contains the provider API. This aligns with the recently
  added reset and mailbox APIs.
* clk_ops .of_xlate(), .request(), and .free() are added so providers
  can customize these operations if needed. This also aligns with the
  recently added reset and mailbox APIs.
* clk_disable() is added.
* All users of the current clock APIs are updated.
* Sandbox clock tests are updated to exercise clock lookup via DT, and
  clock enable/disable.
* rkclk_get_clk() is removed and replaced with standard APIs.

Buildman shows no clock-related errors for any board for which buildman
can download a toolchain.

test/py passes for sandbox (which invokes the dm clk test amongst
others).

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>

Showing 37 changed files with 985 additions and 570 deletions Side-by-side Diff

arch/arm/include/asm/arch-rockchip/clock.h
... ... @@ -62,18 +62,6 @@
62 62 */
63 63 void *rockchip_get_cru(void);
64 64  
65   -/**
66   - * rkclk_get_clk() - get a pointer to a given clock
67   - *
68   - * This is an internal function - use outside the clock subsystem indicates
69   - * that work is needed!
70   - *
71   - * @clk_id: Clock requested
72   - * @devp: Returns a pointer to that clock
73   - * @return 0 if OK, -ve on error
74   - */
75   -int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp);
76   -
77 65 struct rk3288_cru;
78 66 struct rk3288_grf;
79 67  
arch/arm/mach-rockchip/board.c
... ... @@ -9,6 +9,7 @@
9 9 #include <dm.h>
10 10 #include <ram.h>
11 11 #include <asm/io.h>
  12 +#include <asm/arch/clock.h>
12 13  
13 14 DECLARE_GLOBAL_DATA_PTR;
14 15  
15 16  
16 17  
... ... @@ -54,15 +55,43 @@
54 55 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
55 56 char * const argv[])
56 57 {
  58 + static const struct {
  59 + char *name;
  60 + int id;
  61 + } clks[] = {
  62 + { "osc", CLK_OSC },
  63 + { "apll", CLK_ARM },
  64 + { "dpll", CLK_DDR },
  65 + { "cpll", CLK_CODEC },
  66 + { "gpll", CLK_GENERAL },
  67 +#ifdef CONFIG_ROCKCHIP_RK3036
  68 + { "mpll", CLK_NEW },
  69 +#else
  70 + { "npll", CLK_NEW },
  71 +#endif
  72 + };
  73 + int ret, i;
57 74 struct udevice *dev;
58 75  
59   - for (uclass_first_device(UCLASS_CLK, &dev);
60   - dev;
61   - uclass_next_device(&dev)) {
  76 + ret = uclass_get_device(UCLASS_CLK, 0, &dev);
  77 + if (ret) {
  78 + printf("clk-uclass not found\n");
  79 + return 0;
  80 + }
  81 +
  82 + for (i = 0; i < ARRAY_SIZE(clks); i++) {
  83 + struct clk clk;
62 84 ulong rate;
63 85  
64   - rate = clk_get_rate(dev);
65   - printf("%s: %lu\n", dev->name, rate);
  86 + clk.id = clks[i].id;
  87 + ret = clk_request(dev, &clk);
  88 + if (ret < 0)
  89 + continue;
  90 +
  91 + rate = clk_get_rate(&clk);
  92 + printf("%s: %lu\n", clks[i].name, rate);
  93 +
  94 + clk_free(&clk);
66 95 }
67 96  
68 97 return 0;
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
... ... @@ -36,7 +36,7 @@
36 36 struct dram_info {
37 37 struct chan_info chan[2];
38 38 struct ram_info info;
39   - struct udevice *ddr_clk;
  39 + struct clk ddr_clk;
40 40 struct rk3288_cru *cru;
41 41 struct rk3288_grf *grf;
42 42 struct rk3288_sgrf *sgrf;
... ... @@ -576,7 +576,7 @@
576 576 rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
577 577 }
578 578  
579   -static int sdram_init(const struct dram_info *dram,
  579 +static int sdram_init(struct dram_info *dram,
580 580 const struct rk3288_sdram_params *sdram_params)
581 581 {
582 582 int channel;
... ... @@ -592,8 +592,8 @@
592 592 return -E2BIG;
593 593 }
594 594  
595   - debug("ddr clk %s\n", dram->ddr_clk->name);
596   - ret = clk_set_rate(dram->ddr_clk, sdram_params->base.ddr_freq);
  595 + debug("ddr clk dpll\n");
  596 + ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
597 597 debug("ret=%d\n", ret);
598 598 if (ret) {
599 599 debug("Could not set DDR clock\n");
... ... @@ -836,6 +836,7 @@
836 836 struct dram_info *priv = dev_get_priv(dev);
837 837 struct regmap *map;
838 838 int ret;
  839 + struct udevice *dev_clk;
839 840  
840 841 map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
841 842 if (IS_ERR(map))
... ... @@ -856,7 +857,11 @@
856 857 priv->chan[1].pctl = regmap_get_range(map, 2);
857 858 priv->chan[1].publ = regmap_get_range(map, 3);
858 859  
859   - ret = uclass_get_device(UCLASS_CLK, CLK_DDR, &priv->ddr_clk);
  860 + ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
  861 + if (ret)
  862 + return ret;
  863 + priv->ddr_clk.id = CLK_DDR;
  864 + ret = clk_request(dev_clk, &priv->ddr_clk);
860 865 if (ret)
861 866 return ret;
862 867  
arch/arm/mach-snapdragon/clock-apq8016.c
... ... @@ -9,7 +9,7 @@
9 9 */
10 10  
11 11 #include <common.h>
12   -#include <clk.h>
  12 +#include <clk-uclass.h>
13 13 #include <dm.h>
14 14 #include <errno.h>
15 15 #include <asm/io.h>
16 16  
17 17  
... ... @@ -212,11 +212,11 @@
212 212 return 0;
213 213 }
214 214  
215   -ulong msm_set_periph_rate(struct udevice *dev, int periph, ulong rate)
  215 +ulong msm_set_rate(struct clk *clk, ulong rate)
216 216 {
217   - struct msm_clk_priv *priv = dev_get_priv(dev);
  217 + struct msm_clk_priv *priv = dev_get_priv(clk->dev);
218 218  
219   - switch (periph) {
  219 + switch (clk->id) {
220 220 case 0: /* SDC1 */
221 221 return clk_init_sdc(priv, 0, rate);
222 222 break;
... ... @@ -243,7 +243,7 @@
243 243 }
244 244  
245 245 static struct clk_ops msm_clk_ops = {
246   - .set_periph_rate = msm_set_periph_rate,
  246 + .set_rate = msm_set_rate,
247 247 };
248 248  
249 249 static const struct udevice_id msm_clk_ids[] = {
arch/arm/mach-zynq/clk.c
... ... @@ -6,7 +6,6 @@
6 6 */
7 7 #include <common.h>
8 8 #include <errno.h>
9   -#include <clk.h>
10 9 #include <asm/io.h>
11 10 #include <asm/arch/hardware.h>
12 11 #include <asm/arch/clk.h>
arch/mips/mach-pic32/cpu.c
... ... @@ -23,20 +23,36 @@
23 23  
24 24 DECLARE_GLOBAL_DATA_PTR;
25 25  
26   -static ulong clk_get_cpu_rate(void)
  26 +static ulong rate(int id)
27 27 {
28 28 int ret;
29 29 struct udevice *dev;
  30 + struct clk clk;
  31 + ulong rate;
30 32  
31 33 ret = uclass_get_device(UCLASS_CLK, 0, &dev);
32 34 if (ret) {
33   - panic("uclass-clk: device not found\n");
  35 + printf("clk-uclass not found\n");
34 36 return 0;
35 37 }
36 38  
37   - return clk_get_rate(dev);
  39 + clk.id = id;
  40 + ret = clk_request(dev, &clk);
  41 + if (ret < 0)
  42 + return ret;
  43 +
  44 + rate = clk_get_rate(&clk);
  45 +
  46 + clk_free(&clk);
  47 +
  48 + return rate;
38 49 }
39 50  
  51 +static ulong clk_get_cpu_rate(void)
  52 +{
  53 + return rate(PB7CLK);
  54 +}
  55 +
40 56 /* initialize prefetch module related to cpu_clk */
41 57 static void prefetch_init(void)
42 58 {
43 59  
44 60  
45 61  
46 62  
47 63  
48 64  
... ... @@ -127,30 +143,25 @@
127 143 }
128 144 #endif
129 145 #ifdef CONFIG_CMD_CLK
  146 +
130 147 int soc_clk_dump(void)
131 148 {
132   - int i, ret;
133   - struct udevice *dev;
  149 + int i;
134 150  
135   - ret = uclass_get_device(UCLASS_CLK, 0, &dev);
136   - if (ret) {
137   - printf("clk-uclass not found\n");
138   - return ret;
139   - }
140   -
141 151 printf("PLL Speed: %lu MHz\n",
142   - CLK_MHZ(clk_get_periph_rate(dev, PLLCLK)));
143   - printf("CPU Speed: %lu MHz\n", CLK_MHZ(clk_get_rate(dev)));
144   - printf("MPLL Speed: %lu MHz\n",
145   - CLK_MHZ(clk_get_periph_rate(dev, MPLL)));
  152 + CLK_MHZ(rate(PLLCLK)));
146 153  
  154 + printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK)));
  155 +
  156 + printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL)));
  157 +
147 158 for (i = PB1CLK; i <= PB7CLK; i++)
148 159 printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1,
149   - CLK_MHZ(clk_get_periph_rate(dev, i)));
  160 + CLK_MHZ(rate(i)));
150 161  
151 162 for (i = REF1CLK; i <= REF5CLK; i++)
152 163 printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1,
153   - CLK_MHZ(clk_get_periph_rate(dev, i)));
  164 + CLK_MHZ(rate(i)));
154 165 return 0;
155 166 }
156 167 #endif
arch/sandbox/dts/test.dts
... ... @@ -108,8 +108,23 @@
108 108 compatible = "denx,u-boot-fdt-test";
109 109 };
110 110  
111   - clk@0 {
  111 + clk_fixed: clk-fixed {
  112 + compatible = "fixed-clock";
  113 + #clock-cells = <0>;
  114 + clock-frequency = <1234>;
  115 + };
  116 +
  117 + clk_sandbox: clk-sbox {
112 118 compatible = "sandbox,clk";
  119 + #clock-cells = <1>;
  120 + };
  121 +
  122 + clk-test {
  123 + compatible = "sandbox,clk-test";
  124 + clocks = <&clk_fixed>,
  125 + <&clk_sandbox 1>,
  126 + <&clk_sandbox 0>;
  127 + clock-names = "fixed", "i2c", "spi";
113 128 };
114 129  
115 130 eth@10002000 {
arch/sandbox/include/asm/clk.h
  1 +/*
  2 + * Copyright (c) 2016, NVIDIA CORPORATION.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0
  5 + */
  6 +
  7 +#ifndef __SANDBOX_CLK_H
  8 +#define __SANDBOX_CLK_H
  9 +
  10 +#include <common.h>
  11 +
  12 +struct udevice;
  13 +
  14 +/**
  15 + * enum sandbox_clk_id - Identity of clocks implemented by the sandbox clock
  16 + * provider.
  17 + *
  18 + * These IDs are within/relative-to the clock provider.
  19 + */
  20 +enum sandbox_clk_id {
  21 + SANDBOX_CLK_ID_SPI,
  22 + SANDBOX_CLK_ID_I2C,
  23 +
  24 + SANDBOX_CLK_ID_COUNT,
  25 +};
  26 +
  27 +/**
  28 + * enum sandbox_clk_test_id - Identity of the clocks consumed by the sandbox
  29 + * clock test device.
  30 + *
  31 + * These are the IDs the clock consumer knows the clocks as.
  32 + */
  33 +enum sandbox_clk_test_id {
  34 + SANDBOX_CLK_TEST_ID_FIXED,
  35 + SANDBOX_CLK_TEST_ID_SPI,
  36 + SANDBOX_CLK_TEST_ID_I2C,
  37 +
  38 + SANDBOX_CLK_TEST_ID_COUNT,
  39 +};
  40 +
  41 +/**
  42 + * sandbox_clk_query_rate - Query the current rate of a sandbox clock.
  43 + *
  44 + * @dev: The sandbox clock provider device.
  45 + * @id: The clock to query.
  46 + * @return: The rate of the clock.
  47 + */
  48 +ulong sandbox_clk_query_rate(struct udevice *dev, int id);
  49 +/**
  50 + * sandbox_clk_query_enable - Query the enable state of a sandbox clock.
  51 + *
  52 + * @dev: The sandbox clock provider device.
  53 + * @id: The clock to query.
  54 + * @return: The rate of the clock.
  55 + */
  56 +int sandbox_clk_query_enable(struct udevice *dev, int id);
  57 +
  58 +/**
  59 + * sandbox_clk_test_get - Ask the sandbox clock test device to request its
  60 + * clocks.
  61 + *
  62 + * @dev: The sandbox clock test (client) devivce.
  63 + * @return: 0 if OK, or a negative error code.
  64 + */
  65 +int sandbox_clk_test_get(struct udevice *dev);
  66 +/**
  67 + * sandbox_clk_test_get_rate - Ask the sandbox clock test device to query a
  68 + * clock's rate.
  69 + *
  70 + * @dev: The sandbox clock test (client) devivce.
  71 + * @id: The test device's clock ID to query.
  72 + * @return: The rate of the clock.
  73 + */
  74 +ulong sandbox_clk_test_get_rate(struct udevice *dev, int id);
  75 +/**
  76 + * sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a
  77 + * clock's rate.
  78 + *
  79 + * @dev: The sandbox clock test (client) devivce.
  80 + * @id: The test device's clock ID to configure.
  81 + * @return: The new rate of the clock.
  82 + */
  83 +ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate);
  84 +/**
  85 + * sandbox_clk_test_enable - Ask the sandbox clock test device to enable a
  86 + * clock.
  87 + *
  88 + * @dev: The sandbox clock test (client) devivce.
  89 + * @id: The test device's clock ID to configure.
  90 + * @return: 0 if OK, or a negative error code.
  91 + */
  92 +int sandbox_clk_test_enable(struct udevice *dev, int id);
  93 +/**
  94 + * sandbox_clk_test_disable - Ask the sandbox clock test device to disable a
  95 + * clock.
  96 + *
  97 + * @dev: The sandbox clock test (client) devivce.
  98 + * @id: The test device's clock ID to configure.
  99 + * @return: 0 if OK, or a negative error code.
  100 + */
  101 +int sandbox_clk_test_disable(struct udevice *dev, int id);
  102 +/**
  103 + * sandbox_clk_test_free - Ask the sandbox clock test device to free its
  104 + * clocks.
  105 + *
  106 + * @dev: The sandbox clock test (client) devivce.
  107 + * @return: 0 if OK, or a negative error code.
  108 + */
  109 +int sandbox_clk_test_free(struct udevice *dev);
  110 +
  111 +#endif
arch/sandbox/include/asm/test.h
... ... @@ -19,15 +19,6 @@
19 19  
20 20 #define SANDBOX_CLK_RATE 32768
21 21  
22   -enum {
23   - PERIPH_ID_FIRST = 0,
24   - PERIPH_ID_SPI = PERIPH_ID_FIRST,
25   - PERIPH_ID_I2C,
26   - PERIPH_ID_PCI,
27   -
28   - PERIPH_ID_COUNT,
29   -};
30   -
31 22 /* System controller driver data */
32 23 enum {
33 24 SYSCON0 = 32,
board/microchip/pic32mzda/pic32mzda.c
... ... @@ -11,20 +11,31 @@
11 11 #include <common.h>
12 12 #include <dm.h>
13 13 #include <clk.h>
  14 +#include <dt-bindings/clock/microchip,clock.h>
14 15 #include <mach/pic32.h>
15 16  
16 17 #ifdef CONFIG_DISPLAY_BOARDINFO
17 18 int checkboard(void)
18 19 {
19   - ulong rate = 0;
  20 + ulong rate;
20 21 struct udevice *dev;
  22 + struct clk clk;
  23 + int ret;
21 24  
22 25 printf("Core: %s\n", get_core_name());
23 26  
24   - if (!uclass_get_device(UCLASS_CLK, 0, &dev)) {
25   - rate = clk_get_rate(dev);
26   - printf("CPU Speed: %lu MHz\n", rate / 1000000);
27   - }
  27 + if (uclass_get_device(UCLASS_CLK, 0, &dev))
  28 + return 0;
  29 +
  30 + clk.id = PB7CLK;
  31 + ret = clk_request(dev, &clk);
  32 + if (ret < 0)
  33 + return 0;
  34 +
  35 + rate = clk_get_rate(&clk);
  36 + printf("CPU Speed: %lu MHz\n", rate / 1000000);
  37 +
  38 + clk_free(&clk);
28 39  
29 40 return 0;
30 41 }
drivers/clk/Makefile
... ... @@ -9,6 +9,7 @@
9 9 obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
10 10 obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
11 11 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
  12 +obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
12 13 obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
13 14 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
14 15 obj-$(CONFIG_CLK_EXYNOS) += exynos/
drivers/clk/clk-uclass.c
1 1 /*
2 2 * Copyright (C) 2015 Google, Inc
3 3 * Written by Simon Glass <sjg@chromium.org>
  4 + * Copyright (c) 2016, NVIDIA CORPORATION.
4 5 *
5 6 * SPDX-License-Identifier: GPL-2.0+
6 7 */
7 8  
8 9 #include <common.h>
9 10 #include <clk.h>
  11 +#include <clk-uclass.h>
10 12 #include <dm.h>
11 13 #include <errno.h>
12   -#include <dm/lists.h>
13   -#include <dm/root.h>
14 14  
15 15 DECLARE_GLOBAL_DATA_PTR;
16 16  
17   -ulong clk_get_rate(struct udevice *dev)
  17 +static inline struct clk_ops *clk_dev_ops(struct udevice *dev)
18 18 {
19   - struct clk_ops *ops = clk_get_ops(dev);
20   -
21   - if (!ops->get_rate)
22   - return -ENOSYS;
23   -
24   - return ops->get_rate(dev);
  19 + return (struct clk_ops *)dev->driver->ops;
25 20 }
26 21  
27   -ulong clk_set_rate(struct udevice *dev, ulong rate)
  22 +#if CONFIG_IS_ENABLED(OF_CONTROL)
  23 +#ifdef CONFIG_SPL_BUILD
  24 +int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
28 25 {
29   - struct clk_ops *ops = clk_get_ops(dev);
  26 + int ret;
  27 + u32 cell[2];
30 28  
31   - if (!ops->set_rate)
  29 + if (index != 0)
32 30 return -ENOSYS;
33   -
34   - return ops->set_rate(dev, rate);
  31 + assert(clk);
  32 + ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
  33 + if (ret)
  34 + return ret;
  35 + ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
  36 + cell, 2);
  37 + if (ret)
  38 + return ret;
  39 + clk->id = cell[1];
  40 + return 0;
35 41 }
36 42  
37   -int clk_enable(struct udevice *dev, int periph)
  43 +int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
38 44 {
39   - struct clk_ops *ops = clk_get_ops(dev);
40   -
41   - if (!ops->enable)
42   - return -ENOSYS;
43   -
44   - return ops->enable(dev, periph);
  45 + return -ENOSYS;
45 46 }
46   -
47   -ulong clk_get_periph_rate(struct udevice *dev, int periph)
  47 +#else
  48 +static int clk_of_xlate_default(struct clk *clk,
  49 + struct fdtdec_phandle_args *args)
48 50 {
49   - struct clk_ops *ops = clk_get_ops(dev);
  51 + debug("%s(clk=%p)\n", __func__, clk);
50 52  
51   - if (!ops->get_periph_rate)
52   - return -ENOSYS;
  53 + if (args->args_count > 1) {
  54 + debug("Invaild args_count: %d\n", args->args_count);
  55 + return -EINVAL;
  56 + }
53 57  
54   - return ops->get_periph_rate(dev, periph);
55   -}
  58 + if (args->args_count)
  59 + clk->id = args->args[0];
  60 + else
  61 + clk->id = 0;
56 62  
57   -ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate)
58   -{
59   - struct clk_ops *ops = clk_get_ops(dev);
60   -
61   - if (!ops->set_periph_rate)
62   - return -ENOSYS;
63   -
64   - return ops->set_periph_rate(dev, periph, rate);
  63 + return 0;
65 64 }
66 65  
67   -#if CONFIG_IS_ENABLED(OF_CONTROL)
68   -int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp)
  66 +int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
69 67 {
70 68 int ret;
71   -#ifdef CONFIG_SPL_BUILD
72   - u32 cell[2];
73   -
74   - if (index != 0)
75   - return -ENOSYS;
76   - assert(*clk_devp);
77   - ret = uclass_get_device(UCLASS_CLK, 0, clk_devp);
78   - if (ret)
79   - return ret;
80   - ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
81   - cell, 2);
82   - if (ret)
83   - return ret;
84   - return cell[1];
85   -#else
86 69 struct fdtdec_phandle_args args;
  70 + struct udevice *dev_clk;
  71 + struct clk_ops *ops;
87 72  
88   - assert(*clk_devp);
  73 + debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
  74 +
  75 + assert(clk);
89 76 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
90 77 "clocks", "#clock-cells", 0, index,
91 78 &args);
92 79  
93 80  
94 81  
... ... @@ -95,16 +82,117 @@
95 82 return ret;
96 83 }
97 84  
98   - ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, clk_devp);
  85 + ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk);
99 86 if (ret) {
100 87 debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
101 88 __func__, ret);
102 89 return ret;
103 90 }
104   - return args.args_count > 0 ? args.args[0] : 0;
105   -#endif
  91 + ops = clk_dev_ops(dev_clk);
  92 +
  93 + if (ops->of_xlate)
  94 + ret = ops->of_xlate(clk, &args);
  95 + else
  96 + ret = clk_of_xlate_default(clk, &args);
  97 + if (ret) {
  98 + debug("of_xlate() failed: %d\n", ret);
  99 + return ret;
  100 + }
  101 +
  102 + return clk_request(dev_clk, clk);
106 103 }
  104 +
  105 +int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
  106 +{
  107 + int index;
  108 +
  109 + debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
  110 +
  111 + index = fdt_find_string(gd->fdt_blob, dev->of_offset, "clock-names",
  112 + name);
  113 + if (index < 0) {
  114 + debug("fdt_find_string() failed: %d\n", index);
  115 + return index;
  116 + }
  117 +
  118 + return clk_get_by_index(dev, index, clk);
  119 +}
107 120 #endif
  121 +#endif
  122 +
  123 +int clk_request(struct udevice *dev, struct clk *clk)
  124 +{
  125 + struct clk_ops *ops = clk_dev_ops(dev);
  126 +
  127 + debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk);
  128 +
  129 + clk->dev = dev;
  130 +
  131 + if (!ops->request)
  132 + return 0;
  133 +
  134 + return ops->request(clk);
  135 +}
  136 +
  137 +int clk_free(struct clk *clk)
  138 +{
  139 + struct clk_ops *ops = clk_dev_ops(clk->dev);
  140 +
  141 + debug("%s(clk=%p)\n", __func__, clk);
  142 +
  143 + if (!ops->free)
  144 + return 0;
  145 +
  146 + return ops->free(clk);
  147 +}
  148 +
  149 +ulong clk_get_rate(struct clk *clk)
  150 +{
  151 + struct clk_ops *ops = clk_dev_ops(clk->dev);
  152 +
  153 + debug("%s(clk=%p)\n", __func__, clk);
  154 +
  155 + if (!ops->get_rate)
  156 + return -ENOSYS;
  157 +
  158 + return ops->get_rate(clk);
  159 +}
  160 +
  161 +ulong clk_set_rate(struct clk *clk, ulong rate)
  162 +{
  163 + struct clk_ops *ops = clk_dev_ops(clk->dev);
  164 +
  165 + debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
  166 +
  167 + if (!ops->set_rate)
  168 + return -ENOSYS;
  169 +
  170 + return ops->set_rate(clk, rate);
  171 +}
  172 +
  173 +int clk_enable(struct clk *clk)
  174 +{
  175 + struct clk_ops *ops = clk_dev_ops(clk->dev);
  176 +
  177 + debug("%s(clk=%p)\n", __func__, clk);
  178 +
  179 + if (!ops->enable)
  180 + return -ENOSYS;
  181 +
  182 + return ops->enable(clk);
  183 +}
  184 +
  185 +int clk_disable(struct clk *clk)
  186 +{
  187 + struct clk_ops *ops = clk_dev_ops(clk->dev);
  188 +
  189 + debug("%s(clk=%p)\n", __func__, clk);
  190 +
  191 + if (!ops->disable)
  192 + return -ENOSYS;
  193 +
  194 + return ops->disable(clk);
  195 +}
108 196  
109 197 UCLASS_DRIVER(clk) = {
110 198 .id = UCLASS_CLK,
drivers/clk/clk_fixed_rate.c
... ... @@ -5,7 +5,7 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
  8 +#include <clk-uclass.h>
9 9 #include <dm/device.h>
10 10  
11 11 DECLARE_GLOBAL_DATA_PTR;
12 12  
13 13  
14 14  
... ... @@ -16,19 +16,16 @@
16 16  
17 17 #define to_clk_fixed_rate(dev) ((struct clk_fixed_rate *)dev_get_platdata(dev))
18 18  
19   -static ulong clk_fixed_rate_get_rate(struct udevice *dev)
  19 +static ulong clk_fixed_rate_get_rate(struct clk *clk)
20 20 {
21   - return to_clk_fixed_rate(dev)->fixed_rate;
22   -}
  21 + if (clk->id != 0)
  22 + return -EINVAL;
23 23  
24   -static ulong clk_fixed_rate_get_periph_rate(struct udevice *dev, int periph)
25   -{
26   - return clk_fixed_rate_get_rate(dev);
  24 + return to_clk_fixed_rate(clk->dev)->fixed_rate;
27 25 }
28 26  
29 27 const struct clk_ops clk_fixed_rate_ops = {
30 28 .get_rate = clk_fixed_rate_get_rate,
31   - .get_periph_rate = clk_fixed_rate_get_periph_rate,
32 29 };
33 30  
34 31 static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
drivers/clk/clk_pic32.c
... ... @@ -6,7 +6,7 @@
6 6 */
7 7  
8 8 #include <common.h>
9   -#include <clk.h>
  9 +#include <clk-uclass.h>
10 10 #include <dm.h>
11 11 #include <div64.h>
12 12 #include <wait_bit.h>
13 13  
14 14  
15 15  
16 16  
... ... @@ -339,24 +339,17 @@
339 339 pic32_mpll_init(priv);
340 340 }
341 341  
342   -static ulong pic32_clk_get_rate(struct udevice *dev)
  342 +static ulong pic32_get_rate(struct clk *clk)
343 343 {
344   - struct pic32_clk_priv *priv = dev_get_priv(dev);
345   -
346   - return pic32_get_cpuclk(priv);
347   -}
348   -
349   -static ulong pic32_get_periph_rate(struct udevice *dev, int periph)
350   -{
351   - struct pic32_clk_priv *priv = dev_get_priv(dev);
  344 + struct pic32_clk_priv *priv = dev_get_priv(clk->dev);
352 345 ulong rate;
353 346  
354   - switch (periph) {
  347 + switch (clk->id) {
355 348 case PB1CLK ... PB7CLK:
356   - rate = pic32_get_pbclk(priv, periph);
  349 + rate = pic32_get_pbclk(priv, clk->id);
357 350 break;
358 351 case REF1CLK ... REF5CLK:
359   - rate = pic32_get_refclk(priv, periph);
  352 + rate = pic32_get_refclk(priv, clk->id);
360 353 break;
361 354 case PLLCLK:
362 355 rate = pic32_get_pll_rate(priv);
363 356  
364 357  
365 358  
... ... @@ -372,15 +365,15 @@
372 365 return rate;
373 366 }
374 367  
375   -static ulong pic32_set_periph_rate(struct udevice *dev, int periph, ulong rate)
  368 +static ulong pic32_set_rate(struct clk *clk, ulong rate)
376 369 {
377   - struct pic32_clk_priv *priv = dev_get_priv(dev);
  370 + struct pic32_clk_priv *priv = dev_get_priv(clk->dev);
378 371 ulong pll_hz;
379 372  
380   - switch (periph) {
  373 + switch (clk->id) {
381 374 case REF1CLK ... REF5CLK:
382 375 pll_hz = pic32_get_pll_rate(priv);
383   - pic32_set_refclk(priv, periph, pll_hz, rate, ROCLK_SRC_SPLL);
  376 + pic32_set_refclk(priv, clk->id, pll_hz, rate, ROCLK_SRC_SPLL);
384 377 break;
385 378 default:
386 379 break;
... ... @@ -390,9 +383,8 @@
390 383 }
391 384  
392 385 static struct clk_ops pic32_pic32_clk_ops = {
393   - .get_rate = pic32_clk_get_rate,
394   - .set_periph_rate = pic32_set_periph_rate,
395   - .get_periph_rate = pic32_get_periph_rate,
  386 + .set_rate = pic32_set_rate,
  387 + .get_rate = pic32_get_rate,
396 388 };
397 389  
398 390 static int pic32_clk_probe(struct udevice *dev)
drivers/clk/clk_rk3036.c
... ... @@ -5,7 +5,7 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
  8 +#include <clk-uclass.h>
9 9 #include <dm.h>
10 10 #include <errno.h>
11 11 #include <syscon.h>
... ... @@ -18,10 +18,6 @@
18 18  
19 19 DECLARE_GLOBAL_DATA_PTR;
20 20  
21   -struct rk3036_clk_plat {
22   - enum rk_clk_id clk_id;
23   -};
24   -
25 21 struct rk3036_clk_priv {
26 22 struct rk3036_cru *cru;
27 23 ulong rate;
28 24  
29 25  
30 26  
31 27  
32 28  
33 29  
... ... @@ -315,31 +311,30 @@
315 311 return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
316 312 }
317 313  
318   -static ulong rk3036_clk_get_rate(struct udevice *dev)
  314 +static ulong rk3036_clk_get_rate(struct clk *clk)
319 315 {
320   - struct rk3036_clk_plat *plat = dev_get_platdata(dev);
321   - struct rk3036_clk_priv *priv = dev_get_priv(dev);
  316 + struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
322 317  
323   - debug("%s\n", dev->name);
324   - return rkclk_pll_get_rate(priv->cru, plat->clk_id);
  318 + switch (clk->id) {
  319 + case 0 ... 63:
  320 + return rkclk_pll_get_rate(priv->cru, clk->id);
  321 + default:
  322 + return -ENOENT;
  323 + }
325 324 }
326 325  
327   -static ulong rk3036_clk_set_rate(struct udevice *dev, ulong rate)
  326 +static ulong rk3036_clk_set_rate(struct clk *clk, ulong rate)
328 327 {
329   - debug("%s\n", dev->name);
  328 + struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
  329 + ulong new_rate, gclk_rate;
330 330  
331   - return 0;
332   -}
333   -
334   -static ulong rk3036_set_periph_rate(struct udevice *dev, int periph, ulong rate)
335   -{
336   - struct rk3036_clk_priv *priv = dev_get_priv(dev);
337   - ulong new_rate;
338   -
339   - switch (periph) {
  331 + gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
  332 + switch (clk->id) {
  333 + case 0 ... 63:
  334 + return 0;
340 335 case HCLK_EMMC:
341   - new_rate = rockchip_mmc_set_clk(priv->cru, clk_get_rate(dev),
342   - periph, rate);
  336 + new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
  337 + clk->id, rate);
343 338 break;
344 339 default:
345 340 return -ENOENT;
346 341  
347 342  
348 343  
349 344  
350 345  
... ... @@ -351,61 +346,22 @@
351 346 static struct clk_ops rk3036_clk_ops = {
352 347 .get_rate = rk3036_clk_get_rate,
353 348 .set_rate = rk3036_clk_set_rate,
354   - .set_periph_rate = rk3036_set_periph_rate,
355 349 };
356 350  
357 351 static int rk3036_clk_probe(struct udevice *dev)
358 352 {
359   - struct rk3036_clk_plat *plat = dev_get_platdata(dev);
360 353 struct rk3036_clk_priv *priv = dev_get_priv(dev);
361 354  
362   - if (plat->clk_id != CLK_OSC) {
363   - struct rk3036_clk_priv *parent_priv = dev_get_priv(dev->parent);
364   -
365   - priv->cru = parent_priv->cru;
366   - return 0;
367   - }
368 355 priv->cru = (struct rk3036_cru *)dev_get_addr(dev);
369 356 rkclk_init(priv->cru);
370 357  
371 358 return 0;
372 359 }
373 360  
374   -static const char *const clk_name[] = {
375   - "osc",
376   - "apll",
377   - "dpll",
378   - "cpll",
379   - "gpll",
380   - "mpll",
381   -};
382   -
383 361 static int rk3036_clk_bind(struct udevice *dev)
384 362 {
385   - struct rk3036_clk_plat *plat = dev_get_platdata(dev);
386   - int pll, ret;
  363 + int ret;
387 364  
388   - /* We only need to set up the root clock */
389   - if (dev->of_offset == -1) {
390   - plat->clk_id = CLK_OSC;
391   - return 0;
392   - }
393   -
394   - /* Create devices for P main clocks */
395   - for (pll = 1; pll < CLK_COUNT; pll++) {
396   - struct udevice *child;
397   - struct rk3036_clk_plat *cplat;
398   -
399   - debug("%s %s\n", __func__, clk_name[pll]);
400   - ret = device_bind_driver(dev, "clk_rk3036", clk_name[pll],
401   - &child);
402   - if (ret)
403   - return ret;
404   -
405   - cplat = dev_get_platdata(child);
406   - cplat->clk_id = pll;
407   - }
408   -
409 365 /* The reset driver does not have a device node, so bind it here */
410 366 ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
411 367 if (ret)
... ... @@ -424,7 +380,6 @@
424 380 .id = UCLASS_CLK,
425 381 .of_match = rk3036_clk_ids,
426 382 .priv_auto_alloc_size = sizeof(struct rk3036_clk_priv),
427   - .platdata_auto_alloc_size = sizeof(struct rk3036_clk_plat),
428 383 .ops = &rk3036_clk_ops,
429 384 .bind = rk3036_clk_bind,
430 385 .probe = rk3036_clk_probe,
drivers/clk/clk_rk3288.c
... ... @@ -5,7 +5,7 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
  8 +#include <clk-uclass.h>
9 9 #include <dm.h>
10 10 #include <errno.h>
11 11 #include <syscon.h>
... ... @@ -21,10 +21,6 @@
21 21  
22 22 DECLARE_GLOBAL_DATA_PTR;
23 23  
24   -struct rk3288_clk_plat {
25   - enum rk_clk_id clk_id;
26   -};
27   -
28 24 struct rk3288_clk_priv {
29 25 struct rk3288_grf *grf;
30 26 struct rk3288_cru *cru;
31 27  
32 28  
33 29  
... ... @@ -135,34 +131,18 @@
135 131 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
136 132 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
137 133  
138   -int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp)
139   -{
140   - struct udevice *dev;
141   -
142   - for (uclass_find_first_device(UCLASS_CLK, &dev);
143   - dev;
144   - uclass_find_next_device(&dev)) {
145   - struct rk3288_clk_plat *plat = dev_get_platdata(dev);
146   -
147   - if (plat->clk_id == clk_id) {
148   - *devp = dev;
149   - return device_probe(dev);
150   - }
151   - }
152   -
153   - return -ENODEV;
154   -}
155   -
156 134 void *rockchip_get_cru(void)
157 135 {
158 136 struct rk3288_clk_priv *priv;
159 137 struct udevice *dev;
160 138 int ret;
161 139  
162   - ret = rkclk_get_clk(CLK_GENERAL, &dev);
  140 + ret = uclass_get_device(UCLASS_CLK, 0, &dev);
163 141 if (ret)
164 142 return ERR_PTR(ret);
  143 +
165 144 priv = dev_get_priv(dev);
  145 +
166 146 return priv->cru;
167 147 }
168 148  
... ... @@ -539,32 +519,6 @@
539 519 }
540 520 }
541 521  
542   -static ulong rk3288_clk_get_rate(struct udevice *dev)
543   -{
544   - struct rk3288_clk_plat *plat = dev_get_platdata(dev);
545   - struct rk3288_clk_priv *priv = dev_get_priv(dev);
546   -
547   - debug("%s\n", dev->name);
548   - return rkclk_pll_get_rate(priv->cru, plat->clk_id);
549   -}
550   -
551   -static ulong rk3288_clk_set_rate(struct udevice *dev, ulong rate)
552   -{
553   - struct rk3288_clk_plat *plat = dev_get_platdata(dev);
554   - struct rk3288_clk_priv *priv = dev_get_priv(dev);
555   -
556   - debug("%s\n", dev->name);
557   - switch (plat->clk_id) {
558   - case CLK_DDR:
559   - rkclk_configure_ddr(priv->cru, priv->grf, rate);
560   - break;
561   - default:
562   - return -ENOENT;
563   - }
564   -
565   - return 0;
566   -}
567   -
568 522 static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
569 523 int periph)
570 524 {
571 525  
572 526  
573 527  
574 528  
575 529  
... ... @@ -710,27 +664,25 @@
710 664 return rockchip_spi_get_clk(cru, gclk_rate, periph);
711 665 }
712 666  
713   -static ulong rk3288_get_periph_rate(struct udevice *dev, int periph)
  667 +static ulong rk3288_clk_get_rate(struct clk *clk)
714 668 {
715   - struct rk3288_clk_priv *priv = dev_get_priv(dev);
716   - struct udevice *gclk;
  669 + struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
717 670 ulong new_rate, gclk_rate;
718   - int ret;
719 671  
720   - ret = rkclk_get_clk(CLK_GENERAL, &gclk);
721   - if (ret)
722   - return ret;
723   - gclk_rate = clk_get_rate(gclk);
724   - switch (periph) {
  672 + gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
  673 + switch (clk->id) {
  674 + case 0 ... 63:
  675 + new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
  676 + break;
725 677 case HCLK_EMMC:
726 678 case HCLK_SDMMC:
727 679 case HCLK_SDIO0:
728   - new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, periph);
  680 + new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
729 681 break;
730 682 case SCLK_SPI0:
731 683 case SCLK_SPI1:
732 684 case SCLK_SPI2:
733   - new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, periph);
  685 + new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, clk->id);
734 686 break;
735 687 case PCLK_I2C0:
736 688 case PCLK_I2C1:
737 689  
738 690  
739 691  
740 692  
741 693  
742 694  
743 695  
744 696  
... ... @@ -746,36 +698,34 @@
746 698 return new_rate;
747 699 }
748 700  
749   -static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
  701 +static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
750 702 {
751   - struct rk3288_clk_priv *priv = dev_get_priv(dev);
  703 + struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
752 704 struct rk3288_cru *cru = priv->cru;
753   - struct udevice *gclk;
754 705 ulong new_rate, gclk_rate;
755   - int ret;
756 706  
757   - ret = rkclk_get_clk(CLK_GENERAL, &gclk);
758   - if (ret)
759   - return ret;
760   - gclk_rate = clk_get_rate(gclk);
761   - switch (periph) {
  707 + gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
  708 + switch (clk->id) {
  709 + case CLK_DDR:
  710 + new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate);
  711 + break;
762 712 case HCLK_EMMC:
763 713 case HCLK_SDMMC:
764 714 case HCLK_SDIO0:
765   - new_rate = rockchip_mmc_set_clk(cru, gclk_rate, periph, rate);
  715 + new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate);
766 716 break;
767 717 case SCLK_SPI0:
768 718 case SCLK_SPI1:
769 719 case SCLK_SPI2:
770   - new_rate = rockchip_spi_set_clk(cru, gclk_rate, periph, rate);
  720 + new_rate = rockchip_spi_set_clk(cru, gclk_rate, clk->id, rate);
771 721 break;
772 722 #ifndef CONFIG_SPL_BUILD
773 723 case SCLK_MAC:
774   - new_rate = rockchip_mac_set_clk(priv->cru, periph, rate);
  724 + new_rate = rockchip_mac_set_clk(priv->cru, clk->id, rate);
775 725 break;
776 726 case DCLK_VOP0:
777 727 case DCLK_VOP1:
778   - new_rate = rockchip_vop_set_clk(cru, priv->grf, periph, rate);
  728 + new_rate = rockchip_vop_set_clk(cru, priv->grf, clk->id, rate);
779 729 break;
780 730 case SCLK_EDP_24M:
781 731 /* clk_edp_24M source: 24M */
... ... @@ -795,7 +745,7 @@
795 745 div = CPLL_HZ / rate;
796 746 assert((div - 1 < 64) && (div * rate == CPLL_HZ));
797 747  
798   - switch (periph) {
  748 + switch (clk->id) {
799 749 case ACLK_VOP0:
800 750 rk_clrsetreg(&cru->cru_clksel_con[31],
801 751 3 << 6 | 0x1f << 0,
802 752  
803 753  
... ... @@ -831,22 +781,12 @@
831 781 static struct clk_ops rk3288_clk_ops = {
832 782 .get_rate = rk3288_clk_get_rate,
833 783 .set_rate = rk3288_clk_set_rate,
834   - .set_periph_rate = rk3288_set_periph_rate,
835   - .get_periph_rate = rk3288_get_periph_rate,
836 784 };
837 785  
838 786 static int rk3288_clk_probe(struct udevice *dev)
839 787 {
840   - struct rk3288_clk_plat *plat = dev_get_platdata(dev);
841 788 struct rk3288_clk_priv *priv = dev_get_priv(dev);
842 789  
843   - if (plat->clk_id != CLK_OSC) {
844   - struct rk3288_clk_priv *parent_priv = dev_get_priv(dev->parent);
845   -
846   - priv->cru = parent_priv->cru;
847   - priv->grf = parent_priv->grf;
848   - return 0;
849   - }
850 790 priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
851 791 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
852 792 #ifdef CONFIG_SPL_BUILD
853 793  
854 794  
... ... @@ -856,40 +796,10 @@
856 796 return 0;
857 797 }
858 798  
859   -static const char *const clk_name[CLK_COUNT] = {
860   - "osc",
861   - "apll",
862   - "dpll",
863   - "cpll",
864   - "gpll",
865   - "npll",
866   -};
867   -
868 799 static int rk3288_clk_bind(struct udevice *dev)
869 800 {
870   - struct rk3288_clk_plat *plat = dev_get_platdata(dev);
871   - int pll, ret;
  801 + int ret;
872 802  
873   - /* We only need to set up the root clock */
874   - if (dev->of_offset == -1) {
875   - plat->clk_id = CLK_OSC;
876   - return 0;
877   - }
878   -
879   - /* Create devices for P main clocks */
880   - for (pll = 1; pll < CLK_COUNT; pll++) {
881   - struct udevice *child;
882   - struct rk3288_clk_plat *cplat;
883   -
884   - debug("%s %s\n", __func__, clk_name[pll]);
885   - ret = device_bind_driver(dev, "clk_rk3288", clk_name[pll],
886   - &child);
887   - if (ret)
888   - return ret;
889   - cplat = dev_get_platdata(child);
890   - cplat->clk_id = pll;
891   - }
892   -
893 803 /* The reset driver does not have a device node, so bind it here */
894 804 ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
895 805 if (ret)
... ... @@ -908,7 +818,6 @@
908 818 .id = UCLASS_CLK,
909 819 .of_match = rk3288_clk_ids,
910 820 .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
911   - .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
912 821 .ops = &rk3288_clk_ops,
913 822 .bind = rk3288_clk_bind,
914 823 .probe = rk3288_clk_probe,
drivers/clk/clk_sandbox.c
... ... @@ -5,70 +5,72 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
  8 +#include <clk-uclass.h>
9 9 #include <dm.h>
10 10 #include <errno.h>
11   -#include <asm/test.h>
  11 +#include <asm/clk.h>
12 12  
13 13 struct sandbox_clk_priv {
14   - ulong rate;
15   - ulong periph_rate[PERIPH_ID_COUNT];
  14 + ulong rate[SANDBOX_CLK_ID_COUNT];
  15 + bool enabled[SANDBOX_CLK_ID_COUNT];
16 16 };
17 17  
18   -static ulong sandbox_clk_get_rate(struct udevice *dev)
  18 +static ulong sandbox_clk_get_rate(struct clk *clk)
19 19 {
20   - struct sandbox_clk_priv *priv = dev_get_priv(dev);
  20 + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
21 21  
22   - return priv->rate;
  22 + if (clk->id < 0 || clk->id >= SANDBOX_CLK_ID_COUNT)
  23 + return -EINVAL;
  24 +
  25 + return priv->rate[clk->id];
23 26 }
24 27  
25   -static ulong sandbox_clk_set_rate(struct udevice *dev, ulong rate)
  28 +static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
26 29 {
27   - struct sandbox_clk_priv *priv = dev_get_priv(dev);
  30 + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
  31 + ulong old_rate;
28 32  
  33 + if (clk->id < 0 || clk->id >= SANDBOX_CLK_ID_COUNT)
  34 + return -EINVAL;
  35 +
29 36 if (!rate)
30 37 return -EINVAL;
31   - priv->rate = rate;
32   - return 0;
33   -}
34 38  
35   -static ulong sandbox_get_periph_rate(struct udevice *dev, int periph)
36   -{
37   - struct sandbox_clk_priv *priv = dev_get_priv(dev);
  39 + old_rate = priv->rate[clk->id];
  40 + priv->rate[clk->id] = rate;
38 41  
39   - if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT)
40   - return -EINVAL;
41   - return priv->periph_rate[periph];
  42 + return old_rate;
42 43 }
43 44  
44   -static ulong sandbox_set_periph_rate(struct udevice *dev, int periph,
45   - ulong rate)
  45 +static int sandbox_clk_enable(struct clk *clk)
46 46 {
47   - struct sandbox_clk_priv *priv = dev_get_priv(dev);
48   - ulong old_rate;
  47 + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
49 48  
50   - if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT)
  49 + if (clk->id < 0 || clk->id >= SANDBOX_CLK_ID_COUNT)
51 50 return -EINVAL;
52   - old_rate = priv->periph_rate[periph];
53   - priv->periph_rate[periph] = rate;
54 51  
55   - return old_rate;
  52 + priv->enabled[clk->id] = true;
  53 +
  54 + return 0;
56 55 }
57 56  
58   -static int sandbox_clk_probe(struct udevice *dev)
  57 +static int sandbox_clk_disable(struct clk *clk)
59 58 {
60   - struct sandbox_clk_priv *priv = dev_get_priv(dev);
  59 + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
61 60  
62   - priv->rate = SANDBOX_CLK_RATE;
  61 + if (clk->id < 0 || clk->id >= SANDBOX_CLK_ID_COUNT)
  62 + return -EINVAL;
63 63  
  64 + priv->enabled[clk->id] = false;
  65 +
64 66 return 0;
65 67 }
66 68  
67 69 static struct clk_ops sandbox_clk_ops = {
68 70 .get_rate = sandbox_clk_get_rate,
69 71 .set_rate = sandbox_clk_set_rate,
70   - .get_periph_rate = sandbox_get_periph_rate,
71   - .set_periph_rate = sandbox_set_periph_rate,
  72 + .enable = sandbox_clk_enable,
  73 + .disable = sandbox_clk_disable,
72 74 };
73 75  
74 76 static const struct udevice_id sandbox_clk_ids[] = {
75 77  
... ... @@ -82,6 +84,25 @@
82 84 .of_match = sandbox_clk_ids,
83 85 .ops = &sandbox_clk_ops,
84 86 .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
85   - .probe = sandbox_clk_probe,
86 87 };
  88 +
  89 +ulong sandbox_clk_query_rate(struct udevice *dev, int id)
  90 +{
  91 + struct sandbox_clk_priv *priv = dev_get_priv(dev);
  92 +
  93 + if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
  94 + return -EINVAL;
  95 +
  96 + return priv->rate[id];
  97 +}
  98 +
  99 +int sandbox_clk_query_enable(struct udevice *dev, int id)
  100 +{
  101 + struct sandbox_clk_priv *priv = dev_get_priv(dev);
  102 +
  103 + if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
  104 + return -EINVAL;
  105 +
  106 + return priv->enabled[id];
  107 +}
drivers/clk/clk_sandbox_test.c
  1 +/*
  2 + * Copyright (c) 2016, NVIDIA CORPORATION.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0
  5 + */
  6 +
  7 +#include <common.h>
  8 +#include <dm.h>
  9 +#include <clk.h>
  10 +#include <asm/clk.h>
  11 +
  12 +struct sandbox_clk_test {
  13 + struct clk clks[SANDBOX_CLK_TEST_ID_COUNT];
  14 +};
  15 +
  16 +static const char * const sandbox_clk_test_names[] = {
  17 + [SANDBOX_CLK_TEST_ID_FIXED] = "fixed",
  18 + [SANDBOX_CLK_TEST_ID_SPI] = "spi",
  19 + [SANDBOX_CLK_TEST_ID_I2C] = "i2c",
  20 +};
  21 +
  22 +int sandbox_clk_test_get(struct udevice *dev)
  23 +{
  24 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  25 + int i, ret;
  26 +
  27 + for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
  28 + ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
  29 + &sbct->clks[i]);
  30 + if (ret)
  31 + return ret;
  32 + }
  33 +
  34 + return 0;
  35 +}
  36 +
  37 +ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
  38 +{
  39 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  40 +
  41 + if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  42 + return -EINVAL;
  43 +
  44 + return clk_get_rate(&sbct->clks[id]);
  45 +}
  46 +
  47 +ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
  48 +{
  49 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  50 +
  51 + if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  52 + return -EINVAL;
  53 +
  54 + return clk_set_rate(&sbct->clks[id], rate);
  55 +}
  56 +
  57 +int sandbox_clk_test_enable(struct udevice *dev, int id)
  58 +{
  59 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  60 +
  61 + if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  62 + return -EINVAL;
  63 +
  64 + return clk_enable(&sbct->clks[id]);
  65 +}
  66 +
  67 +int sandbox_clk_test_disable(struct udevice *dev, int id)
  68 +{
  69 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  70 +
  71 + if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  72 + return -EINVAL;
  73 +
  74 + return clk_disable(&sbct->clks[id]);
  75 +}
  76 +
  77 +int sandbox_clk_test_free(struct udevice *dev)
  78 +{
  79 + struct sandbox_clk_test *sbct = dev_get_priv(dev);
  80 + int i, ret;
  81 +
  82 + for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
  83 + ret = clk_free(&sbct->clks[i]);
  84 + if (ret)
  85 + return ret;
  86 + }
  87 +
  88 + return 0;
  89 +}
  90 +
  91 +static const struct udevice_id sandbox_clk_test_ids[] = {
  92 + { .compatible = "sandbox,clk-test" },
  93 + { }
  94 +};
  95 +
  96 +U_BOOT_DRIVER(sandbox_clk_test) = {
  97 + .name = "sandbox_clk_test",
  98 + .id = UCLASS_MISC,
  99 + .of_match = sandbox_clk_test_ids,
  100 + .priv_auto_alloc_size = sizeof(struct sandbox_clk_test),
  101 +};
drivers/clk/exynos/clk-exynos7420.c
... ... @@ -9,7 +9,7 @@
9 9 #include <common.h>
10 10 #include <dm.h>
11 11 #include <errno.h>
12   -#include <clk.h>
  12 +#include <clk-uclass.h>
13 13 #include <asm/io.h>
14 14 #include <dt-bindings/clock/exynos7420-clk.h>
15 15 #include "clk-pll.h"
16 16  
17 17  
... ... @@ -67,11 +67,11 @@
67 67 unsigned long sclk_uart2;
68 68 };
69 69  
70   -static ulong exynos7420_topc_get_periph_rate(struct udevice *dev, int periph)
  70 +static ulong exynos7420_topc_get_rate(struct clk *clk)
71 71 {
72   - struct exynos7420_clk_topc_priv *priv = dev_get_priv(dev);
  72 + struct exynos7420_clk_topc_priv *priv = dev_get_priv(clk->dev);
73 73  
74   - switch (periph) {
  74 + switch (clk->id) {
75 75 case DOUT_SCLK_BUS0_PLL:
76 76 case SCLK_BUS0_PLL_A:
77 77 case SCLK_BUS0_PLL_B:
78 78  
... ... @@ -86,14 +86,14 @@
86 86 }
87 87  
88 88 static struct clk_ops exynos7420_clk_topc_ops = {
89   - .get_periph_rate = exynos7420_topc_get_periph_rate,
  89 + .get_rate = exynos7420_topc_get_rate,
90 90 };
91 91  
92 92 static int exynos7420_clk_topc_probe(struct udevice *dev)
93 93 {
94 94 struct exynos7420_clk_topc_priv *priv = dev_get_priv(dev);
95 95 struct exynos7420_clk_cmu_topc *topc;
96   - struct udevice *clk_dev;
  96 + struct clk in_clk;
97 97 unsigned long rate;
98 98 fdt_addr_t base;
99 99 int ret;
100 100  
... ... @@ -105,9 +105,9 @@
105 105 topc = (struct exynos7420_clk_cmu_topc *)base;
106 106 priv->topc = topc;
107 107  
108   - ret = clk_get_by_index(dev, 0, &clk_dev);
  108 + ret = clk_get_by_index(dev, 0, &in_clk);
109 109 if (ret >= 0)
110   - priv->fin_freq = clk_get_rate(clk_dev);
  110 + priv->fin_freq = clk_get_rate(&in_clk);
111 111  
112 112 rate = pll145x_get_rate(&topc->bus0_pll_con[0], priv->fin_freq);
113 113 if (readl(&topc->mux_sel[1]) & (1 << 16))
114 114  
115 115  
... ... @@ -122,12 +122,12 @@
122 122 return 0;
123 123 }
124 124  
125   -static ulong exynos7420_top0_get_periph_rate(struct udevice *dev, int periph)
  125 +static ulong exynos7420_top0_get_rate(struct clk *clk)
126 126 {
127   - struct exynos7420_clk_top0_priv *priv = dev_get_priv(dev);
  127 + struct exynos7420_clk_top0_priv *priv = dev_get_priv(clk->dev);
128 128 struct exynos7420_clk_cmu_top0 *top0 = priv->top0;
129 129  
130   - switch (periph) {
  130 + switch (clk->id) {
131 131 case CLK_SCLK_UART2:
132 132 return priv->mout_top0_bus0_pll_half /
133 133 DIVIDER(&top0->div_peric[3], 8, 0xf);
134 134  
... ... @@ -137,14 +137,14 @@
137 137 }
138 138  
139 139 static struct clk_ops exynos7420_clk_top0_ops = {
140   - .get_periph_rate = exynos7420_top0_get_periph_rate,
  140 + .get_rate = exynos7420_top0_get_rate,
141 141 };
142 142  
143 143 static int exynos7420_clk_top0_probe(struct udevice *dev)
144 144 {
145 145 struct exynos7420_clk_top0_priv *priv;
146 146 struct exynos7420_clk_cmu_top0 *top0;
147   - struct udevice *clk_dev;
  147 + struct clk in_clk;
148 148 fdt_addr_t base;
149 149 int ret;
150 150  
151 151  
... ... @@ -159,10 +159,10 @@
159 159 top0 = (struct exynos7420_clk_cmu_top0 *)base;
160 160 priv->top0 = top0;
161 161  
162   - ret = clk_get_by_index(dev, 1, &clk_dev);
  162 + ret = clk_get_by_index(dev, 1, &in_clk);
163 163 if (ret >= 0) {
164 164 priv->mout_top0_bus0_pll_half =
165   - clk_get_periph_rate(clk_dev, ret);
  165 + clk_get_rate(&in_clk);
166 166 if (readl(&top0->mux_sel[1]) & (1 << 16))
167 167 priv->mout_top0_bus0_pll_half >>= 1;
168 168 }
169 169  
170 170  
171 171  
172 172  
... ... @@ -170,18 +170,18 @@
170 170 return 0;
171 171 }
172 172  
173   -static ulong exynos7420_peric1_get_periph_rate(struct udevice *dev, int periph)
  173 +static ulong exynos7420_peric1_get_rate(struct clk *clk)
174 174 {
175   - struct udevice *clk_dev;
  175 + struct clk in_clk;
176 176 unsigned int ret;
177 177 unsigned long freq = 0;
178 178  
179   - switch (periph) {
  179 + switch (clk->id) {
180 180 case SCLK_UART2:
181   - ret = clk_get_by_index(dev, 3, &clk_dev);
  181 + ret = clk_get_by_index(clk->dev, 3, &in_clk);
182 182 if (ret < 0)
183 183 return ret;
184   - freq = clk_get_periph_rate(clk_dev, ret);
  184 + freq = clk_get_rate(&in_clk);
185 185 break;
186 186 }
187 187  
... ... @@ -189,7 +189,7 @@
189 189 }
190 190  
191 191 static struct clk_ops exynos7420_clk_peric1_ops = {
192   - .get_periph_rate = exynos7420_peric1_get_periph_rate,
  192 + .get_rate = exynos7420_peric1_get_rate,
193 193 };
194 194  
195 195 static const struct udevice_id exynos7420_clk_topc_compat[] = {
drivers/clk/uniphier/clk-uniphier-core.c
... ... @@ -9,14 +9,14 @@
9 9 #include <linux/bitops.h>
10 10 #include <linux/io.h>
11 11 #include <linux/sizes.h>
12   -#include <clk.h>
  12 +#include <clk-uclass.h>
13 13 #include <dm/device.h>
14 14  
15 15 #include "clk-uniphier.h"
16 16  
17   -static int uniphier_clk_enable(struct udevice *dev, int index)
  17 +static int uniphier_clk_enable(struct clk *clk)
18 18 {
19   - struct uniphier_clk_priv *priv = dev_get_priv(dev);
  19 + struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
20 20 struct uniphier_clk_gate_data *gate = priv->socdata->gate;
21 21 unsigned int nr_gate = priv->socdata->nr_gate;
22 22 void __iomem *reg;
... ... @@ -24,7 +24,7 @@
24 24 int i;
25 25  
26 26 for (i = 0; i < nr_gate; i++) {
27   - if (gate[i].index != index)
  27 + if (gate[i].index != clk->id)
28 28 continue;
29 29  
30 30 reg = priv->base + gate[i].reg;
31 31  
... ... @@ -41,9 +41,9 @@
41 41 return 0;
42 42 }
43 43  
44   -static ulong uniphier_clk_get_rate(struct udevice *dev, int index)
  44 +static ulong uniphier_clk_get_rate(struct clk *clk)
45 45 {
46   - struct uniphier_clk_priv *priv = dev_get_priv(dev);
  46 + struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
47 47 struct uniphier_clk_rate_data *rdata = priv->socdata->rate;
48 48 unsigned int nr_rdata = priv->socdata->nr_rate;
49 49 void __iomem *reg;
... ... @@ -52,7 +52,7 @@
52 52 int i;
53 53  
54 54 for (i = 0; i < nr_rdata; i++) {
55   - if (rdata[i].index != index)
  55 + if (rdata[i].index != clk->id)
56 56 continue;
57 57  
58 58 if (rdata[i].reg == UNIPHIER_CLK_RATE_IS_FIXED)
59 59  
... ... @@ -75,9 +75,9 @@
75 75 return matched_rate;
76 76 }
77 77  
78   -static ulong uniphier_clk_set_rate(struct udevice *dev, int index, ulong rate)
  78 +static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate)
79 79 {
80   - struct uniphier_clk_priv *priv = dev_get_priv(dev);
  80 + struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
81 81 struct uniphier_clk_rate_data *rdata = priv->socdata->rate;
82 82 unsigned int nr_rdata = priv->socdata->nr_rate;
83 83 void __iomem *reg;
... ... @@ -87,7 +87,7 @@
87 87  
88 88 /* first, decide the best match rate */
89 89 for (i = 0; i < nr_rdata; i++) {
90   - if (rdata[i].index != index)
  90 + if (rdata[i].index != clk->id)
91 91 continue;
92 92  
93 93 if (rdata[i].reg == UNIPHIER_CLK_RATE_IS_FIXED)
... ... @@ -105,7 +105,7 @@
105 105  
106 106 /* second, really set registers */
107 107 for (i = 0; i < nr_rdata; i++) {
108   - if (rdata[i].index != index || rdata[i].rate != best_rate)
  108 + if (rdata[i].index != clk->id || rdata[i].rate != best_rate)
109 109 continue;
110 110  
111 111 reg = priv->base + rdata[i].reg;
... ... @@ -124,8 +124,8 @@
124 124  
125 125 const struct clk_ops uniphier_clk_ops = {
126 126 .enable = uniphier_clk_enable,
127   - .get_periph_rate = uniphier_clk_get_rate,
128   - .set_periph_rate = uniphier_clk_set_rate,
  127 + .get_rate = uniphier_clk_get_rate,
  128 + .set_rate = uniphier_clk_set_rate,
129 129 };
130 130  
131 131 int uniphier_clk_probe(struct udevice *dev)
drivers/clk/uniphier/clk-uniphier-mio.c
... ... @@ -4,7 +4,6 @@
4 4 * SPDX-License-Identifier: GPL-2.0+
5 5 */
6 6  
7   -#include <clk.h>
8 7 #include <dm/device.h>
9 8  
10 9 #include "clk-uniphier.h"
drivers/i2c/rk_i2c.c
... ... @@ -29,10 +29,9 @@
29 29 #define RK_I2C_FIFO_SIZE 32
30 30  
31 31 struct rk_i2c {
32   - struct udevice *clk;
  32 + struct clk clk;
33 33 struct i2c_regs *regs;
34 34 unsigned int speed;
35   - int clk_id;
36 35 };
37 36  
38 37 static inline void rk_i2c_get_div(int div, int *divh, int *divl)
... ... @@ -55,7 +54,7 @@
55 54 int div, divl, divh;
56 55  
57 56 /* First get i2c rate from pclk */
58   - i2c_rate = clk_get_periph_rate(i2c->clk, i2c->clk_id);
  57 + i2c_rate = clk_get_rate(&i2c->clk);
59 58  
60 59 div = DIV_ROUND_UP(i2c_rate, scl_rate * 8) - 2;
61 60 divh = 0;
... ... @@ -362,7 +361,6 @@
362 361 bus->name, ret);
363 362 return ret;
364 363 }
365   - priv->clk_id = ret;
366 364  
367 365 return 0;
368 366 }
drivers/mmc/msm_sdhci.c
... ... @@ -49,7 +49,8 @@
49 49 "clock-frequency", 400000);
50 50 uint clkd[2]; /* clk_id and clk_no */
51 51 int clk_offset;
52   - struct udevice *clk;
  52 + struct udevice *clk_dev;
  53 + struct clk clk;
53 54 int ret;
54 55  
55 56 ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock", clkd,
56 57  
... ... @@ -61,11 +62,17 @@
61 62 if (clk_offset < 0)
62 63 return clk_offset;
63 64  
64   - ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk);
  65 + ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk_dev);
65 66 if (ret)
66 67 return ret;
67 68  
68   - ret = clk_set_periph_rate(clk, clkd[1], clk_rate);
  69 + clk.id = clkd[1];
  70 + ret = clk_request(clk_dev, &clk);
  71 + if (ret < 0)
  72 + return ret;
  73 +
  74 + ret = clk_set_rate(&clk, clk_rate);
  75 + clk_free(&clk);
69 76 if (ret < 0)
70 77 return ret;
71 78  
drivers/mmc/rockchip_dw_mmc.c
... ... @@ -24,8 +24,7 @@
24 24 };
25 25  
26 26 struct rockchip_dwmmc_priv {
27   - struct udevice *clk;
28   - int periph;
  27 + struct clk clk;
29 28 struct dwmci_host host;
30 29 };
31 30  
... ... @@ -35,7 +34,7 @@
35 34 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
36 35 int ret;
37 36  
38   - ret = clk_set_periph_rate(priv->clk, priv->periph, freq);
  37 + ret = clk_set_rate(&priv->clk, freq);
39 38 if (ret < 0) {
40 39 debug("%s: err=%d\n", __func__, ret);
41 40 return ret;
... ... @@ -81,7 +80,6 @@
81 80 ret = clk_get_by_index(dev, 0, &priv->clk);
82 81 if (ret < 0)
83 82 return ret;
84   - priv->periph = ret;
85 83  
86 84 if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
87 85 "clock-freq-min-max", minmax, 2))
drivers/mmc/uniphier-sd.c
... ... @@ -651,8 +651,7 @@
651 651 struct uniphier_sd_priv *priv = dev_get_priv(dev);
652 652 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
653 653 fdt_addr_t base;
654   - struct udevice *clk_dev;
655   - int clk_id;
  654 + struct clk clk;
656 655 int ret;
657 656  
658 657 priv->dev = dev;
659 658  
660 659  
661 660  
662 661  
... ... @@ -665,20 +664,22 @@
665 664 if (!priv->regbase)
666 665 return -ENOMEM;
667 666  
668   - clk_id = clk_get_by_index(dev, 0, &clk_dev);
669   - if (clk_id < 0) {
  667 + ret = clk_get_by_index(dev, 0, &clk);
  668 + if (ret < 0) {
670 669 dev_err(dev, "failed to get host clock\n");
671   - return clk_id;
  670 + return ret;
672 671 }
673 672  
674 673 /* set to max rate */
675   - priv->mclk = clk_set_periph_rate(clk_dev, clk_id, ULONG_MAX);
  674 + priv->mclk = clk_set_rate(&clk, ULONG_MAX);
676 675 if (IS_ERR_VALUE(priv->mclk)) {
677 676 dev_err(dev, "failed to set rate for host clock\n");
  677 + clk_free(&clk);
678 678 return priv->mclk;
679 679 }
680 680  
681   - ret = clk_enable(clk_dev, clk_id);
  681 + ret = clk_enable(&clk);
  682 + clk_free(&clk);
682 683 if (ret) {
683 684 dev_err(dev, "failed to enable host clock\n");
684 685 return ret;
drivers/serial/serial_msm.c
... ... @@ -150,7 +150,8 @@
150 150 "clock-frequency", 115200);
151 151 uint clkd[2]; /* clk_id and clk_no */
152 152 int clk_offset;
153   - struct udevice *clk;
  153 + struct udevice *clk_dev;
  154 + struct clk clk;
154 155 int ret;
155 156  
156 157 ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock", clkd,
157 158  
... ... @@ -162,11 +163,17 @@
162 163 if (clk_offset < 0)
163 164 return clk_offset;
164 165  
165   - ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk);
  166 + ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk_dev);
166 167 if (ret)
167 168 return ret;
168 169  
169   - ret = clk_set_periph_rate(clk, clkd[1], clk_rate);
  170 + clk.id = clkd[1];
  171 + ret = clk_request(clk_dev, &clk);
  172 + if (ret < 0)
  173 + return ret;
  174 +
  175 + ret = clk_set_rate(&clk, clk_rate);
  176 + clk_free(&clk);
170 177 if (ret < 0)
171 178 return ret;
172 179  
drivers/serial/serial_pic32.c
... ... @@ -135,7 +135,7 @@
135 135 static int pic32_uart_probe(struct udevice *dev)
136 136 {
137 137 struct pic32_uart_priv *priv = dev_get_priv(dev);
138   - struct udevice *clkdev;
  138 + struct clk clk;
139 139 fdt_addr_t addr;
140 140 fdt_size_t size;
141 141 int ret;
142 142  
... ... @@ -148,10 +148,11 @@
148 148 priv->base = ioremap(addr, size);
149 149  
150 150 /* get clock rate */
151   - ret = clk_get_by_index(dev, 0, &clkdev);
  151 + ret = clk_get_by_index(dev, 0, &clk);
152 152 if (ret < 0)
153 153 return ret;
154   - priv->uartclk = clk_get_periph_rate(clkdev, ret);
  154 + priv->uartclk = clk_get_rate(&clk);
  155 + clk_free(&clk);
155 156  
156 157 /* initialize serial */
157 158 return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
drivers/serial/serial_s5p.c
... ... @@ -94,13 +94,13 @@
94 94 u32 uclk;
95 95  
96 96 #ifdef CONFIG_CLK_EXYNOS
97   - struct udevice *clk_dev;
  97 + struct clk clk;
98 98 u32 ret;
99 99  
100   - ret = clk_get_by_index(dev, 1, &clk_dev);
  100 + ret = clk_get_by_index(dev, 1, &clk);
101 101 if (ret < 0)
102 102 return ret;
103   - uclk = clk_get_periph_rate(clk_dev, ret);
  103 + uclk = clk_get_rate(&clk);
104 104 #else
105 105 uclk = get_uart_clk(plat->port_id);
106 106 #endif
drivers/spi/rk_spi.c
... ... @@ -35,8 +35,7 @@
35 35  
36 36 struct rockchip_spi_priv {
37 37 struct rockchip_spi *regs;
38   - struct udevice *clk;
39   - int clk_id;
  38 + struct clk clk;
40 39 unsigned int max_freq;
41 40 unsigned int mode;
42 41 ulong last_transaction_us; /* Time of last transaction end */
... ... @@ -144,7 +143,6 @@
144 143 bus->name, ret);
145 144 return ret;
146 145 }
147   - priv->clk_id = ret;
148 146  
149 147 plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
150 148 50000000);
... ... @@ -175,7 +173,7 @@
175 173 * Use 99 MHz as our clock since it divides nicely into 594 MHz which
176 174 * is the assumed speed for CLK_GENERAL.
177 175 */
178   - ret = clk_set_periph_rate(priv->clk, priv->clk_id, 99000000);
  176 + ret = clk_set_rate(&priv->clk, 99000000);
179 177 if (ret < 0) {
180 178 debug("%s: Failed to set clock: %d\n", __func__, ret);
181 179 return ret;
drivers/usb/host/ehci-generic.c
... ... @@ -26,15 +26,15 @@
26 26 int i;
27 27  
28 28 for (i = 0; ; i++) {
29   - struct udevice *clk_dev;
30   - int clk_id;
  29 + struct clk clk;
  30 + int ret;
31 31  
32   - clk_id = clk_get_by_index(dev, i, &clk_dev);
33   - if (clk_id < 0)
  32 + ret = clk_get_by_index(dev, i, &clk);
  33 + if (ret < 0)
34 34 break;
35   - if (clk_enable(clk_dev, clk_id))
36   - printf("failed to enable clock (dev=%s, id=%d)\n",
37   - clk_dev->name, clk_id);
  35 + if (clk_enable(&clk))
  36 + printf("failed to enable clock %d\n", i);
  37 + clk_free(&clk);
38 38 }
39 39  
40 40 hccr = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
drivers/video/rockchip/rk_edp.c
... ... @@ -1009,8 +1009,7 @@
1009 1009 struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
1010 1010 struct rk_edp_priv *priv = dev_get_priv(dev);
1011 1011 struct rk3288_edp *regs = priv->regs;
1012   - struct udevice *clk;
1013   - int periph;
  1012 + struct clk clk;
1014 1013 int ret;
1015 1014  
1016 1015 ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel",
... ... @@ -1026,8 +1025,8 @@
1026 1025  
1027 1026 ret = clk_get_by_index(dev, 1, &clk);
1028 1027 if (ret >= 0) {
1029   - periph = ret;
1030   - ret = clk_set_periph_rate(clk, periph, 0);
  1028 + ret = clk_set_rate(&clk, 0);
  1029 + clk_free(&clk);
1031 1030 }
1032 1031 if (ret) {
1033 1032 debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
... ... @@ -1036,8 +1035,8 @@
1036 1035  
1037 1036 ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
1038 1037 if (ret >= 0) {
1039   - periph = ret;
1040   - ret = clk_set_periph_rate(clk, periph, 192000000);
  1038 + ret = clk_set_rate(&clk, 192000000);
  1039 + clk_free(&clk);
1041 1040 }
1042 1041 if (ret < 0) {
1043 1042 debug("%s: Failed to set clock in source device '%s': ret=%d\n",
drivers/video/rockchip/rk_hdmi.c
... ... @@ -859,15 +859,15 @@
859 859 {
860 860 struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
861 861 struct rk_hdmi_priv *priv = dev_get_priv(dev);
862   - struct udevice *reg, *clk;
863   - int periph;
  862 + struct udevice *reg;
  863 + struct clk clk;
864 864 int ret;
865 865 int vop_id = uc_plat->source_id;
866 866  
867 867 ret = clk_get_by_index(dev, 0, &clk);
868 868 if (ret >= 0) {
869   - periph = ret;
870   - ret = clk_set_periph_rate(clk, periph, 0);
  869 + ret = clk_set_rate(&clk, 0);
  870 + clk_free(&clk);
871 871 }
872 872 if (ret) {
873 873 debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
... ... @@ -880,8 +880,8 @@
880 880 */
881 881 ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
882 882 if (ret >= 0) {
883   - periph = ret;
884   - ret = clk_set_periph_rate(clk, periph, 384000000);
  883 + ret = clk_set_rate(&clk, 384000000);
  884 + clk_free(&clk);
885 885 }
886 886 if (ret < 0) {
887 887 debug("%s: Failed to set clock in source device '%s': ret=%d\n",
drivers/video/rockchip/rk_lvds.c
... ... @@ -5,7 +5,6 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
9 8 #include <display.h>
10 9 #include <dm.h>
11 10 #include <edid.h>
drivers/video/rockchip/rk_vop.c
... ... @@ -195,7 +195,8 @@
195 195 struct udevice *disp;
196 196 int ret, remote, i, offset;
197 197 struct display_plat *disp_uc_plat;
198   - struct udevice *clk;
  198 + struct udevice *dev_clk;
  199 + struct clk clk;
199 200  
200 201 vop_id = fdtdec_get_int(blob, ep_node, "reg", -1);
201 202 debug("vop_id=%d\n", vop_id);
202 203  
203 204  
... ... @@ -237,11 +238,13 @@
237 238 return ret;
238 239 }
239 240  
240   - ret = rkclk_get_clk(CLK_NEW, &clk);
  241 + ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
241 242 if (!ret) {
242   - ret = clk_set_periph_rate(clk, DCLK_VOP0 + remote_vop_id,
243   - timing.pixelclock.typ);
  243 + clk.id = DCLK_VOP0 + remote_vop_id;
  244 + ret = clk_request(dev_clk, &clk);
244 245 }
  246 + if (!ret)
  247 + ret = clk_set_rate(&clk, timing.pixelclock.typ);
245 248 if (ret) {
246 249 debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
247 250 return ret;
include/clk-uclass.h
  1 +/*
  2 + * Copyright (c) 2015 Google, Inc
  3 + * Written by Simon Glass <sjg@chromium.org>
  4 + * Copyright (c) 2016, NVIDIA CORPORATION.
  5 + *
  6 + * SPDX-License-Identifier: GPL-2.0+
  7 + */
  8 +
  9 +#ifndef _CLK_UCLASS_H
  10 +#define _CLK_UCLASS_H
  11 +
  12 +/* See clk.h for background documentation. */
  13 +
  14 +#include <clk.h>
  15 +#include <fdtdec.h>
  16 +
  17 +/**
  18 + * struct clk_ops - The functions that a clock driver must implement.
  19 + */
  20 +struct clk_ops {
  21 + /**
  22 + * of_xlate - Translate a client's device-tree (OF) clock specifier.
  23 + *
  24 + * The clock core calls this function as the first step in implementing
  25 + * a client's clk_get_by_*() call.
  26 + *
  27 + * If this function pointer is set to NULL, the clock core will use a
  28 + * default implementation, which assumes #clock-cells = <1>, and that
  29 + * the DT cell contains a simple integer clock ID.
  30 + *
  31 + * At present, the clock API solely supports device-tree. If this
  32 + * changes, other xxx_xlate() functions may be added to support those
  33 + * other mechanisms.
  34 + *
  35 + * @clock: The clock struct to hold the translation result.
  36 + * @args: The clock specifier values from device tree.
  37 + * @return 0 if OK, or a negative error code.
  38 + */
  39 + int (*of_xlate)(struct clk *clock,
  40 + struct fdtdec_phandle_args *args);
  41 + /**
  42 + * request - Request a translated clock.
  43 + *
  44 + * The clock core calls this function as the second step in
  45 + * implementing a client's clk_get_by_*() call, following a successful
  46 + * xxx_xlate() call, or as the only step in implementing a client's
  47 + * clk_request() call.
  48 + *
  49 + * @clock: The clock struct to request; this has been fille in by
  50 + * a previoux xxx_xlate() function call, or by the caller
  51 + * of clk_request().
  52 + * @return 0 if OK, or a negative error code.
  53 + */
  54 + int (*request)(struct clk *clock);
  55 + /**
  56 + * free - Free a previously requested clock.
  57 + *
  58 + * This is the implementation of the client clk_free() API.
  59 + *
  60 + * @clock: The clock to free.
  61 + * @return 0 if OK, or a negative error code.
  62 + */
  63 + int (*free)(struct clk *clock);
  64 + /**
  65 + * get_rate() - Get current clock rate.
  66 + *
  67 + * @clk: The clock to query.
  68 + * @return clock rate in Hz, or -ve error code
  69 + */
  70 + ulong (*get_rate)(struct clk *clk);
  71 + /**
  72 + * set_rate() - Set current clock rate.
  73 + *
  74 + * @clk: The clock to manipulate.
  75 + * @rate: New clock rate in Hz.
  76 + * @return new rate, or -ve error code.
  77 + */
  78 + ulong (*set_rate)(struct clk *clk, ulong rate);
  79 + /**
  80 + * enable() - Enable a clock.
  81 + *
  82 + * @clk: The clock to manipulate.
  83 + * @return zero on success, or -ve error code.
  84 + */
  85 + int (*enable)(struct clk *clk);
  86 + /**
  87 + * disable() - Disable a clock.
  88 + *
  89 + * @clk: The clock to manipulate.
  90 + * @return zero on success, or -ve error code.
  91 + */
  92 + int (*disable)(struct clk *clk);
  93 +};
  94 +
  95 +#endif
1 1 /*
2 2 * Copyright (c) 2015 Google, Inc
3 3 * Written by Simon Glass <sjg@chromium.org>
  4 + * Copyright (c) 2016, NVIDIA CORPORATION.
4 5 *
5 6 * SPDX-License-Identifier: GPL-2.0+
6 7 */
7 8  
8 9  
9 10  
10 11  
11 12  
12 13  
13 14  
14 15  
15 16  
16 17  
17 18  
18 19  
19 20  
20 21  
21 22  
22 23  
23 24  
24 25  
25 26  
26 27  
27 28  
28 29  
29 30  
30 31  
31 32  
32 33  
33 34  
... ... @@ -8,126 +9,167 @@
8 9 #ifndef _CLK_H_
9 10 #define _CLK_H_
10 11  
11   -#include <errno.h>
12 12 #include <linux/types.h>
13 13  
  14 +/**
  15 + * A clock is a hardware signal that oscillates autonomously at a specific
  16 + * frequency and duty cycle. Most hardware modules require one or more clock
  17 + * signal to drive their operation. Clock signals are typically generated
  18 + * externally to the HW module consuming them, by an entity this API calls a
  19 + * clock provider. This API provides a standard means for drivers to enable and
  20 + * disable clocks, and to set the rate at which they oscillate.
  21 + *
  22 + * A driver that implements UCLASS_CLOCK is a clock provider. A provider will
  23 + * often implement multiple separate clocks, since the hardware it manages
  24 + * often has this capability. clock_uclass.h describes the interface which
  25 + * clock providers must implement.
  26 + *
  27 + * Clock consumers/clients are the HW modules driven by the clock signals. This
  28 + * header file describes the API used by drivers for those HW modules.
  29 + */
  30 +
14 31 struct udevice;
15 32  
16   -int soc_clk_dump(void);
17   -
18   -struct clk_ops {
19   - /**
20   - * get_rate() - Get current clock rate
21   - *
22   - * @dev: Device to check (UCLASS_CLK)
23   - * @return clock rate in Hz, or -ve error code
  33 +/**
  34 + * struct clk - A handle to (allowing control of) a single clock.
  35 + *
  36 + * Clients provide storage for clock handles. The content of the structure is
  37 + * managed solely by the clock API and clock drivers. A clock struct is
  38 + * initialized by "get"ing the clock struct. The clock struct is passed to all
  39 + * other clock APIs to identify which clock signal to operate upon.
  40 + *
  41 + * @dev: The device which implements the clock signal.
  42 + * @id: The clock signal ID within the provider.
  43 + *
  44 + * Currently, the clock API assumes that a single integer ID is enough to
  45 + * identify and configure any clock signal for any clock provider. If this
  46 + * assumption becomes invalid in the future, the struct could be expanded to
  47 + * either (a) add more fields to allow clock providers to store additional
  48 + * information, or (b) replace the id field with an opaque pointer, which the
  49 + * provider would dynamically allocated during its .of_xlate op, and process
  50 + * during is .request op. This may require the addition of an extra op to clean
  51 + * up the allocation.
  52 + */
  53 +struct clk {
  54 + struct udevice *dev;
  55 + /*
  56 + * Written by of_xlate. We assume a single id is enough for now. In the
  57 + * future, we might add more fields here.
24 58 */
25   - ulong (*get_rate)(struct udevice *dev);
  59 + unsigned long id;
  60 +};
26 61  
27   - /**
28   - * set_rate() - Set current clock rate
29   - *
30   - * @dev: Device to adjust
31   - * @rate: New clock rate in Hz
32   - * @return new rate, or -ve error code
33   - */
34   - ulong (*set_rate)(struct udevice *dev, ulong rate);
  62 +#if CONFIG_IS_ENABLED(OF_CONTROL)
  63 +/**
  64 + * clock_get_by_index - Get/request a clock by integer index.
  65 + *
  66 + * This looks up and requests a clock. The index is relative to the client
  67 + * device; each device is assumed to have n clocks associated with it somehow,
  68 + * and this function finds and requests one of them. The mapping of client
  69 + * device clock indices to provider clocks may be via device-tree properties,
  70 + * board-provided mapping tables, or some other mechanism.
  71 + *
  72 + * @dev: The client device.
  73 + * @index: The index of the clock to request, within the client's list of
  74 + * clocks.
  75 + * @clock A pointer to a clock struct to initialize.
  76 + * @return 0 if OK, or a negative error code.
  77 + */
  78 +int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
35 79  
36   - /**
37   - * enable() - Enable the clock for a peripheral
38   - *
39   - * @dev: clock provider
40   - * @periph: Peripheral ID to enable
41   - * @return zero on success, or -ve error code
42   - */
43   - int (*enable)(struct udevice *dev, int periph);
  80 +/**
  81 + * clock_get_by_name - Get/request a clock by name.
  82 + *
  83 + * This looks up and requests a clock. The name is relative to the client
  84 + * device; each device is assumed to have n clocks associated with it somehow,
  85 + * and this function finds and requests one of them. The mapping of client
  86 + * device clock names to provider clocks may be via device-tree properties,
  87 + * board-provided mapping tables, or some other mechanism.
  88 + *
  89 + * @dev: The client device.
  90 + * @name: The name of the clock to request, within the client's list of
  91 + * clocks.
  92 + * @clock: A pointer to a clock struct to initialize.
  93 + * @return 0 if OK, or a negative error code.
  94 + */
  95 +int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
  96 +#else
  97 +static inline int clk_get_by_index(struct udevice *dev, int index,
  98 + struct clk *clk)
  99 +{
  100 + return -ENOSYS;
  101 +}
44 102  
45   - /**
46   - * get_periph_rate() - Get clock rate for a peripheral
47   - *
48   - * @dev: Device to check (UCLASS_CLK)
49   - * @periph: Peripheral ID to check
50   - * @return clock rate in Hz, or -ve error code
51   - */
52   - ulong (*get_periph_rate)(struct udevice *dev, int periph);
  103 +static int clk_get_by_name(struct udevice *dev, const char *name,
  104 + struct clk *clk)
  105 +{
  106 + return -ENOSYS;
  107 +}
  108 +#endif
53 109  
54   - /**
55   - * set_periph_rate() - Set current clock rate for a peripheral
56   - *
57   - * @dev: Device to update (UCLASS_CLK)
58   - * @periph: Peripheral ID to update
59   - * @return new clock rate in Hz, or -ve error code
60   - */
61   - ulong (*set_periph_rate)(struct udevice *dev, int periph, ulong rate);
62   -};
63   -
64   -#define clk_get_ops(dev) ((struct clk_ops *)(dev)->driver->ops)
65   -
66 110 /**
67   - * clk_get_rate() - Get current clock rate
  111 + * clk_request - Request a clock by provider-specific ID.
68 112 *
69   - * @dev: Device to check (UCLASS_CLK)
70   - * @return clock rate in Hz, or -ve error code
  113 + * This requests a clock using a provider-specific ID. Generally, this function
  114 + * should not be used, since clk_get_by_index/name() provide an interface that
  115 + * better separates clients from intimate knowledge of clock providers.
  116 + * However, this function may be useful in core SoC-specific code.
  117 + *
  118 + * @dev: The clock provider device.
  119 + * @clock: A pointer to a clock struct to initialize. The caller must
  120 + * have already initialized any field in this struct which the
  121 + * clock provider uses to identify the clock.
  122 + * @return 0 if OK, or a negative error code.
71 123 */
72   -ulong clk_get_rate(struct udevice *dev);
  124 +int clk_request(struct udevice *dev, struct clk *clk);
73 125  
74 126 /**
75   - * clk_set_rate() - Set current clock rate
  127 + * clock_free - Free a previously requested clock.
76 128 *
77   - * @dev: Device to adjust
78   - * @rate: New clock rate in Hz
79   - * @return new rate, or -ve error code
  129 + * @clock: A clock struct that was previously successfully requested by
  130 + * clk_request/get_by_*().
  131 + * @return 0 if OK, or a negative error code.
80 132 */
81   -ulong clk_set_rate(struct udevice *dev, ulong rate);
  133 +int clk_free(struct clk *clk);
82 134  
83 135 /**
84   - * clk_enable() - Enable the clock for a peripheral
  136 + * clk_get_rate() - Get current clock rate.
85 137 *
86   - * @dev: clock provider
87   - * @periph: Peripheral ID to enable
88   - * @return zero on success, or -ve error code
  138 + * @clk: A clock struct that was previously successfully requested by
  139 + * clk_request/get_by_*().
  140 + * @return clock rate in Hz, or -ve error code.
89 141 */
90   -int clk_enable(struct udevice *dev, int periph);
  142 +ulong clk_get_rate(struct clk *clk);
91 143  
92 144 /**
93   - * clk_get_periph_rate() - Get current clock rate for a peripheral
  145 + * clk_set_rate() - Set current clock rate.
94 146 *
95   - * @dev: Device to check (UCLASS_CLK)
96   - * @return clock rate in Hz, -ve error code
  147 + * @clk: A clock struct that was previously successfully requested by
  148 + * clk_request/get_by_*().
  149 + * @rate: New clock rate in Hz.
  150 + * @return new rate, or -ve error code.
97 151 */
98   -ulong clk_get_periph_rate(struct udevice *dev, int periph);
  152 +ulong clk_set_rate(struct clk *clk, ulong rate);
99 153  
100 154 /**
101   - * clk_set_periph_rate() - Set current clock rate for a peripheral
  155 + * clk_enable() - Enable (turn on) a clock.
102 156 *
103   - * @dev: Device to update (UCLASS_CLK)
104   - * @periph: Peripheral ID to update
105   - * @return new clock rate in Hz, or -ve error code
  157 + * @clk: A clock struct that was previously successfully requested by
  158 + * clk_request/get_by_*().
  159 + * @return zero on success, or -ve error code.
106 160 */
107   -ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate);
  161 +int clk_enable(struct clk *clk);
108 162  
109   -#if CONFIG_IS_ENABLED(OF_CONTROL)
110 163 /**
111   - * clk_get_by_index() - look up a clock referenced by a device
  164 + * clk_disable() - Disable (turn off) a clock.
112 165 *
113   - * Parse a device's 'clocks' list, returning information on the indexed clock,
114   - * ensuring that it is activated.
115   - *
116   - * @dev: Device containing the clock reference
117   - * @index: Clock index to return (0 = first)
118   - * @clk_devp: Returns clock device
119   - * @return: Peripheral ID for the device to control. This is the first
120   - * argument after the clock node phandle. If there is no arguemnt,
121   - * returns 0. Return -ve error code on any error
  166 + * @clk: A clock struct that was previously successfully requested by
  167 + * clk_request/get_by_*().
  168 + * @return zero on success, or -ve error code.
122 169 */
123   -int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp);
124   -#else
125   -static inline int clk_get_by_index(struct udevice *dev, int index,
126   - struct udevice **clk_devp)
127   -{
128   - return -ENOSYS;
129   -}
130   -#endif
  170 +int clk_disable(struct clk *clk);
131 171  
132   -#endif /* _CLK_H_ */
  172 +int soc_clk_dump(void);
  173 +
  174 +#endif
... ... @@ -5,56 +5,100 @@
5 5 */
6 6  
7 7 #include <common.h>
8   -#include <clk.h>
9 8 #include <dm.h>
10   -#include <asm/test.h>
  9 +#include <asm/clk.h>
11 10 #include <dm/test.h>
12 11 #include <linux/err.h>
13 12 #include <test/ut.h>
14 13  
15   -/* Test that we can find and adjust clocks */
16   -static int dm_test_clk_base(struct unit_test_state *uts)
  14 +static int dm_test_clk(struct unit_test_state *uts)
17 15 {
18   - struct udevice *clk;
  16 + struct udevice *dev_fixed, *dev_clk, *dev_test;
19 17 ulong rate;
20 18  
21   - ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk));
22   - rate = clk_get_rate(clk);
23   - ut_asserteq(SANDBOX_CLK_RATE, rate);
24   - ut_asserteq(-EINVAL, clk_set_rate(clk, 0));
25   - ut_assertok(clk_set_rate(clk, rate * 2));
26   - ut_asserteq(SANDBOX_CLK_RATE * 2, clk_get_rate(clk));
  19 + ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-fixed",
  20 + &dev_fixed));
27 21  
28   - return 0;
29   -}
30   -DM_TEST(dm_test_clk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  22 + ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-sbox",
  23 + &dev_clk));
  24 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  25 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  26 + ut_asserteq(0, sandbox_clk_query_rate(dev_clk, SANDBOX_CLK_ID_SPI));
  27 + ut_asserteq(0, sandbox_clk_query_rate(dev_clk, SANDBOX_CLK_ID_I2C));
31 28  
32   -/* Test that peripheral clocks work as expected */
33   -static int dm_test_clk_periph(struct unit_test_state *uts)
34   -{
35   - struct udevice *clk;
36   - ulong rate;
  29 + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "clk-test",
  30 + &dev_test));
  31 + ut_assertok(sandbox_clk_test_get(dev_test));
37 32  
38   - ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk));
39   - rate = clk_set_periph_rate(clk, PERIPH_ID_COUNT, 123);
40   - ut_asserteq(-EINVAL, rate);
41   - ut_asserteq(1, IS_ERR_VALUE(rate));
  33 + ut_asserteq(1234,
  34 + sandbox_clk_test_get_rate(dev_test,
  35 + SANDBOX_CLK_TEST_ID_FIXED));
  36 + ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
  37 + SANDBOX_CLK_TEST_ID_SPI));
  38 + ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
  39 + SANDBOX_CLK_TEST_ID_I2C));
42 40  
43   - rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 123);
44   - ut_asserteq(0, rate);
45   - ut_asserteq(123, clk_get_periph_rate(clk, PERIPH_ID_SPI));
  41 + rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_FIXED,
  42 + 12345);
  43 + ut_assert(IS_ERR_VALUE(rate));
  44 + rate = sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_FIXED);
  45 + ut_asserteq(1234, rate);
46 46  
47   - rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234);
48   - ut_asserteq(123, rate);
  47 + ut_asserteq(0, sandbox_clk_test_set_rate(dev_test,
  48 + SANDBOX_CLK_TEST_ID_SPI,
  49 + 1000));
  50 + ut_asserteq(0, sandbox_clk_test_set_rate(dev_test,
  51 + SANDBOX_CLK_TEST_ID_I2C,
  52 + 2000));
49 53  
50   - rate = clk_set_periph_rate(clk, PERIPH_ID_I2C, 567);
  54 + ut_asserteq(1000, sandbox_clk_test_get_rate(dev_test,
  55 + SANDBOX_CLK_TEST_ID_SPI));
  56 + ut_asserteq(2000, sandbox_clk_test_get_rate(dev_test,
  57 + SANDBOX_CLK_TEST_ID_I2C));
51 58  
52   - rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234);
53   - ut_asserteq(1234, rate);
  59 + ut_asserteq(1000, sandbox_clk_test_set_rate(dev_test,
  60 + SANDBOX_CLK_TEST_ID_SPI,
  61 + 10000));
  62 + ut_asserteq(2000, sandbox_clk_test_set_rate(dev_test,
  63 + SANDBOX_CLK_TEST_ID_I2C,
  64 + 20000));
54 65  
55   - ut_asserteq(567, clk_get_periph_rate(clk, PERIPH_ID_I2C));
  66 + rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_SPI, 0);
  67 + ut_assert(IS_ERR_VALUE(rate));
  68 + rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C, 0);
  69 + ut_assert(IS_ERR_VALUE(rate));
56 70  
  71 + ut_asserteq(10000, sandbox_clk_test_get_rate(dev_test,
  72 + SANDBOX_CLK_TEST_ID_SPI));
  73 + ut_asserteq(20000, sandbox_clk_test_get_rate(dev_test,
  74 + SANDBOX_CLK_TEST_ID_I2C));
  75 +
  76 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  77 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  78 + ut_asserteq(10000, sandbox_clk_query_rate(dev_clk, SANDBOX_CLK_ID_SPI));
  79 + ut_asserteq(20000, sandbox_clk_query_rate(dev_clk, SANDBOX_CLK_ID_I2C));
  80 +
  81 + ut_assertok(sandbox_clk_test_enable(dev_test, SANDBOX_CLK_TEST_ID_SPI));
  82 + ut_asserteq(1, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  83 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  84 +
  85 + ut_assertok(sandbox_clk_test_enable(dev_test, SANDBOX_CLK_TEST_ID_I2C));
  86 + ut_asserteq(1, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  87 + ut_asserteq(1, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  88 +
  89 + ut_assertok(sandbox_clk_test_disable(dev_test,
  90 + SANDBOX_CLK_TEST_ID_SPI));
  91 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  92 + ut_asserteq(1, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  93 +
  94 + ut_assertok(sandbox_clk_test_disable(dev_test,
  95 + SANDBOX_CLK_TEST_ID_I2C));
  96 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
  97 + ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
  98 +
  99 + ut_assertok(sandbox_clk_test_free(dev_test));
  100 +
57 101 return 0;
58 102 }
59   -DM_TEST(dm_test_clk_periph, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  103 +DM_TEST(dm_test_clk, DM_TESTF_SCAN_FDT);