Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/dpll/zl3073x/dpll.c
50831 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
3
#include <linux/bits.h>
4
#include <linux/bitfield.h>
5
#include <linux/bug.h>
6
#include <linux/container_of.h>
7
#include <linux/dev_printk.h>
8
#include <linux/dpll.h>
9
#include <linux/err.h>
10
#include <linux/kthread.h>
11
#include <linux/math64.h>
12
#include <linux/mod_devicetable.h>
13
#include <linux/module.h>
14
#include <linux/netlink.h>
15
#include <linux/platform_device.h>
16
#include <linux/slab.h>
17
#include <linux/sprintf.h>
18
19
#include "core.h"
20
#include "dpll.h"
21
#include "prop.h"
22
#include "regs.h"
23
24
#define ZL3073X_DPLL_REF_NONE ZL3073X_NUM_REFS
25
#define ZL3073X_DPLL_REF_IS_VALID(_ref) ((_ref) != ZL3073X_DPLL_REF_NONE)
26
27
/**
28
* struct zl3073x_dpll_pin - DPLL pin
29
* @list: this DPLL pin list entry
30
* @dpll: DPLL the pin is registered to
31
* @dpll_pin: pointer to registered dpll_pin
32
* @label: package label
33
* @dir: pin direction
34
* @id: pin id
35
* @prio: pin priority <0, 14>
36
* @selectable: pin is selectable in automatic mode
37
* @esync_control: embedded sync is controllable
38
* @phase_gran: phase adjustment granularity
39
* @pin_state: last saved pin state
40
* @phase_offset: last saved pin phase offset
41
* @freq_offset: last saved fractional frequency offset
42
*/
43
struct zl3073x_dpll_pin {
44
struct list_head list;
45
struct zl3073x_dpll *dpll;
46
struct dpll_pin *dpll_pin;
47
char label[8];
48
enum dpll_pin_direction dir;
49
u8 id;
50
u8 prio;
51
bool selectable;
52
bool esync_control;
53
s32 phase_gran;
54
enum dpll_pin_state pin_state;
55
s64 phase_offset;
56
s64 freq_offset;
57
};
58
59
/*
60
* Supported esync ranges for input and for output per output pair type
61
*/
62
static const struct dpll_pin_frequency esync_freq_ranges[] = {
63
DPLL_PIN_FREQUENCY_RANGE(0, 1),
64
};
65
66
/**
67
* zl3073x_dpll_is_input_pin - check if the pin is input one
68
* @pin: pin to check
69
*
70
* Return: true if pin is input, false if pin is output.
71
*/
72
static bool
73
zl3073x_dpll_is_input_pin(struct zl3073x_dpll_pin *pin)
74
{
75
return pin->dir == DPLL_PIN_DIRECTION_INPUT;
76
}
77
78
/**
79
* zl3073x_dpll_is_p_pin - check if the pin is P-pin
80
* @pin: pin to check
81
*
82
* Return: true if the pin is P-pin, false if it is N-pin
83
*/
84
static bool
85
zl3073x_dpll_is_p_pin(struct zl3073x_dpll_pin *pin)
86
{
87
return zl3073x_is_p_pin(pin->id);
88
}
89
90
static int
91
zl3073x_dpll_pin_direction_get(const struct dpll_pin *dpll_pin, void *pin_priv,
92
const struct dpll_device *dpll, void *dpll_priv,
93
enum dpll_pin_direction *direction,
94
struct netlink_ext_ack *extack)
95
{
96
struct zl3073x_dpll_pin *pin = pin_priv;
97
98
*direction = pin->dir;
99
100
return 0;
101
}
102
103
static int
104
zl3073x_dpll_input_pin_esync_get(const struct dpll_pin *dpll_pin,
105
void *pin_priv,
106
const struct dpll_device *dpll,
107
void *dpll_priv,
108
struct dpll_pin_esync *esync,
109
struct netlink_ext_ack *extack)
110
{
111
struct zl3073x_dpll *zldpll = dpll_priv;
112
struct zl3073x_dev *zldev = zldpll->dev;
113
struct zl3073x_dpll_pin *pin = pin_priv;
114
const struct zl3073x_ref *ref;
115
u8 ref_id;
116
117
ref_id = zl3073x_input_pin_ref_get(pin->id);
118
ref = zl3073x_ref_state_get(zldev, ref_id);
119
120
switch (FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl)) {
121
case ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75:
122
esync->freq = ref->esync_n_div == ZL_REF_ESYNC_DIV_1HZ ? 1 : 0;
123
esync->pulse = 25;
124
break;
125
default:
126
esync->freq = 0;
127
esync->pulse = 0;
128
break;
129
}
130
131
/* If the pin supports esync control expose its range but only
132
* if the current reference frequency is > 1 Hz.
133
*/
134
if (pin->esync_control && zl3073x_ref_freq_get(ref) > 1) {
135
esync->range = esync_freq_ranges;
136
esync->range_num = ARRAY_SIZE(esync_freq_ranges);
137
} else {
138
esync->range = NULL;
139
esync->range_num = 0;
140
}
141
142
return 0;
143
}
144
145
static int
146
zl3073x_dpll_input_pin_esync_set(const struct dpll_pin *dpll_pin,
147
void *pin_priv,
148
const struct dpll_device *dpll,
149
void *dpll_priv, u64 freq,
150
struct netlink_ext_ack *extack)
151
{
152
struct zl3073x_dpll *zldpll = dpll_priv;
153
struct zl3073x_dev *zldev = zldpll->dev;
154
struct zl3073x_dpll_pin *pin = pin_priv;
155
struct zl3073x_ref ref;
156
u8 ref_id, sync_mode;
157
158
ref_id = zl3073x_input_pin_ref_get(pin->id);
159
ref = *zl3073x_ref_state_get(zldev, ref_id);
160
161
/* Use freq == 0 to disable esync */
162
if (!freq)
163
sync_mode = ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR_OFF;
164
else
165
sync_mode = ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75;
166
167
ref.sync_ctrl &= ~ZL_REF_SYNC_CTRL_MODE;
168
ref.sync_ctrl |= FIELD_PREP(ZL_REF_SYNC_CTRL_MODE, sync_mode);
169
170
if (freq) {
171
/* 1 Hz is only supported frequency now */
172
ref.esync_n_div = ZL_REF_ESYNC_DIV_1HZ;
173
}
174
175
/* Update reference configuration */
176
return zl3073x_ref_state_set(zldev, ref_id, &ref);
177
}
178
179
static int
180
zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
181
const struct dpll_device *dpll, void *dpll_priv,
182
s64 *ffo, struct netlink_ext_ack *extack)
183
{
184
struct zl3073x_dpll_pin *pin = pin_priv;
185
186
*ffo = pin->freq_offset;
187
188
return 0;
189
}
190
191
static int
192
zl3073x_dpll_input_pin_frequency_get(const struct dpll_pin *dpll_pin,
193
void *pin_priv,
194
const struct dpll_device *dpll,
195
void *dpll_priv, u64 *frequency,
196
struct netlink_ext_ack *extack)
197
{
198
struct zl3073x_dpll *zldpll = dpll_priv;
199
struct zl3073x_dpll_pin *pin = pin_priv;
200
u8 ref_id;
201
202
ref_id = zl3073x_input_pin_ref_get(pin->id);
203
*frequency = zl3073x_dev_ref_freq_get(zldpll->dev, ref_id);
204
205
return 0;
206
}
207
208
static int
209
zl3073x_dpll_input_pin_frequency_set(const struct dpll_pin *dpll_pin,
210
void *pin_priv,
211
const struct dpll_device *dpll,
212
void *dpll_priv, u64 frequency,
213
struct netlink_ext_ack *extack)
214
{
215
struct zl3073x_dpll *zldpll = dpll_priv;
216
struct zl3073x_dev *zldev = zldpll->dev;
217
struct zl3073x_dpll_pin *pin = pin_priv;
218
struct zl3073x_ref ref;
219
u8 ref_id;
220
221
/* Get reference state */
222
ref_id = zl3073x_input_pin_ref_get(pin->id);
223
ref = *zl3073x_ref_state_get(zldev, ref_id);
224
225
/* Update frequency */
226
zl3073x_ref_freq_set(&ref, frequency);
227
228
/* Commit reference state */
229
return zl3073x_ref_state_set(zldev, ref_id, &ref);
230
}
231
232
/**
233
* zl3073x_dpll_selected_ref_get - get currently selected reference
234
* @zldpll: pointer to zl3073x_dpll
235
* @ref: place to store selected reference
236
*
237
* Check for currently selected reference the DPLL should be locked to
238
* and stores its index to given @ref.
239
*
240
* Return: 0 on success, <0 on error
241
*/
242
static int
243
zl3073x_dpll_selected_ref_get(struct zl3073x_dpll *zldpll, u8 *ref)
244
{
245
struct zl3073x_dev *zldev = zldpll->dev;
246
u8 state, value;
247
int rc;
248
249
switch (zldpll->refsel_mode) {
250
case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
251
/* For automatic mode read refsel_status register */
252
rc = zl3073x_read_u8(zldev,
253
ZL_REG_DPLL_REFSEL_STATUS(zldpll->id),
254
&value);
255
if (rc)
256
return rc;
257
258
/* Extract reference state */
259
state = FIELD_GET(ZL_DPLL_REFSEL_STATUS_STATE, value);
260
261
/* Return the reference only if the DPLL is locked to it */
262
if (state == ZL_DPLL_REFSEL_STATUS_STATE_LOCK)
263
*ref = FIELD_GET(ZL_DPLL_REFSEL_STATUS_REFSEL, value);
264
else
265
*ref = ZL3073X_DPLL_REF_NONE;
266
break;
267
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
268
/* For manual mode return stored value */
269
*ref = zldpll->forced_ref;
270
break;
271
default:
272
/* For other modes like NCO, freerun... there is no input ref */
273
*ref = ZL3073X_DPLL_REF_NONE;
274
break;
275
}
276
277
return 0;
278
}
279
280
/**
281
* zl3073x_dpll_selected_ref_set - select reference in manual mode
282
* @zldpll: pointer to zl3073x_dpll
283
* @ref: input reference to be selected
284
*
285
* Selects the given reference for the DPLL channel it should be
286
* locked to.
287
*
288
* Return: 0 on success, <0 on error
289
*/
290
static int
291
zl3073x_dpll_selected_ref_set(struct zl3073x_dpll *zldpll, u8 ref)
292
{
293
struct zl3073x_dev *zldev = zldpll->dev;
294
u8 mode, mode_refsel;
295
int rc;
296
297
mode = zldpll->refsel_mode;
298
299
switch (mode) {
300
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
301
/* Manual mode with ref selected */
302
if (ref == ZL3073X_DPLL_REF_NONE) {
303
switch (zldpll->lock_status) {
304
case DPLL_LOCK_STATUS_LOCKED_HO_ACQ:
305
case DPLL_LOCK_STATUS_HOLDOVER:
306
/* Switch to forced holdover */
307
mode = ZL_DPLL_MODE_REFSEL_MODE_HOLDOVER;
308
break;
309
default:
310
/* Switch to freerun */
311
mode = ZL_DPLL_MODE_REFSEL_MODE_FREERUN;
312
break;
313
}
314
/* Keep selected reference */
315
ref = zldpll->forced_ref;
316
} else if (ref == zldpll->forced_ref) {
317
/* No register update - same mode and same ref */
318
return 0;
319
}
320
break;
321
case ZL_DPLL_MODE_REFSEL_MODE_FREERUN:
322
case ZL_DPLL_MODE_REFSEL_MODE_HOLDOVER:
323
/* Manual mode without no ref */
324
if (ref == ZL3073X_DPLL_REF_NONE)
325
/* No register update - keep current mode */
326
return 0;
327
328
/* Switch to reflock mode and update ref selection */
329
mode = ZL_DPLL_MODE_REFSEL_MODE_REFLOCK;
330
break;
331
default:
332
/* For other modes like automatic or NCO ref cannot be selected
333
* manually
334
*/
335
return -EOPNOTSUPP;
336
}
337
338
/* Build mode_refsel value */
339
mode_refsel = FIELD_PREP(ZL_DPLL_MODE_REFSEL_MODE, mode) |
340
FIELD_PREP(ZL_DPLL_MODE_REFSEL_REF, ref);
341
342
/* Update dpll_mode_refsel register */
343
rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_MODE_REFSEL(zldpll->id),
344
mode_refsel);
345
if (rc)
346
return rc;
347
348
/* Store new mode and forced reference */
349
zldpll->refsel_mode = mode;
350
zldpll->forced_ref = ref;
351
352
return rc;
353
}
354
355
/**
356
* zl3073x_dpll_connected_ref_get - get currently connected reference
357
* @zldpll: pointer to zl3073x_dpll
358
* @ref: place to store selected reference
359
*
360
* Looks for currently connected the DPLL is locked to and stores its index
361
* to given @ref.
362
*
363
* Return: 0 on success, <0 on error
364
*/
365
static int
366
zl3073x_dpll_connected_ref_get(struct zl3073x_dpll *zldpll, u8 *ref)
367
{
368
struct zl3073x_dev *zldev = zldpll->dev;
369
int rc;
370
371
/* Get currently selected input reference */
372
rc = zl3073x_dpll_selected_ref_get(zldpll, ref);
373
if (rc)
374
return rc;
375
376
/* If the monitor indicates an error nothing is connected */
377
if (ZL3073X_DPLL_REF_IS_VALID(*ref) &&
378
!zl3073x_dev_ref_is_status_ok(zldev, *ref))
379
*ref = ZL3073X_DPLL_REF_NONE;
380
381
return 0;
382
}
383
384
static int
385
zl3073x_dpll_input_pin_phase_offset_get(const struct dpll_pin *dpll_pin,
386
void *pin_priv,
387
const struct dpll_device *dpll,
388
void *dpll_priv, s64 *phase_offset,
389
struct netlink_ext_ack *extack)
390
{
391
struct zl3073x_dpll *zldpll = dpll_priv;
392
struct zl3073x_dev *zldev = zldpll->dev;
393
struct zl3073x_dpll_pin *pin = pin_priv;
394
const struct zl3073x_ref *ref;
395
u8 conn_id, ref_id;
396
s64 ref_phase;
397
int rc;
398
399
/* Get currently connected reference */
400
rc = zl3073x_dpll_connected_ref_get(zldpll, &conn_id);
401
if (rc)
402
return rc;
403
404
/* Report phase offset only for currently connected pin if the phase
405
* monitor feature is disabled and only if the input pin signal is
406
* present.
407
*/
408
ref_id = zl3073x_input_pin_ref_get(pin->id);
409
ref = zl3073x_ref_state_get(zldev, ref_id);
410
if ((!zldpll->phase_monitor && ref_id != conn_id) ||
411
!zl3073x_ref_is_status_ok(ref)) {
412
*phase_offset = 0;
413
return 0;
414
}
415
416
ref_phase = pin->phase_offset;
417
418
/* The DPLL being locked to a higher freq than the current ref
419
* the phase offset is modded to the period of the signal
420
* the dpll is locked to.
421
*/
422
if (ZL3073X_DPLL_REF_IS_VALID(conn_id) && conn_id != ref_id) {
423
u32 conn_freq, ref_freq;
424
425
/* Get frequency of connected and given ref */
426
conn_freq = zl3073x_dev_ref_freq_get(zldev, conn_id);
427
ref_freq = zl3073x_ref_freq_get(ref);
428
429
if (conn_freq > ref_freq) {
430
s64 conn_period, div_factor;
431
432
conn_period = div_s64(PSEC_PER_SEC, conn_freq);
433
div_factor = div64_s64(ref_phase, conn_period);
434
ref_phase -= conn_period * div_factor;
435
}
436
}
437
438
*phase_offset = ref_phase * DPLL_PHASE_OFFSET_DIVIDER;
439
440
return rc;
441
}
442
443
static int
444
zl3073x_dpll_input_pin_phase_adjust_get(const struct dpll_pin *dpll_pin,
445
void *pin_priv,
446
const struct dpll_device *dpll,
447
void *dpll_priv,
448
s32 *phase_adjust,
449
struct netlink_ext_ack *extack)
450
{
451
struct zl3073x_dpll *zldpll = dpll_priv;
452
struct zl3073x_dev *zldev = zldpll->dev;
453
struct zl3073x_dpll_pin *pin = pin_priv;
454
const struct zl3073x_ref *ref;
455
s64 phase_comp;
456
u8 ref_id;
457
458
/* Read reference configuration */
459
ref_id = zl3073x_input_pin_ref_get(pin->id);
460
ref = zl3073x_ref_state_get(zldev, ref_id);
461
462
/* Perform sign extension for 48bit signed value */
463
phase_comp = sign_extend64(ref->phase_comp, 47);
464
465
/* Reverse two's complement negation applied during set and convert
466
* to 32bit signed int
467
*/
468
*phase_adjust = (s32)-phase_comp;
469
470
return 0;
471
}
472
473
static int
474
zl3073x_dpll_input_pin_phase_adjust_set(const struct dpll_pin *dpll_pin,
475
void *pin_priv,
476
const struct dpll_device *dpll,
477
void *dpll_priv,
478
s32 phase_adjust,
479
struct netlink_ext_ack *extack)
480
{
481
struct zl3073x_dpll *zldpll = dpll_priv;
482
struct zl3073x_dev *zldev = zldpll->dev;
483
struct zl3073x_dpll_pin *pin = pin_priv;
484
struct zl3073x_ref ref;
485
u8 ref_id;
486
487
/* Read reference configuration */
488
ref_id = zl3073x_input_pin_ref_get(pin->id);
489
ref = *zl3073x_ref_state_get(zldev, ref_id);
490
491
/* The value in the register is stored as two's complement negation
492
* of requested value.
493
*/
494
ref.phase_comp = -phase_adjust;
495
496
/* Update reference configuration */
497
return zl3073x_ref_state_set(zldev, ref_id, &ref);
498
}
499
500
/**
501
* zl3073x_dpll_ref_prio_get - get priority for given input pin
502
* @pin: pointer to pin
503
* @prio: place to store priority
504
*
505
* Reads current priority for the given input pin and stores the value
506
* to @prio.
507
*
508
* Return: 0 on success, <0 on error
509
*/
510
static int
511
zl3073x_dpll_ref_prio_get(struct zl3073x_dpll_pin *pin, u8 *prio)
512
{
513
struct zl3073x_dpll *zldpll = pin->dpll;
514
struct zl3073x_dev *zldev = zldpll->dev;
515
u8 ref, ref_prio;
516
int rc;
517
518
guard(mutex)(&zldev->multiop_lock);
519
520
/* Read DPLL configuration */
521
rc = zl3073x_mb_op(zldev, ZL_REG_DPLL_MB_SEM, ZL_DPLL_MB_SEM_RD,
522
ZL_REG_DPLL_MB_MASK, BIT(zldpll->id));
523
if (rc)
524
return rc;
525
526
/* Read reference priority - one value for P&N pins (4 bits/pin) */
527
ref = zl3073x_input_pin_ref_get(pin->id);
528
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_REF_PRIO(ref / 2),
529
&ref_prio);
530
if (rc)
531
return rc;
532
533
/* Select nibble according pin type */
534
if (zl3073x_dpll_is_p_pin(pin))
535
*prio = FIELD_GET(ZL_DPLL_REF_PRIO_REF_P, ref_prio);
536
else
537
*prio = FIELD_GET(ZL_DPLL_REF_PRIO_REF_N, ref_prio);
538
539
return rc;
540
}
541
542
/**
543
* zl3073x_dpll_ref_prio_set - set priority for given input pin
544
* @pin: pointer to pin
545
* @prio: place to store priority
546
*
547
* Sets priority for the given input pin.
548
*
549
* Return: 0 on success, <0 on error
550
*/
551
static int
552
zl3073x_dpll_ref_prio_set(struct zl3073x_dpll_pin *pin, u8 prio)
553
{
554
struct zl3073x_dpll *zldpll = pin->dpll;
555
struct zl3073x_dev *zldev = zldpll->dev;
556
u8 ref, ref_prio;
557
int rc;
558
559
guard(mutex)(&zldev->multiop_lock);
560
561
/* Read DPLL configuration into mailbox */
562
rc = zl3073x_mb_op(zldev, ZL_REG_DPLL_MB_SEM, ZL_DPLL_MB_SEM_RD,
563
ZL_REG_DPLL_MB_MASK, BIT(zldpll->id));
564
if (rc)
565
return rc;
566
567
/* Read reference priority - one value shared between P&N pins */
568
ref = zl3073x_input_pin_ref_get(pin->id);
569
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_REF_PRIO(ref / 2), &ref_prio);
570
if (rc)
571
return rc;
572
573
/* Update nibble according pin type */
574
if (zl3073x_dpll_is_p_pin(pin)) {
575
ref_prio &= ~ZL_DPLL_REF_PRIO_REF_P;
576
ref_prio |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_P, prio);
577
} else {
578
ref_prio &= ~ZL_DPLL_REF_PRIO_REF_N;
579
ref_prio |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_N, prio);
580
}
581
582
/* Update reference priority */
583
rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_REF_PRIO(ref / 2), ref_prio);
584
if (rc)
585
return rc;
586
587
/* Commit configuration */
588
return zl3073x_mb_op(zldev, ZL_REG_DPLL_MB_SEM, ZL_DPLL_MB_SEM_WR,
589
ZL_REG_DPLL_MB_MASK, BIT(zldpll->id));
590
}
591
592
/**
593
* zl3073x_dpll_ref_state_get - get status for given input pin
594
* @pin: pointer to pin
595
* @state: place to store status
596
*
597
* Checks current status for the given input pin and stores the value
598
* to @state.
599
*
600
* Return: 0 on success, <0 on error
601
*/
602
static int
603
zl3073x_dpll_ref_state_get(struct zl3073x_dpll_pin *pin,
604
enum dpll_pin_state *state)
605
{
606
struct zl3073x_dpll *zldpll = pin->dpll;
607
struct zl3073x_dev *zldev = zldpll->dev;
608
u8 ref, ref_conn;
609
int rc;
610
611
ref = zl3073x_input_pin_ref_get(pin->id);
612
613
/* Get currently connected reference */
614
rc = zl3073x_dpll_connected_ref_get(zldpll, &ref_conn);
615
if (rc)
616
return rc;
617
618
if (ref == ref_conn) {
619
*state = DPLL_PIN_STATE_CONNECTED;
620
return 0;
621
}
622
623
/* If the DPLL is running in automatic mode and the reference is
624
* selectable and its monitor does not report any error then report
625
* pin as selectable.
626
*/
627
if (zldpll->refsel_mode == ZL_DPLL_MODE_REFSEL_MODE_AUTO &&
628
zl3073x_dev_ref_is_status_ok(zldev, ref) && pin->selectable) {
629
*state = DPLL_PIN_STATE_SELECTABLE;
630
return 0;
631
}
632
633
/* Otherwise report the pin as disconnected */
634
*state = DPLL_PIN_STATE_DISCONNECTED;
635
636
return 0;
637
}
638
639
static int
640
zl3073x_dpll_input_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
641
void *pin_priv,
642
const struct dpll_device *dpll,
643
void *dpll_priv,
644
enum dpll_pin_state *state,
645
struct netlink_ext_ack *extack)
646
{
647
struct zl3073x_dpll_pin *pin = pin_priv;
648
649
return zl3073x_dpll_ref_state_get(pin, state);
650
}
651
652
static int
653
zl3073x_dpll_input_pin_state_on_dpll_set(const struct dpll_pin *dpll_pin,
654
void *pin_priv,
655
const struct dpll_device *dpll,
656
void *dpll_priv,
657
enum dpll_pin_state state,
658
struct netlink_ext_ack *extack)
659
{
660
struct zl3073x_dpll *zldpll = dpll_priv;
661
struct zl3073x_dpll_pin *pin = pin_priv;
662
u8 new_ref;
663
int rc;
664
665
switch (zldpll->refsel_mode) {
666
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
667
case ZL_DPLL_MODE_REFSEL_MODE_FREERUN:
668
case ZL_DPLL_MODE_REFSEL_MODE_HOLDOVER:
669
if (state == DPLL_PIN_STATE_CONNECTED) {
670
/* Choose the pin as new selected reference */
671
new_ref = zl3073x_input_pin_ref_get(pin->id);
672
} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
673
/* No reference */
674
new_ref = ZL3073X_DPLL_REF_NONE;
675
} else {
676
NL_SET_ERR_MSG_MOD(extack,
677
"Invalid pin state for manual mode");
678
return -EINVAL;
679
}
680
681
rc = zl3073x_dpll_selected_ref_set(zldpll, new_ref);
682
break;
683
684
case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
685
if (state == DPLL_PIN_STATE_SELECTABLE) {
686
if (pin->selectable)
687
return 0; /* Pin is already selectable */
688
689
/* Restore pin priority in HW */
690
rc = zl3073x_dpll_ref_prio_set(pin, pin->prio);
691
if (rc)
692
return rc;
693
694
/* Mark pin as selectable */
695
pin->selectable = true;
696
} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
697
if (!pin->selectable)
698
return 0; /* Pin is already disconnected */
699
700
/* Set pin priority to none in HW */
701
rc = zl3073x_dpll_ref_prio_set(pin,
702
ZL_DPLL_REF_PRIO_NONE);
703
if (rc)
704
return rc;
705
706
/* Mark pin as non-selectable */
707
pin->selectable = false;
708
} else {
709
NL_SET_ERR_MSG(extack,
710
"Invalid pin state for automatic mode");
711
return -EINVAL;
712
}
713
break;
714
715
default:
716
/* In other modes we cannot change input reference */
717
NL_SET_ERR_MSG(extack,
718
"Pin state cannot be changed in current mode");
719
rc = -EOPNOTSUPP;
720
break;
721
}
722
723
return rc;
724
}
725
726
static int
727
zl3073x_dpll_input_pin_prio_get(const struct dpll_pin *dpll_pin, void *pin_priv,
728
const struct dpll_device *dpll, void *dpll_priv,
729
u32 *prio, struct netlink_ext_ack *extack)
730
{
731
struct zl3073x_dpll_pin *pin = pin_priv;
732
733
*prio = pin->prio;
734
735
return 0;
736
}
737
738
static int
739
zl3073x_dpll_input_pin_prio_set(const struct dpll_pin *dpll_pin, void *pin_priv,
740
const struct dpll_device *dpll, void *dpll_priv,
741
u32 prio, struct netlink_ext_ack *extack)
742
{
743
struct zl3073x_dpll_pin *pin = pin_priv;
744
int rc;
745
746
if (prio > ZL_DPLL_REF_PRIO_MAX)
747
return -EINVAL;
748
749
/* If the pin is selectable then update HW registers */
750
if (pin->selectable) {
751
rc = zl3073x_dpll_ref_prio_set(pin, prio);
752
if (rc)
753
return rc;
754
}
755
756
/* Save priority */
757
pin->prio = prio;
758
759
return 0;
760
}
761
762
static int
763
zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
764
void *pin_priv,
765
const struct dpll_device *dpll,
766
void *dpll_priv,
767
struct dpll_pin_esync *esync,
768
struct netlink_ext_ack *extack)
769
{
770
struct zl3073x_dpll *zldpll = dpll_priv;
771
struct zl3073x_dev *zldev = zldpll->dev;
772
struct zl3073x_dpll_pin *pin = pin_priv;
773
const struct zl3073x_synth *synth;
774
const struct zl3073x_out *out;
775
u8 clock_type, out_id;
776
u32 synth_freq;
777
778
out_id = zl3073x_output_pin_out_get(pin->id);
779
out = zl3073x_out_state_get(zldev, out_id);
780
781
/* If N-division is enabled, esync is not supported. The register used
782
* for N-division is also used for the esync divider so both cannot
783
* be used.
784
*/
785
switch (zl3073x_out_signal_format_get(out)) {
786
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
787
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
788
return -EOPNOTSUPP;
789
default:
790
break;
791
}
792
793
/* Get attached synth frequency */
794
synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out));
795
synth_freq = zl3073x_synth_freq_get(synth);
796
797
clock_type = FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode);
798
if (clock_type != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) {
799
/* No need to read esync data if it is not enabled */
800
esync->freq = 0;
801
esync->pulse = 0;
802
803
goto finish;
804
}
805
806
/* Compute esync frequency */
807
esync->freq = synth_freq / out->div / out->esync_n_period;
808
809
/* By comparing the esync_pulse_width to the half of the pulse width
810
* the esync pulse percentage can be determined.
811
* Note that half pulse width is in units of half synth cycles, which
812
* is why it reduces down to be output_div.
813
*/
814
esync->pulse = (50 * out->esync_n_width) / out->div;
815
816
finish:
817
/* Set supported esync ranges if the pin supports esync control and
818
* if the output frequency is > 1 Hz.
819
*/
820
if (pin->esync_control && (synth_freq / out->div) > 1) {
821
esync->range = esync_freq_ranges;
822
esync->range_num = ARRAY_SIZE(esync_freq_ranges);
823
} else {
824
esync->range = NULL;
825
esync->range_num = 0;
826
}
827
828
return 0;
829
}
830
831
static int
832
zl3073x_dpll_output_pin_esync_set(const struct dpll_pin *dpll_pin,
833
void *pin_priv,
834
const struct dpll_device *dpll,
835
void *dpll_priv, u64 freq,
836
struct netlink_ext_ack *extack)
837
{
838
struct zl3073x_dpll *zldpll = dpll_priv;
839
struct zl3073x_dev *zldev = zldpll->dev;
840
struct zl3073x_dpll_pin *pin = pin_priv;
841
const struct zl3073x_synth *synth;
842
struct zl3073x_out out;
843
u8 clock_type, out_id;
844
u32 synth_freq;
845
846
out_id = zl3073x_output_pin_out_get(pin->id);
847
out = *zl3073x_out_state_get(zldev, out_id);
848
849
/* If N-division is enabled, esync is not supported. The register used
850
* for N-division is also used for the esync divider so both cannot
851
* be used.
852
*/
853
switch (zl3073x_out_signal_format_get(&out)) {
854
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
855
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
856
return -EOPNOTSUPP;
857
default:
858
break;
859
}
860
861
/* Select clock type */
862
if (freq)
863
clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC;
864
else
865
clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_NORMAL;
866
867
/* Update clock type in output mode */
868
out.mode &= ~ZL_OUTPUT_MODE_CLOCK_TYPE;
869
out.mode |= FIELD_PREP(ZL_OUTPUT_MODE_CLOCK_TYPE, clock_type);
870
871
/* If esync is being disabled just write mailbox and finish */
872
if (!freq)
873
goto write_mailbox;
874
875
/* Get attached synth frequency */
876
synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(&out));
877
synth_freq = zl3073x_synth_freq_get(synth);
878
879
/* Compute and update esync period */
880
out.esync_n_period = synth_freq / (u32)freq / out.div;
881
882
/* Half of the period in units of 1/2 synth cycle can be represented by
883
* the output_div. To get the supported esync pulse width of 25% of the
884
* period the output_div can just be divided by 2. Note that this
885
* assumes that output_div is even, otherwise some resolution will be
886
* lost.
887
*/
888
out.esync_n_width = out.div / 2;
889
890
write_mailbox:
891
/* Commit output configuration */
892
return zl3073x_out_state_set(zldev, out_id, &out);
893
}
894
895
static int
896
zl3073x_dpll_output_pin_frequency_get(const struct dpll_pin *dpll_pin,
897
void *pin_priv,
898
const struct dpll_device *dpll,
899
void *dpll_priv, u64 *frequency,
900
struct netlink_ext_ack *extack)
901
{
902
struct zl3073x_dpll *zldpll = dpll_priv;
903
struct zl3073x_dev *zldev = zldpll->dev;
904
struct zl3073x_dpll_pin *pin = pin_priv;
905
const struct zl3073x_synth *synth;
906
const struct zl3073x_out *out;
907
u32 synth_freq;
908
u8 out_id;
909
910
out_id = zl3073x_output_pin_out_get(pin->id);
911
out = zl3073x_out_state_get(zldev, out_id);
912
913
/* Get attached synth frequency */
914
synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out));
915
synth_freq = zl3073x_synth_freq_get(synth);
916
917
switch (zl3073x_out_signal_format_get(out)) {
918
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
919
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
920
/* In case of divided format we have to distiguish between
921
* given output pin type.
922
*
923
* For P-pin the resulting frequency is computed as simple
924
* division of synth frequency and output divisor.
925
*
926
* For N-pin we have to divide additionally by divisor stored
927
* in esync_n_period output mailbox register that is used as
928
* N-pin divisor for these modes.
929
*/
930
*frequency = synth_freq / out->div;
931
932
if (!zl3073x_dpll_is_p_pin(pin))
933
*frequency = (u32)*frequency / out->esync_n_period;
934
935
break;
936
default:
937
/* In other modes the resulting frequency is computed as
938
* division of synth frequency and output divisor.
939
*/
940
*frequency = synth_freq / out->div;
941
break;
942
}
943
944
return 0;
945
}
946
947
static int
948
zl3073x_dpll_output_pin_frequency_set(const struct dpll_pin *dpll_pin,
949
void *pin_priv,
950
const struct dpll_device *dpll,
951
void *dpll_priv, u64 frequency,
952
struct netlink_ext_ack *extack)
953
{
954
struct zl3073x_dpll *zldpll = dpll_priv;
955
struct zl3073x_dev *zldev = zldpll->dev;
956
struct zl3073x_dpll_pin *pin = pin_priv;
957
const struct zl3073x_synth *synth;
958
u8 out_id, signal_format;
959
u32 new_div, synth_freq;
960
struct zl3073x_out out;
961
962
out_id = zl3073x_output_pin_out_get(pin->id);
963
out = *zl3073x_out_state_get(zldev, out_id);
964
965
/* Get attached synth frequency and compute new divisor */
966
synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(&out));
967
synth_freq = zl3073x_synth_freq_get(synth);
968
new_div = synth_freq / (u32)frequency;
969
970
/* Get used signal format for the given output */
971
signal_format = zl3073x_out_signal_format_get(&out);
972
973
/* Check signal format */
974
if (signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV &&
975
signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV) {
976
/* For non N-divided signal formats the frequency is computed
977
* as division of synth frequency and output divisor.
978
*/
979
out.div = new_div;
980
981
/* For 50/50 duty cycle the divisor is equal to width */
982
out.width = new_div;
983
984
/* Commit output configuration */
985
return zl3073x_out_state_set(zldev, out_id, &out);
986
}
987
988
if (zl3073x_dpll_is_p_pin(pin)) {
989
/* We are going to change output frequency for P-pin but
990
* if the requested frequency is less than current N-pin
991
* frequency then indicate a failure as we are not able
992
* to compute N-pin divisor to keep its frequency unchanged.
993
*
994
* Update divisor for N-pin to keep N-pin frequency.
995
*/
996
out.esync_n_period = (out.esync_n_period * out.div) / new_div;
997
if (!out.esync_n_period)
998
return -EINVAL;
999
1000
/* Update the output divisor */
1001
out.div = new_div;
1002
1003
/* For 50/50 duty cycle the divisor is equal to width */
1004
out.width = out.div;
1005
} else {
1006
/* We are going to change frequency of N-pin but if
1007
* the requested freq is greater or equal than freq of P-pin
1008
* in the output pair we cannot compute divisor for the N-pin.
1009
* In this case indicate a failure.
1010
*
1011
* Update divisor for N-pin
1012
*/
1013
out.esync_n_period = div64_u64(synth_freq, frequency * out.div);
1014
if (!out.esync_n_period)
1015
return -EINVAL;
1016
}
1017
1018
/* For 50/50 duty cycle the divisor is equal to width */
1019
out.esync_n_width = out.esync_n_period;
1020
1021
/* Commit output configuration */
1022
return zl3073x_out_state_set(zldev, out_id, &out);
1023
}
1024
1025
static int
1026
zl3073x_dpll_output_pin_phase_adjust_get(const struct dpll_pin *dpll_pin,
1027
void *pin_priv,
1028
const struct dpll_device *dpll,
1029
void *dpll_priv,
1030
s32 *phase_adjust,
1031
struct netlink_ext_ack *extack)
1032
{
1033
struct zl3073x_dpll *zldpll = dpll_priv;
1034
struct zl3073x_dev *zldev = zldpll->dev;
1035
struct zl3073x_dpll_pin *pin = pin_priv;
1036
const struct zl3073x_out *out;
1037
u8 out_id;
1038
1039
out_id = zl3073x_output_pin_out_get(pin->id);
1040
out = zl3073x_out_state_get(zldev, out_id);
1041
1042
/* Convert value to ps and reverse two's complement negation applied
1043
* during 'set'
1044
*/
1045
*phase_adjust = -out->phase_comp * pin->phase_gran;
1046
1047
return 0;
1048
}
1049
1050
static int
1051
zl3073x_dpll_output_pin_phase_adjust_set(const struct dpll_pin *dpll_pin,
1052
void *pin_priv,
1053
const struct dpll_device *dpll,
1054
void *dpll_priv,
1055
s32 phase_adjust,
1056
struct netlink_ext_ack *extack)
1057
{
1058
struct zl3073x_dpll *zldpll = dpll_priv;
1059
struct zl3073x_dev *zldev = zldpll->dev;
1060
struct zl3073x_dpll_pin *pin = pin_priv;
1061
struct zl3073x_out out;
1062
u8 out_id;
1063
1064
out_id = zl3073x_output_pin_out_get(pin->id);
1065
out = *zl3073x_out_state_get(zldev, out_id);
1066
1067
/* The value in the register is stored as two's complement negation
1068
* of requested value and expressed in half synth clock cycles.
1069
*/
1070
out.phase_comp = -phase_adjust / pin->phase_gran;
1071
1072
/* Update output configuration from mailbox */
1073
return zl3073x_out_state_set(zldev, out_id, &out);
1074
}
1075
1076
static int
1077
zl3073x_dpll_output_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
1078
void *pin_priv,
1079
const struct dpll_device *dpll,
1080
void *dpll_priv,
1081
enum dpll_pin_state *state,
1082
struct netlink_ext_ack *extack)
1083
{
1084
/* If the output pin is registered then it is always connected */
1085
*state = DPLL_PIN_STATE_CONNECTED;
1086
1087
return 0;
1088
}
1089
1090
static int
1091
zl3073x_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
1092
enum dpll_lock_status *status,
1093
enum dpll_lock_status_error *status_error,
1094
struct netlink_ext_ack *extack)
1095
{
1096
struct zl3073x_dpll *zldpll = dpll_priv;
1097
struct zl3073x_dev *zldev = zldpll->dev;
1098
u8 mon_status, state;
1099
int rc;
1100
1101
switch (zldpll->refsel_mode) {
1102
case ZL_DPLL_MODE_REFSEL_MODE_FREERUN:
1103
case ZL_DPLL_MODE_REFSEL_MODE_NCO:
1104
/* In FREERUN and NCO modes the DPLL is always unlocked */
1105
*status = DPLL_LOCK_STATUS_UNLOCKED;
1106
1107
return 0;
1108
default:
1109
break;
1110
}
1111
1112
/* Read DPLL monitor status */
1113
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MON_STATUS(zldpll->id),
1114
&mon_status);
1115
if (rc)
1116
return rc;
1117
state = FIELD_GET(ZL_DPLL_MON_STATUS_STATE, mon_status);
1118
1119
switch (state) {
1120
case ZL_DPLL_MON_STATUS_STATE_LOCK:
1121
if (FIELD_GET(ZL_DPLL_MON_STATUS_HO_READY, mon_status))
1122
*status = DPLL_LOCK_STATUS_LOCKED_HO_ACQ;
1123
else
1124
*status = DPLL_LOCK_STATUS_LOCKED;
1125
break;
1126
case ZL_DPLL_MON_STATUS_STATE_HOLDOVER:
1127
case ZL_DPLL_MON_STATUS_STATE_ACQUIRING:
1128
*status = DPLL_LOCK_STATUS_HOLDOVER;
1129
break;
1130
default:
1131
dev_warn(zldev->dev, "Unknown DPLL monitor status: 0x%02x\n",
1132
mon_status);
1133
*status = DPLL_LOCK_STATUS_UNLOCKED;
1134
break;
1135
}
1136
1137
return 0;
1138
}
1139
1140
static int
1141
zl3073x_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
1142
enum dpll_mode *mode, struct netlink_ext_ack *extack)
1143
{
1144
struct zl3073x_dpll *zldpll = dpll_priv;
1145
1146
switch (zldpll->refsel_mode) {
1147
case ZL_DPLL_MODE_REFSEL_MODE_FREERUN:
1148
case ZL_DPLL_MODE_REFSEL_MODE_HOLDOVER:
1149
case ZL_DPLL_MODE_REFSEL_MODE_NCO:
1150
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
1151
/* Use MANUAL for device FREERUN, HOLDOVER, NCO and
1152
* REFLOCK modes
1153
*/
1154
*mode = DPLL_MODE_MANUAL;
1155
break;
1156
case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
1157
/* Use AUTO for device AUTO mode */
1158
*mode = DPLL_MODE_AUTOMATIC;
1159
break;
1160
default:
1161
return -EINVAL;
1162
}
1163
1164
return 0;
1165
}
1166
1167
static int
1168
zl3073x_dpll_phase_offset_avg_factor_get(const struct dpll_device *dpll,
1169
void *dpll_priv, u32 *factor,
1170
struct netlink_ext_ack *extack)
1171
{
1172
struct zl3073x_dpll *zldpll = dpll_priv;
1173
1174
*factor = zl3073x_dev_phase_avg_factor_get(zldpll->dev);
1175
1176
return 0;
1177
}
1178
1179
static void
1180
zl3073x_dpll_change_work(struct work_struct *work)
1181
{
1182
struct zl3073x_dpll *zldpll;
1183
1184
zldpll = container_of(work, struct zl3073x_dpll, change_work);
1185
dpll_device_change_ntf(zldpll->dpll_dev);
1186
}
1187
1188
static int
1189
zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll,
1190
void *dpll_priv, u32 factor,
1191
struct netlink_ext_ack *extack)
1192
{
1193
struct zl3073x_dpll *item, *zldpll = dpll_priv;
1194
int rc;
1195
1196
if (factor > 15) {
1197
NL_SET_ERR_MSG_FMT(extack,
1198
"Phase offset average factor has to be from range <0,15>");
1199
return -EINVAL;
1200
}
1201
1202
rc = zl3073x_dev_phase_avg_factor_set(zldpll->dev, factor);
1203
if (rc) {
1204
NL_SET_ERR_MSG_FMT(extack,
1205
"Failed to set phase offset averaging factor");
1206
return rc;
1207
}
1208
1209
/* The averaging factor is common for all DPLL channels so after change
1210
* we have to send a notification for other DPLL devices.
1211
*/
1212
list_for_each_entry(item, &zldpll->dev->dplls, list) {
1213
if (item != zldpll)
1214
schedule_work(&item->change_work);
1215
}
1216
1217
return 0;
1218
}
1219
1220
static int
1221
zl3073x_dpll_phase_offset_monitor_get(const struct dpll_device *dpll,
1222
void *dpll_priv,
1223
enum dpll_feature_state *state,
1224
struct netlink_ext_ack *extack)
1225
{
1226
struct zl3073x_dpll *zldpll = dpll_priv;
1227
1228
if (zldpll->phase_monitor)
1229
*state = DPLL_FEATURE_STATE_ENABLE;
1230
else
1231
*state = DPLL_FEATURE_STATE_DISABLE;
1232
1233
return 0;
1234
}
1235
1236
static int
1237
zl3073x_dpll_phase_offset_monitor_set(const struct dpll_device *dpll,
1238
void *dpll_priv,
1239
enum dpll_feature_state state,
1240
struct netlink_ext_ack *extack)
1241
{
1242
struct zl3073x_dpll *zldpll = dpll_priv;
1243
1244
zldpll->phase_monitor = (state == DPLL_FEATURE_STATE_ENABLE);
1245
1246
return 0;
1247
}
1248
1249
static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
1250
.direction_get = zl3073x_dpll_pin_direction_get,
1251
.esync_get = zl3073x_dpll_input_pin_esync_get,
1252
.esync_set = zl3073x_dpll_input_pin_esync_set,
1253
.ffo_get = zl3073x_dpll_input_pin_ffo_get,
1254
.frequency_get = zl3073x_dpll_input_pin_frequency_get,
1255
.frequency_set = zl3073x_dpll_input_pin_frequency_set,
1256
.phase_offset_get = zl3073x_dpll_input_pin_phase_offset_get,
1257
.phase_adjust_get = zl3073x_dpll_input_pin_phase_adjust_get,
1258
.phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set,
1259
.prio_get = zl3073x_dpll_input_pin_prio_get,
1260
.prio_set = zl3073x_dpll_input_pin_prio_set,
1261
.state_on_dpll_get = zl3073x_dpll_input_pin_state_on_dpll_get,
1262
.state_on_dpll_set = zl3073x_dpll_input_pin_state_on_dpll_set,
1263
};
1264
1265
static const struct dpll_pin_ops zl3073x_dpll_output_pin_ops = {
1266
.direction_get = zl3073x_dpll_pin_direction_get,
1267
.esync_get = zl3073x_dpll_output_pin_esync_get,
1268
.esync_set = zl3073x_dpll_output_pin_esync_set,
1269
.frequency_get = zl3073x_dpll_output_pin_frequency_get,
1270
.frequency_set = zl3073x_dpll_output_pin_frequency_set,
1271
.phase_adjust_get = zl3073x_dpll_output_pin_phase_adjust_get,
1272
.phase_adjust_set = zl3073x_dpll_output_pin_phase_adjust_set,
1273
.state_on_dpll_get = zl3073x_dpll_output_pin_state_on_dpll_get,
1274
};
1275
1276
static const struct dpll_device_ops zl3073x_dpll_device_ops = {
1277
.lock_status_get = zl3073x_dpll_lock_status_get,
1278
.mode_get = zl3073x_dpll_mode_get,
1279
.phase_offset_avg_factor_get = zl3073x_dpll_phase_offset_avg_factor_get,
1280
.phase_offset_avg_factor_set = zl3073x_dpll_phase_offset_avg_factor_set,
1281
.phase_offset_monitor_get = zl3073x_dpll_phase_offset_monitor_get,
1282
.phase_offset_monitor_set = zl3073x_dpll_phase_offset_monitor_set,
1283
};
1284
1285
/**
1286
* zl3073x_dpll_pin_alloc - allocate DPLL pin
1287
* @zldpll: pointer to zl3073x_dpll
1288
* @dir: pin direction
1289
* @id: pin id
1290
*
1291
* Allocates and initializes zl3073x_dpll_pin structure for given
1292
* pin id and direction.
1293
*
1294
* Return: pointer to allocated structure on success, error pointer on error
1295
*/
1296
static struct zl3073x_dpll_pin *
1297
zl3073x_dpll_pin_alloc(struct zl3073x_dpll *zldpll, enum dpll_pin_direction dir,
1298
u8 id)
1299
{
1300
struct zl3073x_dpll_pin *pin;
1301
1302
pin = kzalloc(sizeof(*pin), GFP_KERNEL);
1303
if (!pin)
1304
return ERR_PTR(-ENOMEM);
1305
1306
pin->dpll = zldpll;
1307
pin->dir = dir;
1308
pin->id = id;
1309
1310
return pin;
1311
}
1312
1313
/**
1314
* zl3073x_dpll_pin_free - deallocate DPLL pin
1315
* @pin: pin to free
1316
*
1317
* Deallocates DPLL pin previously allocated by @zl3073x_dpll_pin_alloc.
1318
*/
1319
static void
1320
zl3073x_dpll_pin_free(struct zl3073x_dpll_pin *pin)
1321
{
1322
WARN(pin->dpll_pin, "DPLL pin is still registered\n");
1323
1324
kfree(pin);
1325
}
1326
1327
/**
1328
* zl3073x_dpll_pin_register - register DPLL pin
1329
* @pin: pointer to DPLL pin
1330
* @index: absolute pin index for registration
1331
*
1332
* Registers given DPLL pin into DPLL sub-system.
1333
*
1334
* Return: 0 on success, <0 on error
1335
*/
1336
static int
1337
zl3073x_dpll_pin_register(struct zl3073x_dpll_pin *pin, u32 index)
1338
{
1339
struct zl3073x_dpll *zldpll = pin->dpll;
1340
struct zl3073x_pin_props *props;
1341
const struct dpll_pin_ops *ops;
1342
int rc;
1343
1344
/* Get pin properties */
1345
props = zl3073x_pin_props_get(zldpll->dev, pin->dir, pin->id);
1346
if (IS_ERR(props))
1347
return PTR_ERR(props);
1348
1349
/* Save package label, esync capability and phase adjust granularity */
1350
strscpy(pin->label, props->package_label);
1351
pin->esync_control = props->esync_control;
1352
pin->phase_gran = props->dpll_props.phase_gran;
1353
1354
if (zl3073x_dpll_is_input_pin(pin)) {
1355
rc = zl3073x_dpll_ref_prio_get(pin, &pin->prio);
1356
if (rc)
1357
goto err_prio_get;
1358
1359
if (pin->prio == ZL_DPLL_REF_PRIO_NONE) {
1360
/* Clamp prio to max value & mark pin non-selectable */
1361
pin->prio = ZL_DPLL_REF_PRIO_MAX;
1362
pin->selectable = false;
1363
} else {
1364
/* Mark pin as selectable */
1365
pin->selectable = true;
1366
}
1367
}
1368
1369
/* Create or get existing DPLL pin */
1370
pin->dpll_pin = dpll_pin_get(zldpll->dev->clock_id, index, THIS_MODULE,
1371
&props->dpll_props);
1372
if (IS_ERR(pin->dpll_pin)) {
1373
rc = PTR_ERR(pin->dpll_pin);
1374
goto err_pin_get;
1375
}
1376
1377
if (zl3073x_dpll_is_input_pin(pin))
1378
ops = &zl3073x_dpll_input_pin_ops;
1379
else
1380
ops = &zl3073x_dpll_output_pin_ops;
1381
1382
/* Register the pin */
1383
rc = dpll_pin_register(zldpll->dpll_dev, pin->dpll_pin, ops, pin);
1384
if (rc)
1385
goto err_register;
1386
1387
/* Free pin properties */
1388
zl3073x_pin_props_put(props);
1389
1390
return 0;
1391
1392
err_register:
1393
dpll_pin_put(pin->dpll_pin);
1394
err_prio_get:
1395
pin->dpll_pin = NULL;
1396
err_pin_get:
1397
zl3073x_pin_props_put(props);
1398
1399
return rc;
1400
}
1401
1402
/**
1403
* zl3073x_dpll_pin_unregister - unregister DPLL pin
1404
* @pin: pointer to DPLL pin
1405
*
1406
* Unregisters pin previously registered by @zl3073x_dpll_pin_register.
1407
*/
1408
static void
1409
zl3073x_dpll_pin_unregister(struct zl3073x_dpll_pin *pin)
1410
{
1411
struct zl3073x_dpll *zldpll = pin->dpll;
1412
const struct dpll_pin_ops *ops;
1413
1414
WARN(!pin->dpll_pin, "DPLL pin is not registered\n");
1415
1416
if (zl3073x_dpll_is_input_pin(pin))
1417
ops = &zl3073x_dpll_input_pin_ops;
1418
else
1419
ops = &zl3073x_dpll_output_pin_ops;
1420
1421
/* Unregister the pin */
1422
dpll_pin_unregister(zldpll->dpll_dev, pin->dpll_pin, ops, pin);
1423
1424
dpll_pin_put(pin->dpll_pin);
1425
pin->dpll_pin = NULL;
1426
}
1427
1428
/**
1429
* zl3073x_dpll_pins_unregister - unregister all registered DPLL pins
1430
* @zldpll: pointer to zl3073x_dpll structure
1431
*
1432
* Enumerates all DPLL pins registered to given DPLL device and
1433
* unregisters them.
1434
*/
1435
static void
1436
zl3073x_dpll_pins_unregister(struct zl3073x_dpll *zldpll)
1437
{
1438
struct zl3073x_dpll_pin *pin, *next;
1439
1440
list_for_each_entry_safe(pin, next, &zldpll->pins, list) {
1441
zl3073x_dpll_pin_unregister(pin);
1442
list_del(&pin->list);
1443
zl3073x_dpll_pin_free(pin);
1444
}
1445
}
1446
1447
/**
1448
* zl3073x_dpll_pin_is_registrable - check if the pin is registrable
1449
* @zldpll: pointer to zl3073x_dpll structure
1450
* @dir: pin direction
1451
* @index: pin index
1452
*
1453
* Checks if the given pin can be registered to given DPLL. For both
1454
* directions the pin can be registered if it is enabled. In case of
1455
* differential signal type only P-pin is reported as registrable.
1456
* And additionally for the output pin, the pin can be registered only
1457
* if it is connected to synthesizer that is driven by given DPLL.
1458
*
1459
* Return: true if the pin is registrable, false if not
1460
*/
1461
static bool
1462
zl3073x_dpll_pin_is_registrable(struct zl3073x_dpll *zldpll,
1463
enum dpll_pin_direction dir, u8 index)
1464
{
1465
struct zl3073x_dev *zldev = zldpll->dev;
1466
bool is_diff, is_enabled;
1467
const char *name;
1468
1469
if (dir == DPLL_PIN_DIRECTION_INPUT) {
1470
u8 ref_id = zl3073x_input_pin_ref_get(index);
1471
const struct zl3073x_ref *ref;
1472
1473
/* Skip the pin if the DPLL is running in NCO mode */
1474
if (zldpll->refsel_mode == ZL_DPLL_MODE_REFSEL_MODE_NCO)
1475
return false;
1476
1477
name = "REF";
1478
ref = zl3073x_ref_state_get(zldev, ref_id);
1479
is_diff = zl3073x_ref_is_diff(ref);
1480
is_enabled = zl3073x_ref_is_enabled(ref);
1481
} else {
1482
/* Output P&N pair shares single HW output */
1483
u8 out = zl3073x_output_pin_out_get(index);
1484
1485
/* Skip the pin if it is connected to different DPLL channel */
1486
if (zl3073x_dev_out_dpll_get(zldev, out) != zldpll->id) {
1487
dev_dbg(zldev->dev,
1488
"OUT%u is driven by different DPLL\n", out);
1489
1490
return false;
1491
}
1492
1493
name = "OUT";
1494
is_diff = zl3073x_dev_out_is_diff(zldev, out);
1495
is_enabled = zl3073x_dev_output_pin_is_enabled(zldev, index);
1496
}
1497
1498
/* Skip N-pin if the corresponding input/output is differential */
1499
if (is_diff && zl3073x_is_n_pin(index)) {
1500
dev_dbg(zldev->dev, "%s%u is differential, skipping N-pin\n",
1501
name, index / 2);
1502
1503
return false;
1504
}
1505
1506
/* Skip the pin if it is disabled */
1507
if (!is_enabled) {
1508
dev_dbg(zldev->dev, "%s%u%c is disabled\n", name, index / 2,
1509
zl3073x_is_p_pin(index) ? 'P' : 'N');
1510
1511
return false;
1512
}
1513
1514
return true;
1515
}
1516
1517
/**
1518
* zl3073x_dpll_pins_register - register all registerable DPLL pins
1519
* @zldpll: pointer to zl3073x_dpll structure
1520
*
1521
* Enumerates all possible input/output pins and registers all of them
1522
* that are registrable.
1523
*
1524
* Return: 0 on success, <0 on error
1525
*/
1526
static int
1527
zl3073x_dpll_pins_register(struct zl3073x_dpll *zldpll)
1528
{
1529
struct zl3073x_dpll_pin *pin;
1530
enum dpll_pin_direction dir;
1531
u8 id, index;
1532
int rc;
1533
1534
/* Process input pins */
1535
for (index = 0; index < ZL3073X_NUM_PINS; index++) {
1536
/* First input pins and then output pins */
1537
if (index < ZL3073X_NUM_INPUT_PINS) {
1538
id = index;
1539
dir = DPLL_PIN_DIRECTION_INPUT;
1540
} else {
1541
id = index - ZL3073X_NUM_INPUT_PINS;
1542
dir = DPLL_PIN_DIRECTION_OUTPUT;
1543
}
1544
1545
/* Check if the pin registrable to this DPLL */
1546
if (!zl3073x_dpll_pin_is_registrable(zldpll, dir, id))
1547
continue;
1548
1549
pin = zl3073x_dpll_pin_alloc(zldpll, dir, id);
1550
if (IS_ERR(pin)) {
1551
rc = PTR_ERR(pin);
1552
goto error;
1553
}
1554
1555
rc = zl3073x_dpll_pin_register(pin, index);
1556
if (rc)
1557
goto error;
1558
1559
list_add(&pin->list, &zldpll->pins);
1560
}
1561
1562
return 0;
1563
1564
error:
1565
zl3073x_dpll_pins_unregister(zldpll);
1566
1567
return rc;
1568
}
1569
1570
/**
1571
* zl3073x_dpll_device_register - register DPLL device
1572
* @zldpll: pointer to zl3073x_dpll structure
1573
*
1574
* Registers given DPLL device into DPLL sub-system.
1575
*
1576
* Return: 0 on success, <0 on error
1577
*/
1578
static int
1579
zl3073x_dpll_device_register(struct zl3073x_dpll *zldpll)
1580
{
1581
struct zl3073x_dev *zldev = zldpll->dev;
1582
u8 dpll_mode_refsel;
1583
int rc;
1584
1585
/* Read DPLL mode and forcibly selected reference */
1586
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MODE_REFSEL(zldpll->id),
1587
&dpll_mode_refsel);
1588
if (rc)
1589
return rc;
1590
1591
/* Extract mode and selected input reference */
1592
zldpll->refsel_mode = FIELD_GET(ZL_DPLL_MODE_REFSEL_MODE,
1593
dpll_mode_refsel);
1594
zldpll->forced_ref = FIELD_GET(ZL_DPLL_MODE_REFSEL_REF,
1595
dpll_mode_refsel);
1596
1597
zldpll->dpll_dev = dpll_device_get(zldev->clock_id, zldpll->id,
1598
THIS_MODULE);
1599
if (IS_ERR(zldpll->dpll_dev)) {
1600
rc = PTR_ERR(zldpll->dpll_dev);
1601
zldpll->dpll_dev = NULL;
1602
1603
return rc;
1604
}
1605
1606
rc = dpll_device_register(zldpll->dpll_dev,
1607
zl3073x_prop_dpll_type_get(zldev, zldpll->id),
1608
&zl3073x_dpll_device_ops, zldpll);
1609
if (rc) {
1610
dpll_device_put(zldpll->dpll_dev);
1611
zldpll->dpll_dev = NULL;
1612
}
1613
1614
return rc;
1615
}
1616
1617
/**
1618
* zl3073x_dpll_device_unregister - unregister DPLL device
1619
* @zldpll: pointer to zl3073x_dpll structure
1620
*
1621
* Unregisters given DPLL device from DPLL sub-system previously registered
1622
* by @zl3073x_dpll_device_register.
1623
*/
1624
static void
1625
zl3073x_dpll_device_unregister(struct zl3073x_dpll *zldpll)
1626
{
1627
WARN(!zldpll->dpll_dev, "DPLL device is not registered\n");
1628
1629
cancel_work_sync(&zldpll->change_work);
1630
1631
dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops,
1632
zldpll);
1633
dpll_device_put(zldpll->dpll_dev);
1634
zldpll->dpll_dev = NULL;
1635
}
1636
1637
/**
1638
* zl3073x_dpll_pin_phase_offset_check - check for pin phase offset change
1639
* @pin: pin to check
1640
*
1641
* Check for the change of DPLL to connected pin phase offset change.
1642
*
1643
* Return: true on phase offset change, false otherwise
1644
*/
1645
static bool
1646
zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
1647
{
1648
struct zl3073x_dpll *zldpll = pin->dpll;
1649
struct zl3073x_dev *zldev = zldpll->dev;
1650
unsigned int reg;
1651
s64 phase_offset;
1652
u8 ref_id;
1653
int rc;
1654
1655
/* No phase offset if the ref monitor reports signal errors */
1656
ref_id = zl3073x_input_pin_ref_get(pin->id);
1657
if (!zl3073x_dev_ref_is_status_ok(zldev, ref_id))
1658
return false;
1659
1660
/* Select register to read phase offset value depending on pin and
1661
* phase monitor state:
1662
* 1) For connected pin use dpll_phase_err_data register
1663
* 2) For other pins use appropriate ref_phase register if the phase
1664
* monitor feature is enabled.
1665
*/
1666
if (pin->pin_state == DPLL_PIN_STATE_CONNECTED)
1667
reg = ZL_REG_DPLL_PHASE_ERR_DATA(zldpll->id);
1668
else if (zldpll->phase_monitor)
1669
reg = ZL_REG_REF_PHASE(ref_id);
1670
else
1671
return false;
1672
1673
/* Read measured phase offset value */
1674
rc = zl3073x_read_u48(zldev, reg, &phase_offset);
1675
if (rc) {
1676
dev_err(zldev->dev, "Failed to read ref phase offset: %pe\n",
1677
ERR_PTR(rc));
1678
1679
return false;
1680
}
1681
1682
/* Convert to ps */
1683
phase_offset = div_s64(sign_extend64(phase_offset, 47), 100);
1684
1685
/* Compare with previous value */
1686
if (phase_offset != pin->phase_offset) {
1687
dev_dbg(zldev->dev, "%s phase offset changed: %lld -> %lld\n",
1688
pin->label, pin->phase_offset, phase_offset);
1689
pin->phase_offset = phase_offset;
1690
1691
return true;
1692
}
1693
1694
return false;
1695
}
1696
1697
/**
1698
* zl3073x_dpll_pin_ffo_check - check for pin fractional frequency offset change
1699
* @pin: pin to check
1700
*
1701
* Check for the given pin's fractional frequency change.
1702
*
1703
* Return: true on fractional frequency offset change, false otherwise
1704
*/
1705
static bool
1706
zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *pin)
1707
{
1708
struct zl3073x_dpll *zldpll = pin->dpll;
1709
struct zl3073x_dev *zldev = zldpll->dev;
1710
const struct zl3073x_ref *ref;
1711
u8 ref_id;
1712
1713
/* Get reference monitor status */
1714
ref_id = zl3073x_input_pin_ref_get(pin->id);
1715
ref = zl3073x_ref_state_get(zldev, ref_id);
1716
1717
/* Do not report ffo changes if the reference monitor report errors */
1718
if (!zl3073x_ref_is_status_ok(ref))
1719
return false;
1720
1721
/* Compare with previous value */
1722
if (pin->freq_offset != ref->ffo) {
1723
dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n",
1724
pin->label, pin->freq_offset, ref->ffo);
1725
pin->freq_offset = ref->ffo;
1726
1727
return true;
1728
}
1729
1730
return false;
1731
}
1732
1733
/**
1734
* zl3073x_dpll_changes_check - check for changes and send notifications
1735
* @zldpll: pointer to zl3073x_dpll structure
1736
*
1737
* Checks for changes on given DPLL device and its registered DPLL pins
1738
* and sends notifications about them.
1739
*
1740
* This function is periodically called from @zl3073x_dev_periodic_work.
1741
*/
1742
void
1743
zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
1744
{
1745
struct zl3073x_dev *zldev = zldpll->dev;
1746
enum dpll_lock_status lock_status;
1747
struct device *dev = zldev->dev;
1748
struct zl3073x_dpll_pin *pin;
1749
int rc;
1750
1751
zldpll->check_count++;
1752
1753
/* Get current lock status for the DPLL */
1754
rc = zl3073x_dpll_lock_status_get(zldpll->dpll_dev, zldpll,
1755
&lock_status, NULL, NULL);
1756
if (rc) {
1757
dev_err(dev, "Failed to get DPLL%u lock status: %pe\n",
1758
zldpll->id, ERR_PTR(rc));
1759
return;
1760
}
1761
1762
/* If lock status was changed then notify DPLL core */
1763
if (zldpll->lock_status != lock_status) {
1764
zldpll->lock_status = lock_status;
1765
dpll_device_change_ntf(zldpll->dpll_dev);
1766
}
1767
1768
/* Input pin monitoring does make sense only in automatic
1769
* or forced reference modes.
1770
*/
1771
if (zldpll->refsel_mode != ZL_DPLL_MODE_REFSEL_MODE_AUTO &&
1772
zldpll->refsel_mode != ZL_DPLL_MODE_REFSEL_MODE_REFLOCK)
1773
return;
1774
1775
/* Update phase offset latch registers for this DPLL if the phase
1776
* offset monitor feature is enabled.
1777
*/
1778
if (zldpll->phase_monitor) {
1779
rc = zl3073x_ref_phase_offsets_update(zldev, zldpll->id);
1780
if (rc) {
1781
dev_err(zldev->dev,
1782
"Failed to update phase offsets: %pe\n",
1783
ERR_PTR(rc));
1784
return;
1785
}
1786
}
1787
1788
list_for_each_entry(pin, &zldpll->pins, list) {
1789
enum dpll_pin_state state;
1790
bool pin_changed = false;
1791
1792
/* Output pins change checks are not necessary because output
1793
* states are constant.
1794
*/
1795
if (!zl3073x_dpll_is_input_pin(pin))
1796
continue;
1797
1798
rc = zl3073x_dpll_ref_state_get(pin, &state);
1799
if (rc) {
1800
dev_err(dev,
1801
"Failed to get %s on DPLL%u state: %pe\n",
1802
pin->label, zldpll->id, ERR_PTR(rc));
1803
return;
1804
}
1805
1806
if (state != pin->pin_state) {
1807
dev_dbg(dev, "%s state changed: %u->%u\n", pin->label,
1808
pin->pin_state, state);
1809
pin->pin_state = state;
1810
pin_changed = true;
1811
}
1812
1813
/* Check for phase offset and ffo change once per second */
1814
if (zldpll->check_count % 2 == 0) {
1815
if (zl3073x_dpll_pin_phase_offset_check(pin))
1816
pin_changed = true;
1817
1818
if (zl3073x_dpll_pin_ffo_check(pin))
1819
pin_changed = true;
1820
}
1821
1822
if (pin_changed)
1823
dpll_pin_change_ntf(pin->dpll_pin);
1824
}
1825
}
1826
1827
/**
1828
* zl3073x_dpll_init_fine_phase_adjust - do initial fine phase adjustments
1829
* @zldev: pointer to zl3073x device
1830
*
1831
* Performs initial fine phase adjustments needed per datasheet.
1832
*
1833
* Return: 0 on success, <0 on error
1834
*/
1835
int
1836
zl3073x_dpll_init_fine_phase_adjust(struct zl3073x_dev *zldev)
1837
{
1838
int rc;
1839
1840
rc = zl3073x_write_u8(zldev, ZL_REG_SYNTH_PHASE_SHIFT_MASK, 0x1f);
1841
if (rc)
1842
return rc;
1843
1844
rc = zl3073x_write_u8(zldev, ZL_REG_SYNTH_PHASE_SHIFT_INTVL, 0x01);
1845
if (rc)
1846
return rc;
1847
1848
rc = zl3073x_write_u16(zldev, ZL_REG_SYNTH_PHASE_SHIFT_DATA, 0xffff);
1849
if (rc)
1850
return rc;
1851
1852
rc = zl3073x_write_u8(zldev, ZL_REG_SYNTH_PHASE_SHIFT_CTRL, 0x01);
1853
if (rc)
1854
return rc;
1855
1856
return rc;
1857
}
1858
1859
/**
1860
* zl3073x_dpll_alloc - allocate DPLL device
1861
* @zldev: pointer to zl3073x device
1862
* @ch: DPLL channel number
1863
*
1864
* Allocates DPLL device structure for given DPLL channel.
1865
*
1866
* Return: pointer to DPLL device on success, error pointer on error
1867
*/
1868
struct zl3073x_dpll *
1869
zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch)
1870
{
1871
struct zl3073x_dpll *zldpll;
1872
1873
zldpll = kzalloc(sizeof(*zldpll), GFP_KERNEL);
1874
if (!zldpll)
1875
return ERR_PTR(-ENOMEM);
1876
1877
zldpll->dev = zldev;
1878
zldpll->id = ch;
1879
INIT_LIST_HEAD(&zldpll->pins);
1880
INIT_WORK(&zldpll->change_work, zl3073x_dpll_change_work);
1881
1882
return zldpll;
1883
}
1884
1885
/**
1886
* zl3073x_dpll_free - free DPLL device
1887
* @zldpll: pointer to zl3073x_dpll structure
1888
*
1889
* Deallocates given DPLL device previously allocated by @zl3073x_dpll_alloc.
1890
*/
1891
void
1892
zl3073x_dpll_free(struct zl3073x_dpll *zldpll)
1893
{
1894
WARN(zldpll->dpll_dev, "DPLL device is still registered\n");
1895
1896
kfree(zldpll);
1897
}
1898
1899
/**
1900
* zl3073x_dpll_register - register DPLL device and all its pins
1901
* @zldpll: pointer to zl3073x_dpll structure
1902
*
1903
* Registers given DPLL device and all its pins into DPLL sub-system.
1904
*
1905
* Return: 0 on success, <0 on error
1906
*/
1907
int
1908
zl3073x_dpll_register(struct zl3073x_dpll *zldpll)
1909
{
1910
int rc;
1911
1912
rc = zl3073x_dpll_device_register(zldpll);
1913
if (rc)
1914
return rc;
1915
1916
rc = zl3073x_dpll_pins_register(zldpll);
1917
if (rc) {
1918
zl3073x_dpll_device_unregister(zldpll);
1919
return rc;
1920
}
1921
1922
return 0;
1923
}
1924
1925
/**
1926
* zl3073x_dpll_unregister - unregister DPLL device and its pins
1927
* @zldpll: pointer to zl3073x_dpll structure
1928
*
1929
* Unregisters given DPLL device and all its pins from DPLL sub-system
1930
* previously registered by @zl3073x_dpll_register.
1931
*/
1932
void
1933
zl3073x_dpll_unregister(struct zl3073x_dpll *zldpll)
1934
{
1935
/* Unregister all pins and dpll */
1936
zl3073x_dpll_pins_unregister(zldpll);
1937
zl3073x_dpll_device_unregister(zldpll);
1938
}
1939
1940