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