210 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.4 */5 6#ifndef _CCU_NM_H_7#define _CCU_NM_H_8 9#include <linux/clk-provider.h>10 11#include "ccu_common.h"12#include "ccu_div.h"13#include "ccu_frac.h"14#include "ccu_mult.h"15#include "ccu_sdm.h"16 17/*18 * struct ccu_nm - Definition of an N-M clock19 *20 * Clocks based on the formula parent * N / M21 */22struct ccu_nm {23 u32 enable;24 u32 lock;25 26 struct ccu_mult_internal n;27 struct ccu_div_internal m;28 struct ccu_frac_internal frac;29 struct ccu_sdm_internal sdm;30 31 unsigned int fixed_post_div;32 unsigned int min_rate;33 unsigned int max_rate;34 35 struct ccu_common common;36};37 38#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \39 _nshift, _nwidth, \40 _mshift, _mwidth, \41 _sdm_table, _sdm_en, \42 _sdm_reg, _sdm_reg_en, \43 _gate, _lock, _flags) \44 struct ccu_nm _struct = { \45 .enable = _gate, \46 .lock = _lock, \47 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \48 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \49 .sdm = _SUNXI_CCU_SDM(_sdm_table, _sdm_en, \50 _sdm_reg, _sdm_reg_en),\51 .common = { \52 .reg = _reg, \53 .features = CCU_FEATURE_SIGMA_DELTA_MOD, \54 .hw.init = CLK_HW_INIT(_name, \55 _parent, \56 &ccu_nm_ops, \57 _flags), \58 }, \59 }60 61#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \62 _nshift, _nwidth, \63 _mshift, _mwidth, \64 _frac_en, _frac_sel, \65 _frac_rate_0, _frac_rate_1, \66 _gate, _lock, _flags) \67 struct ccu_nm _struct = { \68 .enable = _gate, \69 .lock = _lock, \70 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \71 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \72 .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \73 _frac_rate_0, \74 _frac_rate_1), \75 .common = { \76 .reg = _reg, \77 .features = CCU_FEATURE_FRACTIONAL, \78 .hw.init = CLK_HW_INIT(_name, \79 _parent, \80 &ccu_nm_ops, \81 _flags), \82 }, \83 }84 85#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent, \86 _reg, _min_rate, \87 _nshift, _nwidth, \88 _mshift, _mwidth, \89 _frac_en, _frac_sel, \90 _frac_rate_0, _frac_rate_1,\91 _gate, _lock, _flags) \92 struct ccu_nm _struct = { \93 .enable = _gate, \94 .lock = _lock, \95 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \96 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \97 .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \98 _frac_rate_0, \99 _frac_rate_1), \100 .min_rate = _min_rate, \101 .common = { \102 .reg = _reg, \103 .features = CCU_FEATURE_FRACTIONAL, \104 .hw.init = CLK_HW_INIT(_name, \105 _parent, \106 &ccu_nm_ops, \107 _flags), \108 }, \109 }110 111#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \112 _parent, _reg, \113 _min_rate, _max_rate, \114 _nshift, _nwidth, \115 _mshift, _mwidth, \116 _frac_en, _frac_sel, \117 _frac_rate_0, \118 _frac_rate_1, \119 _gate, _lock, _flags, \120 _features) \121 struct ccu_nm _struct = { \122 .enable = _gate, \123 .lock = _lock, \124 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \125 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \126 .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \127 _frac_rate_0, \128 _frac_rate_1), \129 .min_rate = _min_rate, \130 .max_rate = _max_rate, \131 .common = { \132 .reg = _reg, \133 .features = _features, \134 .hw.init = CLK_HW_INIT(_name, \135 _parent, \136 &ccu_nm_ops, \137 _flags), \138 }, \139 }140 141#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \142 _parent, _reg, \143 _min_rate, _max_rate, \144 _nshift, _nwidth, \145 _mshift, _mwidth, \146 _frac_en, _frac_sel, \147 _frac_rate_0, \148 _frac_rate_1, \149 _gate, _lock, _flags) \150 SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \151 _parent, _reg, \152 _min_rate, _max_rate, \153 _nshift, _nwidth, \154 _mshift, _mwidth, \155 _frac_en, _frac_sel, \156 _frac_rate_0, \157 _frac_rate_1, \158 _gate, _lock, _flags, \159 CCU_FEATURE_FRACTIONAL)160 161#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \162 _parent, _reg, \163 _min_rate, _max_rate, \164 _nshift, _nwidth, \165 _mshift, _mwidth, \166 _frac_en, _frac_sel, \167 _frac_rate_0, \168 _frac_rate_1, \169 _gate, _lock, _flags) \170 SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \171 _parent, _reg, \172 _min_rate, _max_rate, \173 _nshift, _nwidth, \174 _mshift, _mwidth, \175 _frac_en, _frac_sel, \176 _frac_rate_0, \177 _frac_rate_1, \178 _gate, _lock, _flags, \179 CCU_FEATURE_FRACTIONAL |\180 CCU_FEATURE_CLOSEST_RATE)181 182#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \183 _nshift, _nwidth, \184 _mshift, _mwidth, \185 _gate, _lock, _flags) \186 struct ccu_nm _struct = { \187 .enable = _gate, \188 .lock = _lock, \189 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \190 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \191 .common = { \192 .reg = _reg, \193 .hw.init = CLK_HW_INIT(_name, \194 _parent, \195 &ccu_nm_ops, \196 _flags), \197 }, \198 }199 200static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw)201{202 struct ccu_common *common = hw_to_ccu_common(hw);203 204 return container_of(common, struct ccu_nm, common);205}206 207extern const struct clk_ops ccu_nm_ops;208 209#endif /* _CCU_NM_H_ */210