Message ID | 20200311070320.21323-9-pragnesh.patel@sifive.com |
---|---|
State | New |
Headers | show |
Series | RISC-V SiFive FU540 support SPL | expand |
On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel <pragnesh.patel at sifive.com> wrote: > > Added clock enable and disable functions in prci ops > > Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com> > --- > drivers/clk/sifive/fu540-prci.c | 75 +++++++++++++++++++++++++++++++-- > 1 file changed, 72 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c > index 8847178001..c02c0466a8 100644 > --- a/drivers/clk/sifive/fu540-prci.c > +++ b/drivers/clk/sifive/fu540-prci.c > @@ -68,6 +68,11 @@ > #define PRCI_COREPLLCFG0_LOCK_SHIFT 31 > #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) > > +/* COREPLLCFG1 */ > +#define PRCI_COREPLLCFG1_OFFSET 0x8 > +#define PRCI_COREPLLCFG1_CKE_SHIFT 31 > +#define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT) > + > /* DDRPLLCFG0 */ > #define PRCI_DDRPLLCFG0_OFFSET 0xc > #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 > @@ -87,7 +92,7 @@ > > /* DDRPLLCFG1 */ > #define PRCI_DDRPLLCFG1_OFFSET 0x10 > -#define PRCI_DDRPLLCFG1_CKE_SHIFT 24 > +#define PRCI_DDRPLLCFG1_CKE_SHIFT 31 > #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) > > /* GEMGXLPLLCFG0 */ > @@ -114,7 +119,7 @@ > > /* GEMGXLPLLCFG1 */ > #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 > -#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 > +#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31 > #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) > > /* CORECLKSEL */ > @@ -142,7 +147,7 @@ > (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) > > /* CLKMUXSTATUSREG */ > -#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c > +#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c > #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 > #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \ > (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) > @@ -170,6 +175,7 @@ struct __prci_data { > * @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 > + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address > * > * @enable_bypass and @disable_bypass are used for WRPLL instances > * that contain a separate external glitchless clock mux downstream > @@ -180,6 +186,7 @@ struct __prci_wrpll_data { > void (*enable_bypass)(struct __prci_data *pd); > void (*disable_bypass)(struct __prci_data *pd); > u8 cfg0_offs; > + u8 cfg1_offs; > }; > > struct __prci_clock; > @@ -194,6 +201,7 @@ struct __prci_clock_ops { > unsigned long *parent_rate); > unsigned long (*recalc_rate)(struct __prci_clock *pc, > unsigned long parent_rate); > + int (*enable_clk)(struct __prci_clock *pc, bool enable); > }; > > /** > @@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd, > memcpy(&pwd->c, c, sizeof(*c)); > } > > +static void __prci_wrpll_write_cfg1(struct __prci_data *pd, nits: we should also rename the existing function __prci_wrpll_write_cfg() to __prci_wrpll_write_cfg0() > + struct __prci_wrpll_data *pwd, > + u32 enable) > +{ > + __prci_writel(enable, pwd->cfg1_offs, pd); > +} > + [snip] Regards, Bin
Hi Bin, >-----Original Message----- >From: Bin Meng <bmeng.cn at gmail.com> >Sent: 13 March 2020 13:27 >To: Pragnesh Patel <pragnesh.patel at sifive.com> >Cc: U-Boot Mailing List <u-boot at lists.denx.de>; Atish Patra ><atish.patra at wdc.com>; Palmer Dabbelt <palmerdabbelt at google.com>; Paul >Walmsley <paul.walmsley at sifive.com>; Jagan Teki ><jagan at amarulasolutions.com>; Troy Benjegerdes ><troy.benjegerdes at sifive.com>; Anup Patel <anup.patel at wdc.com>; Sagar >Kadam <sagar.kadam at sifive.com>; Rick Chen <rick at andestech.com>; Lukasz >Majewski <lukma at denx.de>; Anatolij Gustschin <agust at denx.de>; Simon >Glass <sjg at chromium.org> >Subject: Re: [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and >disable ops > >On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel ><pragnesh.patel at sifive.com> wrote: >> >> Added clock enable and disable functions in prci ops >> >> Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com> >> --- >> drivers/clk/sifive/fu540-prci.c | 75 >> +++++++++++++++++++++++++++++++-- >> 1 file changed, 72 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/clk/sifive/fu540-prci.c >> b/drivers/clk/sifive/fu540-prci.c index 8847178001..c02c0466a8 100644 >> --- a/drivers/clk/sifive/fu540-prci.c >> +++ b/drivers/clk/sifive/fu540-prci.c >> @@ -68,6 +68,11 @@ >> #define PRCI_COREPLLCFG0_LOCK_SHIFT 31 >> #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << >PRCI_COREPLLCFG0_LOCK_SHIFT) >> >> +/* COREPLLCFG1 */ >> +#define PRCI_COREPLLCFG1_OFFSET 0x8 >> +#define PRCI_COREPLLCFG1_CKE_SHIFT 31 >> +#define PRCI_COREPLLCFG1_CKE_MASK (0x1 << >PRCI_COREPLLCFG1_CKE_SHIFT) >> + >> /* DDRPLLCFG0 */ >> #define PRCI_DDRPLLCFG0_OFFSET 0xc >> #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 >> @@ -87,7 +92,7 @@ >> >> /* DDRPLLCFG1 */ >> #define PRCI_DDRPLLCFG1_OFFSET 0x10 >> -#define PRCI_DDRPLLCFG1_CKE_SHIFT 24 >> +#define PRCI_DDRPLLCFG1_CKE_SHIFT 31 >> #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << >PRCI_DDRPLLCFG1_CKE_SHIFT) >> >> /* GEMGXLPLLCFG0 */ >> @@ -114,7 +119,7 @@ >> >> /* GEMGXLPLLCFG1 */ >> #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 >> -#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 >> +#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31 >> #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << >PRCI_GEMGXLPLLCFG1_CKE_SHIFT) >> >> /* CORECLKSEL */ >> @@ -142,7 +147,7 @@ >> (0x1 << >> PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) >> >> /* CLKMUXSTATUSREG */ >> -#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c >> +#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c >> #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 #define >> PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \ >> (0x1 << >> PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) >> @@ -170,6 +175,7 @@ struct __prci_data { >> * @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 >> + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI >> + base address >> * >> * @enable_bypass and @disable_bypass are used for WRPLL instances >> * that contain a separate external glitchless clock mux downstream >> @@ -180,6 +186,7 @@ struct __prci_wrpll_data { >> void (*enable_bypass)(struct __prci_data *pd); >> void (*disable_bypass)(struct __prci_data *pd); >> u8 cfg0_offs; >> + u8 cfg1_offs; >> }; >> >> struct __prci_clock; >> @@ -194,6 +201,7 @@ struct __prci_clock_ops { >> unsigned long *parent_rate); >> unsigned long (*recalc_rate)(struct __prci_clock *pc, >> unsigned long parent_rate); >> + int (*enable_clk)(struct __prci_clock *pc, bool enable); >> }; >> >> /** >> @@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct >__prci_data *pd, >> memcpy(&pwd->c, c, sizeof(*c)); } >> >> +static void __prci_wrpll_write_cfg1(struct __prci_data *pd, > >nits: we should also rename the existing function >__prci_wrpll_write_cfg() to __prci_wrpll_write_cfg0() > I think you are right. I will check and update in v6. >> + struct __prci_wrpll_data *pwd, >> + u32 enable) { >> + __prci_writel(enable, pwd->cfg1_offs, pd); } >> + > >[snip] > >Regards, >Bin
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c index 8847178001..c02c0466a8 100644 --- a/drivers/clk/sifive/fu540-prci.c +++ b/drivers/clk/sifive/fu540-prci.c @@ -68,6 +68,11 @@ #define PRCI_COREPLLCFG0_LOCK_SHIFT 31 #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) +/* COREPLLCFG1 */ +#define PRCI_COREPLLCFG1_OFFSET 0x8 +#define PRCI_COREPLLCFG1_CKE_SHIFT 31 +#define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT) + /* DDRPLLCFG0 */ #define PRCI_DDRPLLCFG0_OFFSET 0xc #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 @@ -87,7 +92,7 @@ /* DDRPLLCFG1 */ #define PRCI_DDRPLLCFG1_OFFSET 0x10 -#define PRCI_DDRPLLCFG1_CKE_SHIFT 24 +#define PRCI_DDRPLLCFG1_CKE_SHIFT 31 #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) /* GEMGXLPLLCFG0 */ @@ -114,7 +119,7 @@ /* GEMGXLPLLCFG1 */ #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 -#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 +#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31 #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) /* CORECLKSEL */ @@ -142,7 +147,7 @@ (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) /* CLKMUXSTATUSREG */ -#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c +#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \ (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) @@ -170,6 +175,7 @@ struct __prci_data { * @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 + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address * * @enable_bypass and @disable_bypass are used for WRPLL instances * that contain a separate external glitchless clock mux downstream @@ -180,6 +186,7 @@ struct __prci_wrpll_data { void (*enable_bypass)(struct __prci_data *pd); void (*disable_bypass)(struct __prci_data *pd); u8 cfg0_offs; + u8 cfg1_offs; }; struct __prci_clock; @@ -194,6 +201,7 @@ struct __prci_clock_ops { unsigned long *parent_rate); unsigned long (*recalc_rate)(struct __prci_clock *pc, unsigned long parent_rate); + int (*enable_clk)(struct __prci_clock *pc, bool enable); }; /** @@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd, memcpy(&pwd->c, c, sizeof(*c)); } +static void __prci_wrpll_write_cfg1(struct __prci_data *pd, + struct __prci_wrpll_data *pwd, + u32 enable) +{ + __prci_writel(enable, pwd->cfg1_offs, pd); +} + /* Core clock mux control */ /** @@ -447,14 +462,35 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc, return 0; } +static int sifive_fu540_prci_clock_enable(struct __prci_clock *pc, bool enable) +{ + struct __prci_wrpll_data *pwd = pc->pwd; + struct __prci_data *pd = pc->pd; + + if (enable) { + __prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK); + } else { + u32 r; + + r = __prci_readl(pd, pwd->cfg1_offs); + r &= ~PRCI_COREPLLCFG1_CKE_MASK; + + __prci_wrpll_write_cfg1(pd, pwd, r); + } + + return 0; +} + static const struct __prci_clock_ops sifive_fu540_prci_wrpll_clk_ops = { .set_rate = sifive_fu540_prci_wrpll_set_rate, .round_rate = sifive_fu540_prci_wrpll_round_rate, .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, + .enable_clk = sifive_fu540_prci_clock_enable, }; static const struct __prci_clock_ops sifive_fu540_prci_wrpll_ro_clk_ops = { .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, + .enable_clk = sifive_fu540_prci_clock_enable, }; /* TLCLKSEL clock integration */ @@ -484,16 +520,19 @@ 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, + .cfg1_offs = PRCI_COREPLLCFG1_OFFSET, .enable_bypass = __prci_coreclksel_use_hfclk, .disable_bypass = __prci_coreclksel_use_corepll, }; static struct __prci_wrpll_data __prci_ddrpll_data = { .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, + .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET, }; static struct __prci_wrpll_data __prci_gemgxlpll_data = { .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, + .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET, }; /* @@ -580,6 +619,34 @@ static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate) return rate; } +static int sifive_fu540_prci_enable(struct clk *clk) +{ + struct __prci_clock *pc; + + if (ARRAY_SIZE(__prci_init_clocks) <= clk->id) + return -ENXIO; + + pc = &__prci_init_clocks[clk->id]; + if (!pc->pd || !pc->ops->enable_clk) + return -ENXIO; + + return pc->ops->enable_clk(pc, 1); +} + +static int sifive_fu540_prci_disable(struct clk *clk) +{ + struct __prci_clock *pc; + + if (ARRAY_SIZE(__prci_init_clocks) <= clk->id) + return -ENXIO; + + pc = &__prci_init_clocks[clk->id]; + if (!pc->pd || !pc->ops->enable_clk) + return -ENXIO; + + return pc->ops->enable_clk(pc, 0); +} + static int sifive_fu540_prci_probe(struct udevice *dev) { int i, err; @@ -611,6 +678,8 @@ static int sifive_fu540_prci_probe(struct udevice *dev) static struct clk_ops sifive_fu540_prci_ops = { .set_rate = sifive_fu540_prci_set_rate, .get_rate = sifive_fu540_prci_get_rate, + .enable = sifive_fu540_prci_enable, + .disable = sifive_fu540_prci_disable, }; static const struct udevice_id sifive_fu540_prci_ids[] = {
Added clock enable and disable functions in prci ops Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com> --- drivers/clk/sifive/fu540-prci.c | 75 +++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-)