123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- From 43295ddfa3caa2494d682962cb358e9c1177facf Mon Sep 17 00:00:00 2001
- From: Anup Patel <anup.patel@wdc.com>
- Date: Tue, 18 Jun 2019 14:20:23 +0530
- Subject: [PATCH 11/21] clk: sifive: Sync-up main driver with upstream Linux
- 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>
- Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
- Upstream-Status: Submitted
- ---
- 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.22.0
|