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