File Index
Files and directories
Sign in
FILE

ccu_mix.h

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/spacemit/ccu_mix.h OBJECTIVE-C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (c) 2024 SpacemiT Technology Co. Ltd
  4 * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>
  5 */
  6
  7#ifndef _CCU_MIX_H_
  8#define _CCU_MIX_H_
  9
 10#include <linux/clk-provider.h>
 11
 12#include "ccu_common.h"
 13
 14/**
 15 * struct ccu_gate_config - Gate configuration
 16 *
 17 * @mask:	Mask to enable the gate. Some clocks may have more than one bit
 18 *		set in this field.
 19 */
 20struct ccu_gate_config {
 21	u32 mask;
 22};
 23
 24struct ccu_factor_config {
 25	u32 div;
 26	u32 mul;
 27};
 28
 29struct ccu_mux_config {
 30	u8 shift;
 31	u8 width;
 32};
 33
 34struct ccu_div_config {
 35	u8 shift;
 36	u8 width;
 37};
 38
 39struct ccu_mix {
 40	struct ccu_factor_config factor;
 41	struct ccu_gate_config gate;
 42	struct ccu_div_config div;
 43	struct ccu_mux_config mux;
 44	struct ccu_common common;
 45};
 46
 47#define CCU_GATE_INIT(_mask)		{ .mask = _mask }
 48#define CCU_FACTOR_INIT(_div, _mul)	{ .div = _div, .mul = _mul }
 49#define CCU_MUX_INIT(_shift, _width)	{ .shift = _shift, .width = _width }
 50#define CCU_DIV_INIT(_shift, _width)	{ .shift = _shift, .width = _width }
 51
 52#define CCU_PARENT_HW(_parent)		{ .hw = &_parent.common.hw }
 53#define CCU_PARENT_NAME(_name)		{ .fw_name = #_name }
 54
 55#define CCU_MIX_INITHW(_name, _parent, _ops, _flags)			\
 56	.hw.init = &(struct clk_init_data) {				\
 57		.flags		= _flags,				\
 58		.name		= #_name,				\
 59		.parent_data	= (const struct clk_parent_data[])	\
 60					{ _parent },			\
 61		.num_parents	= 1,					\
 62		.ops		= &_ops,				\
 63	}
 64
 65#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags)		\
 66	.hw.init = CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, _flags)
 67
 68#define CCU_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _flags)		\
 69static struct ccu_mix _name = {							\
 70	.gate	= CCU_GATE_INIT(_mask_gate),					\
 71	.common	= {								\
 72		.reg_ctrl	= _reg_ctrl,					\
 73		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags),	\
 74	}									\
 75}
 76
 77#define CCU_FACTOR_DEFINE(_name, _parent, _div, _mul)				\
 78static struct ccu_mix _name = {							\
 79	.factor	= CCU_FACTOR_INIT(_div, _mul),					\
 80	.common = {								\
 81		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_ops, 0),	\
 82	}									\
 83}
 84
 85#define CCU_MUX_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, _flags)	\
 86static struct ccu_mix _name = {							\
 87	.mux	= CCU_MUX_INIT(_shift, _width),					\
 88	.common = {								\
 89		.reg_ctrl	= _reg_ctrl,					\
 90		CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops,	\
 91				       _flags),					\
 92	}									\
 93}
 94
 95#define CCU_DIV_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, _flags)	\
 96static struct ccu_mix _name = {							\
 97	.div	= CCU_DIV_INIT(_shift, _width),					\
 98	.common = {								\
 99		.reg_ctrl	= _reg_ctrl,					\
100		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_ops, _flags)	\
101	}									\
102}
103
104#define CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div,	\
105			       _mul, _flags)					\
106static struct ccu_mix _name = {							\
107	.gate	= CCU_GATE_INIT(_mask_gate),					\
108	.factor	= CCU_FACTOR_INIT(_div, _mul),					\
109	.common = {								\
110		.reg_ctrl	= _reg_ctrl,					\
111		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_gate_ops, _flags)	\
112	}									\
113}
114
115#define CCU_FACTOR_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div,	\
116			       _mul)						\
117	CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div,	\
118			       _mul, 0)
119
120#define CCU_MUX_GATE_DEFINE(_name, _parents, _reg_ctrl, _shift, _width,		\
121			    _mask_gate, _flags)					\
122static struct ccu_mix _name = {							\
123	.gate	= CCU_GATE_INIT(_mask_gate),					\
124	.mux	= CCU_MUX_INIT(_shift, _width),					\
125	.common = {								\
126		.reg_ctrl	= _reg_ctrl,					\
127		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
128				       spacemit_ccu_mux_gate_ops, _flags),	\
129	}									\
130}
131
132#define CCU_DIV_GATE_DEFINE(_name, _parent, _reg_ctrl, _shift, _width,		\
133			    _mask_gate,	_flags)					\
134static struct ccu_mix _name = {							\
135	.gate	= CCU_GATE_INIT(_mask_gate),					\
136	.div	= CCU_DIV_INIT(_shift, _width),					\
137	.common = {								\
138		.reg_ctrl	= _reg_ctrl,					\
139		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_gate_ops,	\
140			       _flags),						\
141	}									\
142}
143
144#define CCU_MUX_DIV_GATE_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth,	\
145				 _muxshift, _muxwidth, _mask_gate, _flags)	\
146static struct ccu_mix _name = {							\
147	.gate	= CCU_GATE_INIT(_mask_gate),					\
148	.div	= CCU_DIV_INIT(_mshift, _mwidth),				\
149	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth),				\
150	.common	= {								\
151		.reg_ctrl	= _reg_ctrl,					\
152		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
153				       spacemit_ccu_mux_div_gate_ops, _flags),	\
154	},									\
155}
156
157#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_fc,	\
158					 _mshift, _mwidth, _mask_fc, _muxshift,	\
159					 _muxwidth, _mask_gate, _flags)		\
160static struct ccu_mix _name = {							\
161	.gate	= CCU_GATE_INIT(_mask_gate),					\
162	.div	= CCU_DIV_INIT(_mshift, _mwidth),				\
163	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth),				\
164	.common = {								\
165		.reg_ctrl	= _reg_ctrl,					\
166		.reg_fc		= _reg_fc,					\
167		.mask_fc	= _mask_fc,					\
168		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
169				       spacemit_ccu_mux_div_gate_ops, _flags),	\
170	},									\
171}
172
173#define CCU_MUX_DIV_GATE_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth,\
174				   _mask_fc, _muxshift, _muxwidth, _mask_gate,	\
175				   _flags)					\
176CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_ctrl, _mshift,\
177				 _mwidth, _mask_fc, _muxshift, _muxwidth,	\
178				 _mask_gate, _flags)
179
180#define CCU_MUX_DIV_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth,	\
181			      _mask_fc, _muxshift, _muxwidth, _flags)		\
182static struct ccu_mix _name = {							\
183	.div	= CCU_DIV_INIT(_mshift, _mwidth),				\
184	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth),				\
185	.common = {								\
186		.reg_ctrl	= _reg_ctrl,					\
187		.reg_fc		= _reg_ctrl,					\
188		.mask_fc	= _mask_fc,					\
189		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
190				       spacemit_ccu_mux_div_ops, _flags),	\
191	},									\
192}
193
194#define CCU_MUX_FC_DEFINE(_name, _parents, _reg_ctrl, _mask_fc,	_muxshift,	\
195			  _muxwidth, _flags)					\
196static struct ccu_mix _name = {							\
197	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth),				\
198	.common = {								\
199		.reg_ctrl	= _reg_ctrl,					\
200		.reg_fc		= _reg_ctrl,					\
201		.mask_fc	= _mask_fc,					\
202		CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops,	\
203				       _flags)					\
204	},									\
205}
206
207static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw)
208{
209	struct ccu_common *common = hw_to_ccu_common(hw);
210
211	return container_of(common, struct ccu_mix, common);
212}
213
214extern const struct clk_ops spacemit_ccu_gate_ops;
215extern const struct clk_ops spacemit_ccu_factor_ops;
216extern const struct clk_ops spacemit_ccu_mux_ops;
217extern const struct clk_ops spacemit_ccu_div_ops;
218extern const struct clk_ops spacemit_ccu_factor_gate_ops;
219extern const struct clk_ops spacemit_ccu_div_gate_ops;
220extern const struct clk_ops spacemit_ccu_mux_gate_ops;
221extern const struct clk_ops spacemit_ccu_mux_div_ops;
222extern const struct clk_ops spacemit_ccu_mux_div_gate_ops;
223#endif /* _CCU_MIX_H_ */
~/ Read-only file preview.