All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anup Patel <Anup.Patel@wdc.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 4/5] clk: sifive: Sync-up main driver with upstream Linux
Date: Wed, 19 Jun 2019 07:01:41 +0000	[thread overview]
Message-ID: <20190619070037.11730-5-anup.patel@wdc.com> (raw)
In-Reply-To: <20190619070037.11730-1-anup.patel@wdc.com>

The DT bindings of SiFive clock driver in upstream Linux has
changes. As-per latest DT bindings, the clock driver takes two
parent clocks and compatible string has also changed.

This patch sync-up SiFive clock driver implementation as-per
upstream Linux so that we now use latest DT bindings.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
---
 drivers/clk/sifive/fu540-prci.c | 96 ++++++++++++++++++++-------------
 1 file changed, 60 insertions(+), 36 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index ceb318e062..ce0769f2d1 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -158,30 +158,32 @@
  * PRCI per-device instance data
  */
 struct __prci_data {
-	void *base;
-	struct clk parent;
+	void *va;
+	struct clk parent_hfclk;
+	struct clk parent_rtcclk;
 };
 
 /**
  * struct __prci_wrpll_data - WRPLL configuration and integration data
  * @c: WRPLL current configuration record
- * @bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
- * @no_bypass: fn ptr to code to not bypass the WRPLL (if applicable; else NULL)
+ * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
+ * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
  * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
  *
- * @bypass and @no_bypass are used for WRPLL instances that contain a separate
- * external glitchless clock mux downstream from the PLL.  The WRPLL internal
- * bypass mux is not glitchless.
+ * @enable_bypass and @disable_bypass are used for WRPLL instances
+ * that contain a separate external glitchless clock mux downstream
+ * from the PLL.  The WRPLL internal bypass mux is not glitchless.
  */
 struct __prci_wrpll_data {
 	struct wrpll_cfg c;
-	void (*bypass)(struct __prci_data *pd);
-	void (*no_bypass)(struct __prci_data *pd);
+	void (*enable_bypass)(struct __prci_data *pd);
+	void (*disable_bypass)(struct __prci_data *pd);
 	u8 cfg0_offs;
 };
 
 struct __prci_clock;
 
+/* struct __prci_clock_ops - clock operations */
 struct __prci_clock_ops {
 	int (*set_rate)(struct __prci_clock *pc,
 			unsigned long rate,
@@ -197,8 +199,7 @@ struct __prci_clock_ops {
  * struct __prci_clock - describes a clock device managed by PRCI
  * @name: user-readable clock name string - should match the manual
  * @parent_name: parent name for this clock
- * @ops: struct clk_ops for the Linux clock framework to use for control
- * @hw: Linux-private clock data
+ * @ops: struct __prci_clock_ops for control
  * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
  * @pd: PRCI-specific data associated with this clock (if not NULL)
  *
@@ -232,12 +233,12 @@ struct __prci_clock {
  */
 static u32 __prci_readl(struct __prci_data *pd, u32 offs)
 {
-	return readl(pd->base + offs);
+	return readl(pd->va + offs);
 }
 
 static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
 {
-	return writel(v, pd->base + offs);
+	writel(v, pd->va + offs);
 }
 
 /* WRPLL-related private functions */
@@ -279,10 +280,8 @@ static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
 	c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
 		     WRPLL_FLAGS_EXT_FEEDBACK_MASK);
 
-	if (r & PRCI_COREPLLCFG0_FSE_MASK)
-		c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
-	else
-		c->flags |= WRPLL_FLAGS_EXT_FEEDBACK_MASK;
+	/* external feedback mode not supported */
+	c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
 }
 
 /**
@@ -300,7 +299,7 @@ static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
  * Returns: a value suitable for writing into a PRCI PLL configuration
  *          register
  */
-static u32 __prci_wrpll_pack(struct wrpll_cfg *c)
+static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
 {
 	u32 r = 0;
 
@@ -308,8 +307,9 @@ static u32 __prci_wrpll_pack(struct wrpll_cfg *c)
 	r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
 	r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
 	r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
-	if (c->flags & WRPLL_FLAGS_INT_FEEDBACK_MASK)
-		r |= PRCI_COREPLLCFG0_FSE_MASK;
+
+	/* external feedback mode not supported */
+	r |= PRCI_COREPLLCFG0_FSE_MASK;
 
 	return r;
 }
@@ -352,7 +352,7 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
 {
 	__prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
 
-	memcpy(&pwd->c, c, sizeof(struct wrpll_cfg));
+	memcpy(&pwd->c, c, sizeof(*c));
 }
 
 /* Core clock mux control */
@@ -431,17 +431,17 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
 
 	r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
 	if (r)
-		return -ERANGE;
+		return r;
 
-	if (pwd->bypass)
-		pwd->bypass(pd);
+	if (pwd->enable_bypass)
+		pwd->enable_bypass(pd);
 
 	__prci_wrpll_write_cfg(pd, pwd, &pwd->c);
 
 	udelay(wrpll_calc_max_lock_us(&pwd->c));
 
-	if (pwd->no_bypass)
-		pwd->no_bypass(pd);
+	if (pwd->disable_bypass)
+		pwd->disable_bypass(pd);
 
 	return 0;
 }
@@ -483,8 +483,8 @@ static const struct __prci_clock_ops sifive_fu540_prci_tlclksel_clk_ops = {
 
 static struct __prci_wrpll_data __prci_corepll_data = {
 	.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
-	.bypass = __prci_coreclksel_use_hfclk,
-	.no_bypass = __prci_coreclksel_use_corepll,
+	.enable_bypass = __prci_coreclksel_use_hfclk,
+	.disable_bypass = __prci_coreclksel_use_corepll,
 };
 
 static struct __prci_wrpll_data __prci_ddrpll_data = {
@@ -525,6 +525,27 @@ static struct __prci_clock __prci_init_clocks[] = {
 	},
 };
 
+static ulong sifive_fu540_prci_parent_rate(struct __prci_clock *pc)
+{
+	ulong parent_rate;
+	struct __prci_clock *p;
+
+	if (strcmp(pc->parent_name, "corepll") == 0) {
+		p = &__prci_init_clocks[PRCI_CLK_COREPLL];
+		if (!p->pd || !p->ops->recalc_rate)
+			return -ENXIO;
+
+		return p->ops->recalc_rate(p, sifive_fu540_prci_parent_rate(p));
+	}
+
+	if (strcmp(pc->parent_name, "rtcclk") == 0)
+		parent_rate = clk_get_rate(&pc->pd->parent_rtcclk);
+	else
+		parent_rate = clk_get_rate(&pc->pd->parent_hfclk);
+
+	return parent_rate;
+}
+
 static ulong sifive_fu540_prci_get_rate(struct clk *clk)
 {
 	struct __prci_clock *pc;
@@ -536,7 +557,7 @@ static ulong sifive_fu540_prci_get_rate(struct clk *clk)
 	if (!pc->pd || !pc->ops->recalc_rate)
 		return -ENXIO;
 
-	return pc->ops->recalc_rate(pc, clk_get_rate(&pc->pd->parent));
+	return pc->ops->recalc_rate(pc, sifive_fu540_prci_parent_rate(pc));
 }
 
 static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate)
@@ -551,7 +572,7 @@ static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate)
 	if (!pc->pd || !pc->ops->set_rate)
 		return -ENXIO;
 
