1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Amarula Solutions.
4 * Author: Jagan Teki <jagan@amarulasolutions.com>
8 #include <clk-uclass.h>
14 #include <asm/arch/ccu.h>
15 #include <linux/bitops.h>
16 #include <linux/log2.h>
18 static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv,
21 return &priv->desc->gates[id];
24 static int sunxi_set_gate(struct clk *clk, bool on)
26 struct ccu_priv *priv = dev_get_priv(clk->dev);
27 const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id);
30 if (!(gate->flags & CCU_CLK_F_IS_VALID)) {
31 printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id);
35 debug("%s: (CLK#%ld) off#0x%x, BIT(%d)\n", __func__,
36 clk->id, gate->off, ilog2(gate->bit));
38 reg = readl(priv->base + gate->off);
44 writel(reg, priv->base + gate->off);
49 static int sunxi_clk_enable(struct clk *clk)
51 return sunxi_set_gate(clk, true);
54 static int sunxi_clk_disable(struct clk *clk)
56 return sunxi_set_gate(clk, false);
59 struct clk_ops sunxi_clk_ops = {
60 .enable = sunxi_clk_enable,
61 .disable = sunxi_clk_disable,
64 int sunxi_clk_probe(struct udevice *dev)
66 struct ccu_priv *priv = dev_get_priv(dev);
67 struct clk_bulk clk_bulk;
68 struct reset_ctl_bulk rst_bulk;
71 priv->base = dev_read_addr_ptr(dev);
75 priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
79 ret = clk_get_bulk(dev, &clk_bulk);
81 clk_enable_bulk(&clk_bulk);
83 ret = reset_get_bulk(dev, &rst_bulk);
85 reset_deassert_bulk(&rst_bulk);