1 // SPDX-License-Identifier: GPL-2.0
3 * Zynq UltraScale+ MPSoC Divider support
5 * Copyright (C) 2016-2019 Xilinx
7 * Adjustable divider clock implementation
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
12 #include <linux/slab.h>
13 #include "clk-zynqmp.h"
16 * DOC: basic adjustable divider clock that cannot gate
18 * Traits of this clock:
19 * prepare - clk_prepare only ensures that parents are prepared
20 * enable - clk_enable only ensures that parents are enabled
21 * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor)
22 * parent - fixed parent. No clk_set_parent support
25 #define to_zynqmp_clk_divider(_hw) \
26 container_of(_hw, struct zynqmp_clk_divider, hw)
28 #define CLK_FRAC BIT(13) /* has a fractional parent */
29 #define CUSTOM_FLAG_CLK_FRAC BIT(0) /* has a fractional parent in custom type flag */
32 * struct zynqmp_clk_divider - adjustable divider clock
33 * @hw: handle between common and hardware-specific interfaces
34 * @flags: Hardware specific flags
35 * @is_frac: The divider is a fractional divider
36 * @clk_id: Id of clock
37 * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2)
38 * @max_div: maximum supported divisor (fetched from firmware)
40 struct zynqmp_clk_divider
{
49 static inline int zynqmp_divider_get_val(unsigned long parent_rate
,
50 unsigned long rate
, u16 flags
)
53 unsigned long up_rate
, down_rate
;
55 if (flags
& CLK_DIVIDER_POWER_OF_TWO
) {
56 up
= DIV_ROUND_UP_ULL((u64
)parent_rate
, rate
);
57 down
= DIV_ROUND_DOWN_ULL((u64
)parent_rate
, rate
);
59 up
= __roundup_pow_of_two(up
);
60 down
= __rounddown_pow_of_two(down
);
62 up_rate
= DIV_ROUND_UP_ULL((u64
)parent_rate
, up
);
63 down_rate
= DIV_ROUND_UP_ULL((u64
)parent_rate
, down
);
65 return (rate
- up_rate
) <= (down_rate
- rate
) ? up
: down
;
68 return DIV_ROUND_CLOSEST(parent_rate
, rate
);
73 * zynqmp_clk_divider_recalc_rate() - Recalc rate of divider clock
74 * @hw: handle between common and hardware-specific interfaces
75 * @parent_rate: rate of parent clock
77 * Return: 0 on success else error+reason
79 static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw
*hw
,
80 unsigned long parent_rate
)
82 struct zynqmp_clk_divider
*divider
= to_zynqmp_clk_divider(hw
);
83 const char *clk_name
= clk_hw_get_name(hw
);
84 u32 clk_id
= divider
->clk_id
;
85 u32 div_type
= divider
->div_type
;
89 ret
= zynqmp_pm_clock_getdivider(clk_id
, &div
);
92 pr_debug("%s() get divider failed for %s, ret = %d\n",
93 __func__
, clk_name
, ret
);
95 if (div_type
== TYPE_DIV1
)
100 if (divider
->flags
& CLK_DIVIDER_POWER_OF_TWO
)
104 WARN(!(divider
->flags
& CLK_DIVIDER_ALLOW_ZERO
),
105 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
110 return DIV_ROUND_UP_ULL(parent_rate
, value
);
114 * zynqmp_clk_divider_round_rate() - Round rate of divider clock
115 * @hw: handle between common and hardware-specific interfaces
116 * @rate: rate of clock to be set
117 * @prate: rate of parent clock
119 * Return: 0 on success else error+reason
121 static long zynqmp_clk_divider_round_rate(struct clk_hw
*hw
,
123 unsigned long *prate
)
125 struct zynqmp_clk_divider
*divider
= to_zynqmp_clk_divider(hw
);
126 const char *clk_name
= clk_hw_get_name(hw
);
127 u32 clk_id
= divider
->clk_id
;
128 u32 div_type
= divider
->div_type
;
133 /* if read only, just return current value */
134 if (divider
->flags
& CLK_DIVIDER_READ_ONLY
) {
135 ret
= zynqmp_pm_clock_getdivider(clk_id
, &bestdiv
);
138 pr_debug("%s() get divider failed for %s, ret = %d\n",
139 __func__
, clk_name
, ret
);
140 if (div_type
== TYPE_DIV1
)
141 bestdiv
= bestdiv
& 0xFFFF;
143 bestdiv
= bestdiv
>> 16;
145 if (divider
->flags
& CLK_DIVIDER_POWER_OF_TWO
)
146 bestdiv
= 1 << bestdiv
;
148 return DIV_ROUND_UP_ULL((u64
)*prate
, bestdiv
);
151 width
= fls(divider
->max_div
);
153 rate
= divider_round_rate(hw
, rate
, prate
, NULL
, width
, divider
->flags
);
155 if (divider
->is_frac
&& (clk_hw_get_flags(hw
) & CLK_SET_RATE_PARENT
) && (rate
% *prate
))
162 * zynqmp_clk_divider_set_rate() - Set rate of divider clock
163 * @hw: handle between common and hardware-specific interfaces
164 * @rate: rate of clock to be set
165 * @parent_rate: rate of parent clock
167 * Return: 0 on success else error+reason
169 static int zynqmp_clk_divider_set_rate(struct clk_hw
*hw
, unsigned long rate
,
170 unsigned long parent_rate
)
172 struct zynqmp_clk_divider
*divider
= to_zynqmp_clk_divider(hw
);
173 const char *clk_name
= clk_hw_get_name(hw
);
174 u32 clk_id
= divider
->clk_id
;
175 u32 div_type
= divider
->div_type
;
179 value
= zynqmp_divider_get_val(parent_rate
, rate
, divider
->flags
);
180 if (div_type
== TYPE_DIV1
) {
181 div
= value
& 0xFFFF;
188 if (divider
->flags
& CLK_DIVIDER_POWER_OF_TWO
)
191 ret
= zynqmp_pm_clock_setdivider(clk_id
, div
);
194 pr_debug("%s() set divider failed for %s, ret = %d\n",
195 __func__
, clk_name
, ret
);
200 static const struct clk_ops zynqmp_clk_divider_ops
= {
201 .recalc_rate
= zynqmp_clk_divider_recalc_rate
,
202 .round_rate
= zynqmp_clk_divider_round_rate
,
203 .set_rate
= zynqmp_clk_divider_set_rate
,
206 static const struct clk_ops zynqmp_clk_divider_ro_ops
= {
207 .recalc_rate
= zynqmp_clk_divider_recalc_rate
,
208 .round_rate
= zynqmp_clk_divider_round_rate
,
212 * zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware.
213 * @clk_id: Id of clock
214 * @type: Divider type
216 * Return: Maximum divisor of a clock if query data is successful
217 * U16_MAX in case of query data is not success
219 static u32
zynqmp_clk_get_max_divisor(u32 clk_id
, u32 type
)
221 struct zynqmp_pm_query_data qdata
= {0};
222 u32 ret_payload
[PAYLOAD_ARG_CNT
];
225 qdata
.qid
= PM_QID_CLOCK_GET_MAX_DIVISOR
;
228 ret
= zynqmp_pm_query_data(qdata
, ret_payload
);
230 * To maintain backward compatibility return maximum possible value
231 * (0xFFFF) if query for max divisor is not successful.
236 return ret_payload
[1];
239 static inline unsigned long zynqmp_clk_map_divider_ccf_flags(
240 const u32 zynqmp_type_flag
)
242 unsigned long ccf_flag
= 0;
244 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_ONE_BASED
)
245 ccf_flag
|= CLK_DIVIDER_ONE_BASED
;
246 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_POWER_OF_TWO
)
247 ccf_flag
|= CLK_DIVIDER_POWER_OF_TWO
;
248 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_ALLOW_ZERO
)
249 ccf_flag
|= CLK_DIVIDER_ALLOW_ZERO
;
250 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_POWER_OF_TWO
)
251 ccf_flag
|= CLK_DIVIDER_HIWORD_MASK
;
252 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_ROUND_CLOSEST
)
253 ccf_flag
|= CLK_DIVIDER_ROUND_CLOSEST
;
254 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_READ_ONLY
)
255 ccf_flag
|= CLK_DIVIDER_READ_ONLY
;
256 if (zynqmp_type_flag
& ZYNQMP_CLK_DIVIDER_MAX_AT_ZERO
)
257 ccf_flag
|= CLK_DIVIDER_MAX_AT_ZERO
;
263 * zynqmp_clk_register_divider() - Register a divider clock
264 * @name: Name of this clock
265 * @clk_id: Id of clock
266 * @parents: Name of this clock's parents
267 * @num_parents: Number of parents
268 * @nodes: Clock topology node
270 * Return: clock hardware to registered clock divider
272 struct clk_hw
*zynqmp_clk_register_divider(const char *name
,
274 const char * const *parents
,
276 const struct clock_topology
*nodes
)
278 struct zynqmp_clk_divider
*div
;
280 struct clk_init_data init
;
283 /* allocate the divider */
284 div
= kzalloc(sizeof(*div
), GFP_KERNEL
);
286 return ERR_PTR(-ENOMEM
);
289 if (nodes
->type_flag
& CLK_DIVIDER_READ_ONLY
)
290 init
.ops
= &zynqmp_clk_divider_ro_ops
;
292 init
.ops
= &zynqmp_clk_divider_ops
;
294 init
.flags
= zynqmp_clk_map_common_ccf_flags(nodes
->flag
);
296 init
.parent_names
= parents
;
297 init
.num_parents
= 1;
299 /* struct clk_divider assignments */
300 div
->is_frac
= !!((nodes
->flag
& CLK_FRAC
) |
301 (nodes
->custom_type_flag
& CUSTOM_FLAG_CLK_FRAC
));
302 div
->flags
= zynqmp_clk_map_divider_ccf_flags(nodes
->type_flag
);
303 div
->hw
.init
= &init
;
304 div
->clk_id
= clk_id
;
305 div
->div_type
= nodes
->type
;
308 * To achieve best possible rate, maximum limit of divider is required
311 div
->max_div
= zynqmp_clk_get_max_divisor(clk_id
, nodes
->type
);
314 ret
= clk_hw_register(NULL
, hw
);