Skip to content

Commit c0380d1

Browse files
Frank Oltmannswens
authored andcommitted
clk: sunxi-ng: nm: Support finding closest rate
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. Acked-by: Maxime Ripard <[email protected]> Reviewed-by: Jernej Skrabec <[email protected]> Signed-off-by: Frank Oltmanns <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Chen-Yu Tsai <[email protected]>
1 parent e373315 commit c0380d1

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

drivers/clk/sunxi-ng/ccu_nm.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent,
2727
return rate;
2828
}
2929

30-
static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate,
31-
struct _ccu_nm *nm)
30+
static unsigned long ccu_nm_find_best(struct ccu_common *common, unsigned long parent,
31+
unsigned long rate, struct _ccu_nm *nm)
3232
{
3333
unsigned long best_rate = 0;
3434
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,
3939
unsigned long tmp_rate = ccu_nm_calc_rate(parent,
4040
_n, _m);
4141

42-
if (tmp_rate > rate)
43-
continue;
44-
45-
if ((rate - tmp_rate) < (rate - best_rate)) {
42+
if (ccu_is_better_rate(common, rate, tmp_rate, best_rate)) {
4643
best_rate = tmp_rate;
4744
best_n = _n;
4845
best_m = _m;
@@ -159,7 +156,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
159156
_nm.min_m = 1;
160157
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
161158

162-
rate = ccu_nm_find_best(*parent_rate, rate, &_nm);
159+
rate = ccu_nm_find_best(&nm->common, *parent_rate, rate, &_nm);
163160

164161
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
165162
rate /= nm->fixed_post_div;
@@ -210,7 +207,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
210207
&_nm.m, &_nm.n);
211208
} else {
212209
ccu_sdm_helper_disable(&nm->common, &nm->sdm);
213-
ccu_nm_find_best(parent_rate, rate, &_nm);
210+
ccu_nm_find_best(&nm->common, parent_rate, rate, &_nm);
214211
}
215212

216213
spin_lock_irqsave(nm->common.lock, flags);

drivers/clk/sunxi-ng/ccu_nm.h

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,16 @@ struct ccu_nm {
108108
}, \
109109
}
110110

111-
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \
111+
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \
112112
_parent, _reg, \
113113
_min_rate, _max_rate, \
114114
_nshift, _nwidth, \
115115
_mshift, _mwidth, \
116116
_frac_en, _frac_sel, \
117117
_frac_rate_0, \
118118
_frac_rate_1, \
119-
_gate, _lock, _flags) \
119+
_gate, _lock, _flags, \
120+
_features) \
120121
struct ccu_nm _struct = { \
121122
.enable = _gate, \
122123
.lock = _lock, \
@@ -129,14 +130,55 @@ struct ccu_nm {
129130
.max_rate = _max_rate, \
130131
.common = { \
131132
.reg = _reg, \
132-
.features = CCU_FEATURE_FRACTIONAL, \
133+
.features = _features, \
133134
.hw.init = CLK_HW_INIT(_name, \
134135
_parent, \
135136
&ccu_nm_ops, \
136137
_flags), \
137138
}, \
138139
}
139140

141+
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \
142+
_parent, _reg, \
143+
_min_rate, _max_rate, \
144+
_nshift, _nwidth, \
145+
_mshift, _mwidth, \
146+
_frac_en, _frac_sel, \
147+
_frac_rate_0, \
148+
_frac_rate_1, \
149+
_gate, _lock, _flags) \
150+
SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \
151+
_parent, _reg, \
152+
_min_rate, _max_rate, \
153+
_nshift, _nwidth, \
154+
_mshift, _mwidth, \
155+
_frac_en, _frac_sel, \
156+
_frac_rate_0, \
157+
_frac_rate_1, \
158+
_gate, _lock, _flags, \
159+
CCU_FEATURE_FRACTIONAL)
160+
161+
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \
162+
_parent, _reg, \
163+
_min_rate, _max_rate, \
164+
_nshift, _nwidth, \
165+
_mshift, _mwidth, \
166+
_frac_en, _frac_sel, \
167+
_frac_rate_0, \
168+
_frac_rate_1, \
169+
_gate, _lock, _flags) \
170+
SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \
171+
_parent, _reg, \
172+
_min_rate, _max_rate, \
173+
_nshift, _nwidth, \
174+
_mshift, _mwidth, \
175+
_frac_en, _frac_sel, \
176+
_frac_rate_0, \
177+
_frac_rate_1, \
178+
_gate, _lock, _flags, \
179+
CCU_FEATURE_FRACTIONAL |\
180+
CCU_FEATURE_CLOSEST_RATE)
181+
140182
#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
141183
_nshift, _nwidth, \
142184
_mshift, _mwidth, \

0 commit comments

Comments
 (0)