This patch modifies the meson clock driver to use syscon/regmap like
the Linux kernel does, as it is needed if we want to share the same
DTS files.
Compatibility is kept with the old behaviour, if needed.

Signed-off-by: Loic Devulder <ldevul...@suse.de>
---
 drivers/clk/clk_meson.c | 49 +++++++++++++++++++++++++++----------------------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/clk_meson.c b/drivers/clk/clk_meson.c
index 236d7342b7..1cb3fde844 100644
--- a/drivers/clk/clk_meson.c
+++ b/drivers/clk/clk_meson.c
@@ -12,6 +12,9 @@
 #include <div64.h>
 #include <dm.h>
 #include <dt-bindings/clock/gxbb-clkc.h>
+#include <regmap.h>
+#include <syscon.h>
+
 #include "clk_meson.h"
 
 /* This driver support only basic clock tree operations :
@@ -65,7 +68,7 @@
 #define XTAL_RATE 24000000
 
 struct meson_clk {
-       void __iomem *addr;
+       struct regmap *regmap;
 };
 
 static ulong meson_div_get_rate(struct clk *clk, unsigned long id);
@@ -217,7 +220,7 @@ static int meson_set_gate_by_id(struct clk *clk, unsigned 
long id, bool on)
 
        debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id);
 
-       clrsetbits_le32(priv->addr + gate->reg,
+       clrsetbits_le32(priv->regmap->ranges[0].start + gate->reg,
                        BIT(gate->bit), on ? BIT(gate->bit) : 0);
 
        /* Propagate to next gate(s) */
@@ -292,7 +295,7 @@ static ulong meson_div_get_rate(struct clk *clk, unsigned 
long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + parm->reg_off);
+       regmap_read(priv->regmap, parm->reg_off, &reg);
        reg = PARM_GET(parm->width, parm->shift, reg);
 
        debug("%s: div of %ld is %d\n", __func__, id, reg + 1);
@@ -318,7 +321,6 @@ static ulong meson_div_set_rate(struct clk *clk, unsigned 
long id, ulong rate,
        unsigned long parent_rate;
        struct parm *parm;
        int parent;
-       u32 reg;
        int ret;
 
        if (current_rate == rate)
@@ -383,9 +385,8 @@ static ulong meson_div_set_rate(struct clk *clk, unsigned 
long id, ulong rate,
 
        debug("%s: setting div of %ld to %d\n", __func__, id, new_div);
 
-       reg = readl(priv->addr + parm->reg_off);
-       writel(PARM_SET(parm->width, parm->shift, reg, new_div - 1),
-              priv->addr + parm->reg_off);
+       regmap_update_bits(priv->regmap, parm->reg_off, SETPMASK(parm->width, 
parm->shift),
+                          (new_div - 1) << parm->shift);
 
        debug("%s: new rate of %ld is %ld\n",
              __func__, id, meson_div_get_rate(clk, id));
@@ -477,7 +478,7 @@ static ulong meson_mux_get_parent(struct clk *clk, unsigned 
long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + parm->reg_off);
+       regmap_read(priv->regmap, parm->reg_off, &reg);
        reg = PARM_GET(parm->width, parm->shift, reg);
 
        debug("%s: parent of %ld is %d (%d)\n",
@@ -494,7 +495,6 @@ static ulong meson_mux_set_parent(struct clk *clk, unsigned 
long id,
        unsigned int new_index = -EINVAL;
        struct parm *parm;
        int *parents;
-       u32 reg;
        int i;
 
        if (IS_ERR_VALUE(cur_parent))
@@ -546,9 +546,8 @@ static ulong meson_mux_set_parent(struct clk *clk, unsigned 
long id,
 
        debug("%s: new index of %ld is %d\n", __func__, id, new_index);
 
-       reg = readl(priv->addr + parm->reg_off);
-       writel(PARM_SET(parm->width, parm->shift, reg, new_index),
-              priv->addr + parm->reg_off);
+       regmap_update_bits(priv->regmap, parm->reg_off, SETPMASK(parm->width, 
parm->shift),
+                          new_index << parm->shift);
 
        debug("%s: new parent of %ld is %ld\n",
              __func__, id, meson_mux_get_parent(clk, id));
@@ -583,7 +582,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk)
        };
 
        /* mux */
-       reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+       regmap_read(priv->regmap, HHI_MPEG_CLK_CNTL, &reg);
        reg = (reg >> 12) & 7;
 
        switch (reg) {
@@ -597,7 +596,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk)
        }
 
        /* divider */
-       reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+       regmap_read(priv->regmap, HHI_MPEG_CLK_CNTL, &reg);
        reg = reg & ((1 << 7) - 1);
 
        return parent_rate / reg;
@@ -640,8 +639,9 @@ static ulong meson_mpll_get_rate(struct clk *clk, unsigned 
long id)
 {
        struct meson_clk *priv = dev_get_priv(clk->dev);
        struct parm *psdm, *pn2;
-       unsigned long reg, sdm, n2;
+       unsigned long sdm, n2;
        unsigned long parent_rate;
+       u32 reg;
 
        switch (id) {
        case CLKID_MPLL0:
@@ -664,10 +664,10 @@ static ulong meson_mpll_get_rate(struct clk *clk, 
unsigned long id)
        if (IS_ERR_VALUE(parent_rate))
                return parent_rate;
 
-       reg = readl(priv->addr + psdm->reg_off);
+       regmap_read(priv->regmap, psdm->reg_off, &reg);
        sdm = PARM_GET(psdm->width, psdm->shift, reg);
 
-       reg = readl(priv->addr + pn2->reg_off);
+       regmap_read(priv->regmap, pn2->reg_off, &reg);
        n2 = PARM_GET(pn2->width, pn2->shift, reg);
 
        return mpll_rate_from_params(parent_rate, sdm, n2);
@@ -708,13 +708,13 @@ static ulong meson_pll_get_rate(struct clk *clk, unsigned 
long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + pn->reg_off);
+       regmap_read(priv->regmap, pn->reg_off, &reg);
        n = PARM_GET(pn->width, pn->shift, reg);
 
-       reg = readl(priv->addr + pm->reg_off);
+       regmap_read(priv->regmap, pm->reg_off, &reg);
        m = PARM_GET(pm->width, pm->shift, reg);
 
-       reg = readl(priv->addr + pod->reg_off);
+       regmap_read(priv->regmap, pod->reg_off, &reg);
        od = PARM_GET(pod->width, pod->shift, reg);
 
        return ((parent_rate_mhz * m / n) >> od) * 1000000;
@@ -885,9 +885,14 @@ static int meson_clk_probe(struct udevice *dev)
 {
        struct meson_clk *priv = dev_get_priv(dev);
 
-       priv->addr = dev_read_addr_ptr(dev);
+       priv->regmap = syscon_node_to_regmap(dev_get_parent(dev)->node);
+       if (IS_ERR(priv->regmap)) {
+               debug("failed to get regmap from parent, trying regs");
 
-       debug("meson-clk: probed at addr %p\n", priv->addr);
+               regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+               if (IS_ERR(priv->regmap))
+                       return PTR_ERR(priv->regmap);
+       }
 
        return 0;
 }
-- 
2.16.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to