1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
6 #include <linux/clk-provider.h>
7 #include <linux/clkdev.h>
8 #include <linux/clk/at91_pmc.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/regmap.h>
15 #define MASTER_PRES_MASK 0x7
16 #define MASTER_PRES_MAX MASTER_PRES_MASK
17 #define MASTER_DIV_SHIFT 8
18 #define MASTER_DIV_MASK 0x7
21 #define PMC_MCR_ID_MSK GENMASK(3, 0)
22 #define PMC_MCR_CMD BIT(7)
23 #define PMC_MCR_DIV GENMASK(10, 8)
24 #define PMC_MCR_CSS GENMASK(20, 16)
25 #define PMC_MCR_CSS_SHIFT (16)
26 #define PMC_MCR_EN BIT(28)
28 #define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK)
30 #define MASTER_MAX_ID 4
32 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
36 struct regmap
*regmap
;
38 const struct clk_master_layout
*layout
;
39 const struct clk_master_characteristics
*characteristics
;
48 static inline bool clk_master_ready(struct clk_master
*master
)
50 unsigned int bit
= master
->id
? AT91_PMC_MCKXRDY
: AT91_PMC_MCKRDY
;
53 regmap_read(master
->regmap
, AT91_PMC_SR
, &status
);
55 return !!(status
& bit
);
58 static int clk_master_prepare(struct clk_hw
*hw
)
60 struct clk_master
*master
= to_clk_master(hw
);
63 spin_lock_irqsave(master
->lock
, flags
);
65 while (!clk_master_ready(master
))
68 spin_unlock_irqrestore(master
->lock
, flags
);
73 static int clk_master_is_prepared(struct clk_hw
*hw
)
75 struct clk_master
*master
= to_clk_master(hw
);
79 spin_lock_irqsave(master
->lock
, flags
);
80 status
= clk_master_ready(master
);
81 spin_unlock_irqrestore(master
->lock
, flags
);
86 static unsigned long clk_master_div_recalc_rate(struct clk_hw
*hw
,
87 unsigned long parent_rate
)
90 unsigned long flags
, rate
= parent_rate
;
91 struct clk_master
*master
= to_clk_master(hw
);
92 const struct clk_master_layout
*layout
= master
->layout
;
93 const struct clk_master_characteristics
*characteristics
=
94 master
->characteristics
;
97 spin_lock_irqsave(master
->lock
, flags
);
98 regmap_read(master
->regmap
, master
->layout
->offset
, &mckr
);
99 spin_unlock_irqrestore(master
->lock
, flags
);
101 mckr
&= layout
->mask
;
103 div
= (mckr
>> MASTER_DIV_SHIFT
) & MASTER_DIV_MASK
;
105 rate
/= characteristics
->divisors
[div
];
107 if (rate
< characteristics
->output
.min
)
108 pr_warn("master clk div is underclocked");
109 else if (rate
> characteristics
->output
.max
)
110 pr_warn("master clk div is overclocked");
115 static const struct clk_ops master_div_ops
= {
116 .prepare
= clk_master_prepare
,
117 .is_prepared
= clk_master_is_prepared
,
118 .recalc_rate
= clk_master_div_recalc_rate
,
121 static int clk_master_div_set_rate(struct clk_hw
*hw
, unsigned long rate
,
122 unsigned long parent_rate
)
124 struct clk_master
*master
= to_clk_master(hw
);
125 const struct clk_master_characteristics
*characteristics
=
126 master
->characteristics
;
130 div
= DIV_ROUND_CLOSEST(parent_rate
, rate
);
131 if (div
> ARRAY_SIZE(characteristics
->divisors
))
134 for (i
= 0; i
< ARRAY_SIZE(characteristics
->divisors
); i
++) {
135 if (!characteristics
->divisors
[i
])
138 if (div
== characteristics
->divisors
[i
]) {
144 if (i
== ARRAY_SIZE(characteristics
->divisors
))
147 spin_lock_irqsave(master
->lock
, flags
);
148 regmap_update_bits(master
->regmap
, master
->layout
->offset
,
149 (MASTER_DIV_MASK
<< MASTER_DIV_SHIFT
),
150 (div
<< MASTER_DIV_SHIFT
));
151 while (!clk_master_ready(master
))
153 spin_unlock_irqrestore(master
->lock
, flags
);
158 static int clk_master_div_determine_rate(struct clk_hw
*hw
,
159 struct clk_rate_request
*req
)
161 struct clk_master
*master
= to_clk_master(hw
);
162 const struct clk_master_characteristics
*characteristics
=
163 master
->characteristics
;
164 struct clk_hw
*parent
;
165 unsigned long parent_rate
, tmp_rate
, best_rate
= 0;
166 int i
, best_diff
= INT_MIN
, tmp_diff
;
168 parent
= clk_hw_get_parent(hw
);
172 parent_rate
= clk_hw_get_rate(parent
);
176 for (i
= 0; i
< ARRAY_SIZE(characteristics
->divisors
); i
++) {
177 if (!characteristics
->divisors
[i
])
180 tmp_rate
= DIV_ROUND_CLOSEST_ULL(parent_rate
,
181 characteristics
->divisors
[i
]);
182 tmp_diff
= abs(tmp_rate
- req
->rate
);
184 if (!best_rate
|| best_diff
> tmp_diff
) {
185 best_diff
= tmp_diff
;
186 best_rate
= tmp_rate
;
193 req
->best_parent_rate
= best_rate
;
194 req
->best_parent_hw
= parent
;
195 req
->rate
= best_rate
;
200 static const struct clk_ops master_div_ops_chg
= {
201 .prepare
= clk_master_prepare
,
202 .is_prepared
= clk_master_is_prepared
,
203 .recalc_rate
= clk_master_div_recalc_rate
,
204 .determine_rate
= clk_master_div_determine_rate
,
205 .set_rate
= clk_master_div_set_rate
,
208 static void clk_sama7g5_master_best_diff(struct clk_rate_request
*req
,
209 struct clk_hw
*parent
,
210 unsigned long parent_rate
,
215 unsigned long tmp_rate
, tmp_diff
;
217 if (div
== MASTER_PRES_MAX
)
218 tmp_rate
= parent_rate
/ 3;
220 tmp_rate
= parent_rate
>> div
;
222 tmp_diff
= abs(req
->rate
- tmp_rate
);
224 if (*best_diff
< 0 || *best_diff
>= tmp_diff
) {
225 *best_rate
= tmp_rate
;
226 *best_diff
= tmp_diff
;
227 req
->best_parent_rate
= parent_rate
;
228 req
->best_parent_hw
= parent
;
232 static int clk_master_pres_determine_rate(struct clk_hw
*hw
,
233 struct clk_rate_request
*req
)
235 struct clk_master
*master
= to_clk_master(hw
);
236 struct clk_rate_request req_parent
= *req
;
237 const struct clk_master_characteristics
*characteristics
=
238 master
->characteristics
;
239 struct clk_hw
*parent
;
240 long best_rate
= LONG_MIN
, best_diff
= LONG_MIN
;
244 if (master
->chg_pid
< 0)
247 parent
= clk_hw_get_parent_by_index(hw
, master
->chg_pid
);
251 for (i
= 0; i
<= MASTER_PRES_MAX
; i
++) {
252 if (characteristics
->have_div3_pres
&& i
== MASTER_PRES_MAX
)
257 req_parent
.rate
= req
->rate
* pres
;
258 if (__clk_determine_rate(parent
, &req_parent
))
261 clk_sama7g5_master_best_diff(req
, parent
, req_parent
.rate
,
262 &best_diff
, &best_rate
, pres
);
270 static int clk_master_pres_set_rate(struct clk_hw
*hw
, unsigned long rate
,
271 unsigned long parent_rate
)
273 struct clk_master
*master
= to_clk_master(hw
);
277 pres
= DIV_ROUND_CLOSEST(parent_rate
, rate
);
278 if (pres
> MASTER_PRES_MAX
)
282 pres
= MASTER_PRES_MAX
;
284 pres
= ffs(pres
) - 1;
286 spin_lock_irqsave(master
->lock
, flags
);
287 regmap_update_bits(master
->regmap
, master
->layout
->offset
,
288 (MASTER_PRES_MASK
<< master
->layout
->pres_shift
),
289 (pres
<< master
->layout
->pres_shift
));
291 while (!clk_master_ready(master
))
293 spin_unlock_irqrestore(master
->lock
, flags
);
298 static unsigned long clk_master_pres_recalc_rate(struct clk_hw
*hw
,
299 unsigned long parent_rate
)
301 struct clk_master
*master
= to_clk_master(hw
);
302 const struct clk_master_characteristics
*characteristics
=
303 master
->characteristics
;
305 unsigned int val
, pres
;
307 spin_lock_irqsave(master
->lock
, flags
);
308 regmap_read(master
->regmap
, master
->layout
->offset
, &val
);
309 spin_unlock_irqrestore(master
->lock
, flags
);
311 pres
= (val
>> master
->layout
->pres_shift
) & MASTER_PRES_MASK
;
312 if (pres
== 3 && characteristics
->have_div3_pres
)
317 return DIV_ROUND_CLOSEST_ULL(parent_rate
, pres
);
320 static u8
clk_master_pres_get_parent(struct clk_hw
*hw
)
322 struct clk_master
*master
= to_clk_master(hw
);
326 spin_lock_irqsave(master
->lock
, flags
);
327 regmap_read(master
->regmap
, master
->layout
->offset
, &mckr
);
328 spin_unlock_irqrestore(master
->lock
, flags
);
330 return mckr
& AT91_PMC_CSS
;
333 static const struct clk_ops master_pres_ops
= {
334 .prepare
= clk_master_prepare
,
335 .is_prepared
= clk_master_is_prepared
,
336 .recalc_rate
= clk_master_pres_recalc_rate
,
337 .get_parent
= clk_master_pres_get_parent
,
340 static const struct clk_ops master_pres_ops_chg
= {
341 .prepare
= clk_master_prepare
,
342 .is_prepared
= clk_master_is_prepared
,
343 .determine_rate
= clk_master_pres_determine_rate
,
344 .recalc_rate
= clk_master_pres_recalc_rate
,
345 .get_parent
= clk_master_pres_get_parent
,
346 .set_rate
= clk_master_pres_set_rate
,
349 static struct clk_hw
* __init
350 at91_clk_register_master_internal(struct regmap
*regmap
,
351 const char *name
, int num_parents
,
352 const char **parent_names
,
353 const struct clk_master_layout
*layout
,
354 const struct clk_master_characteristics
*characteristics
,
355 const struct clk_ops
*ops
, spinlock_t
*lock
, u32 flags
,
358 struct clk_master
*master
;
359 struct clk_init_data init
;
363 if (!name
|| !num_parents
|| !parent_names
|| !lock
)
364 return ERR_PTR(-EINVAL
);
366 master
= kzalloc(sizeof(*master
), GFP_KERNEL
);
368 return ERR_PTR(-ENOMEM
);
372 init
.parent_names
= parent_names
;
373 init
.num_parents
= num_parents
;
376 master
->hw
.init
= &init
;
377 master
->layout
= layout
;
378 master
->characteristics
= characteristics
;
379 master
->regmap
= regmap
;
380 master
->chg_pid
= chg_pid
;
384 ret
= clk_hw_register(NULL
, &master
->hw
);
393 struct clk_hw
* __init
394 at91_clk_register_master_pres(struct regmap
*regmap
,
395 const char *name
, int num_parents
,
396 const char **parent_names
,
397 const struct clk_master_layout
*layout
,
398 const struct clk_master_characteristics
*characteristics
,
399 spinlock_t
*lock
, u32 flags
, int chg_pid
)
401 const struct clk_ops
*ops
;
403 if (flags
& CLK_SET_RATE_GATE
)
404 ops
= &master_pres_ops
;
406 ops
= &master_pres_ops_chg
;
408 return at91_clk_register_master_internal(regmap
, name
, num_parents
,
409 parent_names
, layout
,
410 characteristics
, ops
,
411 lock
, flags
, chg_pid
);
414 struct clk_hw
* __init
415 at91_clk_register_master_div(struct regmap
*regmap
,
416 const char *name
, const char *parent_name
,
417 const struct clk_master_layout
*layout
,
418 const struct clk_master_characteristics
*characteristics
,
419 spinlock_t
*lock
, u32 flags
)
421 const struct clk_ops
*ops
;
423 if (flags
& CLK_SET_RATE_GATE
)
424 ops
= &master_div_ops
;
426 ops
= &master_div_ops_chg
;
428 return at91_clk_register_master_internal(regmap
, name
, 1,
429 &parent_name
, layout
,
430 characteristics
, ops
,
431 lock
, flags
, -EINVAL
);
435 clk_sama7g5_master_recalc_rate(struct clk_hw
*hw
,
436 unsigned long parent_rate
)
438 struct clk_master
*master
= to_clk_master(hw
);
440 return DIV_ROUND_CLOSEST_ULL(parent_rate
, (1 << master
->div
));
443 static int clk_sama7g5_master_determine_rate(struct clk_hw
*hw
,
444 struct clk_rate_request
*req
)
446 struct clk_master
*master
= to_clk_master(hw
);
447 struct clk_rate_request req_parent
= *req
;
448 struct clk_hw
*parent
;
449 long best_rate
= LONG_MIN
, best_diff
= LONG_MIN
;
450 unsigned long parent_rate
;
453 /* First: check the dividers of MCR. */
454 for (i
= 0; i
< clk_hw_get_num_parents(hw
); i
++) {
455 parent
= clk_hw_get_parent_by_index(hw
, i
);
459 parent_rate
= clk_hw_get_rate(parent
);
463 for (div
= 0; div
< MASTER_PRES_MAX
+ 1; div
++) {
464 clk_sama7g5_master_best_diff(req
, parent
, parent_rate
,
465 &best_rate
, &best_diff
,
475 /* Second: try to request rate form changeable parent. */
476 if (master
->chg_pid
< 0)
479 parent
= clk_hw_get_parent_by_index(hw
, master
->chg_pid
);
483 for (div
= 0; div
< MASTER_PRES_MAX
+ 1; div
++) {
484 if (div
== MASTER_PRES_MAX
)
485 req_parent
.rate
= req
->rate
* 3;
487 req_parent
.rate
= req
->rate
<< div
;
489 if (__clk_determine_rate(parent
, &req_parent
))
492 clk_sama7g5_master_best_diff(req
, parent
, req_parent
.rate
,
493 &best_rate
, &best_diff
, div
);
500 pr_debug("MCK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
502 __clk_get_name((req
->best_parent_hw
)->clk
),
503 req
->best_parent_rate
);
508 req
->rate
= best_rate
;
513 static u8
clk_sama7g5_master_get_parent(struct clk_hw
*hw
)
515 struct clk_master
*master
= to_clk_master(hw
);
519 spin_lock_irqsave(master
->lock
, flags
);
520 index
= clk_mux_val_to_index(&master
->hw
, master
->mux_table
, 0,
522 spin_unlock_irqrestore(master
->lock
, flags
);
527 static int clk_sama7g5_master_set_parent(struct clk_hw
*hw
, u8 index
)
529 struct clk_master
*master
= to_clk_master(hw
);
532 if (index
>= clk_hw_get_num_parents(hw
))
535 spin_lock_irqsave(master
->lock
, flags
);
536 master
->parent
= clk_mux_index_to_val(master
->mux_table
, 0, index
);
537 spin_unlock_irqrestore(master
->lock
, flags
);
542 static int clk_sama7g5_master_enable(struct clk_hw
*hw
)
544 struct clk_master
*master
= to_clk_master(hw
);
546 unsigned int val
, cparent
;
548 spin_lock_irqsave(master
->lock
, flags
);
550 regmap_write(master
->regmap
, PMC_MCR
, PMC_MCR_ID(master
->id
));
551 regmap_read(master
->regmap
, PMC_MCR
, &val
);
552 regmap_update_bits(master
->regmap
, PMC_MCR
,
553 PMC_MCR_EN
| PMC_MCR_CSS
| PMC_MCR_DIV
|
554 PMC_MCR_CMD
| PMC_MCR_ID_MSK
,
555 PMC_MCR_EN
| (master
->parent
<< PMC_MCR_CSS_SHIFT
) |
556 (master
->div
<< MASTER_DIV_SHIFT
) |
557 PMC_MCR_CMD
| PMC_MCR_ID(master
->id
));
559 cparent
= (val
& PMC_MCR_CSS
) >> PMC_MCR_CSS_SHIFT
;
561 /* Wait here only if parent is being changed. */
562 while ((cparent
!= master
->parent
) && !clk_master_ready(master
))
565 spin_unlock_irqrestore(master
->lock
, flags
);
570 static void clk_sama7g5_master_disable(struct clk_hw
*hw
)
572 struct clk_master
*master
= to_clk_master(hw
);
575 spin_lock_irqsave(master
->lock
, flags
);
577 regmap_write(master
->regmap
, PMC_MCR
, master
->id
);
578 regmap_update_bits(master
->regmap
, PMC_MCR
,
579 PMC_MCR_EN
| PMC_MCR_CMD
| PMC_MCR_ID_MSK
,
580 PMC_MCR_CMD
| PMC_MCR_ID(master
->id
));
582 spin_unlock_irqrestore(master
->lock
, flags
);
585 static int clk_sama7g5_master_is_enabled(struct clk_hw
*hw
)
587 struct clk_master
*master
= to_clk_master(hw
);
591 spin_lock_irqsave(master
->lock
, flags
);
593 regmap_write(master
->regmap
, PMC_MCR
, master
->id
);
594 regmap_read(master
->regmap
, PMC_MCR
, &val
);
596 spin_unlock_irqrestore(master
->lock
, flags
);
598 return !!(val
& PMC_MCR_EN
);
601 static int clk_sama7g5_master_set_rate(struct clk_hw
*hw
, unsigned long rate
,
602 unsigned long parent_rate
)
604 struct clk_master
*master
= to_clk_master(hw
);
605 unsigned long div
, flags
;
607 div
= DIV_ROUND_CLOSEST(parent_rate
, rate
);
608 if ((div
> (1 << (MASTER_PRES_MAX
- 1))) || (div
& (div
- 1)))
612 div
= MASTER_PRES_MAX
;
616 spin_lock_irqsave(master
->lock
, flags
);
618 spin_unlock_irqrestore(master
->lock
, flags
);
623 static const struct clk_ops sama7g5_master_ops
= {
624 .enable
= clk_sama7g5_master_enable
,
625 .disable
= clk_sama7g5_master_disable
,
626 .is_enabled
= clk_sama7g5_master_is_enabled
,
627 .recalc_rate
= clk_sama7g5_master_recalc_rate
,
628 .determine_rate
= clk_sama7g5_master_determine_rate
,
629 .set_rate
= clk_sama7g5_master_set_rate
,
630 .get_parent
= clk_sama7g5_master_get_parent
,
631 .set_parent
= clk_sama7g5_master_set_parent
,
634 struct clk_hw
* __init
635 at91_clk_sama7g5_register_master(struct regmap
*regmap
,
636 const char *name
, int num_parents
,
637 const char **parent_names
,
639 spinlock_t
*lock
, u8 id
,
640 bool critical
, int chg_pid
)
642 struct clk_master
*master
;
644 struct clk_init_data init
;
649 if (!name
|| !num_parents
|| !parent_names
|| !mux_table
||
650 !lock
|| id
> MASTER_MAX_ID
)
651 return ERR_PTR(-EINVAL
);
653 master
= kzalloc(sizeof(*master
), GFP_KERNEL
);
655 return ERR_PTR(-ENOMEM
);
658 init
.ops
= &sama7g5_master_ops
;
659 init
.parent_names
= parent_names
;
660 init
.num_parents
= num_parents
;
661 init
.flags
= CLK_SET_RATE_GATE
| CLK_SET_PARENT_GATE
;
663 init
.flags
|= CLK_SET_RATE_PARENT
;
665 init
.flags
|= CLK_IS_CRITICAL
;
667 master
->hw
.init
= &init
;
668 master
->regmap
= regmap
;
670 master
->chg_pid
= chg_pid
;
672 master
->mux_table
= mux_table
;
674 spin_lock_irqsave(master
->lock
, flags
);
675 regmap_write(master
->regmap
, PMC_MCR
, master
->id
);
676 regmap_read(master
->regmap
, PMC_MCR
, &val
);
677 master
->parent
= (val
& PMC_MCR_CSS
) >> PMC_MCR_CSS_SHIFT
;
678 master
->div
= (val
& PMC_MCR_DIV
) >> MASTER_DIV_SHIFT
;
679 spin_unlock_irqrestore(master
->lock
, flags
);
682 ret
= clk_hw_register(NULL
, &master
->hw
);
691 const struct clk_master_layout at91rm9200_master_layout
= {
694 .offset
= AT91_PMC_MCKR
,
697 const struct clk_master_layout at91sam9x5_master_layout
= {
700 .offset
= AT91_PMC_MCKR
,