Message ID | 20230717-pll-mipi_set_rate_parent-v4-7-04acf1d39765@oltmanns.dev (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | clk: sunxi-ng: Consider alternative parent rates when determining NKM clock rate | expand |
On Mon, Jul 17, 2023 at 03:34:31PM +0200, Frank Oltmanns wrote: > Use the helper function ccu_is_better_rate() to determine the rate that > is closest to the requested rate, thereby supporting rates that are > higher than the requested rate if the clock uses the > CCU_FEATURE_CLOSEST_RATE. > > Add the macro SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST which > sets CCU_FEATURE_CLOSEST_RATE. > > To avoid code duplication, add the macros > SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT that allows selecting > arbitrary features and use it in the original > SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX as well as the newly introduced > SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST macros. > > Signed-off-by: Frank Oltmanns <frank@oltmanns.dev> > --- > drivers/clk/sunxi-ng/ccu_nm.c | 11 ++++------ > drivers/clk/sunxi-ng/ccu_nm.h | 48 ++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 49 insertions(+), 10 deletions(-) > > diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c > index c1fd11542c45..35d00783d748 100644 > --- a/drivers/clk/sunxi-ng/ccu_nm.c > +++ b/drivers/clk/sunxi-ng/ccu_nm.c > @@ -28,7 +28,7 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent, > } > > static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate, > - struct _ccu_nm *nm) > + struct _ccu_nm *nm, struct ccu_common *common) The common pointer must be the first argument. Once fixed, Acked-by: Maxime Ripard <mripard@kernel.org> Maxime
On 2023-07-17 at 16:12:30 +0200, Maxime Ripard <mripard@kernel.org> wrote: > [[PGP Signed Part:Undecided]] > On Mon, Jul 17, 2023 at 03:34:31PM +0200, Frank Oltmanns wrote: >> Use the helper function ccu_is_better_rate() to determine the rate that >> is closest to the requested rate, thereby supporting rates that are >> higher than the requested rate if the clock uses the >> CCU_FEATURE_CLOSEST_RATE. >> >> Add the macro SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST which >> sets CCU_FEATURE_CLOSEST_RATE. >> >> To avoid code duplication, add the macros >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT that allows selecting >> arbitrary features and use it in the original >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX as well as the newly introduced >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST macros. >> >> Signed-off-by: Frank Oltmanns <frank@oltmanns.dev> >> --- >> drivers/clk/sunxi-ng/ccu_nm.c | 11 ++++------ >> drivers/clk/sunxi-ng/ccu_nm.h | 48 ++++++++++++++++++++++++++++++++++++++++--- >> 2 files changed, 49 insertions(+), 10 deletions(-) >> >> diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c >> index c1fd11542c45..35d00783d748 100644 >> --- a/drivers/clk/sunxi-ng/ccu_nm.c >> +++ b/drivers/clk/sunxi-ng/ccu_nm.c >> @@ -28,7 +28,7 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent, >> } >> >> static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate, >> - struct _ccu_nm *nm) >> + struct _ccu_nm *nm, struct ccu_common *common) > > The common pointer must be the first argument. > Same question as for patch 08: Should I also pull *nm to the beginning? If so, do you have a preference on the order of *nm and *common? Thanks, Frank > > Once fixed, > Acked-by: Maxime Ripard <mripard@kernel.org> > > Maxime > > [[End of PGP Signed Part]]
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index c1fd11542c45..35d00783d748 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -28,7 +28,7 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent, } static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nm *nm) + struct _ccu_nm *nm, struct ccu_common *common) { unsigned long best_rate = 0; unsigned long best_n = 0, best_m = 0; @@ -39,10 +39,7 @@ static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate, unsigned long tmp_rate = ccu_nm_calc_rate(parent, _n, _m); - if (tmp_rate > rate) - continue; - - if ((rate - tmp_rate) < (rate - best_rate)) { + if (ccu_is_better_rate(common, rate, tmp_rate, best_rate)) { best_rate = tmp_rate; best_n = _n; best_m = _m; @@ -159,7 +156,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, _nm.min_m = 1; _nm.max_m = nm->m.max ?: 1 << nm->m.width; - rate = ccu_nm_find_best(*parent_rate, rate, &_nm); + rate = ccu_nm_find_best(*parent_rate, rate, &_nm, &nm->common); if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div; @@ -210,7 +207,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, &_nm.m, &_nm.n); } else { ccu_sdm_helper_disable(&nm->common, &nm->sdm); - ccu_nm_find_best(parent_rate, rate, &_nm); + ccu_nm_find_best(parent_rate, rate, &_nm, &nm->common); } spin_lock_irqsave(nm->common.lock, flags); diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h index 2904e67f05a8..93c11693574f 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.h +++ b/drivers/clk/sunxi-ng/ccu_nm.h @@ -108,7 +108,7 @@ struct ccu_nm { }, \ } -#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ _parent, _reg, \ _min_rate, _max_rate, \ _nshift, _nwidth, \ @@ -116,7 +116,8 @@ struct ccu_nm { _frac_en, _frac_sel, \ _frac_rate_0, \ _frac_rate_1, \ - _gate, _lock, _flags) \ + _gate, _lock, _flags, \ + _features) \ struct ccu_nm _struct = { \ .enable = _gate, \ .lock = _lock, \ @@ -129,7 +130,7 @@ struct ccu_nm { .max_rate = _max_rate, \ .common = { \ .reg = _reg, \ - .features = CCU_FEATURE_FRACTIONAL, \ + .features = _features, \ .hw.init = CLK_HW_INIT(_name, \ _parent, \ &ccu_nm_ops, \ @@ -137,6 +138,47 @@ struct ccu_nm { }, \ } +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ + _parent, _reg, \ + _min_rate, _max_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1, \ + _gate, _lock, _flags) \ + SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ + _parent, _reg, \ + _min_rate, _max_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1, \ + _gate, _lock, _flags, \ + CCU_FEATURE_FRACTIONAL) + +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \ + _parent, _reg, \ + _min_rate, _max_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1, \ + _gate, _lock, _flags) \ + SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ + _parent, _reg, \ + _min_rate, _max_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1, \ + _gate, _lock, _flags, \ + CCU_FEATURE_FRACTIONAL |\ + CCU_FEATURE_CLOSEST_RATE) + #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ _nshift, _nwidth, \ _mshift, _mwidth, \
Use the helper function ccu_is_better_rate() to determine the rate that is closest to the requested rate, thereby supporting rates that are higher than the requested rate if the clock uses the CCU_FEATURE_CLOSEST_RATE. Add the macro SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST which sets CCU_FEATURE_CLOSEST_RATE. To avoid code duplication, add the macros SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT that allows selecting arbitrary features and use it in the original SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX as well as the newly introduced SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST macros. Signed-off-by: Frank Oltmanns <frank@oltmanns.dev> --- drivers/clk/sunxi-ng/ccu_nm.c | 11 ++++------ drivers/clk/sunxi-ng/ccu_nm.h | 48 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 10 deletions(-)