1 // SPDX-License-Identifier: GPL-2.0
3 // Spreadtrum divider clock driver
5 // Copyright (C) 2017 Spreadtrum, Inc.
6 // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
8 #include <linux/clk-provider.h>
12 long sprd_div_helper_round_rate(struct sprd_clk_common
*common
,
13 const struct sprd_div_internal
*div
,
15 unsigned long *parent_rate
)
17 return divider_round_rate(&common
->hw
, rate
, parent_rate
,
20 EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate
);
22 static long sprd_div_round_rate(struct clk_hw
*hw
, unsigned long rate
,
23 unsigned long *parent_rate
)
25 struct sprd_div
*cd
= hw_to_sprd_div(hw
);
27 return sprd_div_helper_round_rate(&cd
->common
, &cd
->div
,
31 unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common
*common
,
32 const struct sprd_div_internal
*div
,
33 unsigned long parent_rate
)
38 regmap_read(common
->regmap
, common
->reg
, ®
);
39 val
= reg
>> div
->shift
;
40 val
&= (1 << div
->width
) - 1;
42 return divider_recalc_rate(&common
->hw
, parent_rate
, val
, NULL
, 0,
45 EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate
);
47 static unsigned long sprd_div_recalc_rate(struct clk_hw
*hw
,
48 unsigned long parent_rate
)
50 struct sprd_div
*cd
= hw_to_sprd_div(hw
);
52 return sprd_div_helper_recalc_rate(&cd
->common
, &cd
->div
, parent_rate
);
55 int sprd_div_helper_set_rate(const struct sprd_clk_common
*common
,
56 const struct sprd_div_internal
*div
,
58 unsigned long parent_rate
)
63 val
= divider_get_val(rate
, parent_rate
, NULL
,
66 regmap_read(common
->regmap
, common
->reg
, ®
);
67 reg
&= ~GENMASK(div
->width
+ div
->shift
- 1, div
->shift
);
69 regmap_write(common
->regmap
, common
->reg
,
70 reg
| (val
<< div
->shift
));
75 EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate
);
77 static int sprd_div_set_rate(struct clk_hw
*hw
, unsigned long rate
,
78 unsigned long parent_rate
)
80 struct sprd_div
*cd
= hw_to_sprd_div(hw
);
82 return sprd_div_helper_set_rate(&cd
->common
, &cd
->div
,
86 const struct clk_ops sprd_div_ops
= {
87 .recalc_rate
= sprd_div_recalc_rate
,
88 .round_rate
= sprd_div_round_rate
,
89 .set_rate
= sprd_div_set_rate
,
91 EXPORT_SYMBOL_GPL(sprd_div_ops
);