xref: /linux/drivers/dpll/zl3073x/core.h (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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