File Index
Files and directories
Sign in
FILE

ccu_mp.h

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/sunxi-ng/ccu_mp.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  4 */
  5
  6#ifndef _CCU_MP_H_
  7#define _CCU_MP_H_
  8
  9#include <linux/bitops.h>
 10#include <linux/clk-provider.h>
 11
 12#include "ccu_common.h"
 13#include "ccu_div.h"
 14#include "ccu_mult.h"
 15#include "ccu_mux.h"
 16
 17/*
 18 * struct ccu_mp - Definition of an M-P clock
 19 *
 20 * Clocks based on the formula parent >> P / M
 21 */
 22struct ccu_mp {
 23	u32			enable;
 24
 25	struct ccu_div_internal		m;
 26	struct ccu_div_internal		p;
 27	struct ccu_mux_internal	mux;
 28
 29	unsigned int		fixed_post_div;
 30
 31	struct ccu_common	common;
 32};
 33
 34#define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
 35					   _mshift, _mwidth,		\
 36					   _pshift, _pwidth,		\
 37					   _muxshift, _muxwidth,	\
 38					   _gate, _postdiv, _flags)	\
 39	struct ccu_mp _struct = {					\
 40		.enable	= _gate,					\
 41		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
 42		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
 43		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
 44		.fixed_post_div	= _postdiv,				\
 45		.common	= {						\
 46			.reg		= _reg,				\
 47			.features	= CCU_FEATURE_FIXED_POSTDIV,	\
 48			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
 49							      _parents, \
 50							      &ccu_mp_ops, \
 51							      _flags),	\
 52		}							\
 53	}
 54
 55#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, \
 56						_reg,			\
 57						_mshift, _mwidth,	\
 58						_pshift, _pwidth,	\
 59						_muxshift, _muxwidth,	\
 60						_gate, _postdiv, _flags)\
 61	struct ccu_mp _struct = {					\
 62		.enable	= _gate,					\
 63		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
 64		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
 65		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
 66		.fixed_post_div	= _postdiv,				\
 67		.common	= {						\
 68			.reg		= _reg,				\
 69			.features	= CCU_FEATURE_FIXED_POSTDIV,	\
 70			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \
 71							_parents,	\
 72							&ccu_mp_ops,	\
 73							_flags),	\
 74		}							\
 75	}
 76
 77#define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
 78				   _mshift, _mwidth,			\
 79				   _pshift, _pwidth,			\
 80				   _muxshift, _muxwidth,		\
 81				   _gate, _flags)			\
 82	struct ccu_mp _struct = {					\
 83		.enable	= _gate,					\
 84		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
 85		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
 86		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
 87		.common	= {						\
 88			.reg		= _reg,				\
 89			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
 90							      _parents, \
 91							      &ccu_mp_ops, \
 92							      _flags),	\
 93		}							\
 94	}
 95
 96#define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg,		\
 97			      _mshift, _mwidth,				\
 98			      _pshift, _pwidth,				\
 99			      _muxshift, _muxwidth,			\
