From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- drivers/clk/sunxi-ng/ccu_mp.h | 172 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu_mp.h (limited to 'drivers/clk/sunxi-ng/ccu_mp.h') diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h new file mode 100644 index 000000000..6e50f3728 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_mp.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016 Maxime Ripard. All rights reserved. + */ + +#ifndef _CCU_MP_H_ +#define _CCU_MP_H_ + +#include +#include + +#include "ccu_common.h" +#include "ccu_div.h" +#include "ccu_mult.h" +#include "ccu_mux.h" + +/* + * struct ccu_mp - Definition of an M-P clock + * + * Clocks based on the formula parent >> P / M + */ +struct ccu_mp { + u32 enable; + + struct ccu_div_internal m; + struct ccu_div_internal p; + struct ccu_mux_internal mux; + + unsigned int fixed_post_div; + + struct ccu_common common; +}; + +#define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _postdiv, _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .fixed_post_div = _postdiv, \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_FIXED_POSTDIV, \ + .hw.init = CLK_HW_INIT_PARENTS(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + +#define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + +#define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _flags) \ + SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + 0, _flags) + +#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + +#define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _flags) \ + SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + 0, _flags) + +#define SUNXI_CCU_MP_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_HW(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + +static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_mp, common); +} + +extern const struct clk_ops ccu_mp_ops; + +/* + * Special class of M-P clock that supports MMC timing modes + * + * Since the MMC clock registers all follow the same layout, we can + * simplify the macro for this particular case. In addition, as + * switching modes also affects the output clock rate, we need to + * have CLK_GET_RATE_NOCACHE for all these types of clocks. + */ + +#define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _flags) \ + struct ccu_mp _struct = { \ + .enable = BIT(31), \ + .m = _SUNXI_CCU_DIV(0, 4), \ + .p = _SUNXI_CCU_DIV(16, 2), \ + .mux = _SUNXI_CCU_MUX(24, 2), \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_MMC_TIMING_SWITCH, \ + .hw.init = CLK_HW_INIT_PARENTS(_name, \ + _parents, \ + &ccu_mp_mmc_ops, \ + CLK_GET_RATE_NOCACHE | \ + _flags), \ + } \ + } + +extern const struct clk_ops ccu_mp_mmc_ops; + +#endif /* _CCU_MP_H_ */ -- cgit v1.2.3