1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> 4 */ 5 6 #ifndef _CLK_SOPHGO_CV1800_PLL_H_ 7 #define _CLK_SOPHGO_CV1800_PLL_H_ 8 9 #include "clk-cv18xx-common.h" 10 11 struct cv1800_clk_pll_limit { 12 struct { 13 u8 min; 14 u8 max; 15 } pre_div, div, post_div, ictrl, mode; 16 }; 17 18 #define _CV1800_PLL_LIMIT(_min, _max) \ 19 { \ 20 .min = _min, \ 21 .max = _max, \ 22 } \ 23 24 #define for_each_pll_limit_range(_var, _restrict) \ 25 for (_var = (_restrict)->min; _var <= (_restrict)->max; _var++) 26 27 struct cv1800_clk_pll_synthesizer { 28 struct cv1800_clk_regbit en; 29 struct cv1800_clk_regbit clk_half; 30 u32 ctrl; 31 u32 set; 32 }; 33 34 #define _PLL_PRE_DIV_SEL_FIELD GENMASK(6, 0) 35 #define _PLL_POST_DIV_SEL_FIELD GENMASK(14, 8) 36 #define _PLL_SEL_MODE_FIELD GENMASK(16, 15) 37 #define _PLL_DIV_SEL_FIELD GENMASK(23, 17) 38 #define _PLL_ICTRL_FIELD GENMASK(26, 24) 39 40 #define _PLL_ALL_FIELD_MASK \ 41 (_PLL_PRE_DIV_SEL_FIELD | \ 42 _PLL_POST_DIV_SEL_FIELD | \ 43 _PLL_SEL_MODE_FIELD | \ 44 _PLL_DIV_SEL_FIELD | \ 45 _PLL_ICTRL_FIELD) 46 47 #define PLL_COPY_REG(_dest, _src) \ 48 (((_dest) & (~_PLL_ALL_FIELD_MASK)) | ((_src) & _PLL_ALL_FIELD_MASK)) 49 50 #define PLL_GET_PRE_DIV_SEL(_reg) \ 51 FIELD_GET(_PLL_PRE_DIV_SEL_FIELD, (_reg)) 52 #define PLL_GET_POST_DIV_SEL(_reg) \ 53 FIELD_GET(_PLL_POST_DIV_SEL_FIELD, (_reg)) 54 #define PLL_GET_SEL_MODE(_reg) \ 55 FIELD_GET(_PLL_SEL_MODE_FIELD, (_reg)) 56 #define PLL_GET_DIV_SEL(_reg) \ 57 FIELD_GET(_PLL_DIV_SEL_FIELD, (_reg)) 58 #define PLL_GET_ICTRL(_reg) \ 59 FIELD_GET(_PLL_ICTRL_FIELD, (_reg)) 60 61 #define PLL_SET_PRE_DIV_SEL(_reg, _val) \ 62 _CV1800_SET_FIELD((_reg), (_val), _PLL_PRE_DIV_SEL_FIELD) 63 #define PLL_SET_POST_DIV_SEL(_reg, _val) \ 64 _CV1800_SET_FIELD((_reg), (_val), _PLL_POST_DIV_SEL_FIELD) 65 #define PLL_SET_SEL_MODE(_reg, _val) \ 66 _CV1800_SET_FIELD((_reg), (_val), _PLL_SEL_MODE_FIELD) 67 #define PLL_SET_DIV_SEL(_reg, _val) \ 68 _CV1800_SET_FIELD((_reg), (_val), _PLL_DIV_SEL_FIELD) 69 #define PLL_SET_ICTRL(_reg, _val) \ 70 _CV1800_SET_FIELD((_reg), (_val), _PLL_ICTRL_FIELD) 71 72 struct cv1800_clk_pll { 73 struct cv1800_clk_common common; 74 u32 pll_reg; 75 struct cv1800_clk_regbit pll_pwd; 76 struct cv1800_clk_regbit pll_status; 77 const struct cv1800_clk_pll_limit *pll_limit; 78 struct cv1800_clk_pll_synthesizer *pll_syn; 79 }; 80 81 #define CV1800_INTEGRAL_PLL(_name, _parent, _pll_reg, \ 82 _pll_pwd_reg, _pll_pwd_shift, \ 83 _pll_status_reg, _pll_status_shift, \ 84 _pll_limit, _flags) \ 85 struct cv1800_clk_pll _name = { \ 86 .common = CV1800_CLK_COMMON(#_name, _parent, \ 87 &cv1800_clk_ipll_ops,\ 88 _flags), \ 89 .pll_reg = _pll_reg, \ 90 .pll_pwd = CV1800_CLK_BIT(_pll_pwd_reg, \ 91 _pll_pwd_shift), \ 92 .pll_status = CV1800_CLK_BIT(_pll_status_reg, \ 93 _pll_status_shift), \ 94 .pll_limit = _pll_limit, \ 95 .pll_syn = NULL, \ 96 } 97 98 #define CV1800_FACTIONAL_PLL(_name, _parent, _pll_reg, \ 99 _pll_pwd_reg, _pll_pwd_shift, \ 100 _pll_status_reg, _pll_status_shift, \ 101 _pll_limit, _pll_syn, _flags) \ 102 struct cv1800_clk_pll _name = { \ 103 .common = CV1800_CLK_COMMON(#_name, _parent, \ 104 &cv1800_clk_fpll_ops,\ 105 _flags), \ 106 .pll_reg = _pll_reg, \ 107 .pll_pwd = CV1800_CLK_BIT(_pll_pwd_reg, \ 108 _pll_pwd_shift), \ 109 .pll_status = CV1800_CLK_BIT(_pll_status_reg, \ 110 _pll_status_shift), \ 111 .pll_limit = _pll_limit, \ 112 .pll_syn = _pll_syn, \ 113 } 114 115 extern const struct clk_ops cv1800_clk_ipll_ops; 116 extern const struct clk_ops cv1800_clk_fpll_ops; 117 118 #endif // _CLK_SOPHGO_CV1800_PLL_H_ 119