Hello Maxime,

On 2 May 2016 19:13, "Maxime Ripard" <[email protected]>
wrote:
>
> Hi,
>
> On Wed, Apr 20, 2016 at 12:47:46AM +0800, Vishnu Patekar wrote:
> > For A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.
> > To handle this, this patch adds predivider table with parent index,
> > prediv shift and width, parents with predivider will have nonzero width.
> >
> > Rate adjustment is moved from clock specific recalc function to generic
> > factors recalc. Also, adds prediv table for a31.
> >
> > Signed-off-by: Vishnu Patekar <[email protected]>
> > ---
> >  drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
> >  drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
> >  drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
> >  3 files changed, 33 insertions(+), 39 deletions(-)
> >
> > diff --git a/drivers/clk/sunxi/clk-factors.c
b/drivers/clk/sunxi/clk-factors.c
> > index ddefe96..8f3b637 100644
> > --- a/drivers/clk/sunxi/clk-factors.c
> > +++ b/drivers/clk/sunxi/clk-factors.c
> > @@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct
clk_hw *hw,
> >                                            unsigned long parent_rate)
> >  {
> >       u8 n = 1, k = 0, p = 0, m = 0;
> > +     u8 par_index = 0;
> >       u32 reg;
> >       unsigned long rate;
> >       struct clk_factors *factors = to_clk_factors(hw);
> >       const struct clk_factors_config *config = factors->config;
> > +     const struct clk_factors_prediv *prediv = factors->prediv_config;
> >
> >       /* Fetch the register value */
> >       reg = readl(factors->reg);
> > @@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct
clk_hw *hw,
> >       if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
> >               p = FACTOR_GET(config->pshift, config->pwidth, reg);
> >
> > -     if (factors->recalc) {
> > -             struct factors_request factors_req = {
> > -                     .parent_rate = parent_rate,
> > -                     .n = n,
> > -                     .k = k,
> > -                     .m = m,
> > -                     .p = p,
> > -             };
> > -
> > +     if (prediv) {
> >               /* get mux details from mux clk structure */
> >               if (factors->mux)
> > -                     factors_req.parent_index =
> > -                             (reg >> factors->mux->shift) &
> > -                             factors->mux->mask;
> > -
> > -             factors->recalc(&factors_req);
> > +                     par_index = (reg >> factors->mux->shift) &
> > +                                     factors->mux->mask;
> >
> > -             return factors_req.rate;
> > +             if (prediv[par_index].width !=
SUNXI_FACTORS_NOT_APPLICABLE) {
> > +                     m = FACTOR_GET(prediv[par_index].shift,
> > +                             prediv[par_index].width, reg);
> > +             }
> >       }
> >
> >       /* Calculate the rate */
> > @@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw
*hw,
> >       for (i = 0; i < num_parents; i++) {
> >               struct factors_request factors_req = {
> >                       .rate = req->rate,
> > -                     .parent_index = i,
> >               };
> > +
> > +             if (factors->prediv_config)
> > +                     factors_req.prediv_width =
> > +
 factors->prediv_config[i].width;
> > +
> >               parent = clk_hw_get_parent_by_index(hw, i);
> >               if (!parent)
> >                       continue;
> > @@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct
device_node *node,
> >       /* set up factors properties */
> >       factors->reg = reg;
> >       factors->config = data->table;
> > +     factors->prediv_config = data->prediv_table;
> >       factors->get_factors = data->getter;
> >       factors->recalc = data->recalc;
> >       factors->lock = lock;
> > diff --git a/drivers/clk/sunxi/clk-factors.h
b/drivers/clk/sunxi/clk-factors.h
> > index 1e63c5b..b1b7745 100644
> > --- a/drivers/clk/sunxi/clk-factors.h
> > +++ b/drivers/clk/sunxi/clk-factors.h
> > @@ -18,10 +18,16 @@ struct clk_factors_config {
> >       u8 n_start;
> >  };
> >
> > +struct clk_factors_prediv {
> > +     u8 parent_index;
> > +     u8 shift;
> > +     u8 width;
> > +};
> > +
> >  struct factors_request {
> >       unsigned long rate;
> >       unsigned long parent_rate;
> > -     u8 parent_index;
> > +     u8 prediv_width;
> >       u8 n;
> >       u8 k;
> >       u8 m;
> > @@ -33,6 +39,7 @@ struct factors_data {
> >       int mux;
> >       int muxmask;
> >       const struct clk_factors_config *table;
> > +     const struct clk_factors_prediv *prediv_table;
> >       void (*getter)(struct factors_request *req);
> >       void (*recalc)(struct factors_request *req);
> >       const char *name;
> > @@ -42,6 +49,7 @@ struct clk_factors {
> >       struct clk_hw hw;
> >       void __iomem *reg;
> >       const struct clk_factors_config *config;
> > +     const struct clk_factors_prediv *prediv_config;
> >       void (*get_factors)(struct factors_request *req);
> >       void (*recalc)(struct factors_request *req);
> >       spinlock_t *lock;
> > diff --git a/drivers/clk/sunxi/clk-sunxi.c
b/drivers/clk/sunxi/clk-sunxi.c
> > index 91de0a0..5a5f26b 100644
> > --- a/drivers/clk/sunxi/clk-sunxi.c
> > +++ b/drivers/clk/sunxi/clk-sunxi.c
> > @@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct
factors_request *req)
> >       req->p = div;
> >  }
> >
> > -#define SUN6I_AHB1_PARENT_PLL6       3
> > -
> >  /**
> >   * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
> >   * AHB rate is calculated as follows
> > @@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct
factors_request *req)
> >       div = DIV_ROUND_UP(req->parent_rate, req->rate);
> >
> >       /* calculate pre-divider if parent is pll6 */
> > -     if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
> > +     if (req->prediv_width) {
> >               if (div < 4)
> >                       calcp = 0;
> >               else if (div / 2 < 4)
>
> You should also remove that code from that function. Now that the core
> can tell the pre-divider configuration, it can adjust the parent rate
> so that you don't have to care anymore.
We still need to get m factor when it's called from set_rate and
determine_rate.

Sorry, I did not your "that code from that function" meaning. I assumed
you're talking about m factor in sun6i_get_ahb1_factors.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to