2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/kernel.h>
15 #include <linux/bitops.h>
16 #include <linux/err.h>
17 #include <linux/export.h>
18 #include <linux/clk-provider.h>
19 #include <linux/regmap.h>
21 #include <asm/div64.h>
25 static u32
ns_to_src(struct src_sel
*s
, u32 ns
)
27 ns
>>= s
->src_sel_shift
;
32 static u32
src_to_ns(struct src_sel
*s
, u8 src
, u32 ns
)
37 mask
<<= s
->src_sel_shift
;
40 ns
|= src
<< s
->src_sel_shift
;
44 static u8
clk_rcg_get_parent(struct clk_hw
*hw
)
46 struct clk_rcg
*rcg
= to_clk_rcg(hw
);
47 int num_parents
= __clk_get_num_parents(hw
->clk
);
51 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
52 ns
= ns_to_src(&rcg
->s
, ns
);
53 for (i
= 0; i
< num_parents
; i
++)
54 if (ns
== rcg
->s
.parent_map
[i
])
60 static int reg_to_bank(struct clk_dyn_rcg
*rcg
, u32 bank
)
62 bank
&= BIT(rcg
->mux_sel_bit
);
66 static u8
clk_dyn_rcg_get_parent(struct clk_hw
*hw
)
68 struct clk_dyn_rcg
*rcg
= to_clk_dyn_rcg(hw
);
69 int num_parents
= __clk_get_num_parents(hw
->clk
);
75 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, &ctl
);
76 bank
= reg_to_bank(rcg
, ctl
);
79 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
80 ns
= ns_to_src(s
, ns
);
82 for (i
= 0; i
< num_parents
; i
++)
83 if (ns
== s
->parent_map
[i
])
89 static int clk_rcg_set_parent(struct clk_hw
*hw
, u8 index
)
91 struct clk_rcg
*rcg
= to_clk_rcg(hw
);
94 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
95 ns
= src_to_ns(&rcg
->s
, rcg
->s
.parent_map
[index
], ns
);
96 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
101 static u32
md_to_m(struct mn
*mn
, u32 md
)
103 md
>>= mn
->m_val_shift
;
104 md
&= BIT(mn
->width
) - 1;
108 static u32
ns_to_pre_div(struct pre_div
*p
, u32 ns
)
110 ns
>>= p
->pre_div_shift
;
111 ns
&= BIT(p
->pre_div_width
) - 1;
115 static u32
pre_div_to_ns(struct pre_div
*p
, u8 pre_div
, u32 ns
)
119 mask
= BIT(p
->pre_div_width
) - 1;
120 mask
<<= p
->pre_div_shift
;
123 ns
|= pre_div
<< p
->pre_div_shift
;
127 static u32
mn_to_md(struct mn
*mn
, u32 m
, u32 n
, u32 md
)
131 mask_w
= BIT(mn
->width
) - 1;
132 mask
= (mask_w
<< mn
->m_val_shift
) | mask_w
;
136 m
<<= mn
->m_val_shift
;
144 static u32
ns_m_to_n(struct mn
*mn
, u32 ns
, u32 m
)
146 ns
= ~ns
>> mn
->n_val_shift
;
147 ns
&= BIT(mn
->width
) - 1;
151 static u32
reg_to_mnctr_mode(struct mn
*mn
, u32 val
)
153 val
>>= mn
->mnctr_mode_shift
;
154 val
&= MNCTR_MODE_MASK
;
158 static u32
mn_to_ns(struct mn
*mn
, u32 m
, u32 n
, u32 ns
)
162 mask
= BIT(mn
->width
) - 1;
163 mask
<<= mn
->n_val_shift
;
169 n
&= BIT(mn
->width
) - 1;
170 n
<<= mn
->n_val_shift
;
177 static u32
mn_to_reg(struct mn
*mn
, u32 m
, u32 n
, u32 val
)
181 mask
= MNCTR_MODE_MASK
<< mn
->mnctr_mode_shift
;
182 mask
|= BIT(mn
->mnctr_en_bit
);
186 val
|= BIT(mn
->mnctr_en_bit
);
187 val
|= MNCTR_MODE_DUAL
<< mn
->mnctr_mode_shift
;
193 static void configure_bank(struct clk_dyn_rcg
*rcg
, const struct freq_tbl
*f
)
195 u32 ns
, md
, ctl
, *regp
;
203 bool banked_mn
= !!rcg
->mn
[1].width
;
204 struct clk_hw
*hw
= &rcg
->clkr
.hw
;
206 enabled
= __clk_is_enabled(hw
->clk
);
208 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
209 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, &ctl
);
213 bank_reg
= rcg
->clkr
.enable_reg
;
216 bank_reg
= rcg
->ns_reg
;
219 bank
= reg_to_bank(rcg
, *regp
);
220 new_bank
= enabled
? !bank
: bank
;
223 mn
= &rcg
->mn
[new_bank
];
224 md_reg
= rcg
->md_reg
[new_bank
];
226 ns
|= BIT(mn
->mnctr_reset_bit
);
227 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
229 regmap_read(rcg
->clkr
.regmap
, md_reg
, &md
);
230 md
= mn_to_md(mn
, f
->m
, f
->n
, md
);
231 regmap_write(rcg
->clkr
.regmap
, md_reg
, md
);
233 ns
= mn_to_ns(mn
, f
->m
, f
->n
, ns
);
234 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
236 ctl
= mn_to_reg(mn
, f
->m
, f
->n
, ctl
);
237 regmap_write(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, ctl
);
239 ns
&= ~BIT(mn
->mnctr_reset_bit
);
240 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
242 p
= &rcg
->p
[new_bank
];
243 ns
= pre_div_to_ns(p
, f
->pre_div
- 1, ns
);
246 s
= &rcg
->s
[new_bank
];
247 ns
= src_to_ns(s
, s
->parent_map
[f
->src
], ns
);
248 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
251 *regp
^= BIT(rcg
->mux_sel_bit
);
252 regmap_write(rcg
->clkr
.regmap
, bank_reg
, *regp
);
256 static int clk_dyn_rcg_set_parent(struct clk_hw
*hw
, u8 index
)
258 struct clk_dyn_rcg
*rcg
= to_clk_dyn_rcg(hw
);
259 u32 ns
, ctl
, md
, reg
;
261 struct freq_tbl f
= { 0 };
262 bool banked_mn
= !!rcg
->mn
[1].width
;
264 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
265 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, &ctl
);
266 reg
= banked_mn
? ctl
: ns
;
268 bank
= reg_to_bank(rcg
, reg
);
271 regmap_read(rcg
->clkr
.regmap
, rcg
->md_reg
[bank
], &md
);
272 f
.m
= md_to_m(&rcg
->mn
[bank
], md
);
273 f
.n
= ns_m_to_n(&rcg
->mn
[bank
], ns
, f
.m
);
275 f
.pre_div
= ns_to_pre_div(&rcg
->p
[bank
], ns
) + 1;
279 configure_bank(rcg
, &f
);
285 * Calculate m/n:d rate
288 * rate = ----------- x ---
292 calc_rate(unsigned long rate
, u32 m
, u32 n
, u32 mode
, u32 pre_div
)
308 clk_rcg_recalc_rate(struct clk_hw
*hw
, unsigned long parent_rate
)
310 struct clk_rcg
*rcg
= to_clk_rcg(hw
);
311 u32 pre_div
, m
= 0, n
= 0, ns
, md
, mode
= 0;
312 struct mn
*mn
= &rcg
->mn
;
314 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
315 pre_div
= ns_to_pre_div(&rcg
->p
, ns
);
318 regmap_read(rcg
->clkr
.regmap
, rcg
->md_reg
, &md
);
320 n
= ns_m_to_n(mn
, ns
, m
);
321 /* MN counter mode is in hw.enable_reg sometimes */
322 if (rcg
->clkr
.enable_reg
!= rcg
->ns_reg
)
323 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, &mode
);
326 mode
= reg_to_mnctr_mode(mn
, mode
);
329 return calc_rate(parent_rate
, m
, n
, mode
, pre_div
);
333 clk_dyn_rcg_recalc_rate(struct clk_hw
*hw
, unsigned long parent_rate
)
335 struct clk_dyn_rcg
*rcg
= to_clk_dyn_rcg(hw
);
336 u32 m
, n
, pre_div
, ns
, md
, mode
, reg
;
339 bool banked_mn
= !!rcg
->mn
[1].width
;
341 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
344 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, ®
);
348 bank
= reg_to_bank(rcg
, reg
);
352 regmap_read(rcg
->clkr
.regmap
, rcg
->md_reg
[bank
], &md
);
354 n
= ns_m_to_n(mn
, ns
, m
);
355 mode
= reg_to_mnctr_mode(mn
, reg
);
356 return calc_rate(parent_rate
, m
, n
, mode
, 0);
358 pre_div
= ns_to_pre_div(&rcg
->p
[bank
], ns
);
359 return calc_rate(parent_rate
, 0, 0, 0, pre_div
);
364 struct freq_tbl
*find_freq(const struct freq_tbl
*f
, unsigned long rate
)
376 static long _freq_tbl_determine_rate(struct clk_hw
*hw
,
377 const struct freq_tbl
*f
, unsigned long rate
,
378 unsigned long *p_rate
, struct clk
**p
)
380 unsigned long clk_flags
;
382 f
= find_freq(f
, rate
);
386 clk_flags
= __clk_get_flags(hw
->clk
);
387 *p
= clk_get_parent_by_index(hw
->clk
, f
->src
);
388 if (clk_flags
& CLK_SET_RATE_PARENT
) {
389 rate
= rate
* f
->pre_div
;
397 rate
= __clk_get_rate(*p
);
404 static long clk_rcg_determine_rate(struct clk_hw
*hw
, unsigned long rate
,
405 unsigned long *p_rate
, struct clk
**p
)
407 struct clk_rcg
*rcg
= to_clk_rcg(hw
);
409 return _freq_tbl_determine_rate(hw
, rcg
->freq_tbl
, rate
, p_rate
, p
);
412 static long clk_dyn_rcg_determine_rate(struct clk_hw
*hw
, unsigned long rate
,
413 unsigned long *p_rate
, struct clk
**p
)
415 struct clk_dyn_rcg
*rcg
= to_clk_dyn_rcg(hw
);
417 return _freq_tbl_determine_rate(hw
, rcg
->freq_tbl
, rate
, p_rate
, p
);
420 static int clk_rcg_set_rate(struct clk_hw
*hw
, unsigned long rate
,
421 unsigned long parent_rate
)
423 struct clk_rcg
*rcg
= to_clk_rcg(hw
);
424 const struct freq_tbl
*f
;
426 struct mn
*mn
= &rcg
->mn
;
428 unsigned int reset_reg
;
430 f
= find_freq(rcg
->freq_tbl
, rate
);
434 if (rcg
->mn
.reset_in_cc
)
435 reset_reg
= rcg
->clkr
.enable_reg
;
437 reset_reg
= rcg
->ns_reg
;
440 mask
= BIT(mn
->mnctr_reset_bit
);
441 regmap_update_bits(rcg
->clkr
.regmap
, reset_reg
, mask
, mask
);
443 regmap_read(rcg
->clkr
.regmap
, rcg
->md_reg
, &md
);
444 md
= mn_to_md(mn
, f
->m
, f
->n
, md
);
445 regmap_write(rcg
->clkr
.regmap
, rcg
->md_reg
, md
);
447 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
448 /* MN counter mode is in hw.enable_reg sometimes */
449 if (rcg
->clkr
.enable_reg
!= rcg
->ns_reg
) {
450 regmap_read(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, &ctl
);
451 ctl
= mn_to_reg(mn
, f
->m
, f
->n
, ctl
);
452 regmap_write(rcg
->clkr
.regmap
, rcg
->clkr
.enable_reg
, ctl
);
454 ns
= mn_to_reg(mn
, f
->m
, f
->n
, ns
);
456 ns
= mn_to_ns(mn
, f
->m
, f
->n
, ns
);
458 regmap_read(rcg
->clkr
.regmap
, rcg
->ns_reg
, &ns
);
461 ns
= pre_div_to_ns(&rcg
->p
, f
->pre_div
- 1, ns
);
462 regmap_write(rcg
->clkr
.regmap
, rcg
->ns_reg
, ns
);
464 regmap_update_bits(rcg
->clkr
.regmap
, reset_reg
, mask
, 0);
469 static int __clk_dyn_rcg_set_rate(struct clk_hw
*hw
, unsigned long rate
)
471 struct clk_dyn_rcg
*rcg
= to_clk_dyn_rcg(hw
);
472 const struct freq_tbl
*f
;
474 f
= find_freq(rcg
->freq_tbl
, rate
);
478 configure_bank(rcg
, f
);
483 static int clk_dyn_rcg_set_rate(struct clk_hw
*hw
, unsigned long rate
,
484 unsigned long parent_rate
)
486 return __clk_dyn_rcg_set_rate(hw
, rate
);
489 static int clk_dyn_rcg_set_rate_and_parent(struct clk_hw
*hw
,
490 unsigned long rate
, unsigned long parent_rate
, u8 index
)
492 return __clk_dyn_rcg_set_rate(hw
, rate
);
495 const struct clk_ops clk_rcg_ops
= {
496 .enable
= clk_enable_regmap
,
497 .disable
= clk_disable_regmap
,
498 .get_parent
= clk_rcg_get_parent
,
499 .set_parent
= clk_rcg_set_parent
,
500 .recalc_rate
= clk_rcg_recalc_rate
,
501 .determine_rate
= clk_rcg_determine_rate
,
502 .set_rate
= clk_rcg_set_rate
,
504 EXPORT_SYMBOL_GPL(clk_rcg_ops
);
506 const struct clk_ops clk_dyn_rcg_ops
= {
507 .enable
= clk_enable_regmap
,
508 .is_enabled
= clk_is_enabled_regmap
,
509 .disable
= clk_disable_regmap
,
510 .get_parent
= clk_dyn_rcg_get_parent
,
511 .set_parent
= clk_dyn_rcg_set_parent
,
512 .recalc_rate
= clk_dyn_rcg_recalc_rate
,
513 .determine_rate
= clk_dyn_rcg_determine_rate
,
514 .set_rate
= clk_dyn_rcg_set_rate
,
515 .set_rate_and_parent
= clk_dyn_rcg_set_rate_and_parent
,
517 EXPORT_SYMBOL_GPL(clk_dyn_rcg_ops
);