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