18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Maxime Ripard. All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _CCU_MP_H_
78c2ecf20Sopenharmony_ci#define _CCU_MP_H_
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/bitops.h>
108c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "ccu_common.h"
138c2ecf20Sopenharmony_ci#include "ccu_div.h"
148c2ecf20Sopenharmony_ci#include "ccu_mult.h"
158c2ecf20Sopenharmony_ci#include "ccu_mux.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/*
188c2ecf20Sopenharmony_ci * struct ccu_mp - Definition of an M-P clock
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci * Clocks based on the formula parent >> P / M
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_cistruct ccu_mp {
238c2ecf20Sopenharmony_ci	u32			enable;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	struct ccu_div_internal		m;
268c2ecf20Sopenharmony_ci	struct ccu_div_internal		p;
278c2ecf20Sopenharmony_ci	struct ccu_mux_internal	mux;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	unsigned int		fixed_post_div;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	struct ccu_common	common;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
358c2ecf20Sopenharmony_ci					   _mshift, _mwidth,		\
368c2ecf20Sopenharmony_ci					   _pshift, _pwidth,		\
378c2ecf20Sopenharmony_ci					   _muxshift, _muxwidth,	\
388c2ecf20Sopenharmony_ci					   _gate, _postdiv, _flags)	\
398c2ecf20Sopenharmony_ci	struct ccu_mp _struct = {					\
408c2ecf20Sopenharmony_ci		.enable	= _gate,					\
418c2ecf20Sopenharmony_ci		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
428c2ecf20Sopenharmony_ci		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
438c2ecf20Sopenharmony_ci		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
448c2ecf20Sopenharmony_ci		.fixed_post_div	= _postdiv,				\
458c2ecf20Sopenharmony_ci		.common	= {						\
468c2ecf20Sopenharmony_ci			.reg		= _reg,				\
478c2ecf20Sopenharmony_ci			.features	= CCU_FEATURE_FIXED_POSTDIV,	\
488c2ecf20Sopenharmony_ci			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
498c2ecf20Sopenharmony_ci							      _parents, \
508c2ecf20Sopenharmony_ci							      &ccu_mp_ops, \
518c2ecf20Sopenharmony_ci							      _flags),	\
528c2ecf20Sopenharmony_ci		}							\
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
568c2ecf20Sopenharmony_ci				   _mshift, _mwidth,			\
578c2ecf20Sopenharmony_ci				   _pshift, _pwidth,			\
588c2ecf20Sopenharmony_ci				   _muxshift, _muxwidth,		\
598c2ecf20Sopenharmony_ci				   _gate, _flags)			\
608c2ecf20Sopenharmony_ci	struct ccu_mp _struct = {					\
618c2ecf20Sopenharmony_ci		.enable	= _gate,					\
628c2ecf20Sopenharmony_ci		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
638c2ecf20Sopenharmony_ci		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
648c2ecf20Sopenharmony_ci		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
658c2ecf20Sopenharmony_ci		.common	= {						\
668c2ecf20Sopenharmony_ci			.reg		= _reg,				\
678c2ecf20Sopenharmony_ci			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
688c2ecf20Sopenharmony_ci							      _parents, \
698c2ecf20Sopenharmony_ci							      &ccu_mp_ops, \
708c2ecf20Sopenharmony_ci							      _flags),	\
718c2ecf20Sopenharmony_ci		}							\
728c2ecf20Sopenharmony_ci	}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg,		\
758c2ecf20Sopenharmony_ci			      _mshift, _mwidth,				\
768c2ecf20Sopenharmony_ci			      _pshift, _pwidth,				\
778c2ecf20Sopenharmony_ci			      _muxshift, _muxwidth,			\
788c2ecf20Sopenharmony_ci			      _flags)					\
798c2ecf20Sopenharmony_ci	SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
808c2ecf20Sopenharmony_ci				   _mshift, _mwidth,			\
818c2ecf20Sopenharmony_ci				   _pshift, _pwidth,			\
828c2ecf20Sopenharmony_ci				   _muxshift, _muxwidth,		\
838c2ecf20Sopenharmony_ci				   0, _flags)
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	struct ccu_common *common = hw_to_ccu_common(hw);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	return container_of(common, struct ccu_mp, common);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciextern const struct clk_ops ccu_mp_ops;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci/*
958c2ecf20Sopenharmony_ci * Special class of M-P clock that supports MMC timing modes
968c2ecf20Sopenharmony_ci *
978c2ecf20Sopenharmony_ci * Since the MMC clock registers all follow the same layout, we can
988c2ecf20Sopenharmony_ci * simplify the macro for this particular case. In addition, as
998c2ecf20Sopenharmony_ci * switching modes also affects the output clock rate, we need to
1008c2ecf20Sopenharmony_ci * have CLK_GET_RATE_NOCACHE for all these types of clocks.
1018c2ecf20Sopenharmony_ci */
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
1048c2ecf20Sopenharmony_ci				       _flags)				\
1058c2ecf20Sopenharmony_ci	struct ccu_mp _struct = {					\
1068c2ecf20Sopenharmony_ci		.enable	= BIT(31),					\
1078c2ecf20Sopenharmony_ci		.m	= _SUNXI_CCU_DIV(0, 4),				\
1088c2ecf20Sopenharmony_ci		.p	= _SUNXI_CCU_DIV(16, 2),			\
1098c2ecf20Sopenharmony_ci		.mux	= _SUNXI_CCU_MUX(24, 2),			\
1108c2ecf20Sopenharmony_ci		.common	= {						\
1118c2ecf20Sopenharmony_ci			.reg		= _reg,				\
1128c2ecf20Sopenharmony_ci			.features	= CCU_FEATURE_MMC_TIMING_SWITCH, \
1138c2ecf20Sopenharmony_ci			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
1148c2ecf20Sopenharmony_ci							      _parents, \
1158c2ecf20Sopenharmony_ci							      &ccu_mp_mmc_ops, \
1168c2ecf20Sopenharmony_ci							      CLK_GET_RATE_NOCACHE | \
1178c2ecf20Sopenharmony_ci							      _flags),	\
1188c2ecf20Sopenharmony_ci		}							\
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ciextern const struct clk_ops ccu_mp_mmc_ops;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci#endif /* _CCU_MP_H_ */
124