16
16
* of the SoC or supplied after the SoC characterization.
17
17
*
18
18
* The below implementation of the CPU clock allows the rate changes of the CPU
19
- * clock and the corresponding rate changes of the auxillary clocks of the CPU
19
+ * clock and the corresponding rate changes of the auxiliary clocks of the CPU
20
20
* domain. The platform clock driver provides a clock register configuration
21
21
* for each configurable rate which is then used to program the clock hardware
22
- * registers to acheive a fast co-oridinated rate change for all the CPU domain
22
+ * registers to achieve a fast coordinated rate change for all the CPU domain
23
23
* clocks.
24
24
*
25
25
* On a rate change request for the CPU clock, the rate change is propagated
26
- * upto the PLL supplying the clock to the CPU domain clock blocks. While the
26
+ * up to the PLL supplying the clock to the CPU domain clock blocks. While the
27
27
* CPU domain PLL is reconfigured, the CPU domain clocks are driven using an
28
28
* alternate clock source. If required, the alternate clock source is divided
29
29
* down in order to keep the output clock rate within the previous OPP limits.
30
- */
30
+ */
31
31
32
32
#include <linux/errno.h>
33
33
#include <linux/io.h>
50
50
#define E5433_DIV_STAT_CPU0 0x500
51
51
#define E5433_DIV_STAT_CPU1 0x504
52
52
53
- #define E4210_DIV0_RATIO0_MASK 0x7
54
- #define E4210_DIV1_HPM_MASK (0x7 << 4)
55
- #define E4210_DIV1_COPY_MASK (0x7 << 0)
56
- #define E4210_MUX_HPM_MASK (1 << 20)
53
+ #define E4210_DIV0_RATIO0_MASK GENMASK(2, 0)
54
+ #define E4210_DIV1_HPM_MASK GENMASK(6, 4)
55
+ #define E4210_DIV1_COPY_MASK GENMASK(2, 0)
56
+ #define E4210_MUX_HPM_MASK BIT( 20)
57
57
#define E4210_DIV0_ATB_SHIFT 16
58
58
#define E4210_DIV0_ATB_MASK (DIV_MASK << E4210_DIV0_ATB_SHIFT)
59
59
60
+ /* Divider stabilization time, msec */
61
+ #define MAX_STAB_TIME 10
60
62
#define MAX_DIV 8
61
- #define DIV_MASK 7
62
- #define DIV_MASK_ALL 0xffffffff
63
- #define MUX_MASK 7
63
+ #define DIV_MASK GENMASK(2, 0)
64
+ #define DIV_MASK_ALL GENMASK(31, 0)
65
+ #define MUX_MASK GENMASK(2, 0)
64
66
65
67
/*
66
68
* Helper function to wait until divider(s) have stabilized after the divider
67
69
* value has changed.
68
70
*/
69
71
static void wait_until_divider_stable (void __iomem * div_reg , unsigned long mask )
70
72
{
71
- unsigned long timeout = jiffies + msecs_to_jiffies (10 );
73
+ unsigned long timeout = jiffies + msecs_to_jiffies (MAX_STAB_TIME );
72
74
73
75
do {
74
76
if (!(readl (div_reg ) & mask ))
@@ -86,9 +88,9 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
86
88
* value was changed.
87
89
*/
88
90
static void wait_until_mux_stable (void __iomem * mux_reg , u32 mux_pos ,
89
- unsigned long mux_value )
91
+ unsigned long mux_value )
90
92
{
91
- unsigned long timeout = jiffies + msecs_to_jiffies (10 );
93
+ unsigned long timeout = jiffies + msecs_to_jiffies (MAX_STAB_TIME );
92
94
93
95
do {
94
96
if (((readl (mux_reg ) >> mux_pos ) & MUX_MASK ) == mux_value )
@@ -101,18 +103,18 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
101
103
pr_err ("%s: re-parenting mux timed-out\n" , __func__ );
102
104
}
103
105
104
- /* common round rate callback useable for all types of CPU clocks */
105
- static long exynos_cpuclk_round_rate (struct clk_hw * hw ,
106
- unsigned long drate , unsigned long * prate )
106
+ /* common round rate callback usable for all types of CPU clocks */
107
+ static long exynos_cpuclk_round_rate (struct clk_hw * hw , unsigned long drate ,
108
+ unsigned long * prate )
107
109
{
108
110
struct clk_hw * parent = clk_hw_get_parent (hw );
109
111
* prate = clk_hw_round_rate (parent , drate );
110
112
return * prate ;
111
113
}
112
114
113
- /* common recalc rate callback useable for all types of CPU clocks */
115
+ /* common recalc rate callback usable for all types of CPU clocks */
114
116
static unsigned long exynos_cpuclk_recalc_rate (struct clk_hw * hw ,
115
- unsigned long parent_rate )
117
+ unsigned long parent_rate )
116
118
{
117
119
/*
118
120
* The CPU clock output (armclk) rate is the same as its parent
@@ -135,7 +137,7 @@ static const struct clk_ops exynos_cpuclk_clk_ops = {
135
137
* dividers to be programmed.
136
138
*/
137
139
static void exynos_set_safe_div (void __iomem * base , unsigned long div ,
138
- unsigned long mask )
140
+ unsigned long mask )
139
141
{
140
142
unsigned long div0 ;
141
143
@@ -151,7 +153,6 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
151
153
{
152
154
const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
153
155
unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
154
- unsigned long alt_div = 0 , alt_div_mask = DIV_MASK ;
155
156
unsigned long div0 , div1 = 0 , mux_reg ;
156
157
unsigned long flags ;
157
158
@@ -187,6 +188,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
187
188
*/
188
189
if (alt_prate > ndata -> old_rate || ndata -> old_rate > ndata -> new_rate ) {
189
190
unsigned long tmp_rate = min (ndata -> old_rate , ndata -> new_rate );
191
+ unsigned long alt_div , alt_div_mask = DIV_MASK ;
190
192
191
193
alt_div = DIV_ROUND_UP (alt_prate , tmp_rate ) - 1 ;
192
194
WARN_ON (alt_div >= MAX_DIV );
@@ -215,7 +217,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
215
217
if (cpuclk -> flags & CLK_CPU_HAS_DIV1 ) {
216
218
writel (div1 , base + E4210_DIV_CPU1 );
217
219
wait_until_divider_stable (base + E4210_DIV_STAT_CPU1 ,
218
- DIV_MASK_ALL );
220
+ DIV_MASK_ALL );
219
221
}
220
222
221
223
spin_unlock_irqrestore (cpuclk -> lock , flags );
@@ -263,7 +265,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
263
265
* dividers to be programmed.
264
266
*/
265
267
static void exynos5433_set_safe_div (void __iomem * base , unsigned long div ,
266
- unsigned long mask )
268
+ unsigned long mask )
267
269
{
268
270
unsigned long div0 ;
269
271
@@ -279,7 +281,6 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
279
281
{
280
282
const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
281
283
unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
282
- unsigned long alt_div = 0 , alt_div_mask = DIV_MASK ;
283
284
unsigned long div0 , div1 = 0 , mux_reg ;
284
285
unsigned long flags ;
285
286
@@ -309,6 +310,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
309
310
*/
310
311
if (alt_prate > ndata -> old_rate || ndata -> old_rate > ndata -> new_rate ) {
311
312
unsigned long tmp_rate = min (ndata -> old_rate , ndata -> new_rate );
313
+ unsigned long alt_div , alt_div_mask = DIV_MASK ;
312
314
313
315
alt_div = DIV_ROUND_UP (alt_prate , tmp_rate ) - 1 ;
314
316
WARN_ON (alt_div >= MAX_DIV );
@@ -358,7 +360,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
358
360
* notifications of the parent clock of cpuclk.
359
361
*/
360
362
static int exynos_cpuclk_notifier_cb (struct notifier_block * nb ,
361
- unsigned long event , void * data )
363
+ unsigned long event , void * data )
362
364
{
363
365
struct clk_notifier_data * ndata = data ;
364
366
struct exynos_cpuclk * cpuclk ;
@@ -381,7 +383,7 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
381
383
* notifications of the parent clock of cpuclk.
382
384
*/
383
385
static int exynos5433_cpuclk_notifier_cb (struct notifier_block * nb ,
384
- unsigned long event , void * data )
386
+ unsigned long event , void * data )
385
387
{
386
388
struct clk_notifier_data * ndata = data ;
387
389
struct exynos_cpuclk * cpuclk ;
@@ -438,11 +440,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
438
440
else
439
441
cpuclk -> clk_nb .notifier_call = exynos_cpuclk_notifier_cb ;
440
442
441
-
442
443
ret = clk_notifier_register (parent -> clk , & cpuclk -> clk_nb );
443
444
if (ret ) {
444
445
pr_err ("%s: failed to register clock notifier for %s\n" ,
445
- __func__ , name );
446
+ __func__ , name );
446
447
goto free_cpuclk ;
447
448
}
448
449
@@ -454,7 +455,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
454
455
455
456
ret = clk_hw_register (NULL , & cpuclk -> hw );
456
457
if (ret ) {
457
- pr_err ("%s: could not register cpuclk %s\n" , __func__ , name );
458
+ pr_err ("%s: could not register cpuclk %s\n" , __func__ , name );
458
459
goto free_cpuclk_data ;
459
460
}
460
461
@@ -482,8 +483,8 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
482
483
for (num_cfgs = 0 ; list -> cfg [num_cfgs ].prate != 0 ; )
483
484
num_cfgs ++ ;
484
485
485
- exynos_register_cpu_clock (ctx , list -> id , list -> name , hws [ list -> parent_id ],
486
- hws [list -> alt_parent_id ], list -> offset , list -> cfg , num_cfgs ,
487
- list -> flags );
486
+ exynos_register_cpu_clock (ctx , list -> id , list -> name ,
487
+ hws [list -> parent_id ], hws [ list -> alt_parent_id ] ,
488
+ list -> offset , list -> cfg , num_cfgs , list -> flags );
488
489
}
489
490
}
0 commit comments