18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Maxime Ripard. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef _CCU_NM_H_ 78c2ecf20Sopenharmony_ci#define _CCU_NM_H_ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "ccu_common.h" 128c2ecf20Sopenharmony_ci#include "ccu_div.h" 138c2ecf20Sopenharmony_ci#include "ccu_frac.h" 148c2ecf20Sopenharmony_ci#include "ccu_mult.h" 158c2ecf20Sopenharmony_ci#include "ccu_sdm.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * struct ccu_nm - Definition of an N-M clock 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Clocks based on the formula parent * N / M 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_cistruct ccu_nm { 238c2ecf20Sopenharmony_ci u32 enable; 248c2ecf20Sopenharmony_ci u32 lock; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci struct ccu_mult_internal n; 278c2ecf20Sopenharmony_ci struct ccu_div_internal m; 288c2ecf20Sopenharmony_ci struct ccu_frac_internal frac; 298c2ecf20Sopenharmony_ci struct ccu_sdm_internal sdm; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci unsigned int fixed_post_div; 328c2ecf20Sopenharmony_ci unsigned int min_rate; 338c2ecf20Sopenharmony_ci unsigned int max_rate; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci struct ccu_common common; 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \ 398c2ecf20Sopenharmony_ci _nshift, _nwidth, \ 408c2ecf20Sopenharmony_ci _mshift, _mwidth, \ 418c2ecf20Sopenharmony_ci _sdm_table, _sdm_en, \ 428c2ecf20Sopenharmony_ci _sdm_reg, _sdm_reg_en, \ 438c2ecf20Sopenharmony_ci _gate, _lock, _flags) \ 448c2ecf20Sopenharmony_ci struct ccu_nm _struct = { \ 458c2ecf20Sopenharmony_ci .enable = _gate, \ 468c2ecf20Sopenharmony_ci .lock = _lock, \ 478c2ecf20Sopenharmony_ci .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 488c2ecf20Sopenharmony_ci .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 498c2ecf20Sopenharmony_ci .sdm = _SUNXI_CCU_SDM(_sdm_table, _sdm_en, \ 508c2ecf20Sopenharmony_ci _sdm_reg, _sdm_reg_en),\ 518c2ecf20Sopenharmony_ci .common = { \ 528c2ecf20Sopenharmony_ci .reg = _reg, \ 538c2ecf20Sopenharmony_ci .features = CCU_FEATURE_SIGMA_DELTA_MOD, \ 548c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 558c2ecf20Sopenharmony_ci _parent, \ 568c2ecf20Sopenharmony_ci &ccu_nm_ops, \ 578c2ecf20Sopenharmony_ci _flags), \ 588c2ecf20Sopenharmony_ci }, \ 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \ 628c2ecf20Sopenharmony_ci _nshift, _nwidth, \ 638c2ecf20Sopenharmony_ci _mshift, _mwidth, \ 648c2ecf20Sopenharmony_ci _frac_en, _frac_sel, \ 658c2ecf20Sopenharmony_ci _frac_rate_0, _frac_rate_1, \ 668c2ecf20Sopenharmony_ci _gate, _lock, _flags) \ 678c2ecf20Sopenharmony_ci struct ccu_nm _struct = { \ 688c2ecf20Sopenharmony_ci .enable = _gate, \ 698c2ecf20Sopenharmony_ci .lock = _lock, \ 708c2ecf20Sopenharmony_ci .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 718c2ecf20Sopenharmony_ci .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 728c2ecf20Sopenharmony_ci .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ 738c2ecf20Sopenharmony_ci _frac_rate_0, \ 748c2ecf20Sopenharmony_ci _frac_rate_1), \ 758c2ecf20Sopenharmony_ci .common = { \ 768c2ecf20Sopenharmony_ci .reg = _reg, \ 778c2ecf20Sopenharmony_ci .features = CCU_FEATURE_FRACTIONAL, \ 788c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 798c2ecf20Sopenharmony_ci _parent, \ 808c2ecf20Sopenharmony_ci &ccu_nm_ops, \ 818c2ecf20Sopenharmony_ci _flags), \ 828c2ecf20Sopenharmony_ci }, \ 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent, \ 868c2ecf20Sopenharmony_ci _reg, _min_rate, \ 878c2ecf20Sopenharmony_ci _nshift, _nwidth, \ 888c2ecf20Sopenharmony_ci _mshift, _mwidth, \ 898c2ecf20Sopenharmony_ci _frac_en, _frac_sel, \ 908c2ecf20Sopenharmony_ci _frac_rate_0, _frac_rate_1,\ 918c2ecf20Sopenharmony_ci _gate, _lock, _flags) \ 928c2ecf20Sopenharmony_ci struct ccu_nm _struct = { \ 938c2ecf20Sopenharmony_ci .enable = _gate, \ 948c2ecf20Sopenharmony_ci .lock = _lock, \ 958c2ecf20Sopenharmony_ci .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 968c2ecf20Sopenharmony_ci .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 978c2ecf20Sopenharmony_ci .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ 988c2ecf20Sopenharmony_ci _frac_rate_0, \ 998c2ecf20Sopenharmony_ci _frac_rate_1), \ 1008c2ecf20Sopenharmony_ci .min_rate = _min_rate, \ 1018c2ecf20Sopenharmony_ci .common = { \ 1028c2ecf20Sopenharmony_ci .reg = _reg, \ 1038c2ecf20Sopenharmony_ci .features = CCU_FEATURE_FRACTIONAL, \ 1048c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 1058c2ecf20Sopenharmony_ci _parent, \ 1068c2ecf20Sopenharmony_ci &ccu_nm_ops, \ 1078c2ecf20Sopenharmony_ci _flags), \ 1088c2ecf20Sopenharmony_ci }, \ 1098c2ecf20Sopenharmony_ci } 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ 1128c2ecf20Sopenharmony_ci _parent, _reg, \ 1138c2ecf20Sopenharmony_ci _min_rate, _max_rate, \ 1148c2ecf20Sopenharmony_ci _nshift, _nwidth, \ 1158c2ecf20Sopenharmony_ci _mshift, _mwidth, \ 1168c2ecf20Sopenharmony_ci _frac_en, _frac_sel, \ 1178c2ecf20Sopenharmony_ci _frac_rate_0, \ 1188c2ecf20Sopenharmony_ci _frac_rate_1, \ 1198c2ecf20Sopenharmony_ci _gate, _lock, _flags) \ 1208c2ecf20Sopenharmony_ci struct ccu_nm _struct = { \ 1218c2ecf20Sopenharmony_ci .enable = _gate, \ 1228c2ecf20Sopenharmony_ci .lock = _lock, \ 1238c2ecf20Sopenharmony_ci .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 1248c2ecf20Sopenharmony_ci .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 1258c2ecf20Sopenharmony_ci .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ 1268c2ecf20Sopenharmony_ci _frac_rate_0, \ 1278c2ecf20Sopenharmony_ci _frac_rate_1), \ 1288c2ecf20Sopenharmony_ci .min_rate = _min_rate, \ 1298c2ecf20Sopenharmony_ci .max_rate = _max_rate, \ 1308c2ecf20Sopenharmony_ci .common = { \ 1318c2ecf20Sopenharmony_ci .reg = _reg, \ 1328c2ecf20Sopenharmony_ci .features = CCU_FEATURE_FRACTIONAL, \ 1338c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 1348c2ecf20Sopenharmony_ci _parent, \ 1358c2ecf20Sopenharmony_ci &ccu_nm_ops, \ 1368c2ecf20Sopenharmony_ci _flags), \ 1378c2ecf20Sopenharmony_ci }, \ 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ 1418c2ecf20Sopenharmony_ci _nshift, _nwidth, \ 1428c2ecf20Sopenharmony_ci _mshift, _mwidth, \ 1438c2ecf20Sopenharmony_ci _gate, _lock, _flags) \ 1448c2ecf20Sopenharmony_ci struct ccu_nm _struct = { \ 1458c2ecf20Sopenharmony_ci .enable = _gate, \ 1468c2ecf20Sopenharmony_ci .lock = _lock, \ 1478c2ecf20Sopenharmony_ci .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 1488c2ecf20Sopenharmony_ci .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 1498c2ecf20Sopenharmony_ci .common = { \ 1508c2ecf20Sopenharmony_ci .reg = _reg, \ 1518c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 1528c2ecf20Sopenharmony_ci _parent, \ 1538c2ecf20Sopenharmony_ci &ccu_nm_ops, \ 1548c2ecf20Sopenharmony_ci _flags), \ 1558c2ecf20Sopenharmony_ci }, \ 1568c2ecf20Sopenharmony_ci } 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct ccu_common *common = hw_to_ccu_common(hw); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci return container_of(common, struct ccu_nm, common); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciextern const struct clk_ops ccu_nm_ops; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#endif /* _CCU_NM_H_ */ 168