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 #define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125
14 #define ICE_DPLL_PIN_PRIO_OUTPUT 0xff
15 #define ICE_DPLL_INPUT_REF_NUM 10
16 #define ICE_DPLL_PHASE_OFFSET_PERIOD 2
17 #define ICE_DPLL_SW_PIN_INPUT_BASE_SFP 4
18 #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP 6
19 #define ICE_DPLL_SW_PIN_OUTPUT_BASE 0
20
21 #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \
22 (ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx))
23
24 #define ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX \
25 (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
26
27 #define ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX \
28 (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
29
30 #define ICE_DPLL_PIN_SW_OUTPUT_ABS(out_idx) \
31 (ICE_DPLL_SW_PIN_OUTPUT_BASE + (out_idx))
32
33 #define ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX \
34 (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
35
36 #define ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX \
37 (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
38
39 #define ICE_SR_PFA_DPLL_DEFAULTS 0x152
40 #define ICE_DPLL_PFA_REF_SYNC_TYPE 0x2420
41 #define ICE_DPLL_PFA_REF_SYNC_TYPE2 0x2424
42 #define ICE_DPLL_PFA_END 0xFFFF
43 #define ICE_DPLL_PFA_HEADER_LEN 4
44 #define ICE_DPLL_PFA_ENTRY_LEN 3
45 #define ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S 4
46 #define ICE_DPLL_PFA_MASK_OFFSET 1
47 #define ICE_DPLL_PFA_VALUE_OFFSET 2
48
49 #define ICE_DPLL_E810C_SFP_NC_PINS 2
50 #define ICE_DPLL_E810C_SFP_NC_START 4
51
52 /**
53 * enum ice_dpll_pin_type - enumerate ice pin types:
54 * @ICE_DPLL_PIN_INVALID: invalid pin type
55 * @ICE_DPLL_PIN_TYPE_INPUT: input pin
56 * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
57 * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
58 * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins
59 */
60 enum ice_dpll_pin_type {
61 ICE_DPLL_PIN_INVALID,
62 ICE_DPLL_PIN_TYPE_INPUT,
63 ICE_DPLL_PIN_TYPE_OUTPUT,
64 ICE_DPLL_PIN_TYPE_RCLK_INPUT,
65 ICE_DPLL_PIN_TYPE_SOFTWARE,
66 };
67
68 static const char * const pin_type_name[] = {
69 [ICE_DPLL_PIN_TYPE_INPUT] = "input",
70 [ICE_DPLL_PIN_TYPE_OUTPUT] = "output",
71 [ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
72 [ICE_DPLL_PIN_TYPE_SOFTWARE] = "software",
73 };
74
75 static const char * const ice_dpll_sw_pin_sma[] = { "SMA1", "SMA2" };
76 static const char * const ice_dpll_sw_pin_ufl[] = { "U.FL1", "U.FL2" };
77
78 static const struct dpll_pin_frequency ice_esync_range[] = {
79 DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
80 };
81
82 /**
83 * ice_dpll_is_sw_pin - check if given pin shall be controlled by SW
84 * @pf: private board structure
85 * @index: index of a pin as understood by FW
86 * @input: true for input, false for output
87 *
88 * Check if the pin shall be controlled by SW - instead of providing raw access
89 * for pin control. For E810 NIC with dpll there is additional MUX-related logic
90 * between SMA/U.FL pins/connectors and dpll device, best to give user access
91 * with series of wrapper functions as from user perspective they convey single
92 * functionality rather then separated pins.
93 *
94 * Return:
95 * * true - pin controlled by SW
96 * * false - pin not controlled by SW
97 */
ice_dpll_is_sw_pin(struct ice_pf * pf,u8 index,bool input)98 static bool ice_dpll_is_sw_pin(struct ice_pf *pf, u8 index, bool input)
99 {
100 if (input && pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
101 index -= ICE_DPLL_SW_PIN_INPUT_BASE_QSFP -
102 ICE_DPLL_SW_PIN_INPUT_BASE_SFP;
103
104 if ((input && (index == ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX ||
105 index == ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX)) ||
106 (!input && (index == ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX ||
107 index == ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX)))
108 return true;
109 return false;
110 }
111
112 /**
113 * ice_dpll_is_reset - check if reset is in progress
114 * @pf: private board structure
115 * @extack: error reporting
116 *
117 * If reset is in progress, fill extack with error.
118 *
119 * Return:
120 * * false - no reset in progress
121 * * true - reset in progress
122 */
ice_dpll_is_reset(struct ice_pf * pf,struct netlink_ext_ack * extack)123 static bool ice_dpll_is_reset(struct ice_pf *pf, struct netlink_ext_ack *extack)
124 {
125 if (ice_is_reset_in_progress(pf->state)) {
126 NL_SET_ERR_MSG(extack, "PF reset in progress");
127 return true;
128 }
129 return false;
130 }
131
132 /**
133 * ice_dpll_pin_freq_set - set pin's frequency
134 * @pf: private board structure
135 * @pin: pointer to a pin
136 * @pin_type: type of pin being configured
137 * @freq: frequency to be set
138 * @extack: error reporting
139 *
140 * Set requested frequency on a pin.
141 *
142 * Context: Called under pf->dplls.lock
143 * Return:
144 * * 0 - success
145 * * negative - error on AQ or wrong pin type given
146 */
147 static int
ice_dpll_pin_freq_set(struct ice_pf * pf,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,const u32 freq,struct netlink_ext_ack * extack)148 ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin,
149 enum ice_dpll_pin_type pin_type, const u32 freq,
150 struct netlink_ext_ack *extack)
151 {
152 u8 flags;
153 int ret;
154
155 switch (pin_type) {
156 case ICE_DPLL_PIN_TYPE_INPUT:
157 flags = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ;
158 ret = ice_aq_set_input_pin_cfg(&pf->hw, pin->idx, flags,
159 pin->flags[0], freq, 0);
160 break;
161 case ICE_DPLL_PIN_TYPE_OUTPUT:
162 flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_FREQ;
163 ret = ice_aq_set_output_pin_cfg(&pf->hw, pin->idx, flags,
164 0, freq, 0);
165 break;
166 default:
167 return -EINVAL;
168 }
169 if (ret) {
170 NL_SET_ERR_MSG_FMT(extack,
171 "err:%d %s failed to set pin freq:%u on pin:%u",
172 ret,
173 libie_aq_str(pf->hw.adminq.sq_last_status),
174 freq, pin->idx);
175 return ret;
176 }
177 pin->freq = freq;
178
179 return 0;
180 }
181
182 /**
183 * ice_dpll_frequency_set - wrapper for pin callback for set frequency
184 * @pin: pointer to a pin
185 * @pin_priv: private data pointer passed on pin registration
186 * @dpll: pointer to dpll
187 * @dpll_priv: private data pointer passed on dpll registration
188 * @frequency: frequency to be set
189 * @extack: error reporting
190 * @pin_type: type of pin being configured
191 *
192 * Wraps internal set frequency command on a pin.
193 *
194 * Context: Acquires pf->dplls.lock
195 * Return:
196 * * 0 - success
197 * * negative - error pin not found or couldn't set in hw
198 */
199 static int
ice_dpll_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,const u32 frequency,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)200 ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv,
201 const struct dpll_device *dpll, void *dpll_priv,
202 const u32 frequency,
203 struct netlink_ext_ack *extack,
204 enum ice_dpll_pin_type pin_type)
205 {
206 struct ice_dpll_pin *p = pin_priv;
207 struct ice_dpll *d = dpll_priv;
208 struct ice_pf *pf = d->pf;
209 int ret;
210
211 if (ice_dpll_is_reset(pf, extack))
212 return -EBUSY;
213
214 mutex_lock(&pf->dplls.lock);
215 ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency, extack);
216 mutex_unlock(&pf->dplls.lock);
217
218 return ret;
219 }
220
221 /**
222 * ice_dpll_input_frequency_set - input pin callback for set frequency
223 * @pin: pointer to a pin
224 * @pin_priv: private data pointer passed on pin registration
225 * @dpll: pointer to dpll
226 * @dpll_priv: private data pointer passed on dpll registration
227 * @frequency: frequency to be set
228 * @extack: error reporting
229 *
230 * Wraps internal set frequency command on a pin.
231 *
232 * Context: Calls a function which acquires pf->dplls.lock
233 * Return:
234 * * 0 - success
235 * * negative - error pin not found or couldn't set in hw
236 */
237 static int
ice_dpll_input_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)238 ice_dpll_input_frequency_set(const struct dpll_pin *pin, void *pin_priv,
239 const struct dpll_device *dpll, void *dpll_priv,
240 u64 frequency, struct netlink_ext_ack *extack)
241 {
242 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
243 extack, ICE_DPLL_PIN_TYPE_INPUT);
244 }
245
246 /**
247 * ice_dpll_output_frequency_set - output pin callback for set frequency
248 * @pin: pointer to a pin
249 * @pin_priv: private data pointer passed on pin registration
250 * @dpll: pointer to dpll
251 * @dpll_priv: private data pointer passed on dpll registration
252 * @frequency: frequency to be set
253 * @extack: error reporting
254 *
255 * Wraps internal set frequency command on a pin.
256 *
257 * Context: Calls a function which acquires pf->dplls.lock
258 * Return:
259 * * 0 - success
260 * * negative - error pin not found or couldn't set in hw
261 */
262 static int
ice_dpll_output_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)263 ice_dpll_output_frequency_set(const struct dpll_pin *pin, void *pin_priv,
264 const struct dpll_device *dpll, void *dpll_priv,
265 u64 frequency, struct netlink_ext_ack *extack)
266 {
267 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
268 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
269 }
270
271 /**
272 * ice_dpll_frequency_get - wrapper for pin callback for get frequency
273 * @pin: pointer to a pin
274 * @pin_priv: private data pointer passed on pin registration
275 * @dpll: pointer to dpll
276 * @dpll_priv: private data pointer passed on dpll registration
277 * @frequency: on success holds pin's frequency
278 * @extack: error reporting
279 * @pin_type: type of pin being configured
280 *
281 * Wraps internal get frequency command of a pin.
282 *
283 * Context: Acquires pf->dplls.lock
284 * Return:
285 * * 0 - success
286 * * negative - error pin not found or couldn't get from hw
287 */
288 static int
ice_dpll_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)289 ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv,
290 const struct dpll_device *dpll, void *dpll_priv,
291 u64 *frequency, struct netlink_ext_ack *extack,
292 enum ice_dpll_pin_type pin_type)
293 {
294 struct ice_dpll_pin *p = pin_priv;
295 struct ice_dpll *d = dpll_priv;
296 struct ice_pf *pf = d->pf;
297
298 mutex_lock(&pf->dplls.lock);
299 *frequency = p->freq;
300 mutex_unlock(&pf->dplls.lock);
301
302 return 0;
303 }
304
305 /**
306 * ice_dpll_input_frequency_get - input pin callback for get frequency
307 * @pin: pointer to a pin
308 * @pin_priv: private data pointer passed on pin registration
309 * @dpll: pointer to dpll
310 * @dpll_priv: private data pointer passed on dpll registration
311 * @frequency: on success holds pin's frequency
312 * @extack: error reporting
313 *
314 * Wraps internal get frequency command of a input pin.
315 *
316 * Context: Calls a function which acquires pf->dplls.lock
317 * Return:
318 * * 0 - success
319 * * negative - error pin not found or couldn't get from hw
320 */
321 static int
ice_dpll_input_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)322 ice_dpll_input_frequency_get(const struct dpll_pin *pin, void *pin_priv,
323 const struct dpll_device *dpll, void *dpll_priv,
324 u64 *frequency, struct netlink_ext_ack *extack)
325 {
326 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
327 extack, ICE_DPLL_PIN_TYPE_INPUT);
328 }
329
330 /**
331 * ice_dpll_output_frequency_get - output pin callback for get frequency
332 * @pin: pointer to a pin
333 * @pin_priv: private data pointer passed on pin registration
334 * @dpll: pointer to dpll
335 * @dpll_priv: private data pointer passed on dpll registration
336 * @frequency: on success holds pin's frequency
337 * @extack: error reporting
338 *
339 * Wraps internal get frequency command of a pin.
340 *
341 * Context: Calls a function which acquires pf->dplls.lock
342 * Return:
343 * * 0 - success
344 * * negative - error pin not found or couldn't get from hw
345 */
346 static int
ice_dpll_output_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)347 ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv,
348 const struct dpll_device *dpll, void *dpll_priv,
349 u64 *frequency, struct netlink_ext_ack *extack)
350 {
351 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
352 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
353 }
354
355 /**
356 * ice_dpll_sw_pin_frequency_set - callback to set frequency of SW pin
357 * @pin: pointer to a pin
358 * @pin_priv: private data pointer passed on pin registration
359 * @dpll: pointer to dpll
360 * @dpll_priv: private data pointer passed on dpll registration
361 * @frequency: on success holds pin's frequency
362 * @extack: error reporting
363 *
364 * Calls set frequency command for corresponding and active input/output pin.
365 *
366 * Context: Calls a function which acquires and releases pf->dplls.lock
367 * Return:
368 * * 0 - success
369 * * negative - error pin not active or couldn't get from hw
370 */
371 static int
ice_dpll_sw_pin_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)372 ice_dpll_sw_pin_frequency_set(const struct dpll_pin *pin, void *pin_priv,
373 const struct dpll_device *dpll, void *dpll_priv,
374 u64 frequency, struct netlink_ext_ack *extack)
375 {
376 struct ice_dpll_pin *sma = pin_priv;
377 int ret;
378
379 if (!sma->active) {
380 NL_SET_ERR_MSG(extack, "pin is not active");
381 return -EINVAL;
382 }
383 if (sma->direction == DPLL_PIN_DIRECTION_INPUT)
384 ret = ice_dpll_input_frequency_set(NULL, sma->input, dpll,
385 dpll_priv, frequency,
386 extack);
387 else
388 ret = ice_dpll_output_frequency_set(NULL, sma->output, dpll,
389 dpll_priv, frequency,
390 extack);
391
392 return ret;
393 }
394
395 /**
396 * ice_dpll_sw_pin_frequency_get - callback for get frequency of SW pin
397 * @pin: pointer to a pin
398 * @pin_priv: private data pointer passed on pin registration
399 * @dpll: pointer to dpll
400 * @dpll_priv: private data pointer passed on dpll registration
401 * @frequency: on success holds pin's frequency
402 * @extack: error reporting
403 *
404 * Calls get frequency command for corresponding active input/output.
405 *
406 * Context: Calls a function which acquires and releases pf->dplls.lock
407 * Return:
408 * * 0 - success
409 * * negative - error pin not active or couldn't get from hw
410 */
411 static int
ice_dpll_sw_pin_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)412 ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv,
413 const struct dpll_device *dpll, void *dpll_priv,
414 u64 *frequency, struct netlink_ext_ack *extack)
415 {
416 struct ice_dpll_pin *sma = pin_priv;
417 int ret;
418
419 if (!sma->active) {
420 *frequency = 0;
421 return 0;
422 }
423 if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
424 ret = ice_dpll_input_frequency_get(NULL, sma->input, dpll,
425 dpll_priv, frequency,
426 extack);
427 } else {
428 ret = ice_dpll_output_frequency_get(NULL, sma->output, dpll,
429 dpll_priv, frequency,
430 extack);
431 }
432
433 return ret;
434 }
435
436 /**
437 * ice_dpll_pin_enable - enable a pin on dplls
438 * @hw: board private hw structure
439 * @pin: pointer to a pin
440 * @dpll_idx: dpll index to connect to output pin
441 * @pin_type: type of pin being enabled
442 * @extack: error reporting
443 *
444 * Enable a pin on both dplls. Store current state in pin->flags.
445 *
446 * Context: Called under pf->dplls.lock
447 * Return:
448 * * 0 - OK
449 * * negative - error
450 */
451 static int
ice_dpll_pin_enable(struct ice_hw * hw,struct ice_dpll_pin * pin,u8 dpll_idx,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)452 ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin,
453 u8 dpll_idx, enum ice_dpll_pin_type pin_type,
454 struct netlink_ext_ack *extack)
455 {
456 u8 flags = 0;
457 int ret;
458
459 switch (pin_type) {
460 case ICE_DPLL_PIN_TYPE_INPUT:
461 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
462 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
463 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
464 ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
465 break;
466 case ICE_DPLL_PIN_TYPE_OUTPUT:
467 flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_SRC_SEL;
468 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
469 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
470 flags |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
471 ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, dpll_idx,
472 0, 0);
473 break;
474 default:
475 return -EINVAL;
476 }
477 if (ret)
478 NL_SET_ERR_MSG_FMT(extack,
479 "err:%d %s failed to enable %s pin:%u",
480 ret, libie_aq_str(hw->adminq.sq_last_status),
481 pin_type_name[pin_type], pin->idx);
482
483 return ret;
484 }
485
486 /**
487 * ice_dpll_pin_disable - disable a pin on dplls
488 * @hw: board private hw structure
489 * @pin: pointer to a pin
490 * @pin_type: type of pin being disabled
491 * @extack: error reporting
492 *
493 * Disable a pin on both dplls. Store current state in pin->flags.
494 *
495 * Context: Called under pf->dplls.lock
496 * Return:
497 * * 0 - OK
498 * * negative - error
499 */
500 static int
ice_dpll_pin_disable(struct ice_hw * hw,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)501 ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
502 enum ice_dpll_pin_type pin_type,
503 struct netlink_ext_ack *extack)
504 {
505 u8 flags = 0;
506 int ret;
507
508 switch (pin_type) {
509 case ICE_DPLL_PIN_TYPE_INPUT:
510 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
511 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
512 ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
513 break;
514 case ICE_DPLL_PIN_TYPE_OUTPUT:
515 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
516 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
517 ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0);
518 break;
519 default:
520 return -EINVAL;
521 }
522 if (ret)
523 NL_SET_ERR_MSG_FMT(extack,
524 "err:%d %s failed to disable %s pin:%u",
525 ret, libie_aq_str(hw->adminq.sq_last_status),
526 pin_type_name[pin_type], pin->idx);
527
528 return ret;
529 }
530
531 /**
532 * ice_dpll_sw_pins_update - update status of all SW pins
533 * @pf: private board struct
534 *
535 * Determine and update pin struct fields (direction/active) of their current
536 * values for all the SW controlled pins.
537 *
538 * Context: Call with pf->dplls.lock held
539 * Return:
540 * * 0 - OK
541 * * negative - error
542 */
543 static int
ice_dpll_sw_pins_update(struct ice_pf * pf)544 ice_dpll_sw_pins_update(struct ice_pf *pf)
545 {
546 struct ice_dplls *d = &pf->dplls;
547 struct ice_dpll_pin *p;
548 u8 data = 0;
549 int ret;
550
551 ret = ice_read_sma_ctrl(&pf->hw, &data);
552 if (ret)
553 return ret;
554 /* no change since last check */
555 if (d->sma_data == data)
556 return 0;
557
558 /*
559 * SMA1/U.FL1 vs SMA2/U.FL2 are using different bit scheme to decide
560 * on their direction and if are active
561 */
562 p = &d->sma[ICE_DPLL_PIN_SW_1_IDX];
563 p->active = true;
564 p->direction = DPLL_PIN_DIRECTION_INPUT;
565 if (data & ICE_SMA1_DIR_EN) {
566 p->direction = DPLL_PIN_DIRECTION_OUTPUT;
567 if (data & ICE_SMA1_TX_EN)
568 p->active = false;
569 }
570
571 p = &d->sma[ICE_DPLL_PIN_SW_2_IDX];
572 p->active = true;
573 p->direction = DPLL_PIN_DIRECTION_INPUT;
574 if ((data & ICE_SMA2_INACTIVE_MASK) == ICE_SMA2_INACTIVE_MASK)
575 p->active = false;
576 else if (data & ICE_SMA2_DIR_EN)
577 p->direction = DPLL_PIN_DIRECTION_OUTPUT;
578
579 p = &d->ufl[ICE_DPLL_PIN_SW_1_IDX];
580 if (!(data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)))
581 p->active = true;
582 else
583 p->active = false;
584
585 p = &d->ufl[ICE_DPLL_PIN_SW_2_IDX];
586 p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_DIS);
587 d->sma_data = data;
588
589 return 0;
590 }
591
592 /**
593 * ice_dpll_pin_state_update - update pin's state
594 * @pf: private board struct
595 * @pin: structure with pin attributes to be updated
596 * @pin_type: type of pin being updated
597 * @extack: error reporting
598 *
599 * Determine pin current state and frequency, then update struct
600 * holding the pin info. For input pin states are separated for each
601 * dpll, for rclk pins states are separated for each parent.
602 *
603 * Context: Called under pf->dplls.lock
604 * Return:
605 * * 0 - OK
606 * * negative - error
607 */
608 static int
ice_dpll_pin_state_update(struct ice_pf * pf,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)609 ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
610 enum ice_dpll_pin_type pin_type,
611 struct netlink_ext_ack *extack)
612 {
613 u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
614 int ret;
615
616 switch (pin_type) {
617 case ICE_DPLL_PIN_TYPE_INPUT:
618 ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
619 NULL, NULL, &pin->flags[0],
620 &pin->freq, &pin->phase_adjust);
621 if (ret)
622 goto err;
623 if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
624 if (pin->pin) {
625 pin->state[pf->dplls.eec.dpll_idx] =
626 pin->pin == pf->dplls.eec.active_input ?
627 DPLL_PIN_STATE_CONNECTED :
628 DPLL_PIN_STATE_SELECTABLE;
629 pin->state[pf->dplls.pps.dpll_idx] =
630 pin->pin == pf->dplls.pps.active_input ?
631 DPLL_PIN_STATE_CONNECTED :
632 DPLL_PIN_STATE_SELECTABLE;
633 } else {
634 pin->state[pf->dplls.eec.dpll_idx] =
635 DPLL_PIN_STATE_SELECTABLE;
636 pin->state[pf->dplls.pps.dpll_idx] =
637 DPLL_PIN_STATE_SELECTABLE;
638 }
639 } else {
640 pin->state[pf->dplls.eec.dpll_idx] =
641 DPLL_PIN_STATE_DISCONNECTED;
642 pin->state[pf->dplls.pps.dpll_idx] =
643 DPLL_PIN_STATE_DISCONNECTED;
644 }
645 break;
646 case ICE_DPLL_PIN_TYPE_OUTPUT:
647 ret = ice_aq_get_output_pin_cfg(&pf->hw, pin->idx,
648 &pin->flags[0], &parent,
649 &pin->freq, NULL);
650 if (ret)
651 goto err;
652
653 parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
654 if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
655 pin->state[pf->dplls.eec.dpll_idx] =
656 parent == pf->dplls.eec.dpll_idx ?
657 DPLL_PIN_STATE_CONNECTED :
658 DPLL_PIN_STATE_DISCONNECTED;
659 pin->state[pf->dplls.pps.dpll_idx] =
660 parent == pf->dplls.pps.dpll_idx ?
661 DPLL_PIN_STATE_CONNECTED :
662 DPLL_PIN_STATE_DISCONNECTED;
663 } else {
664 pin->state[pf->dplls.eec.dpll_idx] =
665 DPLL_PIN_STATE_DISCONNECTED;
666 pin->state[pf->dplls.pps.dpll_idx] =
667 DPLL_PIN_STATE_DISCONNECTED;
668 }
669 break;
670 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
671 for (parent = 0; parent < pf->dplls.rclk.num_parents;
672 parent++) {
673 u8 p = parent;
674
675 ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &p,
676 &port_num,
677 &pin->flags[parent],
678 NULL);
679 if (ret)
680 goto err;
681 if (ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
682 pin->flags[parent])
683 pin->state[parent] = DPLL_PIN_STATE_CONNECTED;
684 else
685 pin->state[parent] =
686 DPLL_PIN_STATE_DISCONNECTED;
687 }
688 break;
689 case ICE_DPLL_PIN_TYPE_SOFTWARE:
690 ret = ice_dpll_sw_pins_update(pf);
691 if (ret)
692 goto err;
693 break;
694 default:
695 return -EINVAL;
696 }
697
698 return 0;
699 err:
700 if (extack)
701 NL_SET_ERR_MSG_FMT(extack,
702 "err:%d %s failed to update %s pin:%u",
703 ret,
704 libie_aq_str(pf->hw.adminq.sq_last_status),
705 pin_type_name[pin_type], pin->idx);
706 else
707 dev_err_ratelimited(ice_pf_to_dev(pf),
708 "err:%d %s failed to update %s pin:%u\n",
709 ret,
710 libie_aq_str(pf->hw.adminq.sq_last_status),
711 pin_type_name[pin_type], pin->idx);
712 return ret;
713 }
714
715 /**
716 * ice_dpll_hw_input_prio_set - set input priority value in hardware
717 * @pf: board private structure
718 * @dpll: ice dpll pointer
719 * @pin: ice pin pointer
720 * @prio: priority value being set on a dpll
721 * @extack: error reporting
722 *
723 * Internal wrapper for setting the priority in the hardware.
724 *
725 * Context: Called under pf->dplls.lock
726 * Return:
727 * * 0 - success
728 * * negative - failure
729 */
730 static int
ice_dpll_hw_input_prio_set(struct ice_pf * pf,struct ice_dpll * dpll,struct ice_dpll_pin * pin,const u32 prio,struct netlink_ext_ack * extack)731 ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
732 struct ice_dpll_pin *pin, const u32 prio,
733 struct netlink_ext_ack *extack)
734 {
735 int ret;
736
737 ret = ice_aq_set_cgu_ref_prio(&pf->hw, dpll->dpll_idx, pin->idx,
738 (u8)prio);
739 if (ret)
740 NL_SET_ERR_MSG_FMT(extack,
741 "err:%d %s failed to set pin prio:%u on pin:%u",
742 ret,
743 libie_aq_str(pf->hw.adminq.sq_last_status),
744 prio, pin->idx);
745 else
746 dpll->input_prio[pin->idx] = prio;
747
748 return ret;
749 }
750
751 /**
752 * ice_dpll_lock_status_get - get dpll lock status callback
753 * @dpll: registered dpll pointer
754 * @dpll_priv: private data pointer passed on dpll registration
755 * @status: on success holds dpll's lock status
756 * @status_error: status error value
757 * @extack: error reporting
758 *
759 * Dpll subsystem callback, provides dpll's lock status.
760 *
761 * Context: Acquires pf->dplls.lock
762 * Return:
763 * * 0 - success
764 * * negative - failure
765 */
766 static int
ice_dpll_lock_status_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_lock_status * status,enum dpll_lock_status_error * status_error,struct netlink_ext_ack * extack)767 ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
768 enum dpll_lock_status *status,
769 enum dpll_lock_status_error *status_error,
770 struct netlink_ext_ack *extack)
771 {
772 struct ice_dpll *d = dpll_priv;
773 struct ice_pf *pf = d->pf;
774
775 mutex_lock(&pf->dplls.lock);
776 *status = d->dpll_state;
777 mutex_unlock(&pf->dplls.lock);
778
779 return 0;
780 }
781
782 /**
783 * ice_dpll_mode_get - get dpll's working mode
784 * @dpll: registered dpll pointer
785 * @dpll_priv: private data pointer passed on dpll registration
786 * @mode: on success holds current working mode of dpll
787 * @extack: error reporting
788 *
789 * Dpll subsystem callback. Provides working mode of dpll.
790 *
791 * Context: Acquires pf->dplls.lock
792 * Return:
793 * * 0 - success
794 * * negative - failure
795 */
ice_dpll_mode_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_mode * mode,struct netlink_ext_ack * extack)796 static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
797 enum dpll_mode *mode,
798 struct netlink_ext_ack *extack)
799 {
800 struct ice_dpll *d = dpll_priv;
801 struct ice_pf *pf = d->pf;
802
803 mutex_lock(&pf->dplls.lock);
804 *mode = d->mode;
805 mutex_unlock(&pf->dplls.lock);
806
807 return 0;
808 }
809
810 /**
811 * ice_dpll_phase_offset_monitor_set - set phase offset monitor state
812 * @dpll: registered dpll pointer
813 * @dpll_priv: private data pointer passed on dpll registration
814 * @state: feature state to be set
815 * @extack: error reporting
816 *
817 * Dpll subsystem callback. Enable/disable phase offset monitor feature of dpll.
818 *
819 * Context: Acquires and releases pf->dplls.lock
820 * Return: 0 - success
821 */
ice_dpll_phase_offset_monitor_set(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state state,struct netlink_ext_ack * extack)822 static int ice_dpll_phase_offset_monitor_set(const struct dpll_device *dpll,
823 void *dpll_priv,
824 enum dpll_feature_state state,
825 struct netlink_ext_ack *extack)
826 {
827 struct ice_dpll *d = dpll_priv;
828 struct ice_pf *pf = d->pf;
829
830 mutex_lock(&pf->dplls.lock);
831 if (state == DPLL_FEATURE_STATE_ENABLE)
832 d->phase_offset_monitor_period = ICE_DPLL_PHASE_OFFSET_PERIOD;
833 else
834 d->phase_offset_monitor_period = 0;
835 mutex_unlock(&pf->dplls.lock);
836
837 return 0;
838 }
839
840 /**
841 * ice_dpll_phase_offset_monitor_get - get phase offset monitor state
842 * @dpll: registered dpll pointer
843 * @dpll_priv: private data pointer passed on dpll registration
844 * @state: on success holds current state of phase offset monitor
845 * @extack: error reporting
846 *
847 * Dpll subsystem callback. Provides current state of phase offset monitor
848 * features on dpll device.
849 *
850 * Context: Acquires and releases pf->dplls.lock
851 * Return: 0 - success
852 */
ice_dpll_phase_offset_monitor_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state * state,struct netlink_ext_ack * extack)853 static int ice_dpll_phase_offset_monitor_get(const struct dpll_device *dpll,
854 void *dpll_priv,
855 enum dpll_feature_state *state,
856 struct netlink_ext_ack *extack)
857 {
858 struct ice_dpll *d = dpll_priv;
859 struct ice_pf *pf = d->pf;
860
861 mutex_lock(&pf->dplls.lock);
862 if (d->phase_offset_monitor_period)
863 *state = DPLL_FEATURE_STATE_ENABLE;
864 else
865 *state = DPLL_FEATURE_STATE_DISABLE;
866 mutex_unlock(&pf->dplls.lock);
867
868 return 0;
869 }
870
871 /**
872 * ice_dpll_pin_state_set - set pin's state on dpll
873 * @pin: pointer to a pin
874 * @pin_priv: private data pointer passed on pin registration
875 * @dpll: registered dpll pointer
876 * @dpll_priv: private data pointer passed on dpll registration
877 * @enable: if pin shalll be enabled
878 * @extack: error reporting
879 * @pin_type: type of a pin
880 *
881 * Set pin state on a pin.
882 *
883 * Context: Acquires pf->dplls.lock
884 * Return:
885 * * 0 - OK or no change required
886 * * negative - error
887 */
888 static int
ice_dpll_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,bool enable,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)889 ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
890 const struct dpll_device *dpll, void *dpll_priv,
891 bool enable, struct netlink_ext_ack *extack,
892 enum ice_dpll_pin_type pin_type)
893 {
894 struct ice_dpll_pin *p = pin_priv;
895 struct ice_dpll *d = dpll_priv;
896 struct ice_pf *pf = d->pf;
897 int ret;
898
899 if (ice_dpll_is_reset(pf, extack))
900 return -EBUSY;
901
902 mutex_lock(&pf->dplls.lock);
903 if (enable)
904 ret = ice_dpll_pin_enable(&pf->hw, p, d->dpll_idx, pin_type,
905 extack);
906 else
907 ret = ice_dpll_pin_disable(&pf->hw, p, pin_type, extack);
908 if (!ret)
909 ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
910 mutex_unlock(&pf->dplls.lock);
911
912 return ret;
913 }
914
915 /**
916 * ice_dpll_output_state_set - enable/disable output pin on dpll device
917 * @pin: pointer to a pin
918 * @pin_priv: private data pointer passed on pin registration
919 * @dpll: dpll being configured
920 * @dpll_priv: private data pointer passed on dpll registration
921 * @state: state of pin to be set
922 * @extack: error reporting
923 *
924 * Dpll subsystem callback. Set given state on output type pin.
925 *
926 * Context: Calls a function which acquires pf->dplls.lock
927 * Return:
928 * * 0 - successfully enabled mode
929 * * negative - failed to enable mode
930 */
931 static int
ice_dpll_output_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)932 ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
933 const struct dpll_device *dpll, void *dpll_priv,
934 enum dpll_pin_state state,
935 struct netlink_ext_ack *extack)
936 {
937 bool enable = state == DPLL_PIN_STATE_CONNECTED;
938 struct ice_dpll_pin *p = pin_priv;
939 struct ice_dpll *d = dpll_priv;
940
941 if (state == DPLL_PIN_STATE_SELECTABLE)
942 return -EINVAL;
943 if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
944 return 0;
945
946 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
947 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
948 }
949
950 /**
951 * ice_dpll_input_state_set - enable/disable input pin on dpll levice
952 * @pin: pointer to a pin
953 * @pin_priv: private data pointer passed on pin registration
954 * @dpll: dpll being configured
955 * @dpll_priv: private data pointer passed on dpll registration
956 * @state: state of pin to be set
957 * @extack: error reporting
958 *
959 * Dpll subsystem callback. Enables given mode on input type pin.
960 *
961 * Context: Calls a function which acquires pf->dplls.lock
962 * Return:
963 * * 0 - successfully enabled mode
964 * * negative - failed to enable mode
965 */
966 static int
ice_dpll_input_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)967 ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv,
968 const struct dpll_device *dpll, void *dpll_priv,
969 enum dpll_pin_state state,
970 struct netlink_ext_ack *extack)
971 {
972 bool enable = state == DPLL_PIN_STATE_SELECTABLE;
973
974 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
975 extack, ICE_DPLL_PIN_TYPE_INPUT);
976 }
977
978 /**
979 * ice_dpll_pin_state_get - set pin's state on dpll
980 * @pin: pointer to a pin
981 * @pin_priv: private data pointer passed on pin registration
982 * @dpll: registered dpll pointer
983 * @dpll_priv: private data pointer passed on dpll registration
984 * @state: on success holds state of the pin
985 * @extack: error reporting
986 * @pin_type: type of questioned pin
987 *
988 * Determine pin state set it on a pin.
989 *
990 * Context: Acquires pf->dplls.lock
991 * Return:
992 * * 0 - success
993 * * negative - failed to get state
994 */
995 static int
ice_dpll_pin_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)996 ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
997 const struct dpll_device *dpll, void *dpll_priv,
998 enum dpll_pin_state *state,
999 struct netlink_ext_ack *extack,
1000 enum ice_dpll_pin_type pin_type)
1001 {
1002 struct ice_dpll_pin *p = pin_priv;
1003 struct ice_dpll *d = dpll_priv;
1004 struct ice_pf *pf = d->pf;
1005 int ret;
1006
1007 if (ice_dpll_is_reset(pf, extack))
1008 return -EBUSY;
1009
1010 mutex_lock(&pf->dplls.lock);
1011 ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
1012 if (ret)
1013 goto unlock;
1014 if (pin_type == ICE_DPLL_PIN_TYPE_INPUT ||
1015 pin_type == ICE_DPLL_PIN_TYPE_OUTPUT)
1016 *state = p->state[d->dpll_idx];
1017 ret = 0;
1018 unlock:
1019 mutex_unlock(&pf->dplls.lock);
1020
1021 return ret;
1022 }
1023
1024 /**
1025 * ice_dpll_output_state_get - get output pin state on dpll device
1026 * @pin: pointer to a pin
1027 * @pin_priv: private data pointer passed on pin registration
1028 * @dpll: registered dpll pointer
1029 * @dpll_priv: private data pointer passed on dpll registration
1030 * @state: on success holds state of the pin
1031 * @extack: error reporting
1032 *
1033 * Dpll subsystem callback. Check state of a pin.
1034 *
1035 * Context: Calls a function which acquires pf->dplls.lock
1036 * Return:
1037 * * 0 - success
1038 * * negative - failed to get state
1039 */
1040 static int
ice_dpll_output_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1041 ice_dpll_output_state_get(const struct dpll_pin *pin, void *pin_priv,
1042 const struct dpll_device *dpll, void *dpll_priv,
1043 enum dpll_pin_state *state,
1044 struct netlink_ext_ack *extack)
1045 {
1046 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1047 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
1048 }
1049
1050 /**
1051 * ice_dpll_input_state_get - get input pin state on dpll device
1052 * @pin: pointer to a pin
1053 * @pin_priv: private data pointer passed on pin registration
1054 * @dpll: registered dpll pointer
1055 * @dpll_priv: private data pointer passed on dpll registration
1056 * @state: on success holds state of the pin
1057 * @extack: error reporting
1058 *
1059 * Dpll subsystem callback. Check state of a input pin.
1060 *
1061 * Context: Calls a function which acquires pf->dplls.lock
1062 * Return:
1063 * * 0 - success
1064 * * negative - failed to get state
1065 */
1066 static int
ice_dpll_input_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1067 ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
1068 const struct dpll_device *dpll, void *dpll_priv,
1069 enum dpll_pin_state *state,
1070 struct netlink_ext_ack *extack)
1071 {
1072 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1073 extack, ICE_DPLL_PIN_TYPE_INPUT);
1074 }
1075
1076 /**
1077 * ice_dpll_sma_direction_set - set direction of SMA pin
1078 * @p: pointer to a pin
1079 * @direction: requested direction of the pin
1080 * @extack: error reporting
1081 *
1082 * Wrapper for dpll subsystem callback. Set direction of a SMA pin.
1083 *
1084 * Context: Call with pf->dplls.lock held
1085 * Return:
1086 * * 0 - success
1087 * * negative - failed to get state
1088 */
ice_dpll_sma_direction_set(struct ice_dpll_pin * p,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1089 static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
1090 enum dpll_pin_direction direction,
1091 struct netlink_ext_ack *extack)
1092 {
1093 u8 data;
1094 int ret;
1095
1096 if (p->direction == direction && p->active)
1097 return 0;
1098 ret = ice_read_sma_ctrl(&p->pf->hw, &data);
1099 if (ret)
1100 return ret;
1101
1102 switch (p->idx) {
1103 case ICE_DPLL_PIN_SW_1_IDX:
1104 data &= ~ICE_SMA1_MASK;
1105 if (direction == DPLL_PIN_DIRECTION_OUTPUT)
1106 data |= ICE_SMA1_DIR_EN;
1107 break;
1108 case ICE_DPLL_PIN_SW_2_IDX:
1109 if (direction == DPLL_PIN_DIRECTION_INPUT) {
1110 data &= ~ICE_SMA2_DIR_EN;
1111 } else {
1112 data &= ~ICE_SMA2_TX_EN;
1113 data |= ICE_SMA2_DIR_EN;
1114 }
1115 break;
1116 default:
1117 return -EINVAL;
1118 }
1119 ret = ice_write_sma_ctrl(&p->pf->hw, data);
1120 if (!ret)
1121 ret = ice_dpll_pin_state_update(p->pf, p,
1122 ICE_DPLL_PIN_TYPE_SOFTWARE,
1123 extack);
1124
1125 return ret;
1126 }
1127
1128 /**
1129 * ice_dpll_ufl_pin_state_set - set U.FL pin state on dpll device
1130 * @pin: pointer to a pin
1131 * @pin_priv: private data pointer passed on pin registration
1132 * @dpll: registered dpll pointer
1133 * @dpll_priv: private data pointer passed on dpll registration
1134 * @state: requested state of the pin
1135 * @extack: error reporting
1136 *
1137 * Dpll subsystem callback. Set the state of a pin.
1138 *
1139 * Context: Acquires and releases pf->dplls.lock
1140 * Return:
1141 * * 0 - success
1142 * * negative - error
1143 */
1144 static int
ice_dpll_ufl_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1145 ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1146 const struct dpll_device *dpll, void *dpll_priv,
1147 enum dpll_pin_state state,
1148 struct netlink_ext_ack *extack)
1149 {
1150 struct ice_dpll_pin *p = pin_priv, *target;
1151 struct ice_dpll *d = dpll_priv;
1152 enum ice_dpll_pin_type type;
1153 struct ice_pf *pf = p->pf;
1154 struct ice_hw *hw;
1155 bool enable;
1156 u8 data;
1157 int ret;
1158
1159 if (ice_dpll_is_reset(pf, extack))
1160 return -EBUSY;
1161
1162 mutex_lock(&pf->dplls.lock);
1163 hw = &pf->hw;
1164 ret = ice_read_sma_ctrl(hw, &data);
1165 if (ret)
1166 goto unlock;
1167
1168 ret = -EINVAL;
1169 switch (p->idx) {
1170 case ICE_DPLL_PIN_SW_1_IDX:
1171 if (state == DPLL_PIN_STATE_CONNECTED) {
1172 data &= ~ICE_SMA1_MASK;
1173 enable = true;
1174 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1175 data |= ICE_SMA1_TX_EN;
1176 enable = false;
1177 } else {
1178 goto unlock;
1179 }
1180 target = p->output;
1181 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1182 break;
1183 case ICE_DPLL_PIN_SW_2_IDX:
1184 if (state == DPLL_PIN_STATE_SELECTABLE) {
1185 data |= ICE_SMA2_DIR_EN;
1186 data &= ~ICE_SMA2_UFL2_RX_DIS;
1187 enable = true;
1188 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1189 data |= ICE_SMA2_UFL2_RX_DIS;
1190 enable = false;
1191 } else {
1192 goto unlock;
1193 }
1194 target = p->input;
1195 type = ICE_DPLL_PIN_TYPE_INPUT;
1196 break;
1197 default:
1198 goto unlock;
1199 }
1200
1201 ret = ice_write_sma_ctrl(hw, data);
1202 if (ret)
1203 goto unlock;
1204 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,
1205 extack);
1206 if (ret)
1207 goto unlock;
1208
1209 if (enable)
1210 ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
1211 else
1212 ret = ice_dpll_pin_disable(hw, target, type, extack);
1213 if (!ret)
1214 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1215
1216 unlock:
1217 mutex_unlock(&pf->dplls.lock);
1218
1219 return ret;
1220 }
1221
1222 /**
1223 * ice_dpll_sw_pin_state_get - get SW pin state
1224 * @pin: pointer to a pin
1225 * @pin_priv: private data pointer passed on pin registration
1226 * @dpll: registered dpll pointer
1227 * @dpll_priv: private data pointer passed on dpll registration
1228 * @state: on success holds state of the pin
1229 * @extack: error reporting
1230 *
1231 * Dpll subsystem callback. Check state of a SW pin.
1232 *
1233 * Context: Acquires and releases pf->dplls.lock
1234 * Return:
1235 * * 0 - success
1236 * * negative - error
1237 */
1238 static int
ice_dpll_sw_pin_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1239 ice_dpll_sw_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1240 const struct dpll_device *dpll, void *dpll_priv,
1241 enum dpll_pin_state *state,
1242 struct netlink_ext_ack *extack)
1243 {
1244 struct ice_dpll_pin *p = pin_priv;
1245 struct ice_dpll *d = dpll_priv;
1246 struct ice_pf *pf = p->pf;
1247 int ret = 0;
1248
1249 if (ice_dpll_is_reset(pf, extack))
1250 return -EBUSY;
1251 mutex_lock(&pf->dplls.lock);
1252 if (!p->active) {
1253 *state = DPLL_PIN_STATE_DISCONNECTED;
1254 goto unlock;
1255 }
1256
1257 if (p->direction == DPLL_PIN_DIRECTION_INPUT) {
1258 ret = ice_dpll_pin_state_update(pf, p->input,
1259 ICE_DPLL_PIN_TYPE_INPUT,
1260 extack);
1261 if (ret)
1262 goto unlock;
1263 *state = p->input->state[d->dpll_idx];
1264 } else {
1265 ret = ice_dpll_pin_state_update(pf, p->output,
1266 ICE_DPLL_PIN_TYPE_OUTPUT,
1267 extack);
1268 if (ret)
1269 goto unlock;
1270 *state = p->output->state[d->dpll_idx];
1271 }
1272 unlock:
1273 mutex_unlock(&pf->dplls.lock);
1274
1275 return ret;
1276 }
1277
1278 /**
1279 * ice_dpll_sma_pin_state_set - set SMA pin state on dpll device
1280 * @pin: pointer to a pin
1281 * @pin_priv: private data pointer passed on pin registration
1282 * @dpll: registered dpll pointer
1283 * @dpll_priv: private data pointer passed on dpll registration
1284 * @state: requested state of the pin
1285 * @extack: error reporting
1286 *
1287 * Dpll subsystem callback. Set state of a pin.
1288 *
1289 * Context: Acquires and releases pf->dplls.lock
1290 * Return:
1291 * * 0 - success
1292 * * negative - failed to get state
1293 */
1294 static int
ice_dpll_sma_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1295 ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1296 const struct dpll_device *dpll, void *dpll_priv,
1297 enum dpll_pin_state state,
1298 struct netlink_ext_ack *extack)
1299 {
1300 struct ice_dpll_pin *sma = pin_priv, *target;
1301 struct ice_dpll *d = dpll_priv;
1302 struct ice_pf *pf = sma->pf;
1303 enum ice_dpll_pin_type type;
1304 bool enable;
1305 int ret;
1306
1307 if (ice_dpll_is_reset(pf, extack))
1308 return -EBUSY;
1309
1310 mutex_lock(&pf->dplls.lock);
1311 if (!sma->active) {
1312 ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
1313 if (ret)
1314 goto unlock;
1315 }
1316 if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
1317 enable = state == DPLL_PIN_STATE_SELECTABLE;
1318 target = sma->input;
1319 type = ICE_DPLL_PIN_TYPE_INPUT;
1320 } else {
1321 enable = state == DPLL_PIN_STATE_CONNECTED;
1322 target = sma->output;
1323 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1324 }
1325
1326 if (enable)
1327 ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
1328 extack);
1329 else
1330 ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
1331 if (!ret)
1332 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1333
1334 unlock:
1335 mutex_unlock(&pf->dplls.lock);
1336
1337 return ret;
1338 }
1339
1340 /**
1341 * ice_dpll_input_prio_get - get dpll's input prio
1342 * @pin: pointer to a pin
1343 * @pin_priv: private data pointer passed on pin registration
1344 * @dpll: registered dpll pointer
1345 * @dpll_priv: private data pointer passed on dpll registration
1346 * @prio: on success - returns input priority on dpll
1347 * @extack: error reporting
1348 *
1349 * Dpll subsystem callback. Handler for getting priority of a input pin.
1350 *
1351 * Context: Acquires pf->dplls.lock
1352 * Return:
1353 * * 0 - success
1354 * * negative - failure
1355 */
1356 static int
ice_dpll_input_prio_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 * prio,struct netlink_ext_ack * extack)1357 ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1358 const struct dpll_device *dpll, void *dpll_priv,
1359 u32 *prio, struct netlink_ext_ack *extack)
1360 {
1361 struct ice_dpll_pin *p = pin_priv;
1362 struct ice_dpll *d = dpll_priv;
1363 struct ice_pf *pf = d->pf;
1364
1365 mutex_lock(&pf->dplls.lock);
1366 *prio = d->input_prio[p->idx];
1367 mutex_unlock(&pf->dplls.lock);
1368
1369 return 0;
1370 }
1371
1372 /**
1373 * ice_dpll_input_prio_set - set dpll input prio
1374 * @pin: pointer to a pin
1375 * @pin_priv: private data pointer passed on pin registration
1376 * @dpll: registered dpll pointer
1377 * @dpll_priv: private data pointer passed on dpll registration
1378 * @prio: input priority to be set on dpll
1379 * @extack: error reporting
1380 *
1381 * Dpll subsystem callback. Handler for setting priority of a input pin.
1382 *
1383 * Context: Acquires pf->dplls.lock
1384 * Return:
1385 * * 0 - success
1386 * * negative - failure
1387 */
1388 static int
ice_dpll_input_prio_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 prio,struct netlink_ext_ack * extack)1389 ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1390 const struct dpll_device *dpll, void *dpll_priv,
1391 u32 prio, struct netlink_ext_ack *extack)
1392 {
1393 struct ice_dpll_pin *p = pin_priv;
1394 struct ice_dpll *d = dpll_priv;
1395 struct ice_pf *pf = d->pf;
1396 int ret;
1397
1398 if (ice_dpll_is_reset(pf, extack))
1399 return -EBUSY;
1400
1401 mutex_lock(&pf->dplls.lock);
1402 ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
1403 mutex_unlock(&pf->dplls.lock);
1404
1405 return ret;
1406 }
1407
1408 static int
ice_dpll_sw_input_prio_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 * prio,struct netlink_ext_ack * extack)1409 ice_dpll_sw_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1410 const struct dpll_device *dpll, void *dpll_priv,
1411 u32 *prio, struct netlink_ext_ack *extack)
1412 {
1413 struct ice_dpll_pin *p = pin_priv;
1414 struct ice_dpll *d = dpll_priv;
1415 struct ice_pf *pf = d->pf;
1416
1417 mutex_lock(&pf->dplls.lock);
1418 if (p->input && p->direction == DPLL_PIN_DIRECTION_INPUT)
1419 *prio = d->input_prio[p->input->idx];
1420 else
1421 *prio = ICE_DPLL_PIN_PRIO_OUTPUT;
1422 mutex_unlock(&pf->dplls.lock);
1423
1424 return 0;
1425 }
1426
1427 static int
ice_dpll_sw_input_prio_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 prio,struct netlink_ext_ack * extack)1428 ice_dpll_sw_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1429 const struct dpll_device *dpll, void *dpll_priv,
1430 u32 prio, struct netlink_ext_ack *extack)
1431 {
1432 struct ice_dpll_pin *p = pin_priv;
1433 struct ice_dpll *d = dpll_priv;
1434 struct ice_pf *pf = d->pf;
1435 int ret;
1436
1437 if (!p->input || p->direction != DPLL_PIN_DIRECTION_INPUT)
1438 return -EINVAL;
1439 if (ice_dpll_is_reset(pf, extack))
1440 return -EBUSY;
1441
1442 mutex_lock(&pf->dplls.lock);
1443 ret = ice_dpll_hw_input_prio_set(pf, d, p->input, prio, extack);
1444 mutex_unlock(&pf->dplls.lock);
1445
1446 return ret;
1447 }
1448
1449 /**
1450 * ice_dpll_input_direction - callback for get input pin direction
1451 * @pin: pointer to a pin
1452 * @pin_priv: private data pointer passed on pin registration
1453 * @dpll: registered dpll pointer
1454 * @dpll_priv: private data pointer passed on dpll registration
1455 * @direction: holds input pin direction
1456 * @extack: error reporting
1457 *
1458 * Dpll subsystem callback. Handler for getting direction of a input pin.
1459 *
1460 * Return:
1461 * * 0 - success
1462 */
1463 static int
ice_dpll_input_direction(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1464 ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
1465 const struct dpll_device *dpll, void *dpll_priv,
1466 enum dpll_pin_direction *direction,
1467 struct netlink_ext_ack *extack)
1468 {
1469 *direction = DPLL_PIN_DIRECTION_INPUT;
1470
1471 return 0;
1472 }
1473
1474 /**
1475 * ice_dpll_output_direction - callback for get output pin direction
1476 * @pin: pointer to a pin
1477 * @pin_priv: private data pointer passed on pin registration
1478 * @dpll: registered dpll pointer
1479 * @dpll_priv: private data pointer passed on dpll registration
1480 * @direction: holds output pin direction
1481 * @extack: error reporting
1482 *
1483 * Dpll subsystem callback. Handler for getting direction of an output pin.
1484 *
1485 * Return:
1486 * * 0 - success
1487 */
1488 static int
ice_dpll_output_direction(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1489 ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
1490 const struct dpll_device *dpll, void *dpll_priv,
1491 enum dpll_pin_direction *direction,
1492 struct netlink_ext_ack *extack)
1493 {
1494 *direction = DPLL_PIN_DIRECTION_OUTPUT;
1495
1496 return 0;
1497 }
1498
1499 /**
1500 * ice_dpll_pin_sma_direction_set - callback for set SMA pin direction
1501 * @pin: pointer to a pin
1502 * @pin_priv: private data pointer passed on pin registration
1503 * @dpll: registered dpll pointer
1504 * @dpll_priv: private data pointer passed on dpll registration
1505 * @direction: requested pin direction
1506 * @extack: error reporting
1507 *
1508 * Dpll subsystem callback. Handler for setting direction of a SMA pin.
1509 *
1510 * Context: Acquires and releases pf->dplls.lock
1511 * Return:
1512 * * 0 - success
1513 * * negative - error
1514 */
1515 static int
ice_dpll_pin_sma_direction_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1516 ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
1517 const struct dpll_device *dpll, void *dpll_priv,
1518 enum dpll_pin_direction direction,
1519 struct netlink_ext_ack *extack)
1520 {
1521 struct ice_dpll_pin *p = pin_priv;
1522 struct ice_pf *pf = p->pf;
1523 int ret;
1524
1525 if (ice_dpll_is_reset(pf, extack))
1526 return -EBUSY;
1527
1528 mutex_lock(&pf->dplls.lock);
1529 ret = ice_dpll_sma_direction_set(p, direction, extack);
1530 mutex_unlock(&pf->dplls.lock);
1531
1532 return ret;
1533 }
1534
1535 /**
1536 * ice_dpll_pin_sw_direction_get - callback for get SW pin direction
1537 * @pin: pointer to a pin
1538 * @pin_priv: private data pointer passed on pin registration
1539 * @dpll: registered dpll pointer
1540 * @dpll_priv: private data pointer passed on dpll registration
1541 * @direction: on success holds pin direction
1542 * @extack: error reporting
1543 *
1544 * Dpll subsystem callback. Handler for getting direction of a SMA pin.
1545 *
1546 * Context: Acquires and releases pf->dplls.lock
1547 * Return:
1548 * * 0 - success
1549 * * negative - error
1550 */
1551 static int
ice_dpll_pin_sw_direction_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1552 ice_dpll_pin_sw_direction_get(const struct dpll_pin *pin, void *pin_priv,
1553 const struct dpll_device *dpll, void *dpll_priv,
1554 enum dpll_pin_direction *direction,
1555 struct netlink_ext_ack *extack)
1556 {
1557 struct ice_dpll_pin *p = pin_priv;
1558 struct ice_pf *pf = p->pf;
1559
1560 if (ice_dpll_is_reset(pf, extack))
1561 return -EBUSY;
1562 mutex_lock(&pf->dplls.lock);
1563 *direction = p->direction;
1564 mutex_unlock(&pf->dplls.lock);
1565
1566 return 0;
1567 }
1568
1569 /**
1570 * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
1571 * @pin: pointer to a pin
1572 * @pin_priv: private data pointer passed on pin registration
1573 * @dpll: registered dpll pointer
1574 * @dpll_priv: private data pointer passed on dpll registration
1575 * @phase_adjust: on success holds pin phase_adjust value
1576 * @extack: error reporting
1577 *
1578 * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
1579 *
1580 * Context: Acquires pf->dplls.lock
1581 * Return:
1582 * * 0 - success
1583 * * negative - error
1584 */
1585 static int
ice_dpll_pin_phase_adjust_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 * phase_adjust,struct netlink_ext_ack * extack)1586 ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1587 const struct dpll_device *dpll, void *dpll_priv,
1588 s32 *phase_adjust,
1589 struct netlink_ext_ack *extack)
1590 {
1591 struct ice_dpll_pin *p = pin_priv;
1592 struct ice_pf *pf = p->pf;
1593
1594 mutex_lock(&pf->dplls.lock);
1595 *phase_adjust = p->phase_adjust;
1596 mutex_unlock(&pf->dplls.lock);
1597
1598 return 0;
1599 }
1600
1601 /**
1602 * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
1603 * @pin: pointer to a pin
1604 * @pin_priv: private data pointer passed on pin registration
1605 * @dpll: registered dpll pointer
1606 * @dpll_priv: private data pointer passed on dpll registration
1607 * @phase_adjust: phase_adjust to be set
1608 * @extack: error reporting
1609 * @type: type of a pin
1610 *
1611 * Helper for dpll subsystem callback. Handler for setting phase adjust value
1612 * of a pin.
1613 *
1614 * Context: Acquires pf->dplls.lock
1615 * Return:
1616 * * 0 - success
1617 * * negative - error
1618 */
1619 static int
ice_dpll_pin_phase_adjust_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 phase_adjust,struct netlink_ext_ack * extack,enum ice_dpll_pin_type type)1620 ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1621 const struct dpll_device *dpll, void *dpll_priv,
1622 s32 phase_adjust,
1623 struct netlink_ext_ack *extack,
1624 enum ice_dpll_pin_type type)
1625 {
1626 struct ice_dpll_pin *p = pin_priv;
1627 struct ice_dpll *d = dpll_priv;
1628 struct ice_pf *pf = d->pf;
1629 u8 flag, flags_en = 0;
1630 int ret;
1631
1632 if (ice_dpll_is_reset(pf, extack))
1633 return -EBUSY;
1634
1635 mutex_lock(&pf->dplls.lock);
1636 switch (type) {
1637 case ICE_DPLL_PIN_TYPE_INPUT:
1638 flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
1639 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
1640 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1641 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
1642 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
1643 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
1644 0, phase_adjust);
1645 break;
1646 case ICE_DPLL_PIN_TYPE_OUTPUT:
1647 flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
1648 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1649 flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1650 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
1651 flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1652 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
1653 phase_adjust);
1654 break;
1655 default:
1656 ret = -EINVAL;
1657 }
1658 if (!ret)
1659 p->phase_adjust = phase_adjust;
1660 mutex_unlock(&pf->dplls.lock);
1661 if (ret)
1662 NL_SET_ERR_MSG_FMT(extack,
1663 "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u",
1664 ret,
1665 libie_aq_str(pf->hw.adminq.sq_last_status),
1666 phase_adjust, p->idx, d->dpll_idx);
1667
1668 return ret;
1669 }
1670
1671 /**
1672 * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
1673 * @pin: pointer to a pin
1674 * @pin_priv: private data pointer passed on pin registration
1675 * @dpll: registered dpll pointer
1676 * @dpll_priv: private data pointer passed on dpll registration
1677 * @phase_adjust: phase_adjust to be set
1678 * @extack: error reporting
1679 *
1680 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
1681 * pin.
1682 *
1683 * Context: Calls a function which acquires and releases pf->dplls.lock
1684 * Return:
1685 * * 0 - success
1686 * * negative - error
1687 */
1688 static int
ice_dpll_input_phase_adjust_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 phase_adjust,struct netlink_ext_ack * extack)1689 ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1690 const struct dpll_device *dpll, void *dpll_priv,
1691 s32 phase_adjust,
1692 struct netlink_ext_ack *extack)
1693 {
1694 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1695 phase_adjust, extack,
1696 ICE_DPLL_PIN_TYPE_INPUT);
1697 }
1698
1699 /**
1700 * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1701 * @pin: pointer to a pin
1702 * @pin_priv: private data pointer passed on pin registration
1703 * @dpll: registered dpll pointer
1704 * @dpll_priv: private data pointer passed on dpll registration
1705 * @phase_adjust: phase_adjust to be set
1706 * @extack: error reporting
1707 *
1708 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1709 * pin.
1710 *
1711 * Context: Calls a function which acquires pf->dplls.lock
1712 * Return:
1713 * * 0 - success
1714 * * negative - error
1715 */
1716 static int
ice_dpll_output_phase_adjust_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 phase_adjust,struct netlink_ext_ack * extack)1717 ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1718 const struct dpll_device *dpll, void *dpll_priv,
1719 s32 phase_adjust,
1720 struct netlink_ext_ack *extack)
1721 {
1722 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1723 phase_adjust, extack,
1724 ICE_DPLL_PIN_TYPE_OUTPUT);
1725 }
1726
1727 /**
1728 * ice_dpll_sw_phase_adjust_get - callback for get SW pin phase adjust
1729 * @pin: pointer to a pin
1730 * @pin_priv: private data pointer passed on pin registration
1731 * @dpll: registered dpll pointer
1732 * @dpll_priv: private data pointer passed on dpll registration
1733 * @phase_adjust: on success holds phase adjust value
1734 * @extack: error reporting
1735 *
1736 * Dpll subsystem callback. Wraps a handler for getting phase adjust on sw
1737 * pin.
1738 *
1739 * Context: Calls a function which acquires and releases pf->dplls.lock
1740 * Return:
1741 * * 0 - success
1742 * * negative - error
1743 */
1744 static int
ice_dpll_sw_phase_adjust_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 * phase_adjust,struct netlink_ext_ack * extack)1745 ice_dpll_sw_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1746 const struct dpll_device *dpll, void *dpll_priv,
1747 s32 *phase_adjust,
1748 struct netlink_ext_ack *extack)
1749 {
1750 struct ice_dpll_pin *p = pin_priv;
1751
1752 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1753 return ice_dpll_pin_phase_adjust_get(p->input->pin, p->input,
1754 dpll, dpll_priv,
1755 phase_adjust, extack);
1756 else
1757 return ice_dpll_pin_phase_adjust_get(p->output->pin, p->output,
1758 dpll, dpll_priv,
1759 phase_adjust, extack);
1760 }
1761
1762 /**
1763 * ice_dpll_sw_phase_adjust_set - callback for set SW pin phase adjust value
1764 * @pin: pointer to a pin
1765 * @pin_priv: private data pointer passed on pin registration
1766 * @dpll: registered dpll pointer
1767 * @dpll_priv: private data pointer passed on dpll registration
1768 * @phase_adjust: phase_adjust to be set
1769 * @extack: error reporting
1770 *
1771 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1772 * pin.
1773 *
1774 * Context: Calls a function which acquires and releases pf->dplls.lock
1775 * Return:
1776 * * 0 - success
1777 * * negative - error
1778 */
1779 static int
ice_dpll_sw_phase_adjust_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s32 phase_adjust,struct netlink_ext_ack * extack)1780 ice_dpll_sw_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1781 const struct dpll_device *dpll, void *dpll_priv,
1782 s32 phase_adjust,
1783 struct netlink_ext_ack *extack)
1784 {
1785 struct ice_dpll_pin *p = pin_priv;
1786
1787 if (!p->active) {
1788 NL_SET_ERR_MSG(extack, "pin is not active");
1789 return -EINVAL;
1790 }
1791 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1792 return ice_dpll_pin_phase_adjust_set(p->input->pin, p->input,
1793 dpll, dpll_priv,
1794 phase_adjust, extack,
1795 ICE_DPLL_PIN_TYPE_INPUT);
1796 else
1797 return ice_dpll_pin_phase_adjust_set(p->output->pin, p->output,
1798 dpll, dpll_priv,
1799 phase_adjust, extack,
1800 ICE_DPLL_PIN_TYPE_OUTPUT);
1801 }
1802
1803 #define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1804 #define ICE_DPLL_PHASE_OFFSET_FACTOR \
1805 (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1806 /**
1807 * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1808 * @pin: pointer to a pin
1809 * @pin_priv: private data pointer passed on pin registration
1810 * @dpll: registered dpll pointer
1811 * @dpll_priv: private data pointer passed on dpll registration
1812 * @phase_offset: on success holds pin phase_offset value
1813 * @extack: error reporting
1814 *
1815 * Dpll subsystem callback. Handler for getting phase shift value between
1816 * dpll's input and output.
1817 *
1818 * Context: Acquires pf->dplls.lock
1819 * Return:
1820 * * 0 - success
1821 * * negative - error
1822 */
1823 static int
ice_dpll_phase_offset_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,s64 * phase_offset,struct netlink_ext_ack * extack)1824 ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1825 const struct dpll_device *dpll, void *dpll_priv,
1826 s64 *phase_offset, struct netlink_ext_ack *extack)
1827 {
1828 struct ice_dpll_pin *p = pin_priv;
1829 struct ice_dpll *d = dpll_priv;
1830 struct ice_pf *pf = d->pf;
1831
1832 mutex_lock(&pf->dplls.lock);
1833 if (d->active_input == pin || (p->input &&
1834 d->active_input == p->input->pin))
1835 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1836 else if (d->phase_offset_monitor_period)
1837 *phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1838 else
1839 *phase_offset = 0;
1840 mutex_unlock(&pf->dplls.lock);
1841
1842 return 0;
1843 }
1844
1845 /**
1846 * ice_dpll_output_esync_set - callback for setting embedded sync
1847 * @pin: pointer to a pin
1848 * @pin_priv: private data pointer passed on pin registration
1849 * @dpll: registered dpll pointer
1850 * @dpll_priv: private data pointer passed on dpll registration
1851 * @freq: requested embedded sync frequency
1852 * @extack: error reporting
1853 *
1854 * Dpll subsystem callback. Handler for setting embedded sync frequency value
1855 * on output pin.
1856 *
1857 * Context: Acquires pf->dplls.lock
1858 * Return:
1859 * * 0 - success
1860 * * negative - error
1861 */
1862 static int
ice_dpll_output_esync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 freq,struct netlink_ext_ack * extack)1863 ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
1864 const struct dpll_device *dpll, void *dpll_priv,
1865 u64 freq, struct netlink_ext_ack *extack)
1866 {
1867 struct ice_dpll_pin *p = pin_priv;
1868 struct ice_dpll *d = dpll_priv;
1869 struct ice_pf *pf = d->pf;
1870 u8 flags = 0;
1871 int ret;
1872
1873 if (ice_dpll_is_reset(pf, extack))
1874 return -EBUSY;
1875 mutex_lock(&pf->dplls.lock);
1876 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1877 flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1878 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
1879 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
1880 ret = 0;
1881 } else {
1882 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1883 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
1884 0, 0, 0);
1885 }
1886 } else {
1887 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
1888 ret = 0;
1889 } else {
1890 flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1891 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
1892 0, 0, 0);
1893 }
1894 }
1895 mutex_unlock(&pf->dplls.lock);
1896
1897 return ret;
1898 }
1899
1900 /**
1901 * ice_dpll_output_esync_get - callback for getting embedded sync config
1902 * @pin: pointer to a pin
1903 * @pin_priv: private data pointer passed on pin registration
1904 * @dpll: registered dpll pointer
1905 * @dpll_priv: private data pointer passed on dpll registration
1906 * @esync: on success holds embedded sync pin properties
1907 * @extack: error reporting
1908 *
1909 * Dpll subsystem callback. Handler for getting embedded sync frequency value
1910 * and capabilities on output pin.
1911 *
1912 * Context: Acquires pf->dplls.lock
1913 * Return:
1914 * * 0 - success
1915 * * negative - error
1916 */
1917 static int
ice_dpll_output_esync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,struct dpll_pin_esync * esync,struct netlink_ext_ack * extack)1918 ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
1919 const struct dpll_device *dpll, void *dpll_priv,
1920 struct dpll_pin_esync *esync,
1921 struct netlink_ext_ack *extack)
1922 {
1923 struct ice_dpll_pin *p = pin_priv;
1924 struct ice_dpll *d = dpll_priv;
1925 struct ice_pf *pf = d->pf;
1926
1927 if (ice_dpll_is_reset(pf, extack))
1928 return -EBUSY;
1929 mutex_lock(&pf->dplls.lock);
1930 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
1931 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
1932 mutex_unlock(&pf->dplls.lock);
1933 return -EOPNOTSUPP;
1934 }
1935 esync->range = ice_esync_range;
1936 esync->range_num = ARRAY_SIZE(ice_esync_range);
1937 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
1938 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
1939 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
1940 } else {
1941 esync->freq = 0;
1942 esync->pulse = 0;
1943 }
1944 mutex_unlock(&pf->dplls.lock);
1945
1946 return 0;
1947 }
1948
1949 /**
1950 * ice_dpll_input_esync_set - callback for setting embedded sync
1951 * @pin: pointer to a pin
1952 * @pin_priv: private data pointer passed on pin registration
1953 * @dpll: registered dpll pointer
1954 * @dpll_priv: private data pointer passed on dpll registration
1955 * @freq: requested embedded sync frequency
1956 * @extack: error reporting
1957 *
1958 * Dpll subsystem callback. Handler for setting embedded sync frequency value
1959 * on input pin.
1960 *
1961 * Context: Acquires pf->dplls.lock
1962 * Return:
1963 * * 0 - success
1964 * * negative - error
1965 */
1966 static int
ice_dpll_input_esync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 freq,struct netlink_ext_ack * extack)1967 ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
1968 const struct dpll_device *dpll, void *dpll_priv,
1969 u64 freq, struct netlink_ext_ack *extack)
1970 {
1971 struct ice_dpll_pin *p = pin_priv;
1972 struct ice_dpll *d = dpll_priv;
1973 struct ice_pf *pf = d->pf;
1974 u8 flags_en = 0;
1975 int ret;
1976
1977 if (ice_dpll_is_reset(pf, extack))
1978 return -EBUSY;
1979 mutex_lock(&pf->dplls.lock);
1980 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
1981 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
1982 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
1983 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
1984 ret = 0;
1985 } else {
1986 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1987 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
1988 flags_en, 0, 0);
1989 }
1990 } else {
1991 if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
1992 ret = 0;
1993 } else {
1994 flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1995 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
1996 flags_en, 0, 0);
1997 }
1998 }
1999 mutex_unlock(&pf->dplls.lock);
2000
2001 return ret;
2002 }
2003
2004 /**
2005 * ice_dpll_input_esync_get - callback for getting embedded sync config
2006 * @pin: pointer to a pin
2007 * @pin_priv: private data pointer passed on pin registration
2008 * @dpll: registered dpll pointer
2009 * @dpll_priv: private data pointer passed on dpll registration
2010 * @esync: on success holds embedded sync pin properties
2011 * @extack: error reporting
2012 *
2013 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2014 * and capabilities on input pin.
2015 *
2016 * Context: Acquires pf->dplls.lock
2017 * Return:
2018 * * 0 - success
2019 * * negative - error
2020 */
2021 static int
ice_dpll_input_esync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,struct dpll_pin_esync * esync,struct netlink_ext_ack * extack)2022 ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
2023 const struct dpll_device *dpll, void *dpll_priv,
2024 struct dpll_pin_esync *esync,
2025 struct netlink_ext_ack *extack)
2026 {
2027 struct ice_dpll_pin *p = pin_priv;
2028 struct ice_dpll *d = dpll_priv;
2029 struct ice_pf *pf = d->pf;
2030
2031 if (ice_dpll_is_reset(pf, extack))
2032 return -EBUSY;
2033 mutex_lock(&pf->dplls.lock);
2034 if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
2035 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2036 mutex_unlock(&pf->dplls.lock);
2037 return -EOPNOTSUPP;
2038 }
2039 esync->range = ice_esync_range;
2040 esync->range_num = ARRAY_SIZE(ice_esync_range);
2041 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2042 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2043 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2044 } else {
2045 esync->freq = 0;
2046 esync->pulse = 0;
2047 }
2048 mutex_unlock(&pf->dplls.lock);
2049
2050 return 0;
2051 }
2052
2053 /**
2054 * ice_dpll_sw_esync_set - callback for setting embedded sync on SW pin
2055 * @pin: pointer to a pin
2056 * @pin_priv: private data pointer passed on pin registration
2057 * @dpll: registered dpll pointer
2058 * @dpll_priv: private data pointer passed on dpll registration
2059 * @freq: requested embedded sync frequency
2060 * @extack: error reporting
2061 *
2062 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2063 * on SW pin.
2064 *
2065 * Context: Calls a function which acquires and releases pf->dplls.lock
2066 * Return:
2067 * * 0 - success
2068 * * negative - error
2069 */
2070 static int
ice_dpll_sw_esync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 freq,struct netlink_ext_ack * extack)2071 ice_dpll_sw_esync_set(const struct dpll_pin *pin, void *pin_priv,
2072 const struct dpll_device *dpll, void *dpll_priv,
2073 u64 freq, struct netlink_ext_ack *extack)
2074 {
2075 struct ice_dpll_pin *p = pin_priv;
2076
2077 if (!p->active) {
2078 NL_SET_ERR_MSG(extack, "pin is not active");
2079 return -EINVAL;
2080 }
2081 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2082 return ice_dpll_input_esync_set(p->input->pin, p->input, dpll,
2083 dpll_priv, freq, extack);
2084 else
2085 return ice_dpll_output_esync_set(p->output->pin, p->output,
2086 dpll, dpll_priv, freq, extack);
2087 }
2088
2089 /**
2090 * ice_dpll_sw_esync_get - callback for getting embedded sync on SW pin
2091 * @pin: pointer to a pin
2092 * @pin_priv: private data pointer passed on pin registration
2093 * @dpll: registered dpll pointer
2094 * @dpll_priv: private data pointer passed on dpll registration
2095 * @esync: on success holds embedded sync frequency and properties
2096 * @extack: error reporting
2097 *
2098 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2099 * of SW pin.
2100 *
2101 * Context: Calls a function which acquires and releases pf->dplls.lock
2102 * Return:
2103 * * 0 - success
2104 * * negative - error
2105 */
2106 static int
ice_dpll_sw_esync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,struct dpll_pin_esync * esync,struct netlink_ext_ack * extack)2107 ice_dpll_sw_esync_get(const struct dpll_pin *pin, void *pin_priv,
2108 const struct dpll_device *dpll, void *dpll_priv,
2109 struct dpll_pin_esync *esync,
2110 struct netlink_ext_ack *extack)
2111 {
2112 struct ice_dpll_pin *p = pin_priv;
2113
2114 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2115 return ice_dpll_input_esync_get(p->input->pin, p->input, dpll,
2116 dpll_priv, esync, extack);
2117 else
2118 return ice_dpll_output_esync_get(p->output->pin, p->output,
2119 dpll, dpll_priv, esync,
2120 extack);
2121 }
2122
2123 /*
2124 * ice_dpll_input_ref_sync_set - callback for setting reference sync feature
2125 * @pin: pointer to a pin
2126 * @pin_priv: private data pointer passed on pin registration
2127 * @ref_pin: pin pointer for reference sync pair
2128 * @ref_pin_priv: private data pointer of ref_pin
2129 * @state: requested state for reference sync for pin pair
2130 * @extack: error reporting
2131 *
2132 * Dpll subsystem callback. Handler for setting reference sync frequency
2133 * feature for input pin.
2134 *
2135 * Context: Acquires and releases pf->dplls.lock
2136 * Return:
2137 * * 0 - success
2138 * * negative - error
2139 */
2140 static int
ice_dpll_input_ref_sync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,const enum dpll_pin_state state,struct netlink_ext_ack * extack)2141 ice_dpll_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2142 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2143 const enum dpll_pin_state state,
2144 struct netlink_ext_ack *extack)
2145 {
2146 struct ice_dpll_pin *p = pin_priv;
2147 struct ice_pf *pf = p->pf;
2148 u8 flags_en = 0;
2149 int ret;
2150
2151 if (ice_dpll_is_reset(pf, extack))
2152 return -EBUSY;
2153 mutex_lock(&pf->dplls.lock);
2154
2155 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2156 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2157 if (state == DPLL_PIN_STATE_CONNECTED)
2158 flags_en |= ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN;
2159 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, flags_en, 0, 0);
2160 if (!ret)
2161 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT,
2162 extack);
2163 mutex_unlock(&pf->dplls.lock);
2164
2165 return ret;
2166 }
2167
2168 /**
2169 * ice_dpll_input_ref_sync_get - callback for getting reference sync config
2170 * @pin: pointer to a pin
2171 * @pin_priv: private data pointer passed on pin registration
2172 * @ref_pin: pin pointer for reference sync pair
2173 * @ref_pin_priv: private data pointer of ref_pin
2174 * @state: on success holds reference sync state for pin pair
2175 * @extack: error reporting
2176 *
2177 * Dpll subsystem callback. Handler for setting reference sync frequency
2178 * feature for input pin.
2179 *
2180 * Context: Acquires and releases pf->dplls.lock
2181 * Return:
2182 * * 0 - success
2183 * * negative - error
2184 */
2185 static int
ice_dpll_input_ref_sync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2186 ice_dpll_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2187 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2188 enum dpll_pin_state *state,
2189 struct netlink_ext_ack *extack)
2190 {
2191 struct ice_dpll_pin *p = pin_priv;
2192 struct ice_pf *pf = p->pf;
2193
2194 if (ice_dpll_is_reset(pf, extack))
2195 return -EBUSY;
2196 mutex_lock(&pf->dplls.lock);
2197 if (p->flags[0] & ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN)
2198 *state = DPLL_PIN_STATE_CONNECTED;
2199 else
2200 *state = DPLL_PIN_STATE_DISCONNECTED;
2201 mutex_unlock(&pf->dplls.lock);
2202
2203 return 0;
2204 }
2205
2206 /*
2207 * ice_dpll_sw_input_ref_sync_set - callback for setting reference sync feature
2208 * @pin: pointer to a pin
2209 * @pin_priv: private data pointer passed on pin registration
2210 * @ref_pin: pin pointer for reference sync pair
2211 * @ref_pin_priv: private data pointer of ref_pin
2212 * @state: requested state for reference sync for pin pair
2213 * @extack: error reporting
2214 *
2215 * Dpll subsystem callback. Handler for setting reference sync
2216 * feature for input pins.
2217 *
2218 * Context: Calls a function which acquires and releases pf->dplls.lock
2219 * Return:
2220 * * 0 - success
2221 * * negative - error
2222 */
2223 static int
ice_dpll_sw_input_ref_sync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,const enum dpll_pin_state state,struct netlink_ext_ack * extack)2224 ice_dpll_sw_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2225 const struct dpll_pin *ref_pin,
2226 void *ref_pin_priv,
2227 const enum dpll_pin_state state,
2228 struct netlink_ext_ack *extack)
2229 {
2230 struct ice_dpll_pin *p = pin_priv;
2231
2232 return ice_dpll_input_ref_sync_set(pin, p->input, ref_pin, ref_pin_priv,
2233 state, extack);
2234 }
2235
2236 /**
2237 * ice_dpll_sw_input_ref_sync_get - callback for getting reference sync config
2238 * @pin: pointer to a pin
2239 * @pin_priv: private data pointer passed on pin registration
2240 * @ref_pin: pin pointer for reference sync pair
2241 * @ref_pin_priv: private data pointer of ref_pin
2242 * @state: on success holds reference sync state for pin pair
2243 * @extack: error reporting
2244 *
2245 * Dpll subsystem callback. Handler for setting reference sync feature for
2246 * input pins.
2247 *
2248 * Context: Calls a function which acquires and releases pf->dplls.lock
2249 * Return:
2250 * * 0 - success
2251 * * negative - error
2252 */
2253 static int
ice_dpll_sw_input_ref_sync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2254 ice_dpll_sw_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2255 const struct dpll_pin *ref_pin,
2256 void *ref_pin_priv,
2257 enum dpll_pin_state *state,
2258 struct netlink_ext_ack *extack)
2259 {
2260 struct ice_dpll_pin *p = pin_priv;
2261
2262 return ice_dpll_input_ref_sync_get(pin, p->input, ref_pin, ref_pin_priv,
2263 state, extack);
2264 }
2265
2266 /**
2267 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
2268 * @pin: pointer to a pin
2269 * @pin_priv: private data pointer passed on pin registration
2270 * @parent_pin: pin parent pointer
2271 * @parent_pin_priv: parent private data pointer passed on pin registration
2272 * @state: state to be set on pin
2273 * @extack: error reporting
2274 *
2275 * Dpll subsystem callback, set a state of a rclk pin on a parent pin
2276 *
2277 * Context: Acquires pf->dplls.lock
2278 * Return:
2279 * * 0 - success
2280 * * negative - failure
2281 */
2282 static int
ice_dpll_rclk_state_on_pin_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * parent_pin,void * parent_pin_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)2283 ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
2284 const struct dpll_pin *parent_pin,
2285 void *parent_pin_priv,
2286 enum dpll_pin_state state,
2287 struct netlink_ext_ack *extack)
2288 {
2289 struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
2290 bool enable = state == DPLL_PIN_STATE_CONNECTED;
2291 struct ice_pf *pf = p->pf;
2292 int ret = -EINVAL;
2293 u32 hw_idx;
2294
2295 if (ice_dpll_is_reset(pf, extack))
2296 return -EBUSY;
2297
2298 mutex_lock(&pf->dplls.lock);
2299 hw_idx = parent->idx - pf->dplls.base_rclk_idx;
2300 if (hw_idx >= pf->dplls.num_inputs)
2301 goto unlock;
2302
2303 if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
2304 (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
2305 NL_SET_ERR_MSG_FMT(extack,
2306 "pin:%u state:%u on parent:%u already set",
2307 p->idx, state, parent->idx);
2308 goto unlock;
2309 }
2310 ret = ice_aq_set_phy_rec_clk_out(&pf->hw, hw_idx, enable,
2311 &p->freq);
2312 if (ret)
2313 NL_SET_ERR_MSG_FMT(extack,
2314 "err:%d %s failed to set pin state:%u for pin:%u on parent:%u",
2315 ret,
2316 libie_aq_str(pf->hw.adminq.sq_last_status),
2317 state, p->idx, parent->idx);
2318 unlock:
2319 mutex_unlock(&pf->dplls.lock);
2320
2321 return ret;
2322 }
2323
2324 /**
2325 * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
2326 * @pin: pointer to a pin
2327 * @pin_priv: private data pointer passed on pin registration
2328 * @parent_pin: pin parent pointer
2329 * @parent_pin_priv: pin parent priv data pointer passed on pin registration
2330 * @state: on success holds pin state on parent pin
2331 * @extack: error reporting
2332 *
2333 * dpll subsystem callback, get a state of a recovered clock pin.
2334 *
2335 * Context: Acquires pf->dplls.lock
2336 * Return:
2337 * * 0 - success
2338 * * negative - failure
2339 */
2340 static int
ice_dpll_rclk_state_on_pin_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * parent_pin,void * parent_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2341 ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
2342 const struct dpll_pin *parent_pin,
2343 void *parent_pin_priv,
2344 enum dpll_pin_state *state,
2345 struct netlink_ext_ack *extack)
2346 {
2347 struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
2348 struct ice_pf *pf = p->pf;
2349 int ret = -EINVAL;
2350 u32 hw_idx;
2351
2352 if (ice_dpll_is_reset(pf, extack))
2353 return -EBUSY;
2354
2355 mutex_lock(&pf->dplls.lock);
2356 hw_idx = parent->idx - pf->dplls.base_rclk_idx;
2357 if (hw_idx >= pf->dplls.num_inputs)
2358 goto unlock;
2359
2360 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
2361 extack);
2362 if (ret)
2363 goto unlock;
2364
2365 *state = p->state[hw_idx];
2366 ret = 0;
2367 unlock:
2368 mutex_unlock(&pf->dplls.lock);
2369
2370 return ret;
2371 }
2372
2373 static const struct dpll_pin_ops ice_dpll_rclk_ops = {
2374 .state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
2375 .state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
2376 .direction_get = ice_dpll_input_direction,
2377 };
2378
2379 static const struct dpll_pin_ops ice_dpll_pin_sma_ops = {
2380 .state_on_dpll_set = ice_dpll_sma_pin_state_set,
2381 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2382 .direction_get = ice_dpll_pin_sw_direction_get,
2383 .direction_set = ice_dpll_pin_sma_direction_set,
2384 .prio_get = ice_dpll_sw_input_prio_get,
2385 .prio_set = ice_dpll_sw_input_prio_set,
2386 .frequency_get = ice_dpll_sw_pin_frequency_get,
2387 .frequency_set = ice_dpll_sw_pin_frequency_set,
2388 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2389 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2390 .phase_offset_get = ice_dpll_phase_offset_get,
2391 .esync_set = ice_dpll_sw_esync_set,
2392 .esync_get = ice_dpll_sw_esync_get,
2393 .ref_sync_set = ice_dpll_sw_input_ref_sync_set,
2394 .ref_sync_get = ice_dpll_sw_input_ref_sync_get,
2395 };
2396
2397 static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
2398 .state_on_dpll_set = ice_dpll_ufl_pin_state_set,
2399 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2400 .direction_get = ice_dpll_pin_sw_direction_get,
2401 .frequency_get = ice_dpll_sw_pin_frequency_get,
2402 .frequency_set = ice_dpll_sw_pin_frequency_set,
2403 .esync_set = ice_dpll_sw_esync_set,
2404 .esync_get = ice_dpll_sw_esync_get,
2405 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2406 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2407 .phase_offset_get = ice_dpll_phase_offset_get,
2408 };
2409
2410 static const struct dpll_pin_ops ice_dpll_input_ops = {
2411 .frequency_get = ice_dpll_input_frequency_get,
2412 .frequency_set = ice_dpll_input_frequency_set,
2413 .state_on_dpll_get = ice_dpll_input_state_get,
2414 .state_on_dpll_set = ice_dpll_input_state_set,
2415 .prio_get = ice_dpll_input_prio_get,
2416 .prio_set = ice_dpll_input_prio_set,
2417 .direction_get = ice_dpll_input_direction,
2418 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2419 .phase_adjust_set = ice_dpll_input_phase_adjust_set,
2420 .phase_offset_get = ice_dpll_phase_offset_get,
2421 .esync_set = ice_dpll_input_esync_set,
2422 .esync_get = ice_dpll_input_esync_get,
2423 .ref_sync_set = ice_dpll_input_ref_sync_set,
2424 .ref_sync_get = ice_dpll_input_ref_sync_get,
2425 };
2426
2427 static const struct dpll_pin_ops ice_dpll_output_ops = {
2428 .frequency_get = ice_dpll_output_frequency_get,
2429 .frequency_set = ice_dpll_output_frequency_set,
2430 .state_on_dpll_get = ice_dpll_output_state_get,
2431 .state_on_dpll_set = ice_dpll_output_state_set,
2432 .direction_get = ice_dpll_output_direction,
2433 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2434 .phase_adjust_set = ice_dpll_output_phase_adjust_set,
2435 .esync_set = ice_dpll_output_esync_set,
2436 .esync_get = ice_dpll_output_esync_get,
2437 };
2438
2439 static const struct dpll_device_ops ice_dpll_ops = {
2440 .lock_status_get = ice_dpll_lock_status_get,
2441 .mode_get = ice_dpll_mode_get,
2442 };
2443
2444 static const struct dpll_device_ops ice_dpll_pom_ops = {
2445 .lock_status_get = ice_dpll_lock_status_get,
2446 .mode_get = ice_dpll_mode_get,
2447 .phase_offset_monitor_set = ice_dpll_phase_offset_monitor_set,
2448 .phase_offset_monitor_get = ice_dpll_phase_offset_monitor_get,
2449 };
2450
2451 /**
2452 * ice_generate_clock_id - generates unique clock_id for registering dpll.
2453 * @pf: board private structure
2454 *
2455 * Generates unique (per board) clock_id for allocation and search of dpll
2456 * devices in Linux dpll subsystem.
2457 *
2458 * Return: generated clock id for the board
2459 */
ice_generate_clock_id(struct ice_pf * pf)2460 static u64 ice_generate_clock_id(struct ice_pf *pf)
2461 {
2462 return pci_get_dsn(pf->pdev);
2463 }
2464
2465 /**
2466 * ice_dpll_notify_changes - notify dpll subsystem about changes
2467 * @d: pointer do dpll
2468 *
2469 * Once change detected appropriate event is submitted to the dpll subsystem.
2470 */
ice_dpll_notify_changes(struct ice_dpll * d)2471 static void ice_dpll_notify_changes(struct ice_dpll *d)
2472 {
2473 bool pin_notified = false;
2474
2475 if (d->prev_dpll_state != d->dpll_state) {
2476 d->prev_dpll_state = d->dpll_state;
2477 dpll_device_change_ntf(d->dpll);
2478 }
2479 if (d->prev_input != d->active_input) {
2480 if (d->prev_input)
2481 dpll_pin_change_ntf(d->prev_input);
2482 d->prev_input = d->active_input;
2483 if (d->active_input) {
2484 dpll_pin_change_ntf(d->active_input);
2485 pin_notified = true;
2486 }
2487 }
2488 if (d->prev_phase_offset != d->phase_offset) {
2489 d->prev_phase_offset = d->phase_offset;
2490 if (!pin_notified && d->active_input)
2491 dpll_pin_change_ntf(d->active_input);
2492 }
2493 }
2494
2495 /**
2496 * ice_dpll_is_pps_phase_monitor - check if dpll capable of phase offset monitor
2497 * @pf: pf private structure
2498 *
2499 * Check if firmware is capable of supporting admin command to provide
2500 * phase offset monitoring on all the input pins on PPS dpll.
2501 *
2502 * Returns:
2503 * * true - PPS dpll phase offset monitoring is supported
2504 * * false - PPS dpll phase offset monitoring is not supported
2505 */
ice_dpll_is_pps_phase_monitor(struct ice_pf * pf)2506 static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
2507 {
2508 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2509 int ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2510 ARRAY_SIZE(meas));
2511
2512 if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_ESRCH)
2513 return false;
2514
2515 return true;
2516 }
2517
2518 /**
2519 * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
2520 * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
2521 * @pin_num: number of pins
2522 * @phase_offset_ntf_mask: bitmask of pin indexes to notify
2523 *
2524 * Iterate over array of pins and call dpll subsystem pin notify if
2525 * corresponding pin index within bitmask is set.
2526 *
2527 * Context: Must be called while pf->dplls.lock is released.
2528 */
ice_dpll_pins_notify_mask(struct ice_dpll_pin * pins,u8 pin_num,u32 phase_offset_ntf_mask)2529 static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
2530 u8 pin_num,
2531 u32 phase_offset_ntf_mask)
2532 {
2533 int i = 0;
2534
2535 for (i = 0; i < pin_num; i++)
2536 if (phase_offset_ntf_mask & (1 << i))
2537 dpll_pin_change_ntf(pins[i].pin);
2538 }
2539
2540 /**
2541 * ice_dpll_pps_update_phase_offsets - update phase offset measurements
2542 * @pf: pf private structure
2543 * @phase_offset_pins_updated: returns mask of updated input pin indexes
2544 *
2545 * Read phase offset measurements for PPS dpll device and store values in
2546 * input pins array. On success phase_offset_pins_updated - fills bitmask of
2547 * updated input pin indexes, pins shall be notified.
2548 *
2549 * Context: Shall be called with pf->dplls.lock being locked.
2550 * Returns:
2551 * * 0 - success or no data available
2552 * * negative - AQ failure
2553 */
ice_dpll_pps_update_phase_offsets(struct ice_pf * pf,u32 * phase_offset_pins_updated)2554 static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf,
2555 u32 *phase_offset_pins_updated)
2556 {
2557 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2558 struct ice_dpll_pin *p;
2559 s64 phase_offset, tmp;
2560 int i, j, ret;
2561
2562 *phase_offset_pins_updated = 0;
2563 ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2564 ARRAY_SIZE(meas));
2565 if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN) {
2566 return 0;
2567 } else if (ret) {
2568 dev_err(ice_pf_to_dev(pf),
2569 "failed to get input pin measurements dpll=%d, ret=%d %s\n",
2570 DPLL_TYPE_PPS, ret,
2571 libie_aq_str(pf->hw.adminq.sq_last_status));
2572 return ret;
2573 }
2574 for (i = 0; i < pf->dplls.num_inputs; i++) {
2575 p = &pf->dplls.inputs[i];
2576 phase_offset = 0;
2577 for (j = 0; j < ICE_CGU_INPUT_PHASE_OFFSET_BYTES; j++) {
2578 tmp = meas[i].phase_offset[j];
2579 #ifdef __LITTLE_ENDIAN
2580 phase_offset += tmp << 8 * j;
2581 #else
2582 phase_offset += tmp << 8 *
2583 (ICE_CGU_INPUT_PHASE_OFFSET_BYTES - 1 - j);
2584 #endif
2585 }
2586 phase_offset = sign_extend64(phase_offset, 47);
2587 if (p->phase_offset != phase_offset) {
2588 dev_dbg(ice_pf_to_dev(pf),
2589 "phase offset changed for pin:%d old:%llx, new:%llx\n",
2590 p->idx, p->phase_offset, phase_offset);
2591 p->phase_offset = phase_offset;
2592 *phase_offset_pins_updated |= (1 << i);
2593 }
2594 }
2595
2596 return 0;
2597 }
2598
2599 /**
2600 * ice_dpll_update_state - update dpll state
2601 * @pf: pf private structure
2602 * @d: pointer to queried dpll device
2603 * @init: if function called on initialization of ice dpll
2604 *
2605 * Poll current state of dpll from hw and update ice_dpll struct.
2606 *
2607 * Context: Called by kworker under pf->dplls.lock
2608 * Return:
2609 * * 0 - success
2610 * * negative - AQ failure
2611 */
2612 static int
ice_dpll_update_state(struct ice_pf * pf,struct ice_dpll * d,bool init)2613 ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
2614 {
2615 struct ice_dpll_pin *p = NULL;
2616 int ret;
2617
2618 ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
2619 &d->input_idx, &d->ref_state, &d->eec_mode,
2620 &d->phase_offset, &d->dpll_state);
2621
2622 dev_dbg(ice_pf_to_dev(pf),
2623 "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
2624 d->dpll_idx, d->prev_input_idx, d->input_idx,
2625 d->dpll_state, d->prev_dpll_state, d->mode);
2626 if (ret) {
2627 dev_err(ice_pf_to_dev(pf),
2628 "update dpll=%d state failed, ret=%d %s\n",
2629 d->dpll_idx, ret,
2630 libie_aq_str(pf->hw.adminq.sq_last_status));
2631 return ret;
2632 }
2633 if (init) {
2634 if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
2635 d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
2636 d->active_input = pf->dplls.inputs[d->input_idx].pin;
2637 p = &pf->dplls.inputs[d->input_idx];
2638 return ice_dpll_pin_state_update(pf, p,
2639 ICE_DPLL_PIN_TYPE_INPUT, NULL);
2640 }
2641 if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
2642 d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
2643 d->active_input = NULL;
2644 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
2645 p = &pf->dplls.inputs[d->input_idx];
2646 d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
2647 d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
2648 if (!p)
2649 return 0;
2650 ret = ice_dpll_pin_state_update(pf, p,
2651 ICE_DPLL_PIN_TYPE_INPUT, NULL);
2652 } else if (d->input_idx != d->prev_input_idx) {
2653 if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2654 p = &pf->dplls.inputs[d->prev_input_idx];
2655 ice_dpll_pin_state_update(pf, p,
2656 ICE_DPLL_PIN_TYPE_INPUT,
2657 NULL);
2658 }
2659 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2660 p = &pf->dplls.inputs[d->input_idx];
2661 d->active_input = p->pin;
2662 ice_dpll_pin_state_update(pf, p,
2663 ICE_DPLL_PIN_TYPE_INPUT,
2664 NULL);
2665 }
2666 d->prev_input_idx = d->input_idx;
2667 }
2668
2669 return ret;
2670 }
2671
2672 /**
2673 * ice_dpll_periodic_work - DPLLs periodic worker
2674 * @work: pointer to kthread_work structure
2675 *
2676 * DPLLs periodic worker is responsible for polling state of dpll.
2677 * Context: Holds pf->dplls.lock
2678 */
ice_dpll_periodic_work(struct kthread_work * work)2679 static void ice_dpll_periodic_work(struct kthread_work *work)
2680 {
2681 struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
2682 struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
2683 struct ice_dpll *de = &pf->dplls.eec;
2684 struct ice_dpll *dp = &pf->dplls.pps;
2685 u32 phase_offset_ntf = 0;
2686 int ret = 0;
2687
2688 if (ice_is_reset_in_progress(pf->state))
2689 goto resched;
2690 mutex_lock(&pf->dplls.lock);
2691 d->periodic_counter++;
2692 ret = ice_dpll_update_state(pf, de, false);
2693 if (!ret)
2694 ret = ice_dpll_update_state(pf, dp, false);
2695 if (!ret && dp->phase_offset_monitor_period &&
2696 d->periodic_counter % dp->phase_offset_monitor_period == 0)
2697 ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf);
2698 if (ret) {
2699 d->cgu_state_acq_err_num++;
2700 /* stop rescheduling this worker */
2701 if (d->cgu_state_acq_err_num >
2702 ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
2703 dev_err(ice_pf_to_dev(pf),
2704 "EEC/PPS DPLLs periodic work disabled\n");
2705 mutex_unlock(&pf->dplls.lock);
2706 return;
2707 }
2708 }
2709 mutex_unlock(&pf->dplls.lock);
2710 ice_dpll_notify_changes(de);
2711 ice_dpll_notify_changes(dp);
2712 if (phase_offset_ntf)
2713 ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
2714 phase_offset_ntf);
2715
2716 resched:
2717 /* Run twice a second or reschedule if update failed */
2718 kthread_queue_delayed_work(d->kworker, &d->work,
2719 ret ? msecs_to_jiffies(10) :
2720 msecs_to_jiffies(500));
2721 }
2722
2723 /**
2724 * ice_dpll_init_ref_sync_inputs - initialize reference sync pin pairs
2725 * @pf: pf private structure
2726 *
2727 * Read DPLL TLV capabilities and initialize reference sync pin pairs in
2728 * dpll subsystem.
2729 *
2730 * Return:
2731 * * 0 - success or nothing to do (no ref-sync tlv are present)
2732 * * negative - AQ failure
2733 */
ice_dpll_init_ref_sync_inputs(struct ice_pf * pf)2734 static int ice_dpll_init_ref_sync_inputs(struct ice_pf *pf)
2735 {
2736 struct ice_dpll_pin *inputs = pf->dplls.inputs;
2737 struct ice_hw *hw = &pf->hw;
2738 u16 addr, len, end, hdr;
2739 int ret;
2740
2741 ret = ice_get_pfa_module_tlv(hw, &hdr, &len, ICE_SR_PFA_DPLL_DEFAULTS);
2742 if (ret) {
2743 dev_err(ice_pf_to_dev(pf),
2744 "Failed to read PFA dpll defaults TLV ret=%d\n", ret);
2745 return ret;
2746 }
2747 end = hdr + len;
2748
2749 for (addr = hdr + ICE_DPLL_PFA_HEADER_LEN; addr < end;
2750 addr += ICE_DPLL_PFA_ENTRY_LEN) {
2751 unsigned long bit, ul_mask, offset;
2752 u16 pin, mask, buf;
2753 bool valid = false;
2754
2755 ret = ice_read_sr_word(hw, addr, &buf);
2756 if (ret)
2757 return ret;
2758
2759 switch (buf) {
2760 case ICE_DPLL_PFA_REF_SYNC_TYPE:
2761 case ICE_DPLL_PFA_REF_SYNC_TYPE2:
2762 {
2763 u16 mask_addr = addr + ICE_DPLL_PFA_MASK_OFFSET;
2764 u16 val_addr = addr + ICE_DPLL_PFA_VALUE_OFFSET;
2765
2766 ret = ice_read_sr_word(hw, mask_addr, &mask);
2767 if (ret)
2768 return ret;
2769 ret = ice_read_sr_word(hw, val_addr, &pin);
2770 if (ret)
2771 return ret;
2772 if (buf == ICE_DPLL_PFA_REF_SYNC_TYPE)
2773 pin >>= ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S;
2774 valid = true;
2775 break;
2776 }
2777 case ICE_DPLL_PFA_END:
2778 addr = end;
2779 break;
2780 default:
2781 continue;
2782 }
2783 if (!valid)
2784 continue;
2785
2786 ul_mask = mask;
2787 offset = 0;
2788 for_each_set_bit(bit, &ul_mask, BITS_PER_TYPE(u16)) {
2789 int i, j;
2790
2791 if (hw->device_id == ICE_DEV_ID_E810C_SFP &&
2792 pin > ICE_DPLL_E810C_SFP_NC_START)
2793 offset = -ICE_DPLL_E810C_SFP_NC_PINS;
2794 i = pin + offset;
2795 j = bit + offset;
2796 if (i < 0 || j < 0)
2797 return -ERANGE;
2798 inputs[i].ref_sync = j;
2799 }
2800 }
2801
2802 return 0;
2803 }
2804
2805 /**
2806 * ice_dpll_release_pins - release pins resources from dpll subsystem
2807 * @pins: pointer to pins array
2808 * @count: number of pins
2809 *
2810 * Release resources of given pins array in the dpll subsystem.
2811 */
ice_dpll_release_pins(struct ice_dpll_pin * pins,int count)2812 static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
2813 {
2814 int i;
2815
2816 for (i = 0; i < count; i++)
2817 dpll_pin_put(pins[i].pin);
2818 }
2819
2820 /**
2821 * ice_dpll_get_pins - get pins from dpll subsystem
2822 * @pf: board private structure
2823 * @pins: pointer to pins array
2824 * @start_idx: get starts from this pin idx value
2825 * @count: number of pins
2826 * @clock_id: clock_id of dpll device
2827 *
2828 * Get pins - allocate - in dpll subsystem, store them in pin field of given
2829 * pins array.
2830 *
2831 * Return:
2832 * * 0 - success
2833 * * negative - allocation failure reason
2834 */
2835 static int
ice_dpll_get_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx,int count,u64 clock_id)2836 ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
2837 int start_idx, int count, u64 clock_id)
2838 {
2839 int i, ret;
2840
2841 for (i = 0; i < count; i++) {
2842 pins[i].pin = dpll_pin_get(clock_id, i + start_idx, THIS_MODULE,
2843 &pins[i].prop);
2844 if (IS_ERR(pins[i].pin)) {
2845 ret = PTR_ERR(pins[i].pin);
2846 goto release_pins;
2847 }
2848 }
2849
2850 return 0;
2851
2852 release_pins:
2853 while (--i >= 0)
2854 dpll_pin_put(pins[i].pin);
2855 return ret;
2856 }
2857
2858 /**
2859 * ice_dpll_unregister_pins - unregister pins from a dpll
2860 * @dpll: dpll device pointer
2861 * @pins: pointer to pins array
2862 * @ops: callback ops registered with the pins
2863 * @count: number of pins
2864 *
2865 * Unregister pins of a given array of pins from given dpll device registered in
2866 * dpll subsystem.
2867 */
2868 static void
ice_dpll_unregister_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)2869 ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
2870 const struct dpll_pin_ops *ops, int count)
2871 {
2872 int i;
2873
2874 for (i = 0; i < count; i++)
2875 if (!pins[i].hidden)
2876 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
2877 }
2878
2879 /**
2880 * ice_dpll_pin_ref_sync_register - register reference sync pins
2881 * @pins: pointer to pins array
2882 * @count: number of pins
2883 *
2884 * Register reference sync pins in dpll subsystem.
2885 *
2886 * Return:
2887 * * 0 - success
2888 * * negative - registration failure reason
2889 */
2890 static int
ice_dpll_pin_ref_sync_register(struct ice_dpll_pin * pins,int count)2891 ice_dpll_pin_ref_sync_register(struct ice_dpll_pin *pins, int count)
2892 {
2893 int ret, i;
2894
2895 for (i = 0; i < count; i++) {
2896 if (!pins[i].hidden && pins[i].ref_sync) {
2897 int j = pins[i].ref_sync;
2898
2899 ret = dpll_pin_ref_sync_pair_add(pins[i].pin,
2900 pins[j].pin);
2901 if (ret)
2902 return ret;
2903 }
2904 }
2905
2906 return 0;
2907 }
2908
2909 /**
2910 * ice_dpll_register_pins - register pins with a dpll
2911 * @dpll: dpll pointer to register pins with
2912 * @pins: pointer to pins array
2913 * @ops: callback ops registered with the pins
2914 * @count: number of pins
2915 *
2916 * Register pins of a given array with given dpll in dpll subsystem.
2917 *
2918 * Return:
2919 * * 0 - success
2920 * * negative - registration failure reason
2921 */
2922 static int
ice_dpll_register_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)2923 ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
2924 const struct dpll_pin_ops *ops, int count)
2925 {
2926 int ret, i;
2927
2928 for (i = 0; i < count; i++) {
2929 if (!pins[i].hidden) {
2930 ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]);
2931 if (ret)
2932 goto unregister_pins;
2933 }
2934 }
2935
2936 return 0;
2937
2938 unregister_pins:
2939 while (--i >= 0)
2940 if (!pins[i].hidden)
2941 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
2942 return ret;
2943 }
2944
2945 /**
2946 * ice_dpll_deinit_direct_pins - deinitialize direct pins
2947 * @cgu: if cgu is present and controlled by this NIC
2948 * @pins: pointer to pins array
2949 * @count: number of pins
2950 * @ops: callback ops registered with the pins
2951 * @first: dpll device pointer
2952 * @second: dpll device pointer
2953 *
2954 * If cgu is owned unregister pins from given dplls.
2955 * Release pins resources to the dpll subsystem.
2956 */
2957 static void
ice_dpll_deinit_direct_pins(bool cgu,struct ice_dpll_pin * pins,int count,const struct dpll_pin_ops * ops,struct dpll_device * first,struct dpll_device * second)2958 ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count,
2959 const struct dpll_pin_ops *ops,
2960 struct dpll_device *first,
2961 struct dpll_device *second)
2962 {
2963 if (cgu) {
2964 ice_dpll_unregister_pins(first, pins, ops, count);
2965 ice_dpll_unregister_pins(second, pins, ops, count);
2966 }
2967 ice_dpll_release_pins(pins, count);
2968 }
2969
2970 /**
2971 * ice_dpll_init_direct_pins - initialize direct pins
2972 * @pf: board private structure
2973 * @cgu: if cgu is present and controlled by this NIC
2974 * @pins: pointer to pins array
2975 * @start_idx: on which index shall allocation start in dpll subsystem
2976 * @count: number of pins
2977 * @ops: callback ops registered with the pins
2978 * @first: dpll device pointer
2979 * @second: dpll device pointer
2980 *
2981 * Allocate directly connected pins of a given array in dpll subsystem.
2982 * If cgu is owned register allocated pins with given dplls.
2983 *
2984 * Return:
2985 * * 0 - success
2986 * * negative - registration failure reason
2987 */
2988 static int
ice_dpll_init_direct_pins(struct ice_pf * pf,bool cgu,struct ice_dpll_pin * pins,int start_idx,int count,const struct dpll_pin_ops * ops,struct dpll_device * first,struct dpll_device * second)2989 ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
2990 struct ice_dpll_pin *pins, int start_idx, int count,
2991 const struct dpll_pin_ops *ops,
2992 struct dpll_device *first, struct dpll_device *second)
2993 {
2994 int ret;
2995
2996 ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id);
2997 if (ret)
2998 return ret;
2999 if (cgu) {
3000 ret = ice_dpll_register_pins(first, pins, ops, count);
3001 if (ret)
3002 goto release_pins;
3003 ret = ice_dpll_register_pins(second, pins, ops, count);
3004 if (ret)
3005 goto unregister_first;
3006 }
3007
3008 return 0;
3009
3010 unregister_first:
3011 ice_dpll_unregister_pins(first, pins, ops, count);
3012 release_pins:
3013 ice_dpll_release_pins(pins, count);
3014 return ret;
3015 }
3016
3017 /**
3018 * ice_dpll_deinit_rclk_pin - release rclk pin resources
3019 * @pf: board private structure
3020 *
3021 * Deregister rclk pin from parent pins and release resources in dpll subsystem.
3022 */
ice_dpll_deinit_rclk_pin(struct ice_pf * pf)3023 static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
3024 {
3025 struct ice_dpll_pin *rclk = &pf->dplls.rclk;
3026 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3027 struct dpll_pin *parent;
3028 int i;
3029
3030 for (i = 0; i < rclk->num_parents; i++) {
3031 parent = pf->dplls.inputs[rclk->parent_idx[i]].pin;
3032 if (!parent)
3033 continue;
3034 dpll_pin_on_pin_unregister(parent, rclk->pin,
3035 &ice_dpll_rclk_ops, rclk);
3036 }
3037 if (WARN_ON_ONCE(!vsi || !vsi->netdev))
3038 return;
3039 dpll_netdev_pin_clear(vsi->netdev);
3040 dpll_pin_put(rclk->pin);
3041 }
3042
3043 /**
3044 * ice_dpll_init_rclk_pins - initialize recovered clock pin
3045 * @pf: board private structure
3046 * @pin: pin to register
3047 * @start_idx: on which index shall allocation start in dpll subsystem
3048 * @ops: callback ops registered with the pins
3049 *
3050 * Allocate resource for recovered clock pin in dpll subsystem. Register the
3051 * pin with the parents it has in the info. Register pin with the pf's main vsi
3052 * netdev.
3053 *
3054 * Return:
3055 * * 0 - success
3056 * * negative - registration failure reason
3057 */
3058 static int
ice_dpll_init_rclk_pins(struct ice_pf * pf,struct ice_dpll_pin * pin,int start_idx,const struct dpll_pin_ops * ops)3059 ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
3060 int start_idx, const struct dpll_pin_ops *ops)
3061 {
3062 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3063 struct dpll_pin *parent;
3064 int ret, i;
3065
3066 if (WARN_ON((!vsi || !vsi->netdev)))
3067 return -EINVAL;
3068 ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
3069 pf->dplls.clock_id);
3070 if (ret)
3071 return ret;
3072 for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
3073 parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[i]].pin;
3074 if (!parent) {
3075 ret = -ENODEV;
3076 goto unregister_pins;
3077 }
3078 ret = dpll_pin_on_pin_register(parent, pf->dplls.rclk.pin,
3079 ops, &pf->dplls.rclk);
3080 if (ret)
3081 goto unregister_pins;
3082 }
3083 dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
3084
3085 return 0;
3086
3087 unregister_pins:
3088 while (i) {
3089 parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[--i]].pin;
3090 dpll_pin_on_pin_unregister(parent, pf->dplls.rclk.pin,
3091 &ice_dpll_rclk_ops, &pf->dplls.rclk);
3092 }
3093 ice_dpll_release_pins(pin, ICE_DPLL_RCLK_NUM_PER_PF);
3094 return ret;
3095 }
3096
3097 /**
3098 * ice_dpll_deinit_pins - deinitialize direct pins
3099 * @pf: board private structure
3100 * @cgu: if cgu is controlled by this pf
3101 *
3102 * If cgu is owned unregister directly connected pins from the dplls.
3103 * Release resources of directly connected pins from the dpll subsystem.
3104 */
ice_dpll_deinit_pins(struct ice_pf * pf,bool cgu)3105 static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
3106 {
3107 struct ice_dpll_pin *outputs = pf->dplls.outputs;
3108 struct ice_dpll_pin *inputs = pf->dplls.inputs;
3109 int num_outputs = pf->dplls.num_outputs;
3110 int num_inputs = pf->dplls.num_inputs;
3111 struct ice_dplls *d = &pf->dplls;
3112 struct ice_dpll *de = &d->eec;
3113 struct ice_dpll *dp = &d->pps;
3114
3115 ice_dpll_deinit_rclk_pin(pf);
3116 if (cgu) {
3117 ice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,
3118 num_inputs);
3119 ice_dpll_unregister_pins(de->dpll, inputs, &ice_dpll_input_ops,
3120 num_inputs);
3121 }
3122 ice_dpll_release_pins(inputs, num_inputs);
3123 if (cgu) {
3124 ice_dpll_unregister_pins(dp->dpll, outputs,
3125 &ice_dpll_output_ops, num_outputs);
3126 ice_dpll_unregister_pins(de->dpll, outputs,
3127 &ice_dpll_output_ops, num_outputs);
3128 ice_dpll_release_pins(outputs, num_outputs);
3129 if (!pf->dplls.generic) {
3130 ice_dpll_deinit_direct_pins(cgu, pf->dplls.ufl,
3131 ICE_DPLL_PIN_SW_NUM,
3132 &ice_dpll_pin_ufl_ops,
3133 pf->dplls.pps.dpll,
3134 pf->dplls.eec.dpll);
3135 ice_dpll_deinit_direct_pins(cgu, pf->dplls.sma,
3136 ICE_DPLL_PIN_SW_NUM,
3137 &ice_dpll_pin_sma_ops,
3138 pf->dplls.pps.dpll,
3139 pf->dplls.eec.dpll);
3140 }
3141 }
3142 }
3143
3144 /**
3145 * ice_dpll_init_pins - init pins and register pins with a dplls
3146 * @pf: board private structure
3147 * @cgu: if cgu is present and controlled by this NIC
3148 *
3149 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
3150 * subsystem.
3151 *
3152 * Return:
3153 * * 0 - success
3154 * * negative - initialization failure reason
3155 */
ice_dpll_init_pins(struct ice_pf * pf,bool cgu)3156 static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
3157 {
3158 int ret, count;
3159
3160 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0,
3161 pf->dplls.num_inputs,
3162 &ice_dpll_input_ops,
3163 pf->dplls.eec.dpll, pf->dplls.pps.dpll);
3164 if (ret)
3165 return ret;
3166 count = pf->dplls.num_inputs;
3167 if (cgu) {
3168 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs,
3169 count,
3170 pf->dplls.num_outputs,
3171 &ice_dpll_output_ops,
3172 pf->dplls.eec.dpll,
3173 pf->dplls.pps.dpll);
3174 if (ret)
3175 goto deinit_inputs;
3176 count += pf->dplls.num_outputs;
3177 if (!pf->dplls.generic) {
3178 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.sma,
3179 count,
3180 ICE_DPLL_PIN_SW_NUM,
3181 &ice_dpll_pin_sma_ops,
3182 pf->dplls.eec.dpll,
3183 pf->dplls.pps.dpll);
3184 if (ret)
3185 goto deinit_outputs;
3186 count += ICE_DPLL_PIN_SW_NUM;
3187 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.ufl,
3188 count,
3189 ICE_DPLL_PIN_SW_NUM,
3190 &ice_dpll_pin_ufl_ops,
3191 pf->dplls.eec.dpll,
3192 pf->dplls.pps.dpll);
3193 if (ret)
3194 goto deinit_sma;
3195 count += ICE_DPLL_PIN_SW_NUM;
3196 }
3197 ret = ice_dpll_pin_ref_sync_register(pf->dplls.inputs,
3198 pf->dplls.num_inputs);
3199 if (ret)
3200 goto deinit_ufl;
3201 ret = ice_dpll_pin_ref_sync_register(pf->dplls.sma,
3202 ICE_DPLL_PIN_SW_NUM);
3203 if (ret)
3204 goto deinit_ufl;
3205 } else {
3206 count += pf->dplls.num_outputs + 2 * ICE_DPLL_PIN_SW_NUM;
3207 }
3208 ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, count + pf->hw.pf_id,
3209 &ice_dpll_rclk_ops);
3210 if (ret)
3211 goto deinit_ufl;
3212
3213 return 0;
3214 deinit_ufl:
3215 ice_dpll_deinit_direct_pins(cgu, pf->dplls.ufl,
3216 ICE_DPLL_PIN_SW_NUM,
3217 &ice_dpll_pin_ufl_ops,
3218 pf->dplls.pps.dpll, pf->dplls.eec.dpll);
3219 deinit_sma:
3220 ice_dpll_deinit_direct_pins(cgu, pf->dplls.sma,
3221 ICE_DPLL_PIN_SW_NUM,
3222 &ice_dpll_pin_sma_ops,
3223 pf->dplls.pps.dpll, pf->dplls.eec.dpll);
3224 deinit_outputs:
3225 ice_dpll_deinit_direct_pins(cgu, pf->dplls.outputs,
3226 pf->dplls.num_outputs,
3227 &ice_dpll_output_ops, pf->dplls.pps.dpll,
3228 pf->dplls.eec.dpll);
3229 deinit_inputs:
3230 ice_dpll_deinit_direct_pins(cgu, pf->dplls.inputs, pf->dplls.num_inputs,
3231 &ice_dpll_input_ops, pf->dplls.pps.dpll,
3232 pf->dplls.eec.dpll);
3233 return ret;
3234 }
3235
3236 /**
3237 * ice_dpll_deinit_dpll - deinitialize dpll device
3238 * @pf: board private structure
3239 * @d: pointer to ice_dpll
3240 * @cgu: if cgu is present and controlled by this NIC
3241 *
3242 * If cgu is owned unregister the dpll from dpll subsystem.
3243 * Release resources of dpll device from dpll subsystem.
3244 */
3245 static void
ice_dpll_deinit_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu)3246 ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
3247 {
3248 if (cgu)
3249 dpll_device_unregister(d->dpll, d->ops, d);
3250 dpll_device_put(d->dpll);
3251 }
3252
3253 /**
3254 * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
3255 * @pf: board private structure
3256 * @d: dpll to be initialized
3257 * @cgu: if cgu is present and controlled by this NIC
3258 * @type: type of dpll being initialized
3259 *
3260 * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled
3261 * by this NIC, register dpll with the callback ops.
3262 *
3263 * Return:
3264 * * 0 - success
3265 * * negative - initialization failure reason
3266 */
3267 static int
ice_dpll_init_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu,enum dpll_type type)3268 ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
3269 enum dpll_type type)
3270 {
3271 u64 clock_id = pf->dplls.clock_id;
3272 int ret;
3273
3274 d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE);
3275 if (IS_ERR(d->dpll)) {
3276 ret = PTR_ERR(d->dpll);
3277 dev_err(ice_pf_to_dev(pf),
3278 "dpll_device_get failed (%p) err=%d\n", d, ret);
3279 return ret;
3280 }
3281 d->pf = pf;
3282 if (cgu) {
3283 const struct dpll_device_ops *ops = &ice_dpll_ops;
3284
3285 if (type == DPLL_TYPE_PPS && ice_dpll_is_pps_phase_monitor(pf))
3286 ops = &ice_dpll_pom_ops;
3287 ice_dpll_update_state(pf, d, true);
3288 ret = dpll_device_register(d->dpll, type, ops, d);
3289 if (ret) {
3290 dpll_device_put(d->dpll);
3291 return ret;
3292 }
3293 d->ops = ops;
3294 }
3295
3296 return 0;
3297 }
3298
3299 /**
3300 * ice_dpll_deinit_worker - deinitialize dpll kworker
3301 * @pf: board private structure
3302 *
3303 * Stop dpll's kworker, release it's resources.
3304 */
ice_dpll_deinit_worker(struct ice_pf * pf)3305 static void ice_dpll_deinit_worker(struct ice_pf *pf)
3306 {
3307 struct ice_dplls *d = &pf->dplls;
3308
3309 kthread_cancel_delayed_work_sync(&d->work);
3310 kthread_destroy_worker(d->kworker);
3311 }
3312
3313 /**
3314 * ice_dpll_init_worker - Initialize DPLLs periodic worker
3315 * @pf: board private structure
3316 *
3317 * Create and start DPLLs periodic worker.
3318 *
3319 * Context: Shall be called after pf->dplls.lock is initialized.
3320 * Return:
3321 * * 0 - success
3322 * * negative - create worker failure
3323 */
ice_dpll_init_worker(struct ice_pf * pf)3324 static int ice_dpll_init_worker(struct ice_pf *pf)
3325 {
3326 struct ice_dplls *d = &pf->dplls;
3327 struct kthread_worker *kworker;
3328
3329 kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
3330 kworker = kthread_run_worker(0, "ice-dplls-%s",
3331 dev_name(ice_pf_to_dev(pf)));
3332 if (IS_ERR(kworker))
3333 return PTR_ERR(kworker);
3334 d->kworker = kworker;
3335 d->cgu_state_acq_err_num = 0;
3336 kthread_queue_delayed_work(d->kworker, &d->work, 0);
3337
3338 return 0;
3339 }
3340
3341 /**
3342 * ice_dpll_phase_range_set - initialize phase adjust range helper
3343 * @range: pointer to phase adjust range struct to be initialized
3344 * @phase_adj: a value to be used as min(-)/max(+) boundary
3345 */
ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range * range,u32 phase_adj)3346 static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
3347 u32 phase_adj)
3348 {
3349 range->min = -phase_adj;
3350 range->max = phase_adj;
3351 }
3352
3353 /**
3354 * ice_dpll_init_info_pins_generic - initializes generic pins info
3355 * @pf: board private structure
3356 * @input: if input pins initialized
3357 *
3358 * Init information for generic pins, cache them in PF's pins structures.
3359 *
3360 * Return:
3361 * * 0 - success
3362 * * negative - init failure reason
3363 */
ice_dpll_init_info_pins_generic(struct ice_pf * pf,bool input)3364 static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
3365 {
3366 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3367 static const char labels[][sizeof("99")] = {
3368 "0", "1", "2", "3", "4", "5", "6", "7", "8",
3369 "9", "10", "11", "12", "13", "14", "15" };
3370 u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3371 enum ice_dpll_pin_type pin_type;
3372 int i, pin_num, ret = -EINVAL;
3373 struct ice_dpll_pin *pins;
3374 u32 phase_adj_max;
3375
3376 if (input) {
3377 pin_num = pf->dplls.num_inputs;
3378 pins = pf->dplls.inputs;
3379 phase_adj_max = pf->dplls.input_phase_adj_max;
3380 pin_type = ICE_DPLL_PIN_TYPE_INPUT;
3381 cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
3382 } else {
3383 pin_num = pf->dplls.num_outputs;
3384 pins = pf->dplls.outputs;
3385 phase_adj_max = pf->dplls.output_phase_adj_max;
3386 pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
3387 }
3388 if (pin_num > ARRAY_SIZE(labels))
3389 return ret;
3390
3391 for (i = 0; i < pin_num; i++) {
3392 pins[i].idx = i;
3393 pins[i].prop.board_label = labels[i];
3394 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3395 phase_adj_max);
3396 pins[i].prop.capabilities = cap;
3397 pins[i].pf = pf;
3398 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3399 if (ret)
3400 break;
3401 if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
3402 pins[i].prop.type = DPLL_PIN_TYPE_MUX;
3403 else
3404 pins[i].prop.type = DPLL_PIN_TYPE_EXT;
3405 if (!input)
3406 continue;
3407 ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
3408 &de->input_prio[i]);
3409 if (ret)
3410 break;
3411 ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
3412 &dp->input_prio[i]);
3413 if (ret)
3414 break;
3415 }
3416
3417 return ret;
3418 }
3419
3420 /**
3421 * ice_dpll_init_info_direct_pins - initializes direct pins info
3422 * @pf: board private structure
3423 * @pin_type: type of pins being initialized
3424 *
3425 * Init information for directly connected pins, cache them in pf's pins
3426 * structures.
3427 *
3428 * Return:
3429 * * 0 - success
3430 * * negative - init failure reason
3431 */
3432 static int
ice_dpll_init_info_direct_pins(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)3433 ice_dpll_init_info_direct_pins(struct ice_pf *pf,
3434 enum ice_dpll_pin_type pin_type)
3435 {
3436 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3437 int num_pins, i, ret = -EINVAL;
3438 struct ice_hw *hw = &pf->hw;
3439 struct ice_dpll_pin *pins;
3440 unsigned long caps;
3441 u32 phase_adj_max;
3442 u8 freq_supp_num;
3443 bool input;
3444
3445 switch (pin_type) {
3446 case ICE_DPLL_PIN_TYPE_INPUT:
3447 pins = pf->dplls.inputs;
3448 num_pins = pf->dplls.num_inputs;
3449 phase_adj_max = pf->dplls.input_phase_adj_max;
3450 input = true;
3451 break;
3452 case ICE_DPLL_PIN_TYPE_OUTPUT:
3453 pins = pf->dplls.outputs;
3454 num_pins = pf->dplls.num_outputs;
3455 phase_adj_max = pf->dplls.output_phase_adj_max;
3456 input = false;
3457 break;
3458 default:
3459 return -EINVAL;
3460 }
3461 if (num_pins != ice_cgu_get_num_pins(hw, input)) {
3462 pf->dplls.generic = true;
3463 return ice_dpll_init_info_pins_generic(pf, input);
3464 }
3465
3466 for (i = 0; i < num_pins; i++) {
3467 caps = 0;
3468 pins[i].idx = i;
3469 pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
3470 pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
3471 if (input) {
3472 ret = ice_aq_get_cgu_ref_prio(hw, de->dpll_idx, i,
3473 &de->input_prio[i]);
3474 if (ret)
3475 return ret;
3476 ret = ice_aq_get_cgu_ref_prio(hw, dp->dpll_idx, i,
3477 &dp->input_prio[i]);
3478 if (ret)
3479 return ret;
3480 caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
3481 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
3482 if (ice_dpll_is_sw_pin(pf, i, true))
3483 pins[i].hidden = true;
3484 } else {
3485 ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
3486 if (ret)
3487 return ret;
3488 if (ice_dpll_is_sw_pin(pf, i, false))
3489 pins[i].hidden = true;
3490 }
3491 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3492 phase_adj_max);
3493 pins[i].prop.capabilities = caps;
3494 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3495 if (ret)
3496 return ret;
3497 pins[i].prop.freq_supported =
3498 ice_cgu_get_pin_freq_supp(hw, i, input, &freq_supp_num);
3499 pins[i].prop.freq_supported_num = freq_supp_num;
3500 pins[i].pf = pf;
3501 }
3502 if (input)
3503 ret = ice_dpll_init_ref_sync_inputs(pf);
3504
3505 return ret;
3506 }
3507
3508 /**
3509 * ice_dpll_init_info_rclk_pin - initializes rclk pin information
3510 * @pf: board private structure
3511 *
3512 * Init information for rclk pin, cache them in pf->dplls.rclk.
3513 *
3514 * Return:
3515 * * 0 - success
3516 * * negative - init failure reason
3517 */
ice_dpll_init_info_rclk_pin(struct ice_pf * pf)3518 static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
3519 {
3520 struct ice_dpll_pin *pin = &pf->dplls.rclk;
3521
3522 pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
3523 pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3524 pin->pf = pf;
3525
3526 return ice_dpll_pin_state_update(pf, pin,
3527 ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
3528 }
3529
3530 /**
3531 * ice_dpll_init_info_sw_pins - initializes software controlled pin information
3532 * @pf: board private structure
3533 *
3534 * Init information for software controlled pins, cache them in
3535 * pf->dplls.sma and pf->dplls.ufl.
3536 *
3537 * Return:
3538 * * 0 - success
3539 * * negative - init failure reason
3540 */
ice_dpll_init_info_sw_pins(struct ice_pf * pf)3541 static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
3542 {
3543 u8 freq_supp_num, pin_abs_idx, input_idx_offset = 0;
3544 struct ice_dplls *d = &pf->dplls;
3545 struct ice_dpll_pin *pin;
3546 u32 phase_adj_max, caps;
3547 int i, ret;
3548
3549 if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
3550 input_idx_offset = ICE_E810_RCLK_PINS_NUM;
3551 phase_adj_max = max(d->input_phase_adj_max, d->output_phase_adj_max);
3552 caps = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3553 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
3554 pin = &d->sma[i];
3555 pin->idx = i;
3556 pin->prop.type = DPLL_PIN_TYPE_EXT;
3557 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + input_idx_offset;
3558 pin->prop.freq_supported =
3559 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
3560 true, &freq_supp_num);
3561 pin->prop.freq_supported_num = freq_supp_num;
3562 pin->prop.capabilities =
3563 (DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE |
3564 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
3565 caps);
3566 pin->pf = pf;
3567 pin->prop.board_label = ice_dpll_sw_pin_sma[i];
3568 pin->input = &d->inputs[pin_abs_idx];
3569 if (pin->input->ref_sync)
3570 pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
3571 pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
3572 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
3573 }
3574 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
3575 pin = &d->ufl[i];
3576 pin->idx = i;
3577 pin->prop.type = DPLL_PIN_TYPE_EXT;
3578 pin->prop.capabilities = caps;
3579 pin->pf = pf;
3580 pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
3581 if (i == ICE_DPLL_PIN_SW_1_IDX) {
3582 pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
3583 pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
3584 pin->prop.freq_supported =
3585 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
3586 false,
3587 &freq_supp_num);
3588 pin->prop.freq_supported_num = freq_supp_num;
3589 pin->input = NULL;
3590 pin->output = &d->outputs[pin_abs_idx];
3591 } else if (i == ICE_DPLL_PIN_SW_2_IDX) {
3592 pin->direction = DPLL_PIN_DIRECTION_INPUT;
3593 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
3594 input_idx_offset;
3595 pin->output = NULL;
3596 pin->input = &d->inputs[pin_abs_idx];
3597 pin->prop.freq_supported =
3598 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
3599 true, &freq_supp_num);
3600 pin->prop.freq_supported_num = freq_supp_num;
3601 pin->prop.capabilities =
3602 (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
3603 caps);
3604 }
3605 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
3606 }
3607 ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE,
3608 NULL);
3609 if (ret)
3610 return ret;
3611
3612 return 0;
3613 }
3614
3615 /**
3616 * ice_dpll_init_pins_info - init pins info wrapper
3617 * @pf: board private structure
3618 * @pin_type: type of pins being initialized
3619 *
3620 * Wraps functions for pin initialization.
3621 *
3622 * Return:
3623 * * 0 - success
3624 * * negative - init failure reason
3625 */
3626 static int
ice_dpll_init_pins_info(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)3627 ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
3628 {
3629 switch (pin_type) {
3630 case ICE_DPLL_PIN_TYPE_INPUT:
3631 case ICE_DPLL_PIN_TYPE_OUTPUT:
3632 return ice_dpll_init_info_direct_pins(pf, pin_type);
3633 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
3634 return ice_dpll_init_info_rclk_pin(pf);
3635 case ICE_DPLL_PIN_TYPE_SOFTWARE:
3636 return ice_dpll_init_info_sw_pins(pf);
3637 default:
3638 return -EINVAL;
3639 }
3640 }
3641
3642 /**
3643 * ice_dpll_deinit_info - release memory allocated for pins info
3644 * @pf: board private structure
3645 *
3646 * Release memory allocated for pins by ice_dpll_init_info function.
3647 */
ice_dpll_deinit_info(struct ice_pf * pf)3648 static void ice_dpll_deinit_info(struct ice_pf *pf)
3649 {
3650 kfree(pf->dplls.inputs);
3651 kfree(pf->dplls.outputs);
3652 kfree(pf->dplls.eec.input_prio);
3653 kfree(pf->dplls.pps.input_prio);
3654 }
3655
3656 /**
3657 * ice_dpll_init_info - prepare pf's dpll information structure
3658 * @pf: board private structure
3659 * @cgu: if cgu is present and controlled by this NIC
3660 *
3661 * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
3662 *
3663 * Return:
3664 * * 0 - success
3665 * * negative - init failure reason
3666 */
ice_dpll_init_info(struct ice_pf * pf,bool cgu)3667 static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
3668 {
3669 struct ice_aqc_get_cgu_abilities abilities;
3670 struct ice_dpll *de = &pf->dplls.eec;
3671 struct ice_dpll *dp = &pf->dplls.pps;
3672 struct ice_dplls *d = &pf->dplls;
3673 struct ice_hw *hw = &pf->hw;
3674 int ret, alloc_size, i;
3675
3676 d->clock_id = ice_generate_clock_id(pf);
3677 ret = ice_aq_get_cgu_abilities(hw, &abilities);
3678 if (ret) {
3679 dev_err(ice_pf_to_dev(pf),
3680 "err:%d %s failed to read cgu abilities\n",
3681 ret, libie_aq_str(hw->adminq.sq_last_status));
3682 return ret;
3683 }
3684
3685 de->dpll_idx = abilities.eec_dpll_idx;
3686 dp->dpll_idx = abilities.pps_dpll_idx;
3687 d->num_inputs = abilities.num_inputs;
3688 d->num_outputs = abilities.num_outputs;
3689 d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
3690 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
3691 d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
3692 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
3693
3694 alloc_size = sizeof(*d->inputs) * d->num_inputs;
3695 d->inputs = kzalloc(alloc_size, GFP_KERNEL);
3696 if (!d->inputs)
3697 return -ENOMEM;
3698
3699 alloc_size = sizeof(*de->input_prio) * d->num_inputs;
3700 de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
3701 if (!de->input_prio)
3702 return -ENOMEM;
3703
3704 dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
3705 if (!dp->input_prio)
3706 return -ENOMEM;
3707
3708 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
3709 if (ret)
3710 goto deinit_info;
3711
3712 if (cgu) {
3713 alloc_size = sizeof(*d->outputs) * d->num_outputs;
3714 d->outputs = kzalloc(alloc_size, GFP_KERNEL);
3715 if (!d->outputs) {
3716 ret = -ENOMEM;
3717 goto deinit_info;
3718 }
3719
3720 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT);
3721 if (ret)
3722 goto deinit_info;
3723 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_SOFTWARE);
3724 if (ret)
3725 goto deinit_info;
3726 }
3727
3728 ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
3729 &pf->dplls.rclk.num_parents);
3730 if (ret)
3731 return ret;
3732 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
3733 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
3734 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
3735 if (ret)
3736 return ret;
3737 de->mode = DPLL_MODE_AUTOMATIC;
3738 dp->mode = DPLL_MODE_AUTOMATIC;
3739
3740 dev_dbg(ice_pf_to_dev(pf),
3741 "%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
3742 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
3743
3744 return 0;
3745
3746 deinit_info:
3747 dev_err(ice_pf_to_dev(pf),
3748 "%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
3749 __func__, d->inputs, de->input_prio,
3750 dp->input_prio, d->outputs);
3751 ice_dpll_deinit_info(pf);
3752 return ret;
3753 }
3754
3755 /**
3756 * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
3757 * the dpll device.
3758 * @pf: board private structure
3759 *
3760 * Handles the cleanup work required after dpll initialization, freeing
3761 * resources and unregistering the dpll, pin and all resources used for
3762 * handling them.
3763 *
3764 * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
3765 */
ice_dpll_deinit(struct ice_pf * pf)3766 void ice_dpll_deinit(struct ice_pf *pf)
3767 {
3768 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
3769
3770 clear_bit(ICE_FLAG_DPLL, pf->flags);
3771 if (cgu)
3772 ice_dpll_deinit_worker(pf);
3773
3774 ice_dpll_deinit_pins(pf, cgu);
3775 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
3776 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
3777 ice_dpll_deinit_info(pf);
3778 mutex_destroy(&pf->dplls.lock);
3779 }
3780
3781 /**
3782 * ice_dpll_init - initialize support for dpll subsystem
3783 * @pf: board private structure
3784 *
3785 * Set up the device dplls, register them and pins connected within Linux dpll
3786 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
3787 * configuration requests.
3788 *
3789 * Context: Initializes pf->dplls.lock mutex.
3790 */
ice_dpll_init(struct ice_pf * pf)3791 void ice_dpll_init(struct ice_pf *pf)
3792 {
3793 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
3794 struct ice_dplls *d = &pf->dplls;
3795 int err = 0;
3796
3797 mutex_init(&d->lock);
3798 err = ice_dpll_init_info(pf, cgu);
3799 if (err)
3800 goto err_exit;
3801 err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
3802 if (err)
3803 goto deinit_info;
3804 err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
3805 if (err)
3806 goto deinit_eec;
3807 err = ice_dpll_init_pins(pf, cgu);
3808 if (err)
3809 goto deinit_pps;
3810 if (cgu) {
3811 err = ice_dpll_init_worker(pf);
3812 if (err)
3813 goto deinit_pins;
3814 }
3815 set_bit(ICE_FLAG_DPLL, pf->flags);
3816
3817 return;
3818
3819 deinit_pins:
3820 ice_dpll_deinit_pins(pf, cgu);
3821 deinit_pps:
3822 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
3823 deinit_eec:
3824 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
3825 deinit_info:
3826 ice_dpll_deinit_info(pf);
3827 err_exit:
3828 mutex_destroy(&d->lock);
3829 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
3830 }
3831