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