26
26
#undef pr_fmt
27
27
#define pr_fmt (fmt ) "%s: " fmt, __func__
28
28
29
- #define div_mask (d ) ((1 << ((d)->width)) - 1)
30
-
31
- static unsigned int _get_table_maxdiv (const struct clk_div_table * table )
32
- {
33
- unsigned int maxdiv = 0 ;
34
- const struct clk_div_table * clkt ;
35
-
36
- for (clkt = table ; clkt -> div ; clkt ++ )
37
- if (clkt -> div > maxdiv )
38
- maxdiv = clkt -> div ;
39
- return maxdiv ;
40
- }
41
-
42
- static unsigned int _get_maxdiv (struct clk_omap_divider * divider )
43
- {
44
- if (divider -> flags & CLK_DIVIDER_ONE_BASED )
45
- return div_mask (divider );
46
- if (divider -> flags & CLK_DIVIDER_POWER_OF_TWO )
47
- return 1 << div_mask (divider );
48
- if (divider -> table )
49
- return _get_table_maxdiv (divider -> table );
50
- return div_mask (divider ) + 1 ;
51
- }
52
-
53
29
static unsigned int _get_table_div (const struct clk_div_table * table ,
54
30
unsigned int val )
55
31
{
@@ -61,6 +37,34 @@ static unsigned int _get_table_div(const struct clk_div_table *table,
61
37
return 0 ;
62
38
}
63
39
40
+ static void _setup_mask (struct clk_omap_divider * divider )
41
+ {
42
+ u16 mask ;
43
+ u32 max_val ;
44
+ const struct clk_div_table * clkt ;
45
+
46
+ if (divider -> table ) {
47
+ max_val = 0 ;
48
+
49
+ for (clkt = divider -> table ; clkt -> div ; clkt ++ )
50
+ if (clkt -> val > max_val )
51
+ max_val = clkt -> val ;
52
+ } else {
53
+ max_val = divider -> max ;
54
+
55
+ if (!(divider -> flags & CLK_DIVIDER_ONE_BASED ) &&
56
+ !(divider -> flags & CLK_DIVIDER_POWER_OF_TWO ))
57
+ max_val -- ;
58
+ }
59
+
60
+ if (divider -> flags & CLK_DIVIDER_POWER_OF_TWO )
61
+ mask = fls (max_val ) - 1 ;
62
+ else
63
+ mask = max_val ;
64
+
65
+ divider -> mask = (1 << fls (mask )) - 1 ;
66
+ }
67
+
64
68
static unsigned int _get_div (struct clk_omap_divider * divider , unsigned int val )
65
69
{
66
70
if (divider -> flags & CLK_DIVIDER_ONE_BASED )
@@ -101,7 +105,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
101
105
unsigned int div , val ;
102
106
103
107
val = ti_clk_ll_ops -> clk_readl (& divider -> reg ) >> divider -> shift ;
104
- val &= div_mask ( divider ) ;
108
+ val &= divider -> mask ;
105
109
106
110
div = _get_div (divider , val );
107
111
if (!div ) {
@@ -180,7 +184,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
180
184
if (!rate )
181
185
rate = 1 ;
182
186
183
- maxdiv = _get_maxdiv ( divider ) ;
187
+ maxdiv = divider -> max ;
184
188
185
189
if (!(clk_hw_get_flags (hw ) & CLK_SET_RATE_PARENT )) {
186
190
parent_rate = * best_parent_rate ;
@@ -219,7 +223,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
219
223
}
220
224
221
225
if (!bestdiv ) {
222
- bestdiv = _get_maxdiv ( divider ) ;
226
+ bestdiv = divider -> max ;
223
227
* best_parent_rate =
224
228
clk_hw_round_rate (clk_hw_get_parent (hw ), 1 );
225
229
}
@@ -249,17 +253,16 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
249
253
divider = to_clk_omap_divider (hw );
250
254
251
255
div = DIV_ROUND_UP (parent_rate , rate );
252
- value = _get_val (divider , div );
253
256
254
- if (value > div_mask (divider ))
255
- value = div_mask (divider );
257
+ if (div > divider -> max )
258
+ div = divider -> max ;
259
+ if (div < divider -> min )
260
+ div = divider -> min ;
256
261
257
- if (divider -> flags & CLK_DIVIDER_HIWORD_MASK ) {
258
- val = div_mask (divider ) << (divider -> shift + 16 );
259
- } else {
260
- val = ti_clk_ll_ops -> clk_readl (& divider -> reg );
261
- val &= ~(div_mask (divider ) << divider -> shift );
262
- }
262
+ value = _get_val (divider , div );
263
+
264
+ val = ti_clk_ll_ops -> clk_readl (& divider -> reg );
265
+ val &= ~(divider -> mask << divider -> shift );
263
266
val |= value << divider -> shift ;
264
267
ti_clk_ll_ops -> clk_writel (val , & divider -> reg );
265
268
@@ -280,7 +283,7 @@ static int clk_divider_save_context(struct clk_hw *hw)
280
283
u32 val ;
281
284
282
285
val = ti_clk_ll_ops -> clk_readl (& divider -> reg ) >> divider -> shift ;
283
- divider -> context = val & div_mask ( divider ) ;
286
+ divider -> context = val & divider -> mask ;
284
287
285
288
return 0 ;
286
289
}
@@ -297,7 +300,7 @@ static void clk_divider_restore_context(struct clk_hw *hw)
297
300
u32 val ;
298
301
299
302
val = ti_clk_ll_ops -> clk_readl (& divider -> reg );
300
- val &= ~(div_mask ( divider ) << divider -> shift );
303
+ val &= ~(divider -> mask << divider -> shift );
301
304
val |= divider -> context << divider -> shift ;
302
305
ti_clk_ll_ops -> clk_writel (val , & divider -> reg );
303
306
}
@@ -341,29 +344,14 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
341
344
u8 flags , struct clk_omap_divider * divider )
342
345
{
343
346
int valid_div = 0 ;
344
- u32 val ;
345
- int div ;
346
347
int i ;
347
348
struct clk_div_table * tmp ;
349
+ u16 min_div = 0 ;
348
350
349
351
if (!div_table ) {
350
- if (flags & CLKF_INDEX_STARTS_AT_ONE )
351
- val = 1 ;
352
- else
353
- val = 0 ;
354
-
355
- div = 1 ;
356
-
357
- while (div < max_div ) {
358
- if (flags & CLKF_INDEX_POWER_OF_TWO )
359
- div <<= 1 ;
360
- else
361
- div ++ ;
362
- val ++ ;
363
- }
364
-
365
- divider -> width = fls (val );
366
-
352
+ divider -> min = 1 ;
353
+ divider -> max = max_div ;
354
+ _setup_mask (divider );
367
355
return 0 ;
368
356
}
369
357
@@ -384,18 +372,22 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
384
372
return - ENOMEM ;
385
373
386
374
valid_div = 0 ;
387
- divider -> width = 0 ;
388
375
389
376
for (i = 0 ; i < num_dividers ; i ++ )
390
377
if (div_table [i ] > 0 ) {
391
378
tmp [valid_div ].div = div_table [i ];
392
379
tmp [valid_div ].val = i ;
393
380
valid_div ++ ;
394
- divider -> width = i ;
381
+ if (div_table [i ] > max_div )
382
+ max_div = div_table [i ];
383
+ if (!min_div || div_table [i ] < min_div )
384
+ min_div = div_table [i ];
395
385
}
396
386
397
- divider -> width = fls (divider -> width );
387
+ divider -> min = min_div ;
388
+ divider -> max = max_div ;
398
389
divider -> table = tmp ;
390
+ _setup_mask (divider );
399
391
400
392
return 0 ;
401
393
}
@@ -451,16 +443,15 @@ static int __init ti_clk_get_div_table(struct device_node *node,
451
443
return 0 ;
452
444
}
453
445
454
- static int _get_divider_width (struct device_node * node ,
455
- const struct clk_div_table * table ,
456
- u8 flags )
446
+ static int _populate_divider_min_max (struct device_node * node ,
447
+ struct clk_omap_divider * divider )
457
448
{
458
- u32 min_div ;
459
- u32 max_div ;
460
- u32 val = 0 ;
461
- u32 div ;
449
+ u32 min_div = 0 ;
450
+ u32 max_div = 0 ;
451
+ u32 val ;
452
+ const struct clk_div_table * clkt ;
462
453
463
- if (!table ) {
454
+ if (!divider -> table ) {
464
455
/* Clk divider table not provided, determine min/max divs */
465
456
if (of_property_read_u32 (node , "ti,min-div" , & min_div ))
466
457
min_div = 1 ;
@@ -469,30 +460,22 @@ static int _get_divider_width(struct device_node *node,
469
460
pr_err ("no max-div for %pOFn!\n" , node );
470
461
return - EINVAL ;
471
462
}
472
-
473
- /* Determine bit width for the field */
474
- if (flags & CLK_DIVIDER_ONE_BASED )
475
- val = 1 ;
476
-
477
- div = min_div ;
478
-
479
- while (div < max_div ) {
480
- if (flags & CLK_DIVIDER_POWER_OF_TWO )
481
- div <<= 1 ;
482
- else
483
- div ++ ;
484
- val ++ ;
485
- }
486
463
} else {
487
- div = 0 ;
488
464
489
- while (table [div ].div ) {
490
- val = table [div ].val ;
491
- div ++ ;
465
+ for (clkt = divider -> table ; clkt -> div ; clkt ++ ) {
466
+ val = clkt -> div ;
467
+ if (val > max_div )
468
+ max_div = val ;
469
+ if (!min_div || val < min_div )
470
+ min_div = val ;
492
471
}
493
472
}
494
473
495
- return fls (val );
474
+ divider -> min = min_div ;
475
+ divider -> max = max_div ;
476
+ _setup_mask (divider );
477
+
478
+ return 0 ;
496
479
}
497
480
498
481
static int __init ti_clk_divider_populate (struct device_node * node ,
@@ -532,9 +515,7 @@ static int __init ti_clk_divider_populate(struct device_node *node,
532
515
if (ret )
533
516
return ret ;
534
517
535
- div -> width = _get_divider_width (node , div -> table , div -> flags );
536
-
537
- return 0 ;
518
+ return _populate_divider_min_max (node , div );
538
519
}
539
520
540
521
/**
0 commit comments