Message ID | 5d62b31309e6402bd9fa608730518b39af823fb3.1561707104.git.leonard.crestez@nxp.com (mailing list archive) |
---|---|
State | RFC |
Headers | show |
Series | Add imx8mm bus frequency switching | expand |
On 19-06-28 10:39:50, Leonard Crestez wrote: > This allows consumers to use min_rate max_rate. > > Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> > --- > drivers/clk/imx/clk-composite-8m.c | 34 +++++++++++++++++++----------- > 1 file changed, 22 insertions(+), 12 deletions(-) > > diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c > index 388bdb94f841..1be82ec08ecd 100644 > --- a/drivers/clk/imx/clk-composite-8m.c > +++ b/drivers/clk/imx/clk-composite-8m.c > @@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw, > divider->flags, PCG_DIV_WIDTH); > } > > static int imx8m_clk_composite_compute_dividers(unsigned long rate, > unsigned long parent_rate, > + unsigned long min_rate, > + unsigned long max_rate, You should pass on the req instead of min_rate and max_rate here. > int *prediv, int *postdiv) > { > int div1, div2; > int error = INT_MAX; > int ret = -EINVAL; > @@ -56,11 +58,17 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, > *prediv = 1; > *postdiv = 1; > > for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) { > for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) { > - int new_error = ((parent_rate / div1) / div2) - rate; > + unsigned long new_rate; > + int new_error; > + > + new_rate = ((parent_rate / div1) / div2); > + if (new_rate < min_rate || new_rate > max_rate) > + continue; > + new_error = new_rate - rate; > > if (abs(new_error) < abs(error)) { > *prediv = div1; > *postdiv = div2; > error = new_error; > @@ -69,38 +77,40 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, > } > } > return ret; > } > > -static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw, > - unsigned long rate, > - unsigned long *prate) > +static int imx8m_clk_composite_divider_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req) > { > int prediv_value; > int div_value; > > - imx8m_clk_composite_compute_dividers(rate, *prate, > - &prediv_value, &div_value); > - rate = DIV_ROUND_UP(*prate, prediv_value); > + imx8m_clk_composite_compute_dividers(req->rate, req->best_parent_rate, > + req->min_rate, req->max_rate, > + &prediv_value, &div_value); > > - return DIV_ROUND_UP(rate, div_value); > + req->rate = DIV_ROUND_UP(req->best_parent_rate, prediv_value); > + req->rate = DIV_ROUND_UP(req->rate, div_value); > > + return 0; > } > > static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, > - unsigned long rate, > - unsigned long parent_rate) > + unsigned long rate, > + unsigned long parent_rate) > { > struct clk_divider *divider = to_clk_divider(hw); > unsigned long flags = 0; > int prediv_value; > int div_value; > int ret; > u32 val; > > ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, > - &prediv_value, &div_value); > + 0, ULONG_MAX, > + &prediv_value, &div_value); > if (ret) > return -EINVAL; > > spin_lock_irqsave(divider->lock, flags); > > @@ -117,11 +127,11 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, > return ret; > } > > static const struct clk_ops imx8m_clk_composite_divider_ops = { > .recalc_rate = imx8m_clk_composite_divider_recalc_rate, > - .round_rate = imx8m_clk_composite_divider_round_rate, > + .determine_rate = imx8m_clk_composite_divider_determine_rate, > .set_rate = imx8m_clk_composite_divider_set_rate, > }; > > struct clk *imx8m_clk_composite_flags(const char *name, > const char * const *parent_names, > -- > 2.17.1 >
On 28.06.2019 11:45, Abel Vesa wrote: > On 19-06-28 10:39:50, Leonard Crestez wrote: >> This allows consumers to use min_rate max_rate. >> >> @@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw, >> divider->flags, PCG_DIV_WIDTH); >> } >> >> static int imx8m_clk_composite_compute_dividers(unsigned long rate, >> unsigned long parent_rate, >> + unsigned long min_rate, >> + unsigned long max_rate, > > You should pass on the req instead of min_rate and max_rate here. Then I'd have to switch imx8m_clk_composite_divider_set_rate to allocate a dummy struct clk_rate_request on the stack. It's clearer if I just pass the minimum parameters required. -- Regards, Leonard
On 19-06-28 08:56:35, Leonard Crestez wrote: > On 28.06.2019 11:45, Abel Vesa wrote: > > On 19-06-28 10:39:50, Leonard Crestez wrote: > > >> This allows consumers to use min_rate max_rate. > >> > >> @@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw, > >> divider->flags, PCG_DIV_WIDTH); > >> } > >> > >> static int imx8m_clk_composite_compute_dividers(unsigned long rate, > >> unsigned long parent_rate, > >> + unsigned long min_rate, > >> + unsigned long max_rate, > > > > You should pass on the req instead of min_rate and max_rate here. > > Then I'd have to switch imx8m_clk_composite_divider_set_rate to allocate > a dummy struct clk_rate_request on the stack. It's clearer if I just > pass the minimum parameters required. > That is correct. Nevermind my earlier comment then. > -- > Regards, > Leonard >
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 388bdb94f841..1be82ec08ecd 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw, divider->flags, PCG_DIV_WIDTH); } static int imx8m_clk_composite_compute_dividers(unsigned long rate, unsigned long parent_rate, + unsigned long min_rate, + unsigned long max_rate, int *prediv, int *postdiv) { int div1, div2; int error = INT_MAX; int ret = -EINVAL; @@ -56,11 +58,17 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, *prediv = 1; *postdiv = 1; for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) { for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) { - int new_error = ((parent_rate / div1) / div2) - rate; + unsigned long new_rate; + int new_error; + + new_rate = ((parent_rate / div1) / div2); + if (new_rate < min_rate || new_rate > max_rate) + continue; + new_error = new_rate - rate; if (abs(new_error) < abs(error)) { *prediv = div1; *postdiv = div2; error = new_error; @@ -69,38 +77,40 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, } } return ret; } -static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int imx8m_clk_composite_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int prediv_value; int div_value; - imx8m_clk_composite_compute_dividers(rate, *prate, - &prediv_value, &div_value); - rate = DIV_ROUND_UP(*prate, prediv_value); + imx8m_clk_composite_compute_dividers(req->rate, req->best_parent_rate, + req->min_rate, req->max_rate, + &prediv_value, &div_value); - return DIV_ROUND_UP(rate, div_value); + req->rate = DIV_ROUND_UP(req->best_parent_rate, prediv_value); + req->rate = DIV_ROUND_UP(req->rate, div_value); + return 0; } static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long parent_rate) + unsigned long rate, + unsigned long parent_rate) { struct clk_divider *divider = to_clk_divider(hw); unsigned long flags = 0; int prediv_value; int div_value; int ret; u32 val; ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, - &prediv_value, &div_value); + 0, ULONG_MAX, + &prediv_value, &div_value); if (ret) return -EINVAL; spin_lock_irqsave(divider->lock, flags); @@ -117,11 +127,11 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, return ret; } static const struct clk_ops imx8m_clk_composite_divider_ops = { .recalc_rate = imx8m_clk_composite_divider_recalc_rate, - .round_rate = imx8m_clk_composite_divider_round_rate, + .determine_rate = imx8m_clk_composite_divider_determine_rate, .set_rate = imx8m_clk_composite_divider_set_rate, }; struct clk *imx8m_clk_composite_flags(const char *name, const char * const *parent_names,
This allows consumers to use min_rate max_rate. Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> --- drivers/clk/imx/clk-composite-8m.c | 34 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-)