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.
