On 21-09-14 14:52:02, Jacky Bai wrote: > On i.MX8ULP, some peripherals have a sw_rst control resides > in the per device PCC clock control register, all others are > same as i.MX7ULP, so update the 7ulp clock composite driver to > support i.MX8ULP to maxmimize the code reuse. > > Signed-off-by: Peng Fan <peng.fan@xxxxxxx> > Signed-off-by: Jacky Bai <ping.bai@xxxxxxx> Reviewed-by: Abel Vesa <abel.vesa@xxxxxxx> > --- > v3 changs: no > --- > drivers/clk/imx/clk-composite-7ulp.c | 61 ++++++++++++++++++++++++++-- > drivers/clk/imx/clk.h | 6 +++ > 2 files changed, 64 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c > index d85ba78abbb1..50ed383320bf 100644 > --- a/drivers/clk/imx/clk-composite-7ulp.c > +++ b/drivers/clk/imx/clk-composite-7ulp.c > @@ -23,11 +23,50 @@ > #define PCG_PCD_WIDTH 3 > #define PCG_PCD_MASK 0x7 > > -struct clk_hw *imx7ulp_clk_hw_composite(const char *name, > +#define SW_RST BIT(28) > + > +static int pcc_gate_enable(struct clk_hw *hw) > +{ > + struct clk_gate *gate = to_clk_gate(hw); > + u32 val; > + int ret; > + > + ret = clk_gate_ops.enable(hw); > + if (ret) > + return ret; > + > + /* > + * release the sw reset for peripherals associated with > + * with this pcc clock. > + */ > + val = readl(gate->reg); > + val |= SW_RST; > + writel(val, gate->reg); > + > + return 0; > +} > + > +static void pcc_gate_disable(struct clk_hw *hw) > +{ > + clk_gate_ops.disable(hw); > +} > + > +static int pcc_gate_is_enabled(struct clk_hw *hw) > +{ > + return clk_gate_ops.is_enabled(hw); > +} > + > +static const struct clk_ops pcc_gate_ops = { > + .enable = pcc_gate_enable, > + .disable = pcc_gate_disable, > + .is_enabled = pcc_gate_is_enabled, > +}; > + > +static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, > const char * const *parent_names, > int num_parents, bool mux_present, > bool rate_present, bool gate_present, > - void __iomem *reg) > + void __iomem *reg, bool has_swrst) > { > struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL; > struct clk_fractional_divider *fd = NULL; > @@ -77,7 +116,7 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name, > hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, > mux_hw, &clk_mux_ops, fd_hw, > &clk_fractional_divider_ops, gate_hw, > - &clk_gate_ops, CLK_SET_RATE_GATE | > + has_swrst ? &pcc_gate_ops : &clk_gate_ops, CLK_SET_RATE_GATE | > CLK_SET_PARENT_GATE); > if (IS_ERR(hw)) { > kfree(mux); > @@ -87,3 +126,19 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name, > > return hw; > } > + > +struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, > + int num_parents, bool mux_present, bool rate_present, > + bool gate_present, void __iomem *reg) > +{ > + return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, > + gate_present, reg, false); > +} > + > +struct clk_hw *imx8ulp_clk_hw_composite(const char *name, const char * const *parent_names, > + int num_parents, bool mux_present, bool rate_present, > + bool gate_present, void __iomem *reg, bool has_swrst) > +{ > + return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, > + gate_present, reg, has_swrst); > +} > diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h > index 3f518559b8f9..a9bcfee7a75b 100644 > --- a/drivers/clk/imx/clk.h > +++ b/drivers/clk/imx/clk.h > @@ -237,6 +237,12 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name, > bool rate_present, bool gate_present, > void __iomem *reg); > > +struct clk_hw *imx8ulp_clk_hw_composite(const char *name, > + const char * const *parent_names, > + int num_parents, bool mux_present, > + bool rate_present, bool gate_present, > + void __iomem *reg, bool has_swrst); > + > struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, > void __iomem *reg, u8 shift, u8 width, > void (*fixup)(u32 *val)); > -- > 2.26.2 >