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/bug.h>
18 #include <linux/export.h>
19 #include <linux/clk-provider.h>
20 #include <linux/delay.h>
21 #include <linux/regmap.h>
23 #include <asm/div64.h>
28 #define CMD_UPDATE BIT(0)
29 #define CMD_ROOT_EN BIT(1)
30 #define CMD_DIRTY_CFG BIT(4)
31 #define CMD_DIRTY_N BIT(5)
32 #define CMD_DIRTY_M BIT(6)
33 #define CMD_DIRTY_D BIT(7)
34 #define CMD_ROOT_OFF BIT(31)
37 #define CFG_SRC_DIV_SHIFT 0
38 #define CFG_SRC_SEL_SHIFT 8
39 #define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT)
40 #define CFG_MODE_SHIFT 12
41 #define CFG_MODE_MASK (0x3 << CFG_MODE_SHIFT)
42 #define CFG_MODE_DUAL_EDGE (0x2 << CFG_MODE_SHIFT)
48 static int clk_rcg2_is_enabled(struct clk_hw
*hw
)
50 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
54 ret
= regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CMD_REG
, &cmd
);
58 return (cmd
& CMD_ROOT_OFF
) != 0;
61 static u8
clk_rcg2_get_parent(struct clk_hw
*hw
)
63 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
64 int num_parents
= __clk_get_num_parents(hw
->clk
);
68 ret
= regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CFG_REG
, &cfg
);
72 cfg
&= CFG_SRC_SEL_MASK
;
73 cfg
>>= CFG_SRC_SEL_SHIFT
;
75 for (i
= 0; i
< num_parents
; i
++)
76 if (cfg
== rcg
->parent_map
[i
])
82 static int update_config(struct clk_rcg2
*rcg
)
86 struct clk_hw
*hw
= &rcg
->clkr
.hw
;
87 const char *name
= __clk_get_name(hw
->clk
);
89 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CMD_REG
,
90 CMD_UPDATE
, CMD_UPDATE
);
94 /* Wait for update to take effect */
95 for (count
= 500; count
> 0; count
--) {
96 ret
= regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CMD_REG
, &cmd
);
99 if (!(cmd
& CMD_UPDATE
))
104 WARN(1, "%s: rcg didn't update its configuration.", name
);
108 static int clk_rcg2_set_parent(struct clk_hw
*hw
, u8 index
)
110 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
113 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CFG_REG
,
115 rcg
->parent_map
[index
] << CFG_SRC_SEL_SHIFT
);
119 return update_config(rcg
);
123 * Calculate m/n:d rate
126 * rate = ----------- x ---
130 calc_rate(unsigned long rate
, u32 m
, u32 n
, u32 mode
, u32 hid_div
)
148 clk_rcg2_recalc_rate(struct clk_hw
*hw
, unsigned long parent_rate
)
150 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
151 u32 cfg
, hid_div
, m
= 0, n
= 0, mode
= 0, mask
;
153 regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CFG_REG
, &cfg
);
155 if (rcg
->mnd_width
) {
156 mask
= BIT(rcg
->mnd_width
) - 1;
157 regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ M_REG
, &m
);
159 regmap_read(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ N_REG
, &n
);
163 mode
= cfg
& CFG_MODE_MASK
;
164 mode
>>= CFG_MODE_SHIFT
;
167 mask
= BIT(rcg
->hid_width
) - 1;
168 hid_div
= cfg
>> CFG_SRC_DIV_SHIFT
;
171 return calc_rate(parent_rate
, m
, n
, mode
, hid_div
);
175 struct freq_tbl
*find_freq(const struct freq_tbl
*f
, unsigned long rate
)
187 static long _freq_tbl_determine_rate(struct clk_hw
*hw
,
188 const struct freq_tbl
*f
, unsigned long rate
,
189 unsigned long *p_rate
, struct clk
**p
)
191 unsigned long clk_flags
;
193 f
= find_freq(f
, rate
);
197 clk_flags
= __clk_get_flags(hw
->clk
);
198 *p
= clk_get_parent_by_index(hw
->clk
, f
->src
);
199 if (clk_flags
& CLK_SET_RATE_PARENT
) {
202 rate
*= f
->pre_div
+ 1;
212 rate
= __clk_get_rate(*p
);
219 static long clk_rcg2_determine_rate(struct clk_hw
*hw
, unsigned long rate
,
220 unsigned long *p_rate
, struct clk
**p
)
222 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
224 return _freq_tbl_determine_rate(hw
, rcg
->freq_tbl
, rate
, p_rate
, p
);
227 static int __clk_rcg2_set_rate(struct clk_hw
*hw
, unsigned long rate
)
229 struct clk_rcg2
*rcg
= to_clk_rcg2(hw
);
230 const struct freq_tbl
*f
;
234 f
= find_freq(rcg
->freq_tbl
, rate
);
238 if (rcg
->mnd_width
&& f
->n
) {
239 mask
= BIT(rcg
->mnd_width
) - 1;
240 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ M_REG
,
245 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ N_REG
,
246 mask
, ~(f
->n
- f
->m
));
250 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ D_REG
,
256 mask
= BIT(rcg
->hid_width
) - 1;
257 mask
|= CFG_SRC_SEL_MASK
| CFG_MODE_MASK
;
258 cfg
= f
->pre_div
<< CFG_SRC_DIV_SHIFT
;
259 cfg
|= rcg
->parent_map
[f
->src
] << CFG_SRC_SEL_SHIFT
;
260 if (rcg
->mnd_width
&& f
->n
)
261 cfg
|= CFG_MODE_DUAL_EDGE
;
262 ret
= regmap_update_bits(rcg
->clkr
.regmap
, rcg
->cmd_rcgr
+ CFG_REG
, mask
,
267 return update_config(rcg
);
270 static int clk_rcg2_set_rate(struct clk_hw
*hw
, unsigned long rate
,
271 unsigned long parent_rate
)
273 return __clk_rcg2_set_rate(hw
, rate
);
276 static int clk_rcg2_set_rate_and_parent(struct clk_hw
*hw
,
277 unsigned long rate
, unsigned long parent_rate
, u8 index
)
279 return __clk_rcg2_set_rate(hw
, rate
);
282 const struct clk_ops clk_rcg2_ops
= {
283 .is_enabled
= clk_rcg2_is_enabled
,
284 .get_parent
= clk_rcg2_get_parent
,
285 .set_parent
= clk_rcg2_set_parent
,
286 .recalc_rate
= clk_rcg2_recalc_rate
,
287 .determine_rate
= clk_rcg2_determine_rate
,
288 .set_rate
= clk_rcg2_set_rate
,
289 .set_rate_and_parent
= clk_rcg2_set_rate_and_parent
,
291 EXPORT_SYMBOL_GPL(clk_rcg2_ops
);