@@ -165,6 +165,7 @@ struct cpg_z_clk {
165
165
struct clk_hw hw ;
166
166
void __iomem * reg ;
167
167
void __iomem * kick_reg ;
168
+ unsigned long max_rate ; /* Maximum rate for normal mode */
168
169
unsigned int fixed_div ;
169
170
u32 mask ;
170
171
};
@@ -190,15 +191,26 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw,
190
191
{
191
192
struct cpg_z_clk * zclk = to_z_clk (hw );
192
193
unsigned int min_mult , max_mult , mult ;
193
- unsigned long prate ;
194
+ unsigned long rate , prate ;
195
+
196
+ rate = min (req -> rate , req -> max_rate );
197
+ if (rate <= zclk -> max_rate ) {
198
+ /* Set parent rate to initial value for normal modes */
199
+ prate = zclk -> max_rate ;
200
+ } else {
201
+ /* Set increased parent rate for boost modes */
202
+ prate = rate ;
203
+ }
204
+ req -> best_parent_rate = clk_hw_round_rate (clk_hw_get_parent (hw ),
205
+ prate * zclk -> fixed_div );
194
206
195
207
prate = req -> best_parent_rate / zclk -> fixed_div ;
196
208
min_mult = max (div64_ul (req -> min_rate * 32ULL , prate ), 1ULL );
197
209
max_mult = min (div64_ul (req -> max_rate * 32ULL , prate ), 32ULL );
198
210
if (max_mult < min_mult )
199
211
return - EINVAL ;
200
212
201
- mult = DIV_ROUND_CLOSEST_ULL (req -> rate * 32ULL , prate );
213
+ mult = DIV_ROUND_CLOSEST_ULL (rate * 32ULL , prate );
202
214
mult = clamp (mult , min_mult , max_mult );
203
215
204
216
req -> rate = DIV_ROUND_CLOSEST_ULL ((u64 )prate * mult , 32 );
@@ -268,7 +280,7 @@ static struct clk * __init cpg_z_clk_register(const char *name,
268
280
269
281
init .name = name ;
270
282
init .ops = & cpg_z_clk_ops ;
271
- init .flags = 0 ;
283
+ init .flags = CLK_SET_RATE_PARENT ;
272
284
init .parent_names = & parent_name ;
273
285
init .num_parents = 1 ;
274
286
@@ -279,9 +291,13 @@ static struct clk * __init cpg_z_clk_register(const char *name,
279
291
zclk -> fixed_div = div ; /* PLLVCO x 1/div x SYS-CPU divider */
280
292
281
293
clk = clk_register (NULL , & zclk -> hw );
282
- if (IS_ERR (clk ))
294
+ if (IS_ERR (clk )) {
283
295
kfree (zclk );
296
+ return clk ;
297
+ }
284
298
299
+ zclk -> max_rate = clk_hw_get_rate (clk_hw_get_parent (& zclk -> hw )) /
300
+ zclk -> fixed_div ;
285
301
return clk ;
286
302
}
287
303
0 commit comments