1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
7 #include <linux/clk-provider.h>
8 #include <linux/module.h>
10 #include "clk-regmap.h"
11 #include "clk-cpu-dyndiv.h"
13 static inline struct meson_clk_cpu_dyndiv_data
*
14 meson_clk_cpu_dyndiv_data(struct clk_regmap
*clk
)
16 return (struct meson_clk_cpu_dyndiv_data
*)clk
->data
;
19 static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw
*hw
,
22 struct clk_regmap
*clk
= to_clk_regmap(hw
);
23 struct meson_clk_cpu_dyndiv_data
*data
= meson_clk_cpu_dyndiv_data(clk
);
25 return divider_recalc_rate(hw
, prate
,
26 meson_parm_read(clk
->map
, &data
->div
),
27 NULL
, 0, data
->div
.width
);
30 static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw
*hw
,
34 struct clk_regmap
*clk
= to_clk_regmap(hw
);
35 struct meson_clk_cpu_dyndiv_data
*data
= meson_clk_cpu_dyndiv_data(clk
);
37 return divider_round_rate(hw
, rate
, prate
, NULL
, data
->div
.width
, 0);
40 static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw
*hw
, unsigned long rate
,
41 unsigned long parent_rate
)
43 struct clk_regmap
*clk
= to_clk_regmap(hw
);
44 struct meson_clk_cpu_dyndiv_data
*data
= meson_clk_cpu_dyndiv_data(clk
);
48 ret
= divider_get_val(rate
, parent_rate
, NULL
, data
->div
.width
, 0);
52 val
= (unsigned int)ret
<< data
->div
.shift
;
54 /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */
55 meson_parm_write(clk
->map
, &data
->dyn
, 1);
57 /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */
58 return regmap_update_bits(clk
->map
, data
->div
.reg_off
,
59 SETPMASK(data
->div
.width
, data
->div
.shift
) |
60 SETPMASK(data
->dyn
.width
, data
->dyn
.shift
),
64 const struct clk_ops meson_clk_cpu_dyndiv_ops
= {
65 .recalc_rate
= meson_clk_cpu_dyndiv_recalc_rate
,
66 .round_rate
= meson_clk_cpu_dyndiv_round_rate
,
67 .set_rate
= meson_clk_cpu_dyndiv_set_rate
,
69 EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops
);
71 MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider");
72 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
73 MODULE_LICENSE("GPL v2");