1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2022, Intel Corporation. */
3
4#include "ice.h"
5#include "ice_lib.h"
6#include "ice_trace.h"
7#include <linux/dpll.h>
8
9#define ICE_CGU_STATE_ACQ_ERR_THRESHOLD 50
10#define ICE_DPLL_PIN_IDX_INVALID 0xff
11#define ICE_DPLL_RCLK_NUM_PER_PF 1
12
13/**
14 * enum ice_dpll_pin_type - enumerate ice pin types:
15 * @ICE_DPLL_PIN_INVALID: invalid pin type
16 * @ICE_DPLL_PIN_TYPE_INPUT: input pin
17 * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
18 * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
19 */
20enum ice_dpll_pin_type {
21 ICE_DPLL_PIN_INVALID,
22 ICE_DPLL_PIN_TYPE_INPUT,
23 ICE_DPLL_PIN_TYPE_OUTPUT,
24 ICE_DPLL_PIN_TYPE_RCLK_INPUT,
25};
26
27static const char * const pin_type_name[] = {
28 [ICE_DPLL_PIN_TYPE_INPUT] = "input",
29 [ICE_DPLL_PIN_TYPE_OUTPUT] = "output",
30 [ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
31};
32
33/**
34 * ice_dpll_pin_freq_set - set pin's frequency
35 * @pf: private board structure
36 * @pin: pointer to a pin
37 * @pin_type: type of pin being configured
38 * @freq: frequency to be set
39 * @extack: error reporting
40 *
41 * Set requested frequency on a pin.
42 *
43 * Context: Called under pf->dplls.lock
44 * Return:
45 * * 0 - success
46 * * negative - error on AQ or wrong pin type given
47 */
48static int
49ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin,
50 enum ice_dpll_pin_type pin_type, const u32 freq,
51 struct netlink_ext_ack *extack)
52{
53 u8 flags;
54 int ret;
55
56 switch (pin_type) {
57 case ICE_DPLL_PIN_TYPE_INPUT:
58 flags = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ;
59 ret = ice_aq_set_input_pin_cfg(hw: &pf->hw, input_idx: pin->idx, flags1: flags,
60 flags2: pin->flags[0], freq, phase_delay: 0);
61 break;
62 case ICE_DPLL_PIN_TYPE_OUTPUT:
63 flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_FREQ;
64 ret = ice_aq_set_output_pin_cfg(hw: &pf->hw, output_idx: pin->idx, flags,
65 src_sel: 0, freq, phase_delay: 0);
66 break;
67 default:
68 return -EINVAL;
69 }
70 if (ret) {
71 NL_SET_ERR_MSG_FMT(extack,
72 "err:%d %s failed to set pin freq:%u on pin:%u\n",
73 ret,
74 ice_aq_str(pf->hw.adminq.sq_last_status),
75 freq, pin->idx);
76 return ret;
77 }
78 pin->freq = freq;
79
80 return 0;
81}
82
83/**
84 * ice_dpll_frequency_set - wrapper for pin callback for set frequency
85 * @pin: pointer to a pin
86 * @pin_priv: private data pointer passed on pin registration
87 * @dpll: pointer to dpll
88 * @dpll_priv: private data pointer passed on dpll registration
89 * @frequency: frequency to be set
90 * @extack: error reporting
91 * @pin_type: type of pin being configured
92 *
93 * Wraps internal set frequency command on a pin.
94 *
95 * Context: Acquires pf->dplls.lock
96 * Return:
97 * * 0 - success
98 * * negative - error pin not found or couldn't set in hw
99 */
100static int
101ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv,
102 const struct dpll_device *dpll, void *dpll_priv,
103 const u32 frequency,
104 struct netlink_ext_ack *extack,
105 enum ice_dpll_pin_type pin_type)
106{
107 struct ice_dpll_pin *p = pin_priv;
108 struct ice_dpll *d = dpll_priv;
109 struct ice_pf *pf = d->pf;
110 int ret;
111
112 mutex_lock(&pf->dplls.lock);
113 ret = ice_dpll_pin_freq_set(pf, pin: p, pin_type, freq: frequency, extack);
114 mutex_unlock(lock: &pf->dplls.lock);
115
116 return ret;
117}
118
119/**
120 * ice_dpll_input_frequency_set - input pin callback for set frequency
121 * @pin: pointer to a pin
122 * @pin_priv: private data pointer passed on pin registration
123 * @dpll: pointer to dpll
124 * @dpll_priv: private data pointer passed on dpll registration
125 * @frequency: frequency to be set
126 * @extack: error reporting
127 *
128 * Wraps internal set frequency command on a pin.
129 *
130 * Context: Calls a function which acquires pf->dplls.lock
131 * Return:
132 * * 0 - success
133 * * negative - error pin not found or couldn't set in hw
134 */
135static int
136ice_dpll_input_frequency_set(const struct dpll_pin *pin, void *pin_priv,
137 const struct dpll_device *dpll, void *dpll_priv,
138 u64 frequency, struct netlink_ext_ack *extack)
139{
140 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
141 extack, pin_type: ICE_DPLL_PIN_TYPE_INPUT);
142}
143
144/**
145 * ice_dpll_output_frequency_set - output pin callback for set frequency
146 * @pin: pointer to a pin
147 * @pin_priv: private data pointer passed on pin registration
148 * @dpll: pointer to dpll
149 * @dpll_priv: private data pointer passed on dpll registration
150 * @frequency: frequency to be set
151 * @extack: error reporting
152 *
153 * Wraps internal set frequency command on a pin.
154 *
155 * Context: Calls a function which acquires pf->dplls.lock
156 * Return:
157 * * 0 - success
158 * * negative - error pin not found or couldn't set in hw
159 */
160static int
161ice_dpll_output_frequency_set(const struct dpll_pin *pin, void *pin_priv,
162 const struct dpll_device *dpll, void *dpll_priv,
163 u64 frequency, struct netlink_ext_ack *extack)
164{
165 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
166 extack, pin_type: ICE_DPLL_PIN_TYPE_OUTPUT);
167}
168
169/**
170 * ice_dpll_frequency_get - wrapper for pin callback for get frequency
171 * @pin: pointer to a pin
172 * @pin_priv: private data pointer passed on pin registration
173 * @dpll: pointer to dpll
174 * @dpll_priv: private data pointer passed on dpll registration
175 * @frequency: on success holds pin's frequency
176 * @extack: error reporting
177 * @pin_type: type of pin being configured
178 *
179 * Wraps internal get frequency command of a pin.
180 *
181 * Context: Acquires pf->dplls.lock
182 * Return:
183 * * 0 - success
184 * * negative - error pin not found or couldn't get from hw
185 */
186static int
187ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv,
188 const struct dpll_device *dpll, void *dpll_priv,
189 u64 *frequency, struct netlink_ext_ack *extack,
190 enum ice_dpll_pin_type pin_type)
191{
192 struct ice_dpll_pin *p = pin_priv;
193 struct ice_dpll *d = dpll_priv;
194 struct ice_pf *pf = d->pf;
195
196 mutex_lock(&pf->dplls.lock);
197 *frequency = p->freq;
198 mutex_unlock(lock: &pf->dplls.lock);
199
200 return 0;
201}
202
203/**
204 * ice_dpll_input_frequency_get - input pin callback for get frequency
205 * @pin: pointer to a pin
206 * @pin_priv: private data pointer passed on pin registration
207 * @dpll: pointer to dpll
208 * @dpll_priv: private data pointer passed on dpll registration
209 * @frequency: on success holds pin's frequency
210 * @extack: error reporting
211 *
212 * Wraps internal get frequency command of a input pin.
213 *
214 * Context: Calls a function which acquires pf->dplls.lock
215 * Return:
216 * * 0 - success
217 * * negative - error pin not found or couldn't get from hw
218 */
219static int
220ice_dpll_input_frequency_get(const struct dpll_pin *pin, void *pin_priv,
221 const struct dpll_device *dpll, void *dpll_priv,
222 u64 *frequency, struct netlink_ext_ack *extack)
223{
224 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
225 extack, pin_type: ICE_DPLL_PIN_TYPE_INPUT);
226}
227
228/**
229 * ice_dpll_output_frequency_get - output pin callback for get frequency
230 * @pin: pointer to a pin
231 * @pin_priv: private data pointer passed on pin registration
232 * @dpll: pointer to dpll
233 * @dpll_priv: private data pointer passed on dpll registration
234 * @frequency: on success holds pin's frequency
235 * @extack: error reporting
236 *
237 * Wraps internal get frequency command of a pin.
238 *
239 * Context: Calls a function which acquires pf->dplls.lock
240 * Return:
241 * * 0 - success
242 * * negative - error pin not found or couldn't get from hw
243 */
244static int
245ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv,
246 const struct dpll_device *dpll, void *dpll_priv,
247 u64 *frequency, struct netlink_ext_ack *extack)
248{
249 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
250 extack, pin_type: ICE_DPLL_PIN_TYPE_OUTPUT);
251}
252
253/**
254 * ice_dpll_pin_enable - enable a pin on dplls
255 * @hw: board private hw structure
256 * @pin: pointer to a pin
257 * @pin_type: type of pin being enabled
258 * @extack: error reporting
259 *
260 * Enable a pin on both dplls. Store current state in pin->flags.
261 *
262 * Context: Called under pf->dplls.lock
263 * Return:
264 * * 0 - OK
265 * * negative - error
266 */
267static int
268ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin,
269 enum ice_dpll_pin_type pin_type,
270 struct netlink_ext_ack *extack)
271{
272 u8 flags = 0;
273 int ret;
274
275 switch (pin_type) {
276 case ICE_DPLL_PIN_TYPE_INPUT:
277 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
278 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
279 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
280 ret = ice_aq_set_input_pin_cfg(hw, input_idx: pin->idx, flags1: 0, flags2: flags, freq: 0, phase_delay: 0);
281 break;
282 case ICE_DPLL_PIN_TYPE_OUTPUT:
283 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
284 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
285 flags |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
286 ret = ice_aq_set_output_pin_cfg(hw, output_idx: pin->idx, flags, src_sel: 0, freq: 0, phase_delay: 0);
287 break;
288 default:
289 return -EINVAL;
290 }
291 if (ret)
292 NL_SET_ERR_MSG_FMT(extack,
293 "err:%d %s failed to enable %s pin:%u\n",
294 ret, ice_aq_str(hw->adminq.sq_last_status),
295 pin_type_name[pin_type], pin->idx);
296
297 return ret;
298}
299
300/**
301 * ice_dpll_pin_disable - disable a pin on dplls
302 * @hw: board private hw structure
303 * @pin: pointer to a pin
304 * @pin_type: type of pin being disabled
305 * @extack: error reporting
306 *
307 * Disable a pin on both dplls. Store current state in pin->flags.
308 *
309 * Context: Called under pf->dplls.lock
310 * Return:
311 * * 0 - OK
312 * * negative - error
313 */
314static int
315ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
316 enum ice_dpll_pin_type pin_type,
317 struct netlink_ext_ack *extack)
318{
319 u8 flags = 0;
320 int ret;
321
322 switch (pin_type) {
323 case ICE_DPLL_PIN_TYPE_INPUT:
324 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
325 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
326 ret = ice_aq_set_input_pin_cfg(hw, input_idx: pin->idx, flags1: 0, flags2: flags, freq: 0, phase_delay: 0);
327 break;
328 case ICE_DPLL_PIN_TYPE_OUTPUT:
329 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
330 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
331 ret = ice_aq_set_output_pin_cfg(hw, output_idx: pin->idx, flags, src_sel: 0, freq: 0, phase_delay: 0);
332 break;
333 default:
334 return -EINVAL;
335 }
336 if (ret)
337 NL_SET_ERR_MSG_FMT(extack,
338 "err:%d %s failed to disable %s pin:%u\n",
339 ret, ice_aq_str(hw->adminq.sq_last_status),
340 pin_type_name[pin_type], pin->idx);
341
342 return ret;
343}
344
345/**
346 * ice_dpll_pin_state_update - update pin's state
347 * @pf: private board struct
348 * @pin: structure with pin attributes to be updated
349 * @pin_type: type of pin being updated
350 * @extack: error reporting
351 *
352 * Determine pin current state and frequency, then update struct
353 * holding the pin info. For input pin states are separated for each
354 * dpll, for rclk pins states are separated for each parent.
355 *
356 * Context: Called under pf->dplls.lock
357 * Return:
358 * * 0 - OK
359 * * negative - error
360 */
361static int
362ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
363 enum ice_dpll_pin_type pin_type,
364 struct netlink_ext_ack *extack)
365{
366 u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
367 int ret;
368
369 switch (pin_type) {
370 case ICE_DPLL_PIN_TYPE_INPUT:
371 ret = ice_aq_get_input_pin_cfg(hw: &pf->hw, input_idx: pin->idx, NULL, NULL,
372 NULL, flags2: &pin->flags[0],
373 freq: &pin->freq, NULL);
374 if (ret)
375 goto err;
376 if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
377 if (pin->pin) {
378 pin->state[pf->dplls.eec.dpll_idx] =
379 pin->pin == pf->dplls.eec.active_input ?
380 DPLL_PIN_STATE_CONNECTED :
381 DPLL_PIN_STATE_SELECTABLE;
382 pin->state[pf->dplls.pps.dpll_idx] =
383 pin->pin == pf->dplls.pps.active_input ?
384 DPLL_PIN_STATE_CONNECTED :
385 DPLL_PIN_STATE_SELECTABLE;
386 } else {
387 pin->state[pf->dplls.eec.dpll_idx] =
388 DPLL_PIN_STATE_SELECTABLE;
389 pin->state[pf->dplls.pps.dpll_idx] =
390 DPLL_PIN_STATE_SELECTABLE;
391 }
392 } else {
393 pin->state[pf->dplls.eec.dpll_idx] =
394 DPLL_PIN_STATE_DISCONNECTED;
395 pin->state[pf->dplls.pps.dpll_idx] =
396 DPLL_PIN_STATE_DISCONNECTED;
397 }
398 break;
399 case ICE_DPLL_PIN_TYPE_OUTPUT:
400 ret = ice_aq_get_output_pin_cfg(hw: &pf->hw, output_idx: pin->idx,
401 flags: &pin->flags[0], NULL,
402 freq: &pin->freq, NULL);
403 if (ret)
404 goto err;
405 if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0])
406 pin->state[0] = DPLL_PIN_STATE_CONNECTED;
407 else
408 pin->state[0] = DPLL_PIN_STATE_DISCONNECTED;
409 break;
410 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
411 for (parent = 0; parent < pf->dplls.rclk.num_parents;
412 parent++) {
413 u8 p = parent;
414
415 ret = ice_aq_get_phy_rec_clk_out(hw: &pf->hw, phy_output: &p,
416 port_num: &port_num,
417 flags: &pin->flags[parent],
418 NULL);
419 if (ret)
420 goto err;
421 if (ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
422 pin->flags[parent])
423 pin->state[parent] = DPLL_PIN_STATE_CONNECTED;
424 else
425 pin->state[parent] =
426 DPLL_PIN_STATE_DISCONNECTED;
427 }
428 break;
429 default:
430 return -EINVAL;
431 }
432
433 return 0;
434err:
435 if (extack)
436 NL_SET_ERR_MSG_FMT(extack,
437 "err:%d %s failed to update %s pin:%u\n",
438 ret,
439 ice_aq_str(pf->hw.adminq.sq_last_status),
440 pin_type_name[pin_type], pin->idx);
441 else
442 dev_err_ratelimited(ice_pf_to_dev(pf),
443 "err:%d %s failed to update %s pin:%u\n",
444 ret,
445 ice_aq_str(pf->hw.adminq.sq_last_status),
446 pin_type_name[pin_type], pin->idx);
447 return ret;
448}
449
450/**
451 * ice_dpll_hw_input_prio_set - set input priority value in hardware
452 * @pf: board private structure
453 * @dpll: ice dpll pointer
454 * @pin: ice pin pointer
455 * @prio: priority value being set on a dpll
456 * @extack: error reporting
457 *
458 * Internal wrapper for setting the priority in the hardware.
459 *
460 * Context: Called under pf->dplls.lock
461 * Return:
462 * * 0 - success
463 * * negative - failure
464 */
465static int
466ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
467 struct ice_dpll_pin *pin, const u32 prio,
468 struct netlink_ext_ack *extack)
469{
470 int ret;
471
472 ret = ice_aq_set_cgu_ref_prio(hw: &pf->hw, dpll_num: dpll->dpll_idx, ref_idx: pin->idx,
473 ref_priority: (u8)prio);
474 if (ret)
475 NL_SET_ERR_MSG_FMT(extack,
476 "err:%d %s failed to set pin prio:%u on pin:%u\n",
477 ret,
478 ice_aq_str(pf->hw.adminq.sq_last_status),
479 prio, pin->idx);
480 else
481 dpll->input_prio[pin->idx] = prio;
482
483 return ret;
484}
485
486/**
487 * ice_dpll_lock_status_get - get dpll lock status callback
488 * @dpll: registered dpll pointer
489 * @dpll_priv: private data pointer passed on dpll registration
490 * @status: on success holds dpll's lock status
491 * @extack: error reporting
492 *
493 * Dpll subsystem callback, provides dpll's lock status.
494 *
495 * Context: Acquires pf->dplls.lock
496 * Return:
497 * * 0 - success
498 * * negative - failure
499 */
500static int
501ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
502 enum dpll_lock_status *status,
503 struct netlink_ext_ack *extack)
504{
505 struct ice_dpll *d = dpll_priv;
506 struct ice_pf *pf = d->pf;
507
508 mutex_lock(&pf->dplls.lock);
509 *status = d->dpll_state;
510 mutex_unlock(lock: &pf->dplls.lock);
511
512 return 0;
513}
514
515/**
516 * ice_dpll_mode_supported - check if dpll's working mode is supported
517 * @dpll: registered dpll pointer
518 * @dpll_priv: private data pointer passed on dpll registration
519 * @mode: mode to be checked for support
520 * @extack: error reporting
521 *
522 * Dpll subsystem callback. Provides information if working mode is supported
523 * by dpll.
524 *
525 * Return:
526 * * true - mode is supported
527 * * false - mode is not supported
528 */
529static bool ice_dpll_mode_supported(const struct dpll_device *dpll,
530 void *dpll_priv,
531 enum dpll_mode mode,
532 struct netlink_ext_ack *extack)
533{
534 if (mode == DPLL_MODE_AUTOMATIC)
535 return true;
536
537 return false;
538}
539
540/**
541 * ice_dpll_mode_get - get dpll's working mode
542 * @dpll: registered dpll pointer
543 * @dpll_priv: private data pointer passed on dpll registration
544 * @mode: on success holds current working mode of dpll
545 * @extack: error reporting
546 *
547 * Dpll subsystem callback. Provides working mode of dpll.
548 *
549 * Context: Acquires pf->dplls.lock
550 * Return:
551 * * 0 - success
552 * * negative - failure
553 */
554static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
555 enum dpll_mode *mode,
556 struct netlink_ext_ack *extack)
557{
558 struct ice_dpll *d = dpll_priv;
559 struct ice_pf *pf = d->pf;
560
561 mutex_lock(&pf->dplls.lock);
562 *mode = d->mode;
563 mutex_unlock(lock: &pf->dplls.lock);
564
565 return 0;
566}
567
568/**
569 * ice_dpll_pin_state_set - set pin's state on dpll
570 * @pin: pointer to a pin
571 * @pin_priv: private data pointer passed on pin registration
572 * @dpll: registered dpll pointer
573 * @dpll_priv: private data pointer passed on dpll registration
574 * @enable: if pin shalll be enabled
575 * @extack: error reporting
576 * @pin_type: type of a pin
577 *
578 * Set pin state on a pin.
579 *
580 * Context: Acquires pf->dplls.lock
581 * Return:
582 * * 0 - OK or no change required
583 * * negative - error
584 */
585static int
586ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
587 const struct dpll_device *dpll, void *dpll_priv,
588 bool enable, struct netlink_ext_ack *extack,
589 enum ice_dpll_pin_type pin_type)
590{
591 struct ice_dpll_pin *p = pin_priv;
592 struct ice_dpll *d = dpll_priv;
593 struct ice_pf *pf = d->pf;
594 int ret;
595
596 mutex_lock(&pf->dplls.lock);
597 if (enable)
598 ret = ice_dpll_pin_enable(hw: &pf->hw, pin: p, pin_type, extack);
599 else
600 ret = ice_dpll_pin_disable(hw: &pf->hw, pin: p, pin_type, extack);
601 if (!ret)
602 ret = ice_dpll_pin_state_update(pf, pin: p, pin_type, extack);
603 mutex_unlock(lock: &pf->dplls.lock);
604
605 return ret;
606}
607
608/**
609 * ice_dpll_output_state_set - enable/disable output pin on dpll device
610 * @pin: pointer to a pin
611 * @pin_priv: private data pointer passed on pin registration
612 * @dpll: dpll being configured
613 * @dpll_priv: private data pointer passed on dpll registration
614 * @state: state of pin to be set
615 * @extack: error reporting
616 *
617 * Dpll subsystem callback. Set given state on output type pin.
618 *
619 * Context: Calls a function which acquires pf->dplls.lock
620 * Return:
621 * * 0 - successfully enabled mode
622 * * negative - failed to enable mode
623 */
624static int
625ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
626 const struct dpll_device *dpll, void *dpll_priv,
627 enum dpll_pin_state state,
628 struct netlink_ext_ack *extack)
629{
630 bool enable = state == DPLL_PIN_STATE_CONNECTED;
631
632 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
633 extack, pin_type: ICE_DPLL_PIN_TYPE_OUTPUT);
634}
635
636/**
637 * ice_dpll_input_state_set - enable/disable input pin on dpll levice
638 * @pin: pointer to a pin
639 * @pin_priv: private data pointer passed on pin registration
640 * @dpll: dpll being configured
641 * @dpll_priv: private data pointer passed on dpll registration
642 * @state: state of pin to be set
643 * @extack: error reporting
644 *
645 * Dpll subsystem callback. Enables given mode on input type pin.
646 *
647 * Context: Calls a function which acquires pf->dplls.lock
648 * Return:
649 * * 0 - successfully enabled mode
650 * * negative - failed to enable mode
651 */
652static int
653ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv,
654 const struct dpll_device *dpll, void *dpll_priv,
655 enum dpll_pin_state state,
656 struct netlink_ext_ack *extack)
657{
658 bool enable = state == DPLL_PIN_STATE_SELECTABLE;
659
660 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
661 extack, pin_type: ICE_DPLL_PIN_TYPE_INPUT);
662}
663
664/**
665 * ice_dpll_pin_state_get - set pin's state on dpll
666 * @pin: pointer to a pin
667 * @pin_priv: private data pointer passed on pin registration
668 * @dpll: registered dpll pointer
669 * @dpll_priv: private data pointer passed on dpll registration
670 * @state: on success holds state of the pin
671 * @extack: error reporting
672 * @pin_type: type of questioned pin
673 *
674 * Determine pin state set it on a pin.
675 *
676 * Context: Acquires pf->dplls.lock
677 * Return:
678 * * 0 - success
679 * * negative - failed to get state
680 */
681static int
682ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
683 const struct dpll_device *dpll, void *dpll_priv,
684 enum dpll_pin_state *state,
685 struct netlink_ext_ack *extack,
686 enum ice_dpll_pin_type pin_type)
687{
688 struct ice_dpll_pin *p = pin_priv;
689 struct ice_dpll *d = dpll_priv;
690 struct ice_pf *pf = d->pf;
691 int ret;
692
693 mutex_lock(&pf->dplls.lock);
694 ret = ice_dpll_pin_state_update(pf, pin: p, pin_type, extack);
695 if (ret)
696 goto unlock;
697 if (pin_type == ICE_DPLL_PIN_TYPE_INPUT)
698 *state = p->state[d->dpll_idx];
699 else if (pin_type == ICE_DPLL_PIN_TYPE_OUTPUT)
700 *state = p->state[0];
701 ret = 0;
702unlock:
703 mutex_unlock(lock: &pf->dplls.lock);
704
705 return ret;
706}
707
708/**
709 * ice_dpll_output_state_get - get output pin state on dpll device
710 * @pin: pointer to a pin
711 * @pin_priv: private data pointer passed on pin registration
712 * @dpll: registered dpll pointer
713 * @dpll_priv: private data pointer passed on dpll registration
714 * @state: on success holds state of the pin
715 * @extack: error reporting
716 *
717 * Dpll subsystem callback. Check state of a pin.
718 *
719 * Context: Calls a function which acquires pf->dplls.lock
720 * Return:
721 * * 0 - success
722 * * negative - failed to get state
723 */
724static int
725ice_dpll_output_state_get(const struct dpll_pin *pin, void *pin_priv,
726 const struct dpll_device *dpll, void *dpll_priv,
727 enum dpll_pin_state *state,
728 struct netlink_ext_ack *extack)
729{
730 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
731 extack, pin_type: ICE_DPLL_PIN_TYPE_OUTPUT);
732}
733
734/**
735 * ice_dpll_input_state_get - get input pin state on dpll device
736 * @pin: pointer to a pin
737 * @pin_priv: private data pointer passed on pin registration
738 * @dpll: registered dpll pointer
739 * @dpll_priv: private data pointer passed on dpll registration
740 * @state: on success holds state of the pin
741 * @extack: error reporting
742 *
743 * Dpll subsystem callback. Check state of a input pin.
744 *
745 * Context: Calls a function which acquires pf->dplls.lock
746 * Return:
747 * * 0 - success
748 * * negative - failed to get state
749 */
750static int
751ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
752 const struct dpll_device *dpll, void *dpll_priv,
753 enum dpll_pin_state *state,
754 struct netlink_ext_ack *extack)
755{
756 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
757 extack, pin_type: ICE_DPLL_PIN_TYPE_INPUT);
758}
759
760/**
761 * ice_dpll_input_prio_get - get dpll's input prio
762 * @pin: pointer to a pin
763 * @pin_priv: private data pointer passed on pin registration
764 * @dpll: registered dpll pointer
765 * @dpll_priv: private data pointer passed on dpll registration
766 * @prio: on success - returns input priority on dpll
767 * @extack: error reporting
768 *
769 * Dpll subsystem callback. Handler for getting priority of a input pin.
770 *
771 * Context: Acquires pf->dplls.lock
772 * Return:
773 * * 0 - success
774 * * negative - failure
775 */
776static int
777ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
778 const struct dpll_device *dpll, void *dpll_priv,
779 u32 *prio, struct netlink_ext_ack *extack)
780{
781 struct ice_dpll_pin *p = pin_priv;
782 struct ice_dpll *d = dpll_priv;
783 struct ice_pf *pf = d->pf;
784
785 mutex_lock(&pf->dplls.lock);
786 *prio = d->input_prio[p->idx];
787 mutex_unlock(lock: &pf->dplls.lock);
788
789 return 0;
790}
791
792/**
793 * ice_dpll_input_prio_set - set dpll input prio
794 * @pin: pointer to a pin
795 * @pin_priv: private data pointer passed on pin registration
796 * @dpll: registered dpll pointer
797 * @dpll_priv: private data pointer passed on dpll registration
798 * @prio: input priority to be set on dpll
799 * @extack: error reporting
800 *
801 * Dpll subsystem callback. Handler for setting priority of a input pin.
802 *
803 * Context: Acquires pf->dplls.lock
804 * Return:
805 * * 0 - success
806 * * negative - failure
807 */
808static int
809ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
810 const struct dpll_device *dpll, void *dpll_priv,
811 u32 prio, struct netlink_ext_ack *extack)
812{
813 struct ice_dpll_pin *p = pin_priv;
814 struct ice_dpll *d = dpll_priv;
815 struct ice_pf *pf = d->pf;
816 int ret;
817
818 if (prio > ICE_DPLL_PRIO_MAX) {
819 NL_SET_ERR_MSG_FMT(extack, "prio out of supported range 0-%d",
820 ICE_DPLL_PRIO_MAX);
821 return -EINVAL;
822 }
823
824 mutex_lock(&pf->dplls.lock);
825 ret = ice_dpll_hw_input_prio_set(pf, dpll: d, pin: p, prio, extack);
826 mutex_unlock(lock: &pf->dplls.lock);
827
828 return ret;
829}
830
831/**
832 * ice_dpll_input_direction - callback for get input pin direction
833 * @pin: pointer to a pin
834 * @pin_priv: private data pointer passed on pin registration
835 * @dpll: registered dpll pointer
836 * @dpll_priv: private data pointer passed on dpll registration
837 * @direction: holds input pin direction
838 * @extack: error reporting
839 *
840 * Dpll subsystem callback. Handler for getting direction of a input pin.
841 *
842 * Return:
843 * * 0 - success
844 */
845static int
846ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
847 const struct dpll_device *dpll, void *dpll_priv,
848 enum dpll_pin_direction *direction,
849 struct netlink_ext_ack *extack)
850{
851 *direction = DPLL_PIN_DIRECTION_INPUT;
852
853 return 0;
854}
855
856/**
857 * ice_dpll_output_direction - callback for get output pin direction
858 * @pin: pointer to a pin
859 * @pin_priv: private data pointer passed on pin registration
860 * @dpll: registered dpll pointer
861 * @dpll_priv: private data pointer passed on dpll registration
862 * @direction: holds output pin direction
863 * @extack: error reporting
864 *
865 * Dpll subsystem callback. Handler for getting direction of an output pin.
866 *
867 * Return:
868 * * 0 - success
869 */
870static int
871ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
872 const struct dpll_device *dpll, void *dpll_priv,
873 enum dpll_pin_direction *direction,
874 struct netlink_ext_ack *extack)
875{
876 *direction = DPLL_PIN_DIRECTION_OUTPUT;
877
878 return 0;
879}
880
881/**
882 * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
883 * @pin: pointer to a pin
884 * @pin_priv: private data pointer passed on pin registration
885 * @dpll: registered dpll pointer
886 * @dpll_priv: private data pointer passed on dpll registration
887 * @phase_adjust: on success holds pin phase_adjust value
888 * @extack: error reporting
889 *
890 * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
891 *
892 * Context: Acquires pf->dplls.lock
893 * Return:
894 * * 0 - success
895 * * negative - error
896 */
897static int
898ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
899 const struct dpll_device *dpll, void *dpll_priv,
900 s32 *phase_adjust,
901 struct netlink_ext_ack *extack)
902{
903 struct ice_dpll_pin *p = pin_priv;
904 struct ice_pf *pf = p->pf;
905
906 mutex_lock(&pf->dplls.lock);
907 *phase_adjust = p->phase_adjust;
908 mutex_unlock(lock: &pf->dplls.lock);
909
910 return 0;
911}
912
913/**
914 * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
915 * @pin: pointer to a pin
916 * @pin_priv: private data pointer passed on pin registration
917 * @dpll: registered dpll pointer
918 * @dpll_priv: private data pointer passed on dpll registration
919 * @phase_adjust: phase_adjust to be set
920 * @extack: error reporting
921 * @type: type of a pin
922 *
923 * Helper for dpll subsystem callback. Handler for setting phase adjust value
924 * of a pin.
925 *
926 * Context: Acquires pf->dplls.lock
927 * Return:
928 * * 0 - success
929 * * negative - error
930 */
931static int
932ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
933 const struct dpll_device *dpll, void *dpll_priv,
934 s32 phase_adjust,
935 struct netlink_ext_ack *extack,
936 enum ice_dpll_pin_type type)
937{
938 struct ice_dpll_pin *p = pin_priv;
939 struct ice_dpll *d = dpll_priv;
940 struct ice_pf *pf = d->pf;
941 u8 flag, flags_en = 0;
942 int ret;
943
944 mutex_lock(&pf->dplls.lock);
945 switch (type) {
946 case ICE_DPLL_PIN_TYPE_INPUT:
947 flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
948 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
949 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
950 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
951 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
952 ret = ice_aq_set_input_pin_cfg(hw: &pf->hw, input_idx: p->idx, flags1: flag, flags2: flags_en,
953 freq: 0, phase_delay: phase_adjust);
954 break;
955 case ICE_DPLL_PIN_TYPE_OUTPUT:
956 flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
957 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
958 flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
959 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
960 flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
961 ret = ice_aq_set_output_pin_cfg(hw: &pf->hw, output_idx: p->idx, flags: flag, src_sel: 0, freq: 0,
962 phase_delay: phase_adjust);
963 break;
964 default:
965 ret = -EINVAL;
966 }
967 if (!ret)
968 p->phase_adjust = phase_adjust;
969 mutex_unlock(lock: &pf->dplls.lock);
970 if (ret)
971 NL_SET_ERR_MSG_FMT(extack,
972 "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n",
973 ret,
974 ice_aq_str(pf->hw.adminq.sq_last_status),
975 phase_adjust, p->idx, d->dpll_idx);
976
977 return ret;
978}
979
980/**
981 * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
982 * @pin: pointer to a pin
983 * @pin_priv: private data pointer passed on pin registration
984 * @dpll: registered dpll pointer
985 * @dpll_priv: private data pointer passed on dpll registration
986 * @phase_adjust: phase_adjust to be set
987 * @extack: error reporting
988 *
989 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
990 * pin.
991 *
992 * Context: Calls a function which acquires pf->dplls.lock
993 * Return:
994 * * 0 - success
995 * * negative - error
996 */
997static int
998ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
999 const struct dpll_device *dpll, void *dpll_priv,
1000 s32 phase_adjust,
1001 struct netlink_ext_ack *extack)
1002{
1003 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1004 phase_adjust, extack,
1005 type: ICE_DPLL_PIN_TYPE_INPUT);
1006}
1007
1008/**
1009 * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1010 * @pin: pointer to a pin
1011 * @pin_priv: private data pointer passed on pin registration
1012 * @dpll: registered dpll pointer
1013 * @dpll_priv: private data pointer passed on dpll registration
1014 * @phase_adjust: phase_adjust to be set
1015 * @extack: error reporting
1016 *
1017 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1018 * pin.
1019 *
1020 * Context: Calls a function which acquires pf->dplls.lock
1021 * Return:
1022 * * 0 - success
1023 * * negative - error
1024 */
1025static int
1026ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1027 const struct dpll_device *dpll, void *dpll_priv,
1028 s32 phase_adjust,
1029 struct netlink_ext_ack *extack)
1030{
1031 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1032 phase_adjust, extack,
1033 type: ICE_DPLL_PIN_TYPE_OUTPUT);
1034}
1035
1036#define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1037#define ICE_DPLL_PHASE_OFFSET_FACTOR \
1038 (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1039/**
1040 * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1041 * @pin: pointer to a pin
1042 * @pin_priv: private data pointer passed on pin registration
1043 * @dpll: registered dpll pointer
1044 * @dpll_priv: private data pointer passed on dpll registration
1045 * @phase_offset: on success holds pin phase_offset value
1046 * @extack: error reporting
1047 *
1048 * Dpll subsystem callback. Handler for getting phase shift value between
1049 * dpll's input and output.
1050 *
1051 * Context: Acquires pf->dplls.lock
1052 * Return:
1053 * * 0 - success
1054 * * negative - error
1055 */
1056static int
1057ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1058 const struct dpll_device *dpll, void *dpll_priv,
1059 s64 *phase_offset, struct netlink_ext_ack *extack)
1060{
1061 struct ice_dpll *d = dpll_priv;
1062 struct ice_pf *pf = d->pf;
1063
1064 mutex_lock(&pf->dplls.lock);
1065 if (d->active_input == pin)
1066 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1067 else
1068 *phase_offset = 0;
1069 mutex_unlock(lock: &pf->dplls.lock);
1070
1071 return 0;
1072}
1073
1074/**
1075 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
1076 * @pin: pointer to a pin
1077 * @pin_priv: private data pointer passed on pin registration
1078 * @parent_pin: pin parent pointer
1079 * @parent_pin_priv: parent private data pointer passed on pin registration
1080 * @state: state to be set on pin
1081 * @extack: error reporting
1082 *
1083 * Dpll subsystem callback, set a state of a rclk pin on a parent pin
1084 *
1085 * Context: Acquires pf->dplls.lock
1086 * Return:
1087 * * 0 - success
1088 * * negative - failure
1089 */
1090static int
1091ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
1092 const struct dpll_pin *parent_pin,
1093 void *parent_pin_priv,
1094 enum dpll_pin_state state,
1095 struct netlink_ext_ack *extack)
1096{
1097 struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
1098 bool enable = state == DPLL_PIN_STATE_CONNECTED;
1099 struct ice_pf *pf = p->pf;
1100 int ret = -EINVAL;
1101 u32 hw_idx;
1102
1103 mutex_lock(&pf->dplls.lock);
1104 hw_idx = parent->idx - pf->dplls.base_rclk_idx;
1105 if (hw_idx >= pf->dplls.num_inputs)
1106 goto unlock;
1107
1108 if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
1109 (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
1110 NL_SET_ERR_MSG_FMT(extack,
1111 "pin:%u state:%u on parent:%u already set",
1112 p->idx, state, parent->idx);
1113 goto unlock;
1114 }
1115 ret = ice_aq_set_phy_rec_clk_out(hw: &pf->hw, phy_output: hw_idx, enable,
1116 freq: &p->freq);
1117 if (ret)
1118 NL_SET_ERR_MSG_FMT(extack,
1119 "err:%d %s failed to set pin state:%u for pin:%u on parent:%u\n",
1120 ret,
1121 ice_aq_str(pf->hw.adminq.sq_last_status),
1122 state, p->idx, parent->idx);
1123unlock:
1124 mutex_unlock(lock: &pf->dplls.lock);
1125
1126 return ret;
1127}
1128
1129/**
1130 * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
1131 * @pin: pointer to a pin
1132 * @pin_priv: private data pointer passed on pin registration
1133 * @parent_pin: pin parent pointer
1134 * @parent_pin_priv: pin parent priv data pointer passed on pin registration
1135 * @state: on success holds pin state on parent pin
1136 * @extack: error reporting
1137 *
1138 * dpll subsystem callback, get a state of a recovered clock pin.
1139 *
1140 * Context: Acquires pf->dplls.lock
1141 * Return:
1142 * * 0 - success
1143 * * negative - failure
1144 */
1145static int
1146ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
1147 const struct dpll_pin *parent_pin,
1148 void *parent_pin_priv,
1149 enum dpll_pin_state *state,
1150 struct netlink_ext_ack *extack)
1151{
1152 struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
1153 struct ice_pf *pf = p->pf;
1154 int ret = -EINVAL;
1155 u32 hw_idx;
1156
1157 mutex_lock(&pf->dplls.lock);
1158 hw_idx = parent->idx - pf->dplls.base_rclk_idx;
1159 if (hw_idx >= pf->dplls.num_inputs)
1160 goto unlock;
1161
1162 ret = ice_dpll_pin_state_update(pf, pin: p, pin_type: ICE_DPLL_PIN_TYPE_RCLK_INPUT,
1163 extack);
1164 if (ret)
1165 goto unlock;
1166
1167 *state = p->state[hw_idx];
1168 ret = 0;
1169unlock:
1170 mutex_unlock(lock: &pf->dplls.lock);
1171
1172 return ret;
1173}
1174
1175static const struct dpll_pin_ops ice_dpll_rclk_ops = {
1176 .state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
1177 .state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
1178 .direction_get = ice_dpll_input_direction,
1179};
1180
1181static const struct dpll_pin_ops ice_dpll_input_ops = {
1182 .frequency_get = ice_dpll_input_frequency_get,
1183 .frequency_set = ice_dpll_input_frequency_set,
1184 .state_on_dpll_get = ice_dpll_input_state_get,
1185 .state_on_dpll_set = ice_dpll_input_state_set,
1186 .prio_get = ice_dpll_input_prio_get,
1187 .prio_set = ice_dpll_input_prio_set,
1188 .direction_get = ice_dpll_input_direction,
1189 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
1190 .phase_adjust_set = ice_dpll_input_phase_adjust_set,
1191 .phase_offset_get = ice_dpll_phase_offset_get,
1192};
1193
1194static const struct dpll_pin_ops ice_dpll_output_ops = {
1195 .frequency_get = ice_dpll_output_frequency_get,
1196 .frequency_set = ice_dpll_output_frequency_set,
1197 .state_on_dpll_get = ice_dpll_output_state_get,
1198 .state_on_dpll_set = ice_dpll_output_state_set,
1199 .direction_get = ice_dpll_output_direction,
1200 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
1201 .phase_adjust_set = ice_dpll_output_phase_adjust_set,
1202};
1203
1204static const struct dpll_device_ops ice_dpll_ops = {
1205 .lock_status_get = ice_dpll_lock_status_get,
1206 .mode_supported = ice_dpll_mode_supported,
1207 .mode_get = ice_dpll_mode_get,
1208};
1209
1210/**
1211 * ice_generate_clock_id - generates unique clock_id for registering dpll.
1212 * @pf: board private structure
1213 *
1214 * Generates unique (per board) clock_id for allocation and search of dpll
1215 * devices in Linux dpll subsystem.
1216 *
1217 * Return: generated clock id for the board
1218 */
1219static u64 ice_generate_clock_id(struct ice_pf *pf)
1220{
1221 return pci_get_dsn(dev: pf->pdev);
1222}
1223
1224/**
1225 * ice_dpll_notify_changes - notify dpll subsystem about changes
1226 * @d: pointer do dpll
1227 *
1228 * Once change detected appropriate event is submitted to the dpll subsystem.
1229 */
1230static void ice_dpll_notify_changes(struct ice_dpll *d)
1231{
1232 bool pin_notified = false;
1233
1234 if (d->prev_dpll_state != d->dpll_state) {
1235 d->prev_dpll_state = d->dpll_state;
1236 dpll_device_change_ntf(dpll: d->dpll);
1237 }
1238 if (d->prev_input != d->active_input) {
1239 if (d->prev_input)
1240 dpll_pin_change_ntf(pin: d->prev_input);
1241 d->prev_input = d->active_input;
1242 if (d->active_input) {
1243 dpll_pin_change_ntf(pin: d->active_input);
1244 pin_notified = true;
1245 }
1246 }
1247 if (d->prev_phase_offset != d->phase_offset) {
1248 d->prev_phase_offset = d->phase_offset;
1249 if (!pin_notified && d->active_input)
1250 dpll_pin_change_ntf(pin: d->active_input);
1251 }
1252}
1253
1254/**
1255 * ice_dpll_update_state - update dpll state
1256 * @pf: pf private structure
1257 * @d: pointer to queried dpll device
1258 * @init: if function called on initialization of ice dpll
1259 *
1260 * Poll current state of dpll from hw and update ice_dpll struct.
1261 *
1262 * Context: Called by kworker under pf->dplls.lock
1263 * Return:
1264 * * 0 - success
1265 * * negative - AQ failure
1266 */
1267static int
1268ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
1269{
1270 struct ice_dpll_pin *p = NULL;
1271 int ret;
1272
1273 ret = ice_get_cgu_state(hw: &pf->hw, dpll_idx: d->dpll_idx, last_dpll_state: d->prev_dpll_state,
1274 pin: &d->input_idx, ref_state: &d->ref_state, eec_mode: &d->eec_mode,
1275 phase_offset: &d->phase_offset, dpll_state: &d->dpll_state);
1276
1277 dev_dbg(ice_pf_to_dev(pf),
1278 "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
1279 d->dpll_idx, d->prev_input_idx, d->input_idx,
1280 d->dpll_state, d->prev_dpll_state, d->mode);
1281 if (ret) {
1282 dev_err(ice_pf_to_dev(pf),
1283 "update dpll=%d state failed, ret=%d %s\n",
1284 d->dpll_idx, ret,
1285 ice_aq_str(pf->hw.adminq.sq_last_status));
1286 return ret;
1287 }
1288 if (init) {
1289 if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
1290 d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
1291 d->active_input = pf->dplls.inputs[d->input_idx].pin;
1292 p = &pf->dplls.inputs[d->input_idx];
1293 return ice_dpll_pin_state_update(pf, pin: p,
1294 pin_type: ICE_DPLL_PIN_TYPE_INPUT, NULL);
1295 }
1296 if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
1297 d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
1298 d->active_input = NULL;
1299 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
1300 p = &pf->dplls.inputs[d->input_idx];
1301 d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
1302 d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
1303 if (!p)
1304 return 0;
1305 ret = ice_dpll_pin_state_update(pf, pin: p,
1306 pin_type: ICE_DPLL_PIN_TYPE_INPUT, NULL);
1307 } else if (d->input_idx != d->prev_input_idx) {
1308 if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
1309 p = &pf->dplls.inputs[d->prev_input_idx];
1310 ice_dpll_pin_state_update(pf, pin: p,
1311 pin_type: ICE_DPLL_PIN_TYPE_INPUT,
1312 NULL);
1313 }
1314 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
1315 p = &pf->dplls.inputs[d->input_idx];
1316 d->active_input = p->pin;
1317 ice_dpll_pin_state_update(pf, pin: p,
1318 pin_type: ICE_DPLL_PIN_TYPE_INPUT,
1319 NULL);
1320 }
1321 d->prev_input_idx = d->input_idx;
1322 }
1323
1324 return ret;
1325}
1326
1327/**
1328 * ice_dpll_periodic_work - DPLLs periodic worker
1329 * @work: pointer to kthread_work structure
1330 *
1331 * DPLLs periodic worker is responsible for polling state of dpll.
1332 * Context: Holds pf->dplls.lock
1333 */
1334static void ice_dpll_periodic_work(struct kthread_work *work)
1335{
1336 struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
1337 struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
1338 struct ice_dpll *de = &pf->dplls.eec;
1339 struct ice_dpll *dp = &pf->dplls.pps;
1340 int ret;
1341
1342 mutex_lock(&pf->dplls.lock);
1343 ret = ice_dpll_update_state(pf, d: de, init: false);
1344 if (!ret)
1345 ret = ice_dpll_update_state(pf, d: dp, init: false);
1346 if (ret) {
1347 d->cgu_state_acq_err_num++;
1348 /* stop rescheduling this worker */
1349 if (d->cgu_state_acq_err_num >
1350 ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
1351 dev_err(ice_pf_to_dev(pf),
1352 "EEC/PPS DPLLs periodic work disabled\n");
1353 mutex_unlock(lock: &pf->dplls.lock);
1354 return;
1355 }
1356 }
1357 mutex_unlock(lock: &pf->dplls.lock);
1358 ice_dpll_notify_changes(d: de);
1359 ice_dpll_notify_changes(d: dp);
1360
1361 /* Run twice a second or reschedule if update failed */
1362 kthread_queue_delayed_work(worker: d->kworker, dwork: &d->work,
1363 delay: ret ? msecs_to_jiffies(m: 10) :
1364 msecs_to_jiffies(m: 500));
1365}
1366
1367/**
1368 * ice_dpll_release_pins - release pins resources from dpll subsystem
1369 * @pins: pointer to pins array
1370 * @count: number of pins
1371 *
1372 * Release resources of given pins array in the dpll subsystem.
1373 */
1374static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
1375{
1376 int i;
1377
1378 for (i = 0; i < count; i++)
1379 dpll_pin_put(pin: pins[i].pin);
1380}
1381
1382/**
1383 * ice_dpll_get_pins - get pins from dpll subsystem
1384 * @pf: board private structure
1385 * @pins: pointer to pins array
1386 * @start_idx: get starts from this pin idx value
1387 * @count: number of pins
1388 * @clock_id: clock_id of dpll device
1389 *
1390 * Get pins - allocate - in dpll subsystem, store them in pin field of given
1391 * pins array.
1392 *
1393 * Return:
1394 * * 0 - success
1395 * * negative - allocation failure reason
1396 */
1397static int
1398ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
1399 int start_idx, int count, u64 clock_id)
1400{
1401 int i, ret;
1402
1403 for (i = 0; i < count; i++) {
1404 pins[i].pin = dpll_pin_get(clock_id, dev_driver_id: i + start_idx, THIS_MODULE,
1405 prop: &pins[i].prop);
1406 if (IS_ERR(ptr: pins[i].pin)) {
1407 ret = PTR_ERR(ptr: pins[i].pin);
1408 goto release_pins;
1409 }
1410 }
1411
1412 return 0;
1413
1414release_pins:
1415 while (--i >= 0)
1416 dpll_pin_put(pin: pins[i].pin);
1417 return ret;
1418}
1419
1420/**
1421 * ice_dpll_unregister_pins - unregister pins from a dpll
1422 * @dpll: dpll device pointer
1423 * @pins: pointer to pins array
1424 * @ops: callback ops registered with the pins
1425 * @count: number of pins
1426 *
1427 * Unregister pins of a given array of pins from given dpll device registered in
1428 * dpll subsystem.
1429 */
1430static void
1431ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
1432 const struct dpll_pin_ops *ops, int count)
1433{
1434 int i;
1435
1436 for (i = 0; i < count; i++)
1437 dpll_pin_unregister(dpll, pin: pins[i].pin, ops, priv: &pins[i]);
1438}
1439
1440/**
1441 * ice_dpll_register_pins - register pins with a dpll
1442 * @dpll: dpll pointer to register pins with
1443 * @pins: pointer to pins array
1444 * @ops: callback ops registered with the pins
1445 * @count: number of pins
1446 *
1447 * Register pins of a given array with given dpll in dpll subsystem.
1448 *
1449 * Return:
1450 * * 0 - success
1451 * * negative - registration failure reason
1452 */
1453static int
1454ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
1455 const struct dpll_pin_ops *ops, int count)
1456{
1457 int ret, i;
1458
1459 for (i = 0; i < count; i++) {
1460 ret = dpll_pin_register(dpll, pin: pins[i].pin, ops, priv: &pins[i]);
1461 if (ret)
1462 goto unregister_pins;
1463 }
1464
1465 return 0;
1466
1467unregister_pins:
1468 while (--i >= 0)
1469 dpll_pin_unregister(dpll, pin: pins[i].pin, ops, priv: &pins[i]);
1470 return ret;
1471}
1472
1473/**
1474 * ice_dpll_deinit_direct_pins - deinitialize direct pins
1475 * @cgu: if cgu is present and controlled by this NIC
1476 * @pins: pointer to pins array
1477 * @count: number of pins
1478 * @ops: callback ops registered with the pins
1479 * @first: dpll device pointer
1480 * @second: dpll device pointer
1481 *
1482 * If cgu is owned unregister pins from given dplls.
1483 * Release pins resources to the dpll subsystem.
1484 */
1485static void
1486ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count,
1487 const struct dpll_pin_ops *ops,
1488 struct dpll_device *first,
1489 struct dpll_device *second)
1490{
1491 if (cgu) {
1492 ice_dpll_unregister_pins(dpll: first, pins, ops, count);
1493 ice_dpll_unregister_pins(dpll: second, pins, ops, count);
1494 }
1495 ice_dpll_release_pins(pins, count);
1496}
1497
1498/**
1499 * ice_dpll_init_direct_pins - initialize direct pins
1500 * @pf: board private structure
1501 * @cgu: if cgu is present and controlled by this NIC
1502 * @pins: pointer to pins array
1503 * @start_idx: on which index shall allocation start in dpll subsystem
1504 * @count: number of pins
1505 * @ops: callback ops registered with the pins
1506 * @first: dpll device pointer
1507 * @second: dpll device pointer
1508 *
1509 * Allocate directly connected pins of a given array in dpll subsystem.
1510 * If cgu is owned register allocated pins with given dplls.
1511 *
1512 * Return:
1513 * * 0 - success
1514 * * negative - registration failure reason
1515 */
1516static int
1517ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
1518 struct ice_dpll_pin *pins, int start_idx, int count,
1519 const struct dpll_pin_ops *ops,
1520 struct dpll_device *first, struct dpll_device *second)
1521{
1522 int ret;
1523
1524 ret = ice_dpll_get_pins(pf, pins, start_idx, count, clock_id: pf->dplls.clock_id);
1525 if (ret)
1526 return ret;
1527 if (cgu) {
1528 ret = ice_dpll_register_pins(dpll: first, pins, ops, count);
1529 if (ret)
1530 goto release_pins;
1531 ret = ice_dpll_register_pins(dpll: second, pins, ops, count);
1532 if (ret)
1533 goto unregister_first;
1534 }
1535
1536 return 0;
1537
1538unregister_first:
1539 ice_dpll_unregister_pins(dpll: first, pins, ops, count);
1540release_pins:
1541 ice_dpll_release_pins(pins, count);
1542 return ret;
1543}
1544
1545/**
1546 * ice_dpll_deinit_rclk_pin - release rclk pin resources
1547 * @pf: board private structure
1548 *
1549 * Deregister rclk pin from parent pins and release resources in dpll subsystem.
1550 */
1551static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
1552{
1553 struct ice_dpll_pin *rclk = &pf->dplls.rclk;
1554 struct ice_vsi *vsi = ice_get_main_vsi(pf);
1555 struct dpll_pin *parent;
1556 int i;
1557
1558 for (i = 0; i < rclk->num_parents; i++) {
1559 parent = pf->dplls.inputs[rclk->parent_idx[i]].pin;
1560 if (!parent)
1561 continue;
1562 dpll_pin_on_pin_unregister(parent, pin: rclk->pin,
1563 ops: &ice_dpll_rclk_ops, priv: rclk);
1564 }
1565 if (WARN_ON_ONCE(!vsi || !vsi->netdev))
1566 return;
1567 netdev_dpll_pin_clear(dev: vsi->netdev);
1568 dpll_pin_put(pin: rclk->pin);
1569}
1570
1571/**
1572 * ice_dpll_init_rclk_pins - initialize recovered clock pin
1573 * @pf: board private structure
1574 * @pin: pin to register
1575 * @start_idx: on which index shall allocation start in dpll subsystem
1576 * @ops: callback ops registered with the pins
1577 *
1578 * Allocate resource for recovered clock pin in dpll subsystem. Register the
1579 * pin with the parents it has in the info. Register pin with the pf's main vsi
1580 * netdev.
1581 *
1582 * Return:
1583 * * 0 - success
1584 * * negative - registration failure reason
1585 */
1586static int
1587ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
1588 int start_idx, const struct dpll_pin_ops *ops)
1589{
1590 struct ice_vsi *vsi = ice_get_main_vsi(pf);
1591 struct dpll_pin *parent;
1592 int ret, i;
1593
1594 ret = ice_dpll_get_pins(pf, pins: pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
1595 clock_id: pf->dplls.clock_id);
1596 if (ret)
1597 return ret;
1598 for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
1599 parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[i]].pin;
1600 if (!parent) {
1601 ret = -ENODEV;
1602 goto unregister_pins;
1603 }
1604 ret = dpll_pin_on_pin_register(parent, pin: pf->dplls.rclk.pin,
1605 ops, priv: &pf->dplls.rclk);
1606 if (ret)
1607 goto unregister_pins;
1608 }
1609 if (WARN_ON((!vsi || !vsi->netdev)))
1610 return -EINVAL;
1611 netdev_dpll_pin_set(dev: vsi->netdev, dpll_pin: pf->dplls.rclk.pin);
1612
1613 return 0;
1614
1615unregister_pins:
1616 while (i) {
1617 parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[--i]].pin;
1618 dpll_pin_on_pin_unregister(parent, pin: pf->dplls.rclk.pin,
1619 ops: &ice_dpll_rclk_ops, priv: &pf->dplls.rclk);
1620 }
1621 ice_dpll_release_pins(pins: pin, ICE_DPLL_RCLK_NUM_PER_PF);
1622 return ret;
1623}
1624
1625/**
1626 * ice_dpll_deinit_pins - deinitialize direct pins
1627 * @pf: board private structure
1628 * @cgu: if cgu is controlled by this pf
1629 *
1630 * If cgu is owned unregister directly connected pins from the dplls.
1631 * Release resources of directly connected pins from the dpll subsystem.
1632 */
1633static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
1634{
1635 struct ice_dpll_pin *outputs = pf->dplls.outputs;
1636 struct ice_dpll_pin *inputs = pf->dplls.inputs;
1637 int num_outputs = pf->dplls.num_outputs;
1638 int num_inputs = pf->dplls.num_inputs;
1639 struct ice_dplls *d = &pf->dplls;
1640 struct ice_dpll *de = &d->eec;
1641 struct ice_dpll *dp = &d->pps;
1642
1643 ice_dpll_deinit_rclk_pin(pf);
1644 if (cgu) {
1645 ice_dpll_unregister_pins(dpll: dp->dpll, pins: inputs, ops: &ice_dpll_input_ops,
1646 count: num_inputs);
1647 ice_dpll_unregister_pins(dpll: de->dpll, pins: inputs, ops: &ice_dpll_input_ops,
1648 count: num_inputs);
1649 }
1650 ice_dpll_release_pins(pins: inputs, count: num_inputs);
1651 if (cgu) {
1652 ice_dpll_unregister_pins(dpll: dp->dpll, pins: outputs,
1653 ops: &ice_dpll_output_ops, count: num_outputs);
1654 ice_dpll_unregister_pins(dpll: de->dpll, pins: outputs,
1655 ops: &ice_dpll_output_ops, count: num_outputs);
1656 ice_dpll_release_pins(pins: outputs, count: num_outputs);
1657 }
1658}
1659
1660/**
1661 * ice_dpll_init_pins - init pins and register pins with a dplls
1662 * @pf: board private structure
1663 * @cgu: if cgu is present and controlled by this NIC
1664 *
1665 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
1666 * subsystem.
1667 *
1668 * Return:
1669 * * 0 - success
1670 * * negative - initialization failure reason
1671 */
1672static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
1673{
1674 u32 rclk_idx;
1675 int ret;
1676
1677 ret = ice_dpll_init_direct_pins(pf, cgu, pins: pf->dplls.inputs, start_idx: 0,
1678 count: pf->dplls.num_inputs,
1679 ops: &ice_dpll_input_ops,
1680 first: pf->dplls.eec.dpll, second: pf->dplls.pps.dpll);
1681 if (ret)
1682 return ret;
1683 if (cgu) {
1684 ret = ice_dpll_init_direct_pins(pf, cgu, pins: pf->dplls.outputs,
1685 start_idx: pf->dplls.num_inputs,
1686 count: pf->dplls.num_outputs,
1687 ops: &ice_dpll_output_ops,
1688 first: pf->dplls.eec.dpll,
1689 second: pf->dplls.pps.dpll);
1690 if (ret)
1691 goto deinit_inputs;
1692 }
1693 rclk_idx = pf->dplls.num_inputs + pf->dplls.num_outputs + pf->hw.pf_id;
1694 ret = ice_dpll_init_rclk_pins(pf, pin: &pf->dplls.rclk, start_idx: rclk_idx,
1695 ops: &ice_dpll_rclk_ops);
1696 if (ret)
1697 goto deinit_outputs;
1698
1699 return 0;
1700deinit_outputs:
1701 ice_dpll_deinit_direct_pins(cgu, pins: pf->dplls.outputs,
1702 count: pf->dplls.num_outputs,
1703 ops: &ice_dpll_output_ops, first: pf->dplls.pps.dpll,
1704 second: pf->dplls.eec.dpll);
1705deinit_inputs:
1706 ice_dpll_deinit_direct_pins(cgu, pins: pf->dplls.inputs, count: pf->dplls.num_inputs,
1707 ops: &ice_dpll_input_ops, first: pf->dplls.pps.dpll,
1708 second: pf->dplls.eec.dpll);
1709 return ret;
1710}
1711
1712/**
1713 * ice_dpll_deinit_dpll - deinitialize dpll device
1714 * @pf: board private structure
1715 * @d: pointer to ice_dpll
1716 * @cgu: if cgu is present and controlled by this NIC
1717 *
1718 * If cgu is owned unregister the dpll from dpll subsystem.
1719 * Release resources of dpll device from dpll subsystem.
1720 */
1721static void
1722ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
1723{
1724 if (cgu)
1725 dpll_device_unregister(dpll: d->dpll, ops: &ice_dpll_ops, priv: d);
1726 dpll_device_put(dpll: d->dpll);
1727}
1728
1729/**
1730 * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
1731 * @pf: board private structure
1732 * @d: dpll to be initialized
1733 * @cgu: if cgu is present and controlled by this NIC
1734 * @type: type of dpll being initialized
1735 *
1736 * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled
1737 * by this NIC, register dpll with the callback ops.
1738 *
1739 * Return:
1740 * * 0 - success
1741 * * negative - initialization failure reason
1742 */
1743static int
1744ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
1745 enum dpll_type type)
1746{
1747 u64 clock_id = pf->dplls.clock_id;
1748 int ret;
1749
1750 d->dpll = dpll_device_get(clock_id, dev_driver_id: d->dpll_idx, THIS_MODULE);
1751 if (IS_ERR(ptr: d->dpll)) {
1752 ret = PTR_ERR(ptr: d->dpll);
1753 dev_err(ice_pf_to_dev(pf),
1754 "dpll_device_get failed (%p) err=%d\n", d, ret);
1755 return ret;
1756 }
1757 d->pf = pf;
1758 if (cgu) {
1759 ret = dpll_device_register(dpll: d->dpll, type, ops: &ice_dpll_ops, priv: d);
1760 if (ret) {
1761 dpll_device_put(dpll: d->dpll);
1762 return ret;
1763 }
1764 }
1765
1766 return 0;
1767}
1768
1769/**
1770 * ice_dpll_deinit_worker - deinitialize dpll kworker
1771 * @pf: board private structure
1772 *
1773 * Stop dpll's kworker, release it's resources.
1774 */
1775static void ice_dpll_deinit_worker(struct ice_pf *pf)
1776{
1777 struct ice_dplls *d = &pf->dplls;
1778
1779 kthread_cancel_delayed_work_sync(work: &d->work);
1780 kthread_destroy_worker(worker: d->kworker);
1781}
1782
1783/**
1784 * ice_dpll_init_worker - Initialize DPLLs periodic worker
1785 * @pf: board private structure
1786 *
1787 * Create and start DPLLs periodic worker.
1788 *
1789 * Context: Shall be called after pf->dplls.lock is initialized.
1790 * Return:
1791 * * 0 - success
1792 * * negative - create worker failure
1793 */
1794static int ice_dpll_init_worker(struct ice_pf *pf)
1795{
1796 struct ice_dplls *d = &pf->dplls;
1797 struct kthread_worker *kworker;
1798
1799 ice_dpll_update_state(pf, d: &d->eec, init: true);
1800 ice_dpll_update_state(pf, d: &d->pps, init: true);
1801 kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
1802 kworker = kthread_create_worker(flags: 0, namefmt: "ice-dplls-%s",
1803 dev_name(ice_pf_to_dev(pf)));
1804 if (IS_ERR(ptr: kworker))
1805 return PTR_ERR(ptr: kworker);
1806 d->kworker = kworker;
1807 d->cgu_state_acq_err_num = 0;
1808 kthread_queue_delayed_work(worker: d->kworker, dwork: &d->work, delay: 0);
1809
1810 return 0;
1811}
1812
1813/**
1814 * ice_dpll_init_info_direct_pins - initializes direct pins info
1815 * @pf: board private structure
1816 * @pin_type: type of pins being initialized
1817 *
1818 * Init information for directly connected pins, cache them in pf's pins
1819 * structures.
1820 *
1821 * Return:
1822 * * 0 - success
1823 * * negative - init failure reason
1824 */
1825static int
1826ice_dpll_init_info_direct_pins(struct ice_pf *pf,
1827 enum ice_dpll_pin_type pin_type)
1828{
1829 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
1830 int num_pins, i, ret = -EINVAL;
1831 struct ice_hw *hw = &pf->hw;
1832 struct ice_dpll_pin *pins;
1833 u8 freq_supp_num;
1834 bool input;
1835
1836 switch (pin_type) {
1837 case ICE_DPLL_PIN_TYPE_INPUT:
1838 pins = pf->dplls.inputs;
1839 num_pins = pf->dplls.num_inputs;
1840 input = true;
1841 break;
1842 case ICE_DPLL_PIN_TYPE_OUTPUT:
1843 pins = pf->dplls.outputs;
1844 num_pins = pf->dplls.num_outputs;
1845 input = false;
1846 break;
1847 default:
1848 return -EINVAL;
1849 }
1850
1851 for (i = 0; i < num_pins; i++) {
1852 pins[i].idx = i;
1853 pins[i].prop.board_label = ice_cgu_get_pin_name(hw, pin: i, input);
1854 pins[i].prop.type = ice_cgu_get_pin_type(hw, pin: i, input);
1855 if (input) {
1856 ret = ice_aq_get_cgu_ref_prio(hw, dpll_num: de->dpll_idx, ref_idx: i,
1857 ref_prio: &de->input_prio[i]);
1858 if (ret)
1859 return ret;
1860 ret = ice_aq_get_cgu_ref_prio(hw, dpll_num: dp->dpll_idx, ref_idx: i,
1861 ref_prio: &dp->input_prio[i]);
1862 if (ret)
1863 return ret;
1864 pins[i].prop.capabilities |=
1865 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
1866 pins[i].prop.phase_range.min =
1867 pf->dplls.input_phase_adj_max;
1868 pins[i].prop.phase_range.max =
1869 -pf->dplls.input_phase_adj_max;
1870 } else {
1871 pins[i].prop.phase_range.min =
1872 pf->dplls.output_phase_adj_max;
1873 pins[i].prop.phase_range.max =
1874 -pf->dplls.output_phase_adj_max;
1875 }
1876 pins[i].prop.capabilities |=
1877 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
1878 ret = ice_dpll_pin_state_update(pf, pin: &pins[i], pin_type, NULL);
1879 if (ret)
1880 return ret;
1881 pins[i].prop.freq_supported =
1882 ice_cgu_get_pin_freq_supp(hw, pin: i, input, num: &freq_supp_num);
1883 pins[i].prop.freq_supported_num = freq_supp_num;
1884 pins[i].pf = pf;
1885 }
1886
1887 return ret;
1888}
1889
1890/**
1891 * ice_dpll_init_info_rclk_pin - initializes rclk pin information
1892 * @pf: board private structure
1893 *
1894 * Init information for rclk pin, cache them in pf->dplls.rclk.
1895 *
1896 * Return:
1897 * * 0 - success
1898 * * negative - init failure reason
1899 */
1900static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
1901{
1902 struct ice_dpll_pin *pin = &pf->dplls.rclk;
1903
1904 pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
1905 pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
1906 pin->pf = pf;
1907
1908 return ice_dpll_pin_state_update(pf, pin,
1909 pin_type: ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
1910}
1911
1912/**
1913 * ice_dpll_init_pins_info - init pins info wrapper
1914 * @pf: board private structure
1915 * @pin_type: type of pins being initialized
1916 *
1917 * Wraps functions for pin initialization.
1918 *
1919 * Return:
1920 * * 0 - success
1921 * * negative - init failure reason
1922 */
1923static int
1924ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
1925{
1926 switch (pin_type) {
1927 case ICE_DPLL_PIN_TYPE_INPUT:
1928 case ICE_DPLL_PIN_TYPE_OUTPUT:
1929 return ice_dpll_init_info_direct_pins(pf, pin_type);
1930 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
1931 return ice_dpll_init_info_rclk_pin(pf);
1932 default:
1933 return -EINVAL;
1934 }
1935}
1936
1937/**
1938 * ice_dpll_deinit_info - release memory allocated for pins info
1939 * @pf: board private structure
1940 *
1941 * Release memory allocated for pins by ice_dpll_init_info function.
1942 */
1943static void ice_dpll_deinit_info(struct ice_pf *pf)
1944{
1945 kfree(objp: pf->dplls.inputs);
1946 kfree(objp: pf->dplls.outputs);
1947 kfree(objp: pf->dplls.eec.input_prio);
1948 kfree(objp: pf->dplls.pps.input_prio);
1949}
1950
1951/**
1952 * ice_dpll_init_info - prepare pf's dpll information structure
1953 * @pf: board private structure
1954 * @cgu: if cgu is present and controlled by this NIC
1955 *
1956 * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
1957 *
1958 * Return:
1959 * * 0 - success
1960 * * negative - init failure reason
1961 */
1962static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
1963{
1964 struct ice_aqc_get_cgu_abilities abilities;
1965 struct ice_dpll *de = &pf->dplls.eec;
1966 struct ice_dpll *dp = &pf->dplls.pps;
1967 struct ice_dplls *d = &pf->dplls;
1968 struct ice_hw *hw = &pf->hw;
1969 int ret, alloc_size, i;
1970
1971 d->clock_id = ice_generate_clock_id(pf);
1972 ret = ice_aq_get_cgu_abilities(hw, abilities: &abilities);
1973 if (ret) {
1974 dev_err(ice_pf_to_dev(pf),
1975 "err:%d %s failed to read cgu abilities\n",
1976 ret, ice_aq_str(hw->adminq.sq_last_status));
1977 return ret;
1978 }
1979
1980 de->dpll_idx = abilities.eec_dpll_idx;
1981 dp->dpll_idx = abilities.pps_dpll_idx;
1982 d->num_inputs = abilities.num_inputs;
1983 d->num_outputs = abilities.num_outputs;
1984 d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj);
1985 d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj);
1986
1987 alloc_size = sizeof(*d->inputs) * d->num_inputs;
1988 d->inputs = kzalloc(size: alloc_size, GFP_KERNEL);
1989 if (!d->inputs)
1990 return -ENOMEM;
1991
1992 alloc_size = sizeof(*de->input_prio) * d->num_inputs;
1993 de->input_prio = kzalloc(size: alloc_size, GFP_KERNEL);
1994 if (!de->input_prio)
1995 return -ENOMEM;
1996
1997 dp->input_prio = kzalloc(size: alloc_size, GFP_KERNEL);
1998 if (!dp->input_prio)
1999 return -ENOMEM;
2000
2001 ret = ice_dpll_init_pins_info(pf, pin_type: ICE_DPLL_PIN_TYPE_INPUT);
2002 if (ret)
2003 goto deinit_info;
2004
2005 if (cgu) {
2006 alloc_size = sizeof(*d->outputs) * d->num_outputs;
2007 d->outputs = kzalloc(size: alloc_size, GFP_KERNEL);
2008 if (!d->outputs) {
2009 ret = -ENOMEM;
2010 goto deinit_info;
2011 }
2012
2013 ret = ice_dpll_init_pins_info(pf, pin_type: ICE_DPLL_PIN_TYPE_OUTPUT);
2014 if (ret)
2015 goto deinit_info;
2016 }
2017
2018 ret = ice_get_cgu_rclk_pin_info(hw: &pf->hw, base_idx: &d->base_rclk_idx,
2019 pin_num: &pf->dplls.rclk.num_parents);
2020 if (ret)
2021 return ret;
2022 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
2023 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
2024 ret = ice_dpll_init_pins_info(pf, pin_type: ICE_DPLL_PIN_TYPE_RCLK_INPUT);
2025 if (ret)
2026 return ret;
2027 de->mode = DPLL_MODE_AUTOMATIC;
2028 dp->mode = DPLL_MODE_AUTOMATIC;
2029
2030 dev_dbg(ice_pf_to_dev(pf),
2031 "%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
2032 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
2033
2034 return 0;
2035
2036deinit_info:
2037 dev_err(ice_pf_to_dev(pf),
2038 "%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
2039 __func__, d->inputs, de->input_prio,
2040 dp->input_prio, d->outputs);
2041 ice_dpll_deinit_info(pf);
2042 return ret;
2043}
2044
2045/**
2046 * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
2047 * the dpll device.
2048 * @pf: board private structure
2049 *
2050 * Handles the cleanup work required after dpll initialization, freeing
2051 * resources and unregistering the dpll, pin and all resources used for
2052 * handling them.
2053 *
2054 * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
2055 */
2056void ice_dpll_deinit(struct ice_pf *pf)
2057{
2058 bool cgu = ice_is_feature_supported(pf, f: ICE_F_CGU);
2059
2060 clear_bit(nr: ICE_FLAG_DPLL, addr: pf->flags);
2061 if (cgu)
2062 ice_dpll_deinit_worker(pf);
2063
2064 ice_dpll_deinit_pins(pf, cgu);
2065 ice_dpll_deinit_dpll(pf, d: &pf->dplls.pps, cgu);
2066 ice_dpll_deinit_dpll(pf, d: &pf->dplls.eec, cgu);
2067 ice_dpll_deinit_info(pf);
2068 mutex_destroy(lock: &pf->dplls.lock);
2069}
2070
2071/**
2072 * ice_dpll_init - initialize support for dpll subsystem
2073 * @pf: board private structure
2074 *
2075 * Set up the device dplls, register them and pins connected within Linux dpll
2076 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
2077 * configuration requests.
2078 *
2079 * Context: Initializes pf->dplls.lock mutex.
2080 */
2081void ice_dpll_init(struct ice_pf *pf)
2082{
2083 bool cgu = ice_is_feature_supported(pf, f: ICE_F_CGU);
2084 struct ice_dplls *d = &pf->dplls;
2085 int err = 0;
2086
2087 err = ice_dpll_init_info(pf, cgu);
2088 if (err)
2089 goto err_exit;
2090 err = ice_dpll_init_dpll(pf, d: &pf->dplls.eec, cgu, type: DPLL_TYPE_EEC);
2091 if (err)
2092 goto deinit_info;
2093 err = ice_dpll_init_dpll(pf, d: &pf->dplls.pps, cgu, type: DPLL_TYPE_PPS);
2094 if (err)
2095 goto deinit_eec;
2096 err = ice_dpll_init_pins(pf, cgu);
2097 if (err)
2098 goto deinit_pps;
2099 mutex_init(&d->lock);
2100 if (cgu) {
2101 err = ice_dpll_init_worker(pf);
2102 if (err)
2103 goto deinit_pins;
2104 }
2105 set_bit(nr: ICE_FLAG_DPLL, addr: pf->flags);
2106
2107 return;
2108
2109deinit_pins:
2110 ice_dpll_deinit_pins(pf, cgu);
2111deinit_pps:
2112 ice_dpll_deinit_dpll(pf, d: &pf->dplls.pps, cgu);
2113deinit_eec:
2114 ice_dpll_deinit_dpll(pf, d: &pf->dplls.eec, cgu);
2115deinit_info:
2116 ice_dpll_deinit_info(pf);
2117err_exit:
2118 mutex_destroy(lock: &d->lock);
2119 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
2120}
2121

source code of linux/drivers/net/ethernet/intel/ice/ice_dpll.c