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