1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> 4 */ 5 6 #ifndef _CLK_SOPHGO_CV1800_IP_H_ 7 #define _CLK_SOPHGO_CV1800_IP_H_ 8 9 #include "clk-cv18xx-common.h" 10 11 struct cv1800_clk_gate { 12 struct cv1800_clk_common common; 13 struct cv1800_clk_regbit gate; 14 }; 15 16 struct cv1800_clk_div_data { 17 u32 reg; 18 u32 mask; 19 u32 width; 20 u32 init; 21 u32 flags; 22 }; 23 24 struct cv1800_clk_div { 25 struct cv1800_clk_common common; 26 struct cv1800_clk_regbit gate; 27 struct cv1800_clk_regfield div; 28 }; 29 30 struct cv1800_clk_bypass_div { 31 struct cv1800_clk_div div; 32 struct cv1800_clk_regbit bypass; 33 }; 34 35 struct cv1800_clk_mux { 36 struct cv1800_clk_common common; 37 struct cv1800_clk_regbit gate; 38 struct cv1800_clk_regfield div; 39 struct cv1800_clk_regfield mux; 40 }; 41 42 struct cv1800_clk_bypass_mux { 43 struct cv1800_clk_mux mux; 44 struct cv1800_clk_regbit bypass; 45 }; 46 47 struct cv1800_clk_mmux { 48 struct cv1800_clk_common common; 49 struct cv1800_clk_regbit gate; 50 struct cv1800_clk_regfield div[2]; 51 struct cv1800_clk_regfield mux[2]; 52 struct cv1800_clk_regbit bypass; 53 struct cv1800_clk_regbit clk_sel; 54 const s8 *parent2sel; 55 const u8 *sel2parent[2]; 56 }; 57 58 struct cv1800_clk_audio { 59 struct cv1800_clk_common common; 60 struct cv1800_clk_regbit src_en; 61 struct cv1800_clk_regbit output_en; 62 struct cv1800_clk_regbit div_en; 63 struct cv1800_clk_regbit div_up; 64 struct cv1800_clk_regfield m; 65 struct cv1800_clk_regfield n; 66 u32 target_rate; 67 }; 68 69 #define CV1800_GATE(_name, _parent, _gate_reg, _gate_shift, _flags) \ 70 struct cv1800_clk_gate _name = { \ 71 .common = CV1800_CLK_COMMON(#_name, _parent, \ 72 &cv1800_clk_gate_ops, \ 73 _flags), \ 74 .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift), \ 75 } 76 77 #define _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ 78 _div_reg, _div_shift, _div_width, _div_init, \ 79 _div_flag, _ops, _flags) \ 80 { \ 81 .common = CV1800_CLK_COMMON(#_name, _parent, \ 82 _ops, _flags), \ 83 .gate = CV1800_CLK_BIT(_gate_reg, \ 84 _gate_shift), \ 85 .div = CV1800_CLK_REG(_div_reg, _div_shift, \ 86 _div_width, _div_init, \ 87 _div_flag), \ 88 } 89 90 #define _CV1800_FIXED_DIV_FLAG \ 91 (CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST) 92 93 #define _CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ 94 _fix_div, _ops, _flags) \ 95 { \ 96 .common = CV1800_CLK_COMMON(#_name, _parent, \ 97 _ops, _flags), \ 98 .gate = CV1800_CLK_BIT(_gate_reg, \ 99 _gate_shift), \ 100 .div = CV1800_CLK_REG(0, 0, 0, \ 101 _fix_div, \ 102 _CV1800_FIXED_DIV_FLAG),\ 103 } 104 105 #define CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ 106 _div_reg, _div_shift, _div_width, _div_init, \ 107 _div_flag, _flags) \ 108 struct cv1800_clk_div _name = \ 109 _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ 110 _div_reg, _div_shift, _div_width, _div_init,\ 111 _div_flag, &cv1800_clk_div_ops, _flags) 112 113 #define CV1800_BYPASS_DIV(_name, _parent, _gate_reg, _gate_shift, \ 114 _div_reg, _div_shift, _div_width, _div_init, \ 115 _div_flag, _bypass_reg, _bypass_shift, _flags)\ 116 struct cv1800_clk_bypass_div _name = { \ 117 .div = _CV1800_DIV(_name, _parent, \ 118 _gate_reg, _gate_shift, \ 119 _div_reg, _div_shift, \ 120 _div_width, _div_init, _div_flag, \ 121 &cv1800_clk_bypass_div_ops, \ 122 _flags), \ 123 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ 124 } 125 126 #define CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ 127 _fix_div, _flags) \ 128 struct cv1800_clk_div _name = \ 129 _CV1800_FIXED_DIV(_name, _parent, \ 130 _gate_reg, _gate_shift, \ 131 _fix_div, \ 132 &cv1800_clk_div_ops, _flags) \ 133 134 #define CV1800_BYPASS_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ 135 _fix_div, _bypass_reg, _bypass_shift, \ 136 _flags) \ 137 struct cv1800_clk_bypass_div _name = { \ 138 .div = _CV1800_FIXED_DIV(_name, _parent, \ 139 _gate_reg, _gate_shift, \ 140 _fix_div, \ 141 &cv1800_clk_bypass_div_ops, \ 142 _flags), \ 143 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ 144 } 145 146 #define _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ 147 _div_reg, _div_shift, _div_width, _div_init, \ 148 _div_flag, \ 149 _mux_reg, _mux_shift, _mux_width, \ 150 _ops, _flags) \ 151 { \ 152 .common = CV1800_CLK_COMMON(#_name, _parent, \ 153 _ops, _flags), \ 154 .gate = CV1800_CLK_BIT(_gate_reg, \ 155 _gate_shift), \ 156 .div = CV1800_CLK_REG(_div_reg, _div_shift, \ 157 _div_width, _div_init, \ 158 _div_flag), \ 159 .mux = CV1800_CLK_REG(_mux_reg, _mux_shift, \ 160 _mux_width, 0, 0), \ 161 } 162 163 #define CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ 164 _div_reg, _div_shift, _div_width, _div_init, \ 165 _div_flag, \ 166 _mux_reg, _mux_shift, _mux_width, _flags) \ 167 struct cv1800_clk_mux _name = \ 168 _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ 169 _div_reg, _div_shift, _div_width, _div_init,\ 170 _div_flag, _mux_reg, _mux_shift, _mux_width,\ 171 &cv1800_clk_mux_ops, _flags) 172 173 #define CV1800_BYPASS_MUX(_name, _parent, _gate_reg, _gate_shift, \ 174 _div_reg, _div_shift, _div_width, _div_init, \ 175 _div_flag, \ 176 _mux_reg, _mux_shift, _mux_width, \ 177 _bypass_reg, _bypass_shift, _flags) \ 178 struct cv1800_clk_bypass_mux _name = { \ 179 .mux = _CV1800_MUX(_name, _parent, \ 180 _gate_reg, _gate_shift, \ 181 _div_reg, _div_shift, _div_width, \ 182 _div_init, _div_flag, \ 183 _mux_reg, _mux_shift, _mux_width, \ 184 &cv1800_clk_bypass_mux_ops, \ 185 _flags), \ 186 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ 187 } 188 189 #define CV1800_MMUX(_name, _parent, _gate_reg, _gate_shift, \ 190 _div0_reg, _div0_shift, _div0_width, _div0_init, \ 191 _div0_flag, \ 192 _div1_reg, _div1_shift, _div1_width, _div1_init, \ 193 _div1_flag, \ 194 _mux0_reg, _mux0_shift, _mux0_width, \ 195 _mux1_reg, _mux1_shift, _mux1_width, \ 196 _bypass_reg, _bypass_shift, \ 197 _clk_sel_reg, _clk_sel_shift, \ 198 _parent2sel, _sel2parent0, _sel2parent1, _flags) \ 199 struct cv1800_clk_mmux _name = { \ 200 .common = CV1800_CLK_COMMON(#_name, _parent, \ 201 &cv1800_clk_mmux_ops,\ 202 _flags), \ 203 .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift),\ 204 .div = { \ 205 CV1800_CLK_REG(_div0_reg, _div0_shift, \ 206 _div0_width, _div0_init, \ 207 _div0_flag), \ 208 CV1800_CLK_REG(_div1_reg, _div1_shift, \ 209 _div1_width, _div1_init, \ 210 _div1_flag), \ 211 }, \ 212 .mux = { \ 213 CV1800_CLK_REG(_mux0_reg, _mux0_shift, \ 214 _mux0_width, 0, 0), \ 215 CV1800_CLK_REG(_mux1_reg, _mux1_shift, \ 216 _mux1_width, 0, 0), \ 217 }, \ 218 .bypass = CV1800_CLK_BIT(_bypass_reg, \ 219 _bypass_shift), \ 220 .clk_sel = CV1800_CLK_BIT(_clk_sel_reg, \ 221 _clk_sel_shift), \ 222 .parent2sel = _parent2sel, \ 223 .sel2parent = { _sel2parent0, _sel2parent1 }, \ 224 } 225 226 #define CV1800_ACLK(_name, _parent, \ 227 _src_en_reg, _src_en_reg_shift, \ 228 _output_en_reg, _output_en_shift, \ 229 _div_en_reg, _div_en_reg_shift, \ 230 _div_up_reg, _div_up_reg_shift, \ 231 _m_reg, _m_shift, _m_width, _m_flag, \ 232 _n_reg, _n_shift, _n_width, _n_flag, \ 233 _target_rate, _flags) \ 234 struct cv1800_clk_audio _name = { \ 235 .common = CV1800_CLK_COMMON(#_name, _parent, \ 236 &cv1800_clk_audio_ops,\ 237 _flags), \ 238 .src_en = CV1800_CLK_BIT(_src_en_reg, \ 239 _src_en_reg_shift), \ 240 .output_en = CV1800_CLK_BIT(_output_en_reg, \ 241 _output_en_shift), \ 242 .div_en = CV1800_CLK_BIT(_div_en_reg, \ 243 _div_en_reg_shift), \ 244 .div_up = CV1800_CLK_BIT(_div_up_reg, \ 245 _div_up_reg_shift), \ 246 .m = CV1800_CLK_REG(_m_reg, _m_shift, \ 247 _m_width, 0, _m_flag), \ 248 .n = CV1800_CLK_REG(_n_reg, _n_shift, \ 249 _n_width, 0, _n_flag), \ 250 .target_rate = _target_rate, \ 251 } 252 253 extern const struct clk_ops cv1800_clk_gate_ops; 254 extern const struct clk_ops cv1800_clk_div_ops; 255 extern const struct clk_ops cv1800_clk_bypass_div_ops; 256 extern const struct clk_ops cv1800_clk_mux_ops; 257 extern const struct clk_ops cv1800_clk_bypass_mux_ops; 258 extern const struct clk_ops cv1800_clk_mmux_ops; 259 extern const struct clk_ops cv1800_clk_audio_ops; 260 261 #endif // _CLK_SOPHGO_CV1800_IP_H_ 262