xref: /linux/drivers/dpll/zl3073x/core.h (revision 3e20009988e2470063824c58b19d1c80816cc46d)
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 
zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev * zldev)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
zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev * zldev)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
zl3073x_is_n_pin(u8 id)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
zl3073x_is_p_pin(u8 id)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
zl3073x_input_pin_ref_get(u8 id)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
zl3073x_output_pin_out_get(u8 id)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
zl3073x_dev_ref_freq_get(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_ref_is_diff(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_ref_is_status_ok(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_synth_freq_get(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_out_synth_get(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_out_is_enabled(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_out_dpll_get(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_output_pin_freq_get(struct zl3073x_dev * zldev,u8 id)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
zl3073x_dev_out_is_diff(struct zl3073x_dev * zldev,u8 index)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
zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev * zldev,u8 id)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