100			      _flags)					\
101	SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
102				   _mshift, _mwidth,			\
103				   _pshift, _pwidth,			\
104				   _muxshift, _muxwidth,		\
105				   0, _flags)
106
107#define SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(_struct, _name, _parents, _reg, \
108					      _mshift, _mwidth,		\
109					      _pshift, _pwidth,		\
110					      _muxshift, _muxwidth,	\
111					      _gate, _postdiv,		\
112					      _flags)			\
113	struct ccu_mp _struct = {					\
114		.enable	= _gate,					\
115		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
116		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
117		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
118		.fixed_post_div = _postdiv,				\
119		.common	= {						\
120			.reg		= _reg,				\
121			.features	= CCU_FEATURE_FIXED_POSTDIV |	\
122						CCU_FEATURE_DUAL_DIV,	\
123			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \
124								   _parents, \
125								   &ccu_mp_ops, \
126								   _flags), \
127		}							\
128	}
129
130#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, _reg, \
131					     _mshift, _mwidth,		\
132					     _pshift, _pwidth,		\
133					     _muxshift, _muxwidth,	\
134					     _gate, _flags, _features)	\
135	struct ccu_mp _struct = {					\
136		.enable	= _gate,					\
137		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
138		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
139		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
140		.common	= {						\
141			.reg		= _reg,				\
142			.features	= _features,			\
143			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \
144								   _parents, \
145								   &ccu_mp_ops, \
146								   _flags), \
147		}							\
148	}
149
150#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
151					_mshift, _mwidth,		\
152					_pshift, _pwidth,		\
153					_muxshift, _muxwidth,		\
154					_gate, _flags)			\
155	SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents,	\
156					     _reg, _mshift, _mwidth,	\
157					     _pshift, _pwidth,		\
158					     _muxshift, _muxwidth,	\
159					     _gate, _flags, 0)
160
161#define SUNXI_CCU_DUALDIV_MUX_GATE(_struct, _name, _parents, _reg,	\
162				   _mshift, _mwidth,			\
163				   _pshift, _pwidth,			\
164				   _muxshift, _muxwidth,		\
165				   _gate, _flags)			\
166	SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents,	\
167					     _reg, _mshift, _mwidth,	\
168					     _pshift, _pwidth,		\
169					     _muxshift, _muxwidth,	\
170					     _gate, _flags,		\
171					     CCU_FEATURE_DUAL_DIV)
172
173#define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg,	\
174				   _mshift, _mwidth,			\
175				   _pshift, _pwidth,			\
176				   _muxshift, _muxwidth,		\
177				   _flags)				\
178	SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
179					_mshift, _mwidth,		\
180					_pshift, _pwidth,		\
181					_muxshift, _muxwidth,		\
182					0, _flags)
183
184#define SUNXI_CCU_MP_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
185				      _mshift, _mwidth,			\
186				      _pshift, _pwidth,			\
187				      _muxshift, _muxwidth,		\
188				      _gate, _flags)			\
189	struct ccu_mp _struct = {					\
190		.enable	= _gate,					\
191		.m	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
192		.p	= _SUNXI_CCU_DIV(_pshift, _pwidth),		\
193		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
194		.common	= {						\
195			.reg		= _reg,				\
196			.hw.init	= CLK_HW_INIT_PARENTS_HW(_name, \
197								 _parents, \
198								 &ccu_mp_ops, \
199								 _flags), \
200		}							\
201	}
202
203static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
204{
205	struct ccu_common *common = hw_to_ccu_common(hw);
206
207	return container_of(common, struct ccu_mp, common);
208}
209
210extern const struct clk_ops ccu_mp_ops;
211
212/*
213 * Special class of M-P clock that supports MMC timing modes
214 *
215 * Since the MMC clock registers all follow the same layout, we can
216 * simplify the macro for this particular case. In addition, as
217 * switching modes also affects the output clock rate, we need to
218 * have CLK_GET_RATE_NOCACHE for all these types of clocks.
219 */
220
221#define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
222				       _flags)				\
223	struct ccu_mp _struct = {					\
224		.enable	= BIT(31),					\
225		.m	= _SUNXI_CCU_DIV(0, 4),				\
226		.p	= _SUNXI_CCU_DIV(16, 2),			\
227		.mux	= _SUNXI_CCU_MUX(24, 2),			\
228		.common	= {						\
229			.reg		= _reg,				\
230			.features	= CCU_FEATURE_MMC_TIMING_SWITCH, \
231			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
232							      _parents, \
233							      &ccu_mp_mmc_ops, \
234							      CLK_GET_RATE_NOCACHE | \
235							      _flags),	\
236		}							\
237	}
238
239extern const struct clk_ops ccu_mp_mmc_ops;
240
241#endif /* _CCU_MP_H_ */
~/ Read-only file preview.