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