1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _ZL3073X_CORE_H 4 #define _ZL3073X_CORE_H 5 6 #include <linux/bitfield.h> 7 #include <linux/kthread.h> 8 #include <linux/list.h> 9 #include <linux/mutex.h> 10 #include <linux/types.h> 11 12 #include "out.h" 13 #include "ref.h" 14 #include "regs.h" 15 #include "synth.h" 16 17 struct device; 18 struct regmap; 19 struct zl3073x_dpll; 20 21 /* 22 * Hardware limits for ZL3073x chip family 23 */ 24 #define ZL3073X_MAX_CHANNELS 5 25 #define ZL3073X_NUM_REFS 10 26 #define ZL3073X_NUM_OUTS 10 27 #define ZL3073X_NUM_SYNTHS 5 28 #define ZL3073X_NUM_INPUT_PINS ZL3073X_NUM_REFS 29 #define ZL3073X_NUM_OUTPUT_PINS (ZL3073X_NUM_OUTS * 2) 30 #define ZL3073X_NUM_PINS (ZL3073X_NUM_INPUT_PINS + \ 31 ZL3073X_NUM_OUTPUT_PINS) 32 33 /** 34 * struct zl3073x_dev - zl3073x device 35 * @dev: pointer to device 36 * @regmap: regmap to access device registers 37 * @multiop_lock: to serialize multiple register operations 38 * @chip_id: chip ID read from hardware 39 * @ref: array of input references' invariants 40 * @out: array of outs' invariants 41 * @synth: array of synths' invariants 42 * @dplls: list of DPLLs 43 * @kworker: thread for periodic work 44 * @work: periodic work 45 * @clock_id: clock id of the device 46 * @phase_avg_factor: phase offset measurement averaging factor 47 */ 48 struct zl3073x_dev { 49 struct device *dev; 50 struct regmap *regmap; 51 struct mutex multiop_lock; 52 u16 chip_id; 53 54 /* Invariants */ 55 struct zl3073x_ref ref[ZL3073X_NUM_REFS]; 56 struct zl3073x_out out[ZL3073X_NUM_OUTS]; 57 struct zl3073x_synth synth[ZL3073X_NUM_SYNTHS]; 58 59 /* DPLL channels */ 60 struct list_head dplls; 61 62 /* Monitor */ 63 struct kthread_worker *kworker; 64 struct kthread_delayed_work work; 65 66 /* Devlink parameters */ 67 u64 clock_id; 68 u8 phase_avg_factor; 69 }; 70 71 struct zl3073x_chip_info { 72 const u16 *ids; 73 size_t num_ids; 74 int num_channels; 75 }; 76 77 extern const struct zl3073x_chip_info zl30731_chip_info; 78 extern const struct zl3073x_chip_info zl30732_chip_info; 79 extern const struct zl3073x_chip_info zl30733_chip_info; 80 extern const struct zl3073x_chip_info zl30734_chip_info; 81 extern const struct zl3073x_chip_info zl30735_chip_info; 82 extern const struct regmap_config zl3073x_regmap_config; 83 84 struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev); 85 int zl3073x_dev_probe(struct zl3073x_dev *zldev, 86 const struct zl3073x_chip_info *chip_info); 87 88 int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full); 89 void zl3073x_dev_stop(struct zl3073x_dev *zldev); 90 91 static inline u8 zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev *zldev) 92 { 93 return zldev->phase_avg_factor; 94 } 95 96 int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor); 97 98 /********************** 99 * Registers operations 100 **********************/ 101 102 /** 103 * struct zl3073x_hwreg_seq_item - HW register write sequence item 104 * @addr: HW register to be written 105 * @value: value to be written to HW register 106 * @mask: bitmask indicating bits to be updated 107 * @wait: number of ms to wait after register write 108 */ 109 struct zl3073x_hwreg_seq_item { 110 u32 addr; 111 u32 value; 112 u32 mask; 113 u32 wait; 114 }; 115 116 #define HWREG_SEQ_ITEM(_addr, _value, _mask, _wait) \ 117 { \ 118 .addr = _addr, \ 119 .value = FIELD_PREP_CONST(_mask, _value), \ 120 .mask = _mask, \ 121 .wait = _wait, \ 122 } 123 124 int zl3073x_mb_op(struct zl3073x_dev *zldev, unsigned int op_reg, u8 op_val, 125 unsigned int mask_reg, u16 mask_val); 126 int zl3073x_poll_zero_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 mask); 127 int zl3073x_read_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 *val); 128 int zl3073x_read_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 *val); 129 int zl3073x_read_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 *val); 130 int zl3073x_read_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 *val); 131 int zl3073x_write_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 val); 132 int zl3073x_write_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 val); 133 int zl3073x_write_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 val); 134 int zl3073x_write_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 val); 135 int zl3073x_read_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 *value); 136 int zl3073x_write_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value); 137 int zl3073x_update_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value, 138 u32 mask); 139 int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev, 140 const struct zl3073x_hwreg_seq_item *seq, 141 size_t num_items); 142 143 /***************** 144 * Misc operations 145 *****************/ 146 147 int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel); 148 149 /** 150 * zl3073x_dev_is_ref_phase_comp_32bit - check ref phase comp register size 151 * @zldev: pointer to zl3073x device 152 * 153 * Some chip IDs have a 32-bit wide ref_phase_offset_comp register instead 154 * of the default 48-bit. 155 * 156 * Return: true if the register is 32-bit, false if 48-bit 157 */ 158 static inline bool 159 zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev) 160 { 161 switch (zldev->chip_id) { 162 case 0x0E30: 163 case 0x0E93: 164 case 0x0E94: 165 case 0x0E95: 166 case 0x0E96: 167 case 0x0E97: 168 case 0x1F60: 169 return true; 170 default: 171 return false; 172 } 173 } 174 175 static inline bool 176 zl3073x_is_n_pin(u8 id) 177 { 178 /* P-pins ids are even while N-pins are odd */ 179 return id & 1; 180 } 181 182 static inline bool 183 zl3073x_is_p_pin(u8 id) 184 { 185 return !zl3073x_is_n_pin(id); 186 } 187 188 /** 189 * zl3073x_input_pin_ref_get - get reference for given input pin 190 * @id: input pin id 191 * 192 * Return: reference id for the given input pin 193 */ 194 static inline u8 195 zl3073x_input_pin_ref_get(u8 id) 196 { 197 return id; 198 } 199 200 /** 201 * zl3073x_output_pin_out_get - get output for the given output pin 202 * @id: output pin id 203 * 204 * Return: output id for the given output pin 205 */ 206 static inline u8 207 zl3073x_output_pin_out_get(u8 id) 208 { 209 /* Output pin pair shares the single output */ 210 return id / 2; 211 } 212 213 /** 214 * zl3073x_dev_ref_freq_get - get input reference frequency 215 * @zldev: pointer to zl3073x device 216 * @index: input reference index 217 * 218 * Return: frequency of given input reference 219 */ 220 static inline u32 221 zl3073x_dev_ref_freq_get(struct zl3073x_dev *zldev, u8 index) 222 { 223 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 224 225 return zl3073x_ref_freq_get(ref); 226 } 227 228 /** 229 * zl3073x_dev_ref_is_diff - check if the given input reference is differential 230 * @zldev: pointer to zl3073x device 231 * @index: input reference index 232 * 233 * Return: true if reference is differential, false if reference is single-ended 234 */ 235 static inline bool 236 zl3073x_dev_ref_is_diff(struct zl3073x_dev *zldev, u8 index) 237 { 238 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 239 240 return zl3073x_ref_is_diff(ref); 241 } 242 243 /* 244 * zl3073x_dev_ref_is_status_ok - check the given input reference status 245 * @zldev: pointer to zl3073x device 246 * @index: input reference index 247 * 248 * Return: true if the status is ok, false otherwise 249 */ 250 static inline bool 251 zl3073x_dev_ref_is_status_ok(struct zl3073x_dev *zldev, u8 index) 252 { 253 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 254 255 return zl3073x_ref_is_status_ok(ref); 256 } 257 258 /** 259 * zl3073x_dev_synth_freq_get - get synth current freq 260 * @zldev: pointer to zl3073x device 261 * @index: synth index 262 * 263 * Return: frequency of given synthetizer 264 */ 265 static inline u32 266 zl3073x_dev_synth_freq_get(struct zl3073x_dev *zldev, u8 index) 267 { 268 const struct zl3073x_synth *synth; 269 270 synth = zl3073x_synth_state_get(zldev, index); 271 return zl3073x_synth_freq_get(synth); 272 } 273 274 /** 275 * zl3073x_dev_out_synth_get - get synth connected to given output 276 * @zldev: pointer to zl3073x device 277 * @index: output index 278 * 279 * Return: index of synth connected to given output. 280 */ 281 static inline u8 282 zl3073x_dev_out_synth_get(struct zl3073x_dev *zldev, u8 index) 283 { 284 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 285 286 return zl3073x_out_synth_get(out); 287 } 288 289 /** 290 * zl3073x_dev_out_is_enabled - check if the given output is enabled 291 * @zldev: pointer to zl3073x device 292 * @index: output index 293 * 294 * Return: true if the output is enabled, false otherwise 295 */ 296 static inline bool 297 zl3073x_dev_out_is_enabled(struct zl3073x_dev *zldev, u8 index) 298 { 299 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 300 const struct zl3073x_synth *synth; 301 u8 synth_id; 302 303 /* Output is enabled only if associated synth is enabled */ 304 synth_id = zl3073x_out_synth_get(out); 305 synth = zl3073x_synth_state_get(zldev, synth_id); 306 307 return zl3073x_synth_is_enabled(synth) && zl3073x_out_is_enabled(out); 308 } 309 310 /** 311 * zl3073x_dev_out_dpll_get - get DPLL ID the output is driven by 312 * @zldev: pointer to zl3073x device 313 * @index: output index 314 * 315 * Return: ID of DPLL the given output is driven by 316 */ 317 static inline 318 u8 zl3073x_dev_out_dpll_get(struct zl3073x_dev *zldev, u8 index) 319 { 320 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 321 const struct zl3073x_synth *synth; 322 u8 synth_id; 323 324 /* Get synthesizer connected to given output */ 325 synth_id = zl3073x_out_synth_get(out); 326 synth = zl3073x_synth_state_get(zldev, synth_id); 327 328 /* Return DPLL that drives the synth */ 329 return zl3073x_synth_dpll_get(synth); 330 } 331 332 /** 333 * zl3073x_dev_output_pin_freq_get - get output pin frequency 334 * @zldev: pointer to zl3073x device 335 * @id: output pin id 336 * 337 * Computes the output pin frequency based on the synth frequency, output 338 * divisor, and signal format. For N-div formats, N-pin frequency is 339 * additionally divided by esync_n_period. 340 * 341 * Return: frequency of the given output pin in Hz 342 */ 343 static inline u32 344 zl3073x_dev_output_pin_freq_get(struct zl3073x_dev *zldev, u8 id) 345 { 346 const struct zl3073x_synth *synth; 347 const struct zl3073x_out *out; 348 u8 out_id; 349 u32 freq; 350 351 out_id = zl3073x_output_pin_out_get(id); 352 out = zl3073x_out_state_get(zldev, out_id); 353 synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out)); 354 freq = zl3073x_synth_freq_get(synth) / out->div; 355 356 if (zl3073x_out_is_ndiv(out) && zl3073x_is_n_pin(id)) 357 freq /= out->esync_n_period; 358 359 return freq; 360 } 361 362 /** 363 * zl3073x_dev_out_is_diff - check if the given output is differential 364 * @zldev: pointer to zl3073x device 365 * @index: output index 366 * 367 * Return: true if output is differential, false if output is single-ended 368 */ 369 static inline bool 370 zl3073x_dev_out_is_diff(struct zl3073x_dev *zldev, u8 index) 371 { 372 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 373 374 return zl3073x_out_is_diff(out); 375 } 376 377 /** 378 * zl3073x_dev_output_pin_is_enabled - check if the given output pin is enabled 379 * @zldev: pointer to zl3073x device 380 * @id: output pin id 381 * 382 * Checks if the output of the given output pin is enabled and also that 383 * its signal format also enables the given pin. 384 * 385 * Return: true if output pin is enabled, false if output pin is disabled 386 */ 387 static inline bool 388 zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev *zldev, u8 id) 389 { 390 u8 out_id = zl3073x_output_pin_out_get(id); 391 const struct zl3073x_out *out; 392 393 out = zl3073x_out_state_get(zldev, out_id); 394 395 /* Check if the output is enabled - call _dev_ helper that 396 * additionally checks for attached synth enablement. 397 */ 398 if (!zl3073x_dev_out_is_enabled(zldev, out_id)) 399 return false; 400 401 /* Check signal format */ 402 switch (zl3073x_out_signal_format_get(out)) { 403 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_DISABLED: 404 /* Both output pins are disabled by signal format */ 405 return false; 406 407 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1P: 408 /* Output is one single ended P-pin output */ 409 if (zl3073x_is_n_pin(id)) 410 return false; 411 break; 412 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1N: 413 /* Output is one single ended N-pin output */ 414 if (zl3073x_is_p_pin(id)) 415 return false; 416 break; 417 default: 418 /* For other format both pins are enabled */ 419 break; 420 } 421 422 return true; 423 } 424 425 #endif /* _ZL3073X_CORE_H */ 426