[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
On Tue, May 31, 2016 at 10:39:05AM +0200, Jean-Francois Moine wrote: > On Mon, 30 May 2016 20:45:32 +0200 > Maxime Ripard wrote: > > > I went over all the A83T clocks, and most of them could be > > covered. The issue only lies in the PLLs and their additional 1-bit > > dividers. > > > > If we just choos to ignore (one of) them, it should be pretty trivial > > to implement with the current clock classes we have. > > Hi Maxime, > > I already did the job for all the A83T clocks. > It is not fully tested yet, but, to be sure we are on the same way, > I am sending a RFC series. Awesome, thanks! 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 linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. signature.asc Description: PGP signature
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
On Mon, 30 May 2016 20:45:32 +0200 Maxime Ripard wrote: > I went over all the A83T clocks, and most of them could be > covered. The issue only lies in the PLLs and their additional 1-bit > dividers. > > If we just choos to ignore (one of) them, it should be pretty trivial > to implement with the current clock classes we have. Hi Maxime, I already did the job for all the A83T clocks. It is not fully tested yet, but, to be sure we are on the same way, I am sending a RFC series. -- Ken ar c'hentaƱ | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/ -- 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 linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
Hi Vishnu, On Mon, May 16, 2016 at 07:28:42AM +0800, Vishnu Patekar wrote: > > > @@ -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. Sorry for the late answer. I don't know if you've seen it, but I have been working on a new clock framework. I went over all the A83T clocks, and most of them could be covered. The issue only lies in the PLLs and their additional 1-bit dividers. If we just choos to ignore (one of) them, it should be pretty trivial to implement with the current clock classes we have. There's also the current assumption that there's a single parent that has a pre-divider, but that can easily be fixed by setting up an array. 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 linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. signature.asc Description: PGP signature
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
Hello Maxime, On 2 May 2016 19:13, "Maxime Ripard" 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 > > --- > > 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_
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
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 > --- > 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..5a5
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
Hello Wens, On Mon, Apr 25, 2016 at 10:51 PM, Chen-Yu Tsai wrote: > Hi, > > On Wed, Apr 20, 2016 at 12:47 AM, 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 >> --- >> 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); > > You removed usage of this callback. Please remove it from the data structures > as well, so no one assumes it's still applica
[linux-sunxi] Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
Hi, On Wed, Apr 20, 2016 at 12:47 AM, 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 > --- > 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); You removed usage of this callback. Please remove it from the data structures as well, so no one assumes it's still applicable. > 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_