162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2016 Maxime Ripard. All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _CCU_NM_H_
762306a36Sopenharmony_ci#define _CCU_NM_H_
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/clk-provider.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "ccu_common.h"
1262306a36Sopenharmony_ci#include "ccu_div.h"
1362306a36Sopenharmony_ci#include "ccu_frac.h"
1462306a36Sopenharmony_ci#include "ccu_mult.h"
1562306a36Sopenharmony_ci#include "ccu_sdm.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/*
1862306a36Sopenharmony_ci * struct ccu_nm - Definition of an N-M clock
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * Clocks based on the formula parent * N / M
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_cistruct ccu_nm {
2362306a36Sopenharmony_ci	u32			enable;
2462306a36Sopenharmony_ci	u32			lock;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	struct ccu_mult_internal	n;
2762306a36Sopenharmony_ci	struct ccu_div_internal		m;
2862306a36Sopenharmony_ci	struct ccu_frac_internal	frac;
2962306a36Sopenharmony_ci	struct ccu_sdm_internal		sdm;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	unsigned int		fixed_post_div;
3262306a36Sopenharmony_ci	unsigned int		min_rate;
3362306a36Sopenharmony_ci	unsigned int		max_rate;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	struct ccu_common	common;
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg,	\
3962306a36Sopenharmony_ci					_nshift, _nwidth,		\
4062306a36Sopenharmony_ci					_mshift, _mwidth,		\
4162306a36Sopenharmony_ci					_sdm_table, _sdm_en,		\
4262306a36Sopenharmony_ci					_sdm_reg, _sdm_reg_en,		\
4362306a36Sopenharmony_ci					_gate, _lock, _flags)		\
4462306a36Sopenharmony_ci	struct ccu_nm _struct = {					\
4562306a36Sopenharmony_ci		.enable		= _gate,				\
4662306a36Sopenharmony_ci		.lock		= _lock,				\
4762306a36Sopenharmony_ci		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
4862306a36Sopenharmony_ci		.m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\
4962306a36Sopenharmony_ci		.sdm		= _SUNXI_CCU_SDM(_sdm_table, _sdm_en,	\
5062306a36Sopenharmony_ci						 _sdm_reg, _sdm_reg_en),\
5162306a36Sopenharmony_ci		.common		= {					\
5262306a36Sopenharmony_ci			.reg		= _reg,				\
5362306a36Sopenharmony_ci			.features	= CCU_FEATURE_SIGMA_DELTA_MOD,	\
5462306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
5562306a36Sopenharmony_ci						      _parent,		\
5662306a36Sopenharmony_ci						      &ccu_nm_ops,	\
5762306a36Sopenharmony_ci						      _flags),		\
5862306a36Sopenharmony_ci		},							\
5962306a36Sopenharmony_ci	}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg,	\
6262306a36Sopenharmony_ci					 _nshift, _nwidth,		\
6362306a36Sopenharmony_ci					 _mshift, _mwidth,		\
6462306a36Sopenharmony_ci					 _frac_en, _frac_sel,		\
6562306a36Sopenharmony_ci					 _frac_rate_0, _frac_rate_1,	\
6662306a36Sopenharmony_ci					 _gate, _lock, _flags)		\
6762306a36Sopenharmony_ci	struct ccu_nm _struct = {					\
6862306a36Sopenharmony_ci		.enable		= _gate,				\
6962306a36Sopenharmony_ci		.lock		= _lock,				\
7062306a36Sopenharmony_ci		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
7162306a36Sopenharmony_ci		.m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\
7262306a36Sopenharmony_ci		.frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\
7362306a36Sopenharmony_ci						  _frac_rate_0,		\
7462306a36Sopenharmony_ci						  _frac_rate_1),	\
7562306a36Sopenharmony_ci		.common		= {					\
7662306a36Sopenharmony_ci			.reg		= _reg,				\
7762306a36Sopenharmony_ci			.features	= CCU_FEATURE_FRACTIONAL,	\
7862306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
7962306a36Sopenharmony_ci						      _parent,		\
8062306a36Sopenharmony_ci						      &ccu_nm_ops,	\
8162306a36Sopenharmony_ci						      _flags),		\
8262306a36Sopenharmony_ci		},							\
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent,	\
8662306a36Sopenharmony_ci					     _reg, _min_rate,		\
8762306a36Sopenharmony_ci					     _nshift, _nwidth,		\
8862306a36Sopenharmony_ci					     _mshift, _mwidth,		\
8962306a36Sopenharmony_ci					     _frac_en, _frac_sel,	\
9062306a36Sopenharmony_ci					     _frac_rate_0, _frac_rate_1,\
9162306a36Sopenharmony_ci					     _gate, _lock, _flags)	\
9262306a36Sopenharmony_ci	struct ccu_nm _struct = {					\
9362306a36Sopenharmony_ci		.enable		= _gate,				\
9462306a36Sopenharmony_ci		.lock		= _lock,				\
9562306a36Sopenharmony_ci		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
9662306a36Sopenharmony_ci		.m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\
9762306a36Sopenharmony_ci		.frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\
9862306a36Sopenharmony_ci						  _frac_rate_0,		\
9962306a36Sopenharmony_ci						  _frac_rate_1),	\
10062306a36Sopenharmony_ci		.min_rate	= _min_rate,				\
10162306a36Sopenharmony_ci		.common		= {					\
10262306a36Sopenharmony_ci			.reg		= _reg,				\
10362306a36Sopenharmony_ci			.features	= CCU_FEATURE_FRACTIONAL,	\
10462306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
10562306a36Sopenharmony_ci						      _parent,		\
10662306a36Sopenharmony_ci						      &ccu_nm_ops,	\
10762306a36Sopenharmony_ci						      _flags),		\
10862306a36Sopenharmony_ci		},							\
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\
11262306a36Sopenharmony_ci						 _parent, _reg,		\
11362306a36Sopenharmony_ci						 _min_rate, _max_rate,	\
11462306a36Sopenharmony_ci						 _nshift, _nwidth,	\
11562306a36Sopenharmony_ci						 _mshift, _mwidth,	\
11662306a36Sopenharmony_ci						 _frac_en, _frac_sel,	\
11762306a36Sopenharmony_ci						 _frac_rate_0,		\
11862306a36Sopenharmony_ci						 _frac_rate_1,		\
11962306a36Sopenharmony_ci						 _gate, _lock, _flags,	\
12062306a36Sopenharmony_ci						 _features)		\
12162306a36Sopenharmony_ci	struct ccu_nm _struct = {					\
12262306a36Sopenharmony_ci		.enable		= _gate,				\
12362306a36Sopenharmony_ci		.lock		= _lock,				\
12462306a36Sopenharmony_ci		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
12562306a36Sopenharmony_ci		.m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\
12662306a36Sopenharmony_ci		.frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\
12762306a36Sopenharmony_ci						  _frac_rate_0,		\
12862306a36Sopenharmony_ci						  _frac_rate_1),	\
12962306a36Sopenharmony_ci		.min_rate	= _min_rate,				\
13062306a36Sopenharmony_ci		.max_rate	= _max_rate,				\
13162306a36Sopenharmony_ci		.common		= {					\
13262306a36Sopenharmony_ci			.reg		= _reg,				\
13362306a36Sopenharmony_ci			.features	= _features,			\
13462306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
13562306a36Sopenharmony_ci						      _parent,		\
13662306a36Sopenharmony_ci						      &ccu_nm_ops,	\
13762306a36Sopenharmony_ci						      _flags),		\
13862306a36Sopenharmony_ci		},							\
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name,	\
14262306a36Sopenharmony_ci						 _parent, _reg,		\
14362306a36Sopenharmony_ci						 _min_rate, _max_rate,	\
14462306a36Sopenharmony_ci						 _nshift, _nwidth,	\
14562306a36Sopenharmony_ci						 _mshift, _mwidth,	\
14662306a36Sopenharmony_ci						 _frac_en, _frac_sel,	\
14762306a36Sopenharmony_ci						 _frac_rate_0,		\
14862306a36Sopenharmony_ci						 _frac_rate_1,		\
14962306a36Sopenharmony_ci						 _gate, _lock, _flags)	\
15062306a36Sopenharmony_ci	SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\
15162306a36Sopenharmony_ci						_parent, _reg,		\
15262306a36Sopenharmony_ci						_min_rate, _max_rate,	\
15362306a36Sopenharmony_ci						_nshift, _nwidth,	\
15462306a36Sopenharmony_ci						_mshift, _mwidth,	\
15562306a36Sopenharmony_ci						_frac_en, _frac_sel,	\
15662306a36Sopenharmony_ci						_frac_rate_0,		\
15762306a36Sopenharmony_ci						_frac_rate_1,		\
15862306a36Sopenharmony_ci						_gate, _lock, _flags,	\
15962306a36Sopenharmony_ci						CCU_FEATURE_FRACTIONAL)
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \
16262306a36Sopenharmony_ci						 _parent, _reg,		\
16362306a36Sopenharmony_ci						 _min_rate, _max_rate,	\
16462306a36Sopenharmony_ci						 _nshift, _nwidth,	\
16562306a36Sopenharmony_ci						 _mshift, _mwidth,	\
16662306a36Sopenharmony_ci						 _frac_en, _frac_sel,	\
16762306a36Sopenharmony_ci						 _frac_rate_0,		\
16862306a36Sopenharmony_ci						 _frac_rate_1,		\
16962306a36Sopenharmony_ci						 _gate, _lock, _flags)	\
17062306a36Sopenharmony_ci	SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\
17162306a36Sopenharmony_ci						_parent, _reg,		\
17262306a36Sopenharmony_ci						_min_rate, _max_rate,	\
17362306a36Sopenharmony_ci						_nshift, _nwidth,	\
17462306a36Sopenharmony_ci						_mshift, _mwidth,	\
17562306a36Sopenharmony_ci						_frac_en, _frac_sel,	\
17662306a36Sopenharmony_ci						_frac_rate_0,		\
17762306a36Sopenharmony_ci						_frac_rate_1,		\
17862306a36Sopenharmony_ci						_gate, _lock, _flags,	\
17962306a36Sopenharmony_ci						CCU_FEATURE_FRACTIONAL |\
18062306a36Sopenharmony_ci						CCU_FEATURE_CLOSEST_RATE)
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg,	\
18362306a36Sopenharmony_ci				    _nshift, _nwidth,			\
18462306a36Sopenharmony_ci				    _mshift, _mwidth,			\
18562306a36Sopenharmony_ci				    _gate, _lock, _flags)		\
18662306a36Sopenharmony_ci	struct ccu_nm _struct = {					\
18762306a36Sopenharmony_ci		.enable		= _gate,				\
18862306a36Sopenharmony_ci		.lock		= _lock,				\
18962306a36Sopenharmony_ci		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
19062306a36Sopenharmony_ci		.m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\
19162306a36Sopenharmony_ci		.common		= {					\
19262306a36Sopenharmony_ci			.reg		= _reg,				\
19362306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
19462306a36Sopenharmony_ci						      _parent,		\
19562306a36Sopenharmony_ci						      &ccu_nm_ops,	\
19662306a36Sopenharmony_ci						      _flags),		\
19762306a36Sopenharmony_ci		},							\
19862306a36Sopenharmony_ci	}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	struct ccu_common *common = hw_to_ccu_common(hw);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	return container_of(common, struct ccu_nm, common);
20562306a36Sopenharmony_ci}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciextern const struct clk_ops ccu_nm_ops;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci#endif /* _CCU_NM_H_ */
210