1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar>
5 * Adjustable factor-based clock implementation
8 #include <linux/clk-provider.h>
9 #include <linux/delay.h>
10 #include <linux/err.h>
12 #include <linux/of_address.h>
13 #include <linux/slab.h>
14 #include <linux/string.h>
16 #include "clk-factors.h"
19 * DOC: basic adjustable factor-based clock
21 * Traits of this clock:
22 * prepare - clk_prepare only ensures that parents are prepared
23 * enable - clk_enable only ensures that parents are enabled
24 * rate - rate is adjustable.
25 * clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1)
26 * parent - fixed parent. No clk_set_parent support
29 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
31 #define FACTORS_MAX_PARENTS 5
33 #define SETMASK(len, pos) (((1U << (len)) - 1) << (pos))
34 #define CLRMASK(len, pos) (~(SETMASK(len, pos)))
35 #define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
37 #define FACTOR_SET(bit, len, reg, val) \
38 (((reg) & CLRMASK(len, bit)) | (val << (bit)))
40 static unsigned long clk_factors_recalc_rate(struct clk_hw
*hw
,
41 unsigned long parent_rate
)
43 u8 n
= 1, k
= 0, p
= 0, m
= 0;
46 struct clk_factors
*factors
= to_clk_factors(hw
);
47 const struct clk_factors_config
*config
= factors
->config
;
49 /* Fetch the register value */
50 reg
= readl(factors
->reg
);
52 /* Get each individual factor if applicable */
53 if (config
->nwidth
!= SUNXI_FACTORS_NOT_APPLICABLE
)
54 n
= FACTOR_GET(config
->nshift
, config
->nwidth
, reg
);
55 if (config
->kwidth
!= SUNXI_FACTORS_NOT_APPLICABLE
)
56 k
= FACTOR_GET(config
->kshift
, config
->kwidth
, reg
);
57 if (config
->mwidth
!= SUNXI_FACTORS_NOT_APPLICABLE
)
58 m
= FACTOR_GET(config
->mshift
, config
->mwidth
, reg
);
59 if (config
->pwidth
!= SUNXI_FACTORS_NOT_APPLICABLE
)
60 p
= FACTOR_GET(config
->pshift
, config
->pwidth
, reg
);
62 if (factors
->recalc
) {
63 struct factors_request factors_req
= {
64 .parent_rate
= parent_rate
,
71 /* get mux details from mux clk structure */
73 factors_req
.parent_index
=
74 (reg
>> factors
->mux
->shift
) &
77 factors
->recalc(&factors_req
);
79 return factors_req
.rate
;
82 /* Calculate the rate */
83 rate
= (parent_rate
* (n
+ config
->n_start
) * (k
+ 1) >> p
) / (m
+ 1);
88 static int clk_factors_determine_rate(struct clk_hw
*hw
,
89 struct clk_rate_request
*req
)
91 struct clk_factors
*factors
= to_clk_factors(hw
);
92 struct clk_hw
*parent
, *best_parent
= NULL
;
94 unsigned long parent_rate
, best
= 0, child_rate
, best_child_rate
= 0;
96 /* find the parent that can help provide the fastest rate <= rate */
97 num_parents
= clk_hw_get_num_parents(hw
);
98 for (i
= 0; i
< num_parents
; i
++) {
99 struct factors_request factors_req
= {
103 parent
= clk_hw_get_parent_by_index(hw
, i
);
106 if (clk_hw_get_flags(hw
) & CLK_SET_RATE_PARENT
)
107 parent_rate
= clk_hw_round_rate(parent
, req
->rate
);
109 parent_rate
= clk_hw_get_rate(parent
);
111 factors_req
.parent_rate
= parent_rate
;
112 factors
->get_factors(&factors_req
);
113 child_rate
= factors_req
.rate
;
115 if (child_rate
<= req
->rate
&& child_rate
> best_child_rate
) {
116 best_parent
= parent
;
118 best_child_rate
= child_rate
;
125 req
->best_parent_hw
= best_parent
;
126 req
->best_parent_rate
= best
;
127 req
->rate
= best_child_rate
;
132 static int clk_factors_set_rate(struct clk_hw
*hw
, unsigned long rate
,
133 unsigned long parent_rate
)
135 struct factors_request req
= {
137 .parent_rate
= parent_rate
,
140 struct clk_factors
*factors
= to_clk_factors(hw
);
141 const struct clk_factors_config
*config
= factors
->config
;
142 unsigned long flags
= 0;
144 factors
->get_factors(&req
);
147 spin_lock_irqsave(factors
->lock
, flags
);
149 /* Fetch the register value */
150 reg
= readl(factors
->reg
);
152 /* Set up the new factors - macros do not do anything if width is 0 */
153 reg
= FACTOR_SET(config
->nshift
, config
->nwidth
, reg
, req
.n
);
154 reg
= FACTOR_SET(config
->kshift
, config
->kwidth
, reg
, req
.k
);
155 reg
= FACTOR_SET(config
->mshift
, config
->mwidth
, reg
, req
.m
);
156 reg
= FACTOR_SET(config
->pshift
, config
->pwidth
, reg
, req
.p
);
159 writel(reg
, factors
->reg
);
161 /* delay 500us so pll stabilizes */
162 __delay((rate
>> 20) * 500 / 2);
165 spin_unlock_irqrestore(factors
->lock
, flags
);
170 static const struct clk_ops clk_factors_ops
= {
171 .determine_rate
= clk_factors_determine_rate
,
172 .recalc_rate
= clk_factors_recalc_rate
,
173 .set_rate
= clk_factors_set_rate
,
176 static struct clk
*__sunxi_factors_register(struct device_node
*node
,
177 const struct factors_data
*data
,
178 spinlock_t
*lock
, void __iomem
*reg
,
182 struct clk_factors
*factors
;
183 struct clk_gate
*gate
= NULL
;
184 struct clk_mux
*mux
= NULL
;
185 struct clk_hw
*gate_hw
= NULL
;
186 struct clk_hw
*mux_hw
= NULL
;
187 const char *clk_name
= node
->name
;
188 const char *parents
[FACTORS_MAX_PARENTS
];
191 /* if we have a mux, we will have >1 parents */
192 i
= of_clk_parent_fill(node
, parents
, FACTORS_MAX_PARENTS
);
195 * some factor clocks, such as pll5 and pll6, may have multiple
196 * outputs, and have their name designated in factors_data
199 clk_name
= data
->name
;
201 of_property_read_string(node
, "clock-output-names", &clk_name
);
203 factors
= kzalloc(sizeof(struct clk_factors
), GFP_KERNEL
);
207 /* set up factors properties */
209 factors
->config
= data
->table
;
210 factors
->get_factors
= data
->getter
;
211 factors
->recalc
= data
->recalc
;
212 factors
->lock
= lock
;
214 /* Add a gate if this factor clock can be gated */
216 gate
= kzalloc(sizeof(struct clk_gate
), GFP_KERNEL
);
220 factors
->gate
= gate
;
222 /* set up gate properties */
224 gate
->bit_idx
= data
->enable
;
225 gate
->lock
= factors
->lock
;
229 /* Add a mux if this factor clock can be muxed */
231 mux
= kzalloc(sizeof(struct clk_mux
), GFP_KERNEL
);
237 /* set up gate properties */
239 mux
->shift
= data
->mux
;
240 mux
->mask
= data
->muxmask
;
241 mux
->lock
= factors
->lock
;
245 clk
= clk_register_composite(NULL
, clk_name
,
247 mux_hw
, &clk_mux_ops
,
248 &factors
->hw
, &clk_factors_ops
,
249 gate_hw
, &clk_gate_ops
, CLK_IS_CRITICAL
);
253 ret
= of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
260 /* TODO: The composite clock stuff will leak a bit here. */
272 struct clk
*sunxi_factors_register(struct device_node
*node
,
273 const struct factors_data
*data
,
277 return __sunxi_factors_register(node
, data
, lock
, reg
, 0);
280 struct clk
*sunxi_factors_register_critical(struct device_node
*node
,
281 const struct factors_data
*data
,
285 return __sunxi_factors_register(node
, data
, lock
, reg
, CLK_IS_CRITICAL
);
288 void sunxi_factors_unregister(struct device_node
*node
, struct clk
*clk
)
290 struct clk_hw
*hw
= __clk_get_hw(clk
);
291 struct clk_factors
*factors
;
296 factors
= to_clk_factors(hw
);
298 of_clk_del_provider(node
);
299 /* TODO: The composite clock stuff will leak a bit here. */
302 kfree(factors
->gate
);