-	err = pc->ops->set_rate(pc, rate, clk_get_rate(&pc->pd->parent));
+	err = pc->ops->set_rate(pc, rate, sifive_fu540_prci_parent_rate(pc));
 	if (err)
 		return err;
 
@@ -564,11 +585,15 @@ static int sifive_fu540_prci_probe(struct udevice *dev)
 	struct __prci_clock *pc;
 	struct __prci_data *pd = dev_get_priv(dev);
 
-	pd->base = (void *)dev_read_addr(dev);
-	if (IS_ERR(pd->base))
-		return PTR_ERR(pd->base);
+	pd->va = (void *)dev_read_addr(dev);
+	if (IS_ERR(pd->va))
+		return PTR_ERR(pd->va);
+
+	err = clk_get_by_index(dev, 0, &pd->parent_hfclk);
+	if (err)
+		return err;
 
-	err = clk_get_by_index(dev, 0, &pd->parent);
+	err = clk_get_by_index(dev, 1, &pd->parent_rtcclk);
 	if (err)
 		return err;
 
@@ -588,8 +613,7 @@ static struct clk_ops sifive_fu540_prci_ops = {
 };
 
 static const struct udevice_id sifive_fu540_prci_ids[] = {
-	{ .compatible = "sifive,fu540-c000-prci0" },
-	{ .compatible = "sifive,aloeprci0" },
+	{ .compatible = "sifive,fu540-c000-prci" },
 	{ }
 };
 
-- 
2.17.1

  parent reply	other threads:[~2019-06-19  7:01 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-19  7:01 [U-Boot] [PATCH v3 0/5] Update SiFive Unleashed Drivers Anup Patel
2019-06-19  7:01 ` [U-Boot] [PATCH v3 1/5] clk: sifive: Factor-out PLL library as separate module Anup Patel
2019-06-19  7:01 ` [U-Boot] [PATCH v3 2/5] clk: sifive: Sync-up WRPLL library with upstream Linux Anup Patel
2019-06-19  7:01 ` [U-Boot] [PATCH v3 3/5] clk: sifive: Sync-up DT bindings header " Anup Patel
2019-06-19  7:01 ` Anup Patel [this message]
2019-06-19  7:01 ` [U-Boot] [PATCH v3 5/5] clk: sifive: Drop GEMGXL clock driver Anup Patel
2019-06-19  7:03 ` [U-Boot] [PATCH v3 0/5] Update SiFive Unleashed Drivers Bin Meng
2019-06-19  8:24   ` Anup Patel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190619070037.11730-5-anup.patel@wdc.com \
    --to=anup.patel@wdc.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.