Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
Loading...
v5.14.15
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  4 */
  5
  6#ifndef _CCU_DIV_H_
  7#define _CCU_DIV_H_
  8
  9#include <linux/clk-provider.h>
 10
 11#include "ccu_common.h"
 12#include "ccu_mux.h"
 13
 14/**
 15 * struct ccu_div_internal - Internal divider description
 16 * @shift: Bit offset of the divider in its register
 17 * @width: Width of the divider field in its register
 18 * @max: Maximum value allowed for that divider. This is the
 19 *       arithmetic value, not the maximum value to be set in the
 20 *       register.
 21 * @flags: clk_divider flags to apply on this divider
 22 * @table: Divider table pointer (if applicable)
 23 *
 24 * That structure represents a single divider, and is meant to be
 25 * embedded in other structures representing the various clock
 26 * classes.
 27 *
 28 * It is basically a wrapper around the clk_divider functions
 29 * arguments.
 30 */
 31struct ccu_div_internal {
 32	u8			shift;
 33	u8			width;
 34
 35	u32			max;
 36	u32			offset;
 37
 38	u32			flags;
 39
 40	struct clk_div_table	*table;
 41};
 42
 43#define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags)	\
 44	{								\
 45		.shift	= _shift,					\
 46		.width	= _width,					\
 47		.flags	= _flags,					\
 48		.table	= _table,					\
 49	}
 50
 51#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)			\
 52	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
 53
 54#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
 55	{								\
 56		.shift	= _shift,					\
 57		.width	= _width,					\
 58		.flags	= _flags,					\
 59		.max	= _max,						\
 60		.offset	= _off,						\
 61	}
 62
 63#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)		\
 64	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
 65
 66#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)			\
 67	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
 68
 69#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)			\
 70	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
 71
 72#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)			\
 73	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
 74
 75#define _SUNXI_CCU_DIV(_shift, _width)					\
 76	_SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
 77
 78struct ccu_div {
 79	u32			enable;
 80
 81	struct ccu_div_internal	div;
 82	struct ccu_mux_internal	mux;
 83	struct ccu_common	common;
 84	unsigned int		fixed_post_div;
 85};
 86
 87#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
 88				      _shift, _width,			\
 89				      _table, _gate, _flags)		\
 90	struct ccu_div _struct = {					\
 91		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\
 92						       _table),		\
 93		.enable		= _gate,				\
 94		.common	= {						\
 95			.reg		= _reg,				\
 96			.hw.init	= CLK_HW_INIT(_name,		\
 97						      _parent,		\
 98						      &ccu_div_ops,	\
 99						      _flags),		\
100		}							\
101	}
102
103
104#define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg,		\
105			    _shift, _width,				\
106			    _table, _flags)				\
107	SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
108				      _shift, _width, _table, 0,	\
109				      _flags)
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
112					_parents, _table,		\
113					_reg,				\
114					_mshift, _mwidth,		\
115					_muxshift, _muxwidth,		\
116					_gate, _flags)			\
117	struct ccu_div _struct = {					\
118		.enable	= _gate,					\
119		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
120		.mux	= _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
121		.common	= {						\
122			.reg		= _reg,				\
123			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
124							      _parents, \
125							      &ccu_div_ops, \
126							      _flags),	\
127		},							\
128	}
129
130#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
131				  _mshift, _mwidth, _muxshift, _muxwidth, \
132				  _gate, _flags)			\
133	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
134					_parents, NULL,			\
135					_reg, _mshift, _mwidth,		\
136					_muxshift, _muxwidth,		\
137					_gate, _flags)
138
139#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,		\
140			     _mshift, _mwidth, _muxshift, _muxwidth,	\
141			     _flags)					\
142	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
143					_parents, NULL,			\
144					_reg, _mshift, _mwidth,		\
145					_muxshift, _muxwidth,		\
146					0, _flags)
147
148
149#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
150			      _mshift, _mwidth,	_gate,			\
151			      _flags)					\
152	struct ccu_div _struct = {					\
153		.enable	= _gate,					\
154		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
155		.common	= {						\
156			.reg		= _reg,				\
157			.hw.init	= CLK_HW_INIT(_name,		\
158						      _parent,		\
159						      &ccu_div_ops,	\
160						      _flags),		\
161		},							\
162	}
163
164#define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth,	\
165		    _flags)						\
166	SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
167			      _mshift, _mwidth, 0, _flags)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
169static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
170{
171	struct ccu_common *common = hw_to_ccu_common(hw);
172
173	return container_of(common, struct ccu_div, common);
174}
175
176extern const struct clk_ops ccu_div_ops;
177
178#endif /* _CCU_DIV_H_ */
v6.2
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  4 */
  5
  6#ifndef _CCU_DIV_H_
  7#define _CCU_DIV_H_
  8
  9#include <linux/clk-provider.h>
 10
 11#include "ccu_common.h"
 12#include "ccu_mux.h"
 13
 14/**
 15 * struct ccu_div_internal - Internal divider description
 16 * @shift: Bit offset of the divider in its register
 17 * @width: Width of the divider field in its register
 18 * @max: Maximum value allowed for that divider. This is the
 19 *       arithmetic value, not the maximum value to be set in the
 20 *       register.
 21 * @flags: clk_divider flags to apply on this divider
 22 * @table: Divider table pointer (if applicable)
 23 *
 24 * That structure represents a single divider, and is meant to be
 25 * embedded in other structures representing the various clock
 26 * classes.
 27 *
 28 * It is basically a wrapper around the clk_divider functions
 29 * arguments.
 30 */
 31struct ccu_div_internal {
 32	u8			shift;
 33	u8			width;
 34
 35	u32			max;
 36	u32			offset;
 37
 38	u32			flags;
 39
 40	struct clk_div_table	*table;
 41};
 42
 43#define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags)	\
 44	{								\
 45		.shift	= _shift,					\
 46		.width	= _width,					\
 47		.flags	= _flags,					\
 48		.table	= _table,					\
 49	}
 50
 51#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)			\
 52	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
 53
 54#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
 55	{								\
 56		.shift	= _shift,					\
 57		.width	= _width,					\
 58		.flags	= _flags,					\
 59		.max	= _max,						\
 60		.offset	= _off,						\
 61	}
 62
 63#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)		\
 64	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
 65
 66#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)			\
 67	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
 68
 69#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)			\
 70	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
 71
 72#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)			\
 73	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
 74
 75#define _SUNXI_CCU_DIV(_shift, _width)					\
 76	_SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
 77
 78struct ccu_div {
 79	u32			enable;
 80
 81	struct ccu_div_internal	div;
 82	struct ccu_mux_internal	mux;
 83	struct ccu_common	common;
 84	unsigned int		fixed_post_div;
 85};
 86
 87#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
 88				      _shift, _width,			\
 89				      _table, _gate, _flags)		\
 90	struct ccu_div _struct = {					\
 91		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\
 92						       _table),		\
 93		.enable		= _gate,				\
 94		.common	= {						\
 95			.reg		= _reg,				\
 96			.hw.init	= CLK_HW_INIT(_name,		\
 97						      _parent,		\
 98						      &ccu_div_ops,	\
 99						      _flags),		\
100		}							\
101	}
102
103
104#define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg,		\
105			    _shift, _width,				\
106			    _table, _flags)				\
107	SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
108				      _shift, _width, _table, 0,	\
109				      _flags)
110
111#define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg,		\
112			       _shift, _width,				\
113			       _table, _flags)				\
114	struct ccu_div _struct = {					\
115		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\
116						       _table),		\
117		.common	= {						\
118			.reg		= _reg,				\
119			.hw.init	= CLK_HW_INIT_HW(_name,		\
120							 _parent,	\
121							 &ccu_div_ops,	\
122							 _flags),	\
123		}							\
124	}
125
126
127#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
128					_parents, _table,		\
129					_reg,				\
130					_mshift, _mwidth,		\
131					_muxshift, _muxwidth,		\
132					_gate, _flags)			\
133	struct ccu_div _struct = {					\
134		.enable	= _gate,					\
135		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
136		.mux	= _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
137		.common	= {						\
138			.reg		= _reg,				\
139			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
140							      _parents, \
141							      &ccu_div_ops, \
142							      _flags),	\
143		},							\
144	}
145
146#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
147				  _mshift, _mwidth, _muxshift, _muxwidth, \
148				  _gate, _flags)			\
149	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
150					_parents, NULL,			\
151					_reg, _mshift, _mwidth,		\
152					_muxshift, _muxwidth,		\
153					_gate, _flags)
154
155#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,		\
156			     _mshift, _mwidth, _muxshift, _muxwidth,	\
157			     _flags)					\
158	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\
159					_parents, NULL,			\
160					_reg, _mshift, _mwidth,		\
161					_muxshift, _muxwidth,		\
162					0, _flags)
163
164
165#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
166			      _mshift, _mwidth,	_gate,			\
167			      _flags)					\
168	struct ccu_div _struct = {					\
169		.enable	= _gate,					\
170		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
171		.common	= {						\
172			.reg		= _reg,				\
173			.hw.init	= CLK_HW_INIT(_name,		\
174						      _parent,		\
175						      &ccu_div_ops,	\
176						      _flags),		\
177		},							\
178	}
179
180#define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth,	\
181		    _flags)						\
182	SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
183			      _mshift, _mwidth, 0, _flags)
184
185#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
186				       _mshift, _mwidth,		\
187				       _muxshift, _muxwidth,		\
188				       _gate, _flags)			\
189	struct ccu_div _struct = {					\
190		.enable	= _gate,					\
191		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
192		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
193		.common	= {						\
194			.reg		= _reg,				\
195			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \
196								   _parents, \
197								   &ccu_div_ops, \
198								   _flags), \
199		},							\
200	}
201
202#define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg,	\
203				  _mshift, _mwidth,			\
204				  _muxshift, _muxwidth,			\
205				  _flags)				\
206	SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,  \
207				       _mshift, _mwidth,		\
208				       _muxshift, _muxwidth,		\
209				       0, _flags)
210
211#define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
212				     _mshift, _mwidth, _muxshift, _muxwidth, \
213				     _gate, _flags)			\
214	struct ccu_div _struct = {					\
215		.enable	= _gate,					\
216		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
217		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\
218		.common	= {						\
219			.reg		= _reg,				\
220			.hw.init	= CLK_HW_INIT_PARENTS_HW(_name,	\
221								 _parents, \
222								 &ccu_div_ops, \
223								 _flags), \
224		},							\
225	}
226
227#define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,	\
228				  _mshift, _mwidth, _gate,		\
229				  _flags)				\
230	struct ccu_div _struct = {					\
231		.enable	= _gate,					\
232		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
233		.common	= {						\
234			.reg		= _reg,				\
235			.hw.init	= CLK_HW_INIT_HWS(_name,	\
236							  _parent,	\
237							  &ccu_div_ops,	\
238							  _flags),	\
239		},							\
240	}
241
242#define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift,		\
243			_mwidth, _flags)				\
244	SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,	\
245				  _mshift, _mwidth, 0, _flags)
246
247static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
248{
249	struct ccu_common *common = hw_to_ccu_common(hw);
250
251	return container_of(common, struct ccu_div, common);
252}
253
254extern const struct clk_ops ccu_div_ops;
255
256#endif /* _CCU_DIV_H_ */