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