blob: 6ccf52127b027a4087d5a4f1076928888c62f468 [file] [log] [blame]
Vyacheslav Bocharovdbd22182022-04-24 11:21:54 +03001// SPDX-License-Identifier: GPL-2.0+
2
Vyacheslav Bocharovdbd22182022-04-24 11:21:54 +03003#include <log.h>
4#include <asm/io.h>
5#include <clk-uclass.h>
6#include <dm.h>
7#include <regmap.h>
8#include <syscon.h>
9#include <dt-bindings/clock/axg-aoclkc.h>
10
11#include "clk_meson.h"
12
13struct meson_clk {
14 struct regmap *map;
15};
16
17#define AO_CLK_GATE0 0x40
18#define AO_SAR_CLK 0x90
19
20static struct meson_gate gates[] = {
21 MESON_GATE(CLKID_AO_SAR_ADC, AO_CLK_GATE0, 7),
22 MESON_GATE(CLKID_AO_SAR_ADC_CLK, AO_SAR_CLK, 7),
23};
24
25static int meson_set_gate(struct clk *clk, bool on)
26{
27 struct meson_clk *priv = dev_get_priv(clk->dev);
28 struct meson_gate *gate;
29
30 gate = &gates[clk->id];
31
32 regmap_update_bits(priv->map, gate->reg,
33 BIT(gate->bit), on ? BIT(gate->bit) : 0);
34
35 return 0;
36}
37
38static int meson_clk_enable(struct clk *clk)
39{
40 return meson_set_gate(clk, true);
41}
42
43static int meson_clk_disable(struct clk *clk)
44{
45 return meson_set_gate(clk, false);
46}
47
48static int meson_clk_probe(struct udevice *dev)
49{
50 struct meson_clk *priv = dev_get_priv(dev);
51
52 priv->map = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev)));
53 if (IS_ERR(priv->map))
54 return PTR_ERR(priv->map);
55
56 return 0;
57}
58
59static int meson_clk_request(struct clk *clk)
60{
61 if (clk->id >= ARRAY_SIZE(gates))
62 return -ENOENT;
63
64 return 0;
65}
66
67static struct clk_ops meson_clk_ops = {
68 .disable = meson_clk_disable,
69 .enable = meson_clk_enable,
70 .request = meson_clk_request,
71};
72
73static const struct udevice_id meson_clk_ids[] = {
74 { .compatible = "amlogic,meson-axg-aoclkc" },
75 { }
76};
77
78U_BOOT_DRIVER(meson_clk_axg_ao) = {
79 .name = "meson_clk_axg_ao",
80 .id = UCLASS_CLK,
81 .of_match = meson_clk_ids,
82 .priv_auto = sizeof(struct meson_clk),
83 .ops = &meson_clk_ops,
84 .probe = meson_clk_probe,
85};