From patchwork Fri Nov 2 14:32:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Loic Devulder X-Patchwork-Id: 992342 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42ml230kZPzB4Wd for ; Sat, 3 Nov 2018 01:34:02 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 9A571C22554; Fri, 2 Nov 2018 14:33:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 90030C22567; Fri, 2 Nov 2018 14:32:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B3525C22534; Fri, 2 Nov 2018 14:32:31 +0000 (UTC) Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by lists.denx.de (Postfix) with ESMTPS id B8D94C22543 for ; Fri, 2 Nov 2018 14:32:30 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 50C1CB005 for ; Fri, 2 Nov 2018 14:32:30 +0000 (UTC) From: Loic Devulder To: u-boot@lists.denx.de Date: Fri, 2 Nov 2018 15:32:27 +0100 Message-Id: <20181102143229.28314-2-ldevulder@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181102143229.28314-1-ldevulder@suse.de> References: <20181102143229.28314-1-ldevulder@suse.de> Subject: [U-Boot] [RFC PATCH 1/3] ARM: meson: Add regmap support for clock driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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 --- 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 #include #include +#include +#include + #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 = 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 = 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 >> 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 & ((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, ®); sdm = PARM_GET(psdm->width, psdm->shift, reg); - reg = readl(priv->addr + pn2->reg_off); + regmap_read(priv->regmap, pn2->reg_off, ®); 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, ®); n = PARM_GET(pn->width, pn->shift, reg); - reg = readl(priv->addr + pm->reg_off); + regmap_read(priv->regmap, pm->reg_off, ®); m = PARM_GET(pm->width, pm->shift, reg); - reg = readl(priv->addr + pod->reg_off); + regmap_read(priv->regmap, pod->reg_off, ®); 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; }