|  | /* SPDX-License-Identifier: GPL-2.0-only */ | 
|  | /* | 
|  | * Copyright (c) 2016 Maxime Ripard. All rights reserved. | 
|  | */ | 
|  |  | 
|  | #ifndef _CCU_NM_H_ | 
|  | #define _CCU_NM_H_ | 
|  |  | 
|  | #include <linux/clk-provider.h> | 
|  |  | 
|  | #include "ccu_common.h" | 
|  | #include "ccu_div.h" | 
|  | #include "ccu_frac.h" | 
|  | #include "ccu_mult.h" | 
|  | #include "ccu_sdm.h" | 
|  |  | 
|  | /* | 
|  | * struct ccu_nm - Definition of an N-M clock | 
|  | * | 
|  | * Clocks based on the formula parent * N / M | 
|  | */ | 
|  | struct ccu_nm { | 
|  | u32			enable; | 
|  | u32			lock; | 
|  |  | 
|  | struct ccu_mult_internal	n; | 
|  | struct ccu_div_internal		m; | 
|  | struct ccu_frac_internal	frac; | 
|  | struct ccu_sdm_internal		sdm; | 
|  |  | 
|  | unsigned int		fixed_post_div; | 
|  | unsigned int		min_rate; | 
|  | unsigned int		max_rate; | 
|  |  | 
|  | struct ccu_common	common; | 
|  | }; | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg,	\ | 
|  | _nshift, _nwidth,		\ | 
|  | _mshift, _mwidth,		\ | 
|  | _sdm_table, _sdm_en,		\ | 
|  | _sdm_reg, _sdm_reg_en,		\ | 
|  | _gate, _lock, _flags)		\ | 
|  | struct ccu_nm _struct = {					\ | 
|  | .enable		= _gate,				\ | 
|  | .lock		= _lock,				\ | 
|  | .n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\ | 
|  | .m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\ | 
|  | .sdm		= _SUNXI_CCU_SDM(_sdm_table, _sdm_en,	\ | 
|  | _sdm_reg, _sdm_reg_en),\ | 
|  | .common		= {					\ | 
|  | .reg		= _reg,				\ | 
|  | .features	= CCU_FEATURE_SIGMA_DELTA_MOD,	\ | 
|  | .hw.init	= CLK_HW_INIT(_name,		\ | 
|  | _parent,		\ | 
|  | &ccu_nm_ops,	\ | 
|  | _flags),		\ | 
|  | },							\ | 
|  | } | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg,	\ | 
|  | _nshift, _nwidth,		\ | 
|  | _mshift, _mwidth,		\ | 
|  | _frac_en, _frac_sel,		\ | 
|  | _frac_rate_0, _frac_rate_1,	\ | 
|  | _gate, _lock, _flags)		\ | 
|  | struct ccu_nm _struct = {					\ | 
|  | .enable		= _gate,				\ | 
|  | .lock		= _lock,				\ | 
|  | .n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\ | 
|  | .m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\ | 
|  | .frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1),	\ | 
|  | .common		= {					\ | 
|  | .reg		= _reg,				\ | 
|  | .features	= CCU_FEATURE_FRACTIONAL,	\ | 
|  | .hw.init	= CLK_HW_INIT(_name,		\ | 
|  | _parent,		\ | 
|  | &ccu_nm_ops,	\ | 
|  | _flags),		\ | 
|  | },							\ | 
|  | } | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent,	\ | 
|  | _reg, _min_rate,		\ | 
|  | _nshift, _nwidth,		\ | 
|  | _mshift, _mwidth,		\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0, _frac_rate_1,\ | 
|  | _gate, _lock, _flags)	\ | 
|  | struct ccu_nm _struct = {					\ | 
|  | .enable		= _gate,				\ | 
|  | .lock		= _lock,				\ | 
|  | .n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\ | 
|  | .m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\ | 
|  | .frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1),	\ | 
|  | .min_rate	= _min_rate,				\ | 
|  | .common		= {					\ | 
|  | .reg		= _reg,				\ | 
|  | .features	= CCU_FEATURE_FRACTIONAL,	\ | 
|  | .hw.init	= CLK_HW_INIT(_name,		\ | 
|  | _parent,		\ | 
|  | &ccu_nm_ops,	\ | 
|  | _flags),		\ | 
|  | },							\ | 
|  | } | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\ | 
|  | _parent, _reg,		\ | 
|  | _min_rate, _max_rate,	\ | 
|  | _nshift, _nwidth,	\ | 
|  | _mshift, _mwidth,	\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1,		\ | 
|  | _gate, _lock, _flags,	\ | 
|  | _features)		\ | 
|  | struct ccu_nm _struct = {					\ | 
|  | .enable		= _gate,				\ | 
|  | .lock		= _lock,				\ | 
|  | .n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\ | 
|  | .m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\ | 
|  | .frac		= _SUNXI_CCU_FRAC(_frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1),	\ | 
|  | .min_rate	= _min_rate,				\ | 
|  | .max_rate	= _max_rate,				\ | 
|  | .common		= {					\ | 
|  | .reg		= _reg,				\ | 
|  | .features	= _features,			\ | 
|  | .hw.init	= CLK_HW_INIT(_name,		\ | 
|  | _parent,		\ | 
|  | &ccu_nm_ops,	\ | 
|  | _flags),		\ | 
|  | },							\ | 
|  | } | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name,	\ | 
|  | _parent, _reg,		\ | 
|  | _min_rate, _max_rate,	\ | 
|  | _nshift, _nwidth,	\ | 
|  | _mshift, _mwidth,	\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1,		\ | 
|  | _gate, _lock, _flags)	\ | 
|  | SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\ | 
|  | _parent, _reg,		\ | 
|  | _min_rate, _max_rate,	\ | 
|  | _nshift, _nwidth,	\ | 
|  | _mshift, _mwidth,	\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1,		\ | 
|  | _gate, _lock, _flags,	\ | 
|  | CCU_FEATURE_FRACTIONAL) | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \ | 
|  | _parent, _reg,		\ | 
|  | _min_rate, _max_rate,	\ | 
|  | _nshift, _nwidth,	\ | 
|  | _mshift, _mwidth,	\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1,		\ | 
|  | _gate, _lock, _flags)	\ | 
|  | SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,	\ | 
|  | _parent, _reg,		\ | 
|  | _min_rate, _max_rate,	\ | 
|  | _nshift, _nwidth,	\ | 
|  | _mshift, _mwidth,	\ | 
|  | _frac_en, _frac_sel,	\ | 
|  | _frac_rate_0,		\ | 
|  | _frac_rate_1,		\ | 
|  | _gate, _lock, _flags,	\ | 
|  | CCU_FEATURE_FRACTIONAL |\ | 
|  | CCU_FEATURE_CLOSEST_RATE) | 
|  |  | 
|  | #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg,	\ | 
|  | _nshift, _nwidth,			\ | 
|  | _mshift, _mwidth,			\ | 
|  | _gate, _lock, _flags)		\ | 
|  | struct ccu_nm _struct = {					\ | 
|  | .enable		= _gate,				\ | 
|  | .lock		= _lock,				\ | 
|  | .n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\ | 
|  | .m		= _SUNXI_CCU_DIV(_mshift, _mwidth),	\ | 
|  | .common		= {					\ | 
|  | .reg		= _reg,				\ | 
|  | .hw.init	= CLK_HW_INIT(_name,		\ | 
|  | _parent,		\ | 
|  | &ccu_nm_ops,	\ | 
|  | _flags),		\ | 
|  | },							\ | 
|  | } | 
|  |  | 
|  | static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw) | 
|  | { | 
|  | struct ccu_common *common = hw_to_ccu_common(hw); | 
|  |  | 
|  | return container_of(common, struct ccu_nm, common); | 
|  | } | 
|  |  | 
|  | extern const struct clk_ops ccu_nm_ops; | 
|  |  | 
|  | #endif /* _CCU_NM_H_ */ |