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 "ice_txclk.h"
8 #include <linux/dpll.h>
9 #include <linux/property.h>
10
11 #define ICE_CGU_STATE_ACQ_ERR_THRESHOLD 50
12 #define ICE_DPLL_PIN_IDX_INVALID 0xff
13 #define ICE_DPLL_RCLK_NUM_PER_PF 1
14 #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25
15 #define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125
16 #define ICE_DPLL_PIN_PRIO_OUTPUT 0xff
17 #define ICE_DPLL_INPUT_REF_NUM 10
18 #define ICE_DPLL_PHASE_OFFSET_PERIOD 2
19 #define ICE_DPLL_SW_PIN_INPUT_BASE_SFP 4
20 #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP 6
21 #define ICE_DPLL_SW_PIN_OUTPUT_BASE 0
22
23 #define E825_RCLK_PARENT_0_PIN_IDX 0
24 #define E825_RCLK_PARENT_1_PIN_IDX 1
25
26 #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \
27 (ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx))
28
29 #define ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX \
30 (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
31
32 #define ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX \
33 (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
34
35 #define ICE_DPLL_PIN_SW_OUTPUT_ABS(out_idx) \
36 (ICE_DPLL_SW_PIN_OUTPUT_BASE + (out_idx))
37
38 #define ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX \
39 (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
40
41 #define ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX \
42 (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
43
44 #define ICE_SR_PFA_DPLL_DEFAULTS 0x152
45 #define ICE_DPLL_PFA_REF_SYNC_TYPE 0x2420
46 #define ICE_DPLL_PFA_REF_SYNC_TYPE2 0x2424
47 #define ICE_DPLL_PFA_END 0xFFFF
48 #define ICE_DPLL_PFA_HEADER_LEN 4
49 #define ICE_DPLL_PFA_ENTRY_LEN 3
50 #define ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S 4
51 #define ICE_DPLL_PFA_MASK_OFFSET 1
52 #define ICE_DPLL_PFA_VALUE_OFFSET 2
53
54 #define ICE_DPLL_E810C_SFP_NC_PINS 2
55 #define ICE_DPLL_E810C_SFP_NC_START 4
56
57 /**
58 * enum ice_dpll_pin_type - enumerate ice pin types:
59 * @ICE_DPLL_PIN_INVALID: invalid pin type
60 * @ICE_DPLL_PIN_TYPE_INPUT: input pin
61 * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
62 * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
63 * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins
64 * @ICE_DPLL_PIN_TYPE_TXCLK: transmit clock reference input pin
65 */
66 enum ice_dpll_pin_type {
67 ICE_DPLL_PIN_INVALID,
68 ICE_DPLL_PIN_TYPE_INPUT,
69 ICE_DPLL_PIN_TYPE_OUTPUT,
70 ICE_DPLL_PIN_TYPE_RCLK_INPUT,
71 ICE_DPLL_PIN_TYPE_SOFTWARE,
72 ICE_DPLL_PIN_TYPE_TXCLK,
73 };
74
75 static const char * const pin_type_name[] = {
76 [ICE_DPLL_PIN_TYPE_INPUT] = "input",
77 [ICE_DPLL_PIN_TYPE_OUTPUT] = "output",
78 [ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
79 [ICE_DPLL_PIN_TYPE_SOFTWARE] = "software",
80 [ICE_DPLL_PIN_TYPE_TXCLK] = "txclk-input",
81 };
82
83 static const char * const ice_dpll_sw_pin_sma[] = { "SMA1", "SMA2" };
84 static const char * const ice_dpll_sw_pin_ufl[] = { "U.FL1", "U.FL2" };
85 static const char * const ice_dpll_ext_eref_pin = "EXT_EREF0";
86 static const char * const ice_dpll_fwnode_ext_synce = "clk_ref_synce";
87
88 static const struct dpll_pin_frequency ice_esync_range[] = {
89 DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
90 };
91
92 /**
93 * ice_dpll_is_sw_pin - check if given pin shall be controlled by SW
94 * @pf: private board structure
95 * @index: index of a pin as understood by FW
96 * @input: true for input, false for output
97 *
98 * Check if the pin shall be controlled by SW - instead of providing raw access
99 * for pin control. For E810 NIC with dpll there is additional MUX-related logic
100 * between SMA/U.FL pins/connectors and dpll device, best to give user access
101 * with series of wrapper functions as from user perspective they convey single
102 * functionality rather then separated pins.
103 *
104 * Return:
105 * * true - pin controlled by SW
106 * * false - pin not controlled by SW
107 */
ice_dpll_is_sw_pin(struct ice_pf * pf,u8 index,bool input)108 static bool ice_dpll_is_sw_pin(struct ice_pf *pf, u8 index, bool input)
109 {
110 if (input && pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
111 index -= ICE_DPLL_SW_PIN_INPUT_BASE_QSFP -
112 ICE_DPLL_SW_PIN_INPUT_BASE_SFP;
113
114 if ((input && (index == ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX ||
115 index == ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX)) ||
116 (!input && (index == ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX ||
117 index == ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX)))
118 return true;
119 return false;
120 }
121
122 /**
123 * ice_dpll_is_reset - check if reset is in progress
124 * @pf: private board structure
125 * @extack: error reporting
126 *
127 * If reset is in progress, fill extack with error.
128 *
129 * Return:
130 * * false - no reset in progress
131 * * true - reset in progress
132 */
ice_dpll_is_reset(struct ice_pf * pf,struct netlink_ext_ack * extack)133 static bool ice_dpll_is_reset(struct ice_pf *pf, struct netlink_ext_ack *extack)
134 {
135 if (ice_is_reset_in_progress(pf->state)) {
136 NL_SET_ERR_MSG(extack, "PF reset in progress");
137 return true;
138 }
139 return false;
140 }
141
142 /**
143 * ice_dpll_pin_freq_set - set pin's frequency
144 * @pf: private board structure
145 * @pin: pointer to a pin
146 * @pin_type: type of pin being configured
147 * @freq: frequency to be set
148 * @extack: error reporting
149 *
150 * Set requested frequency on a pin.
151 *
152 * Context: Called under pf->dplls.lock
153 * Return:
154 * * 0 - success
155 * * negative - error on AQ or wrong pin type given
156 */
157 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)158 ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin,
159 enum ice_dpll_pin_type pin_type, const u32 freq,
160 struct netlink_ext_ack *extack)
161 {
162 u8 flags;
163 int ret;
164
165 switch (pin_type) {
166 case ICE_DPLL_PIN_TYPE_INPUT:
167 flags = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ;
168 ret = ice_aq_set_input_pin_cfg(&pf->hw, pin->idx, flags,
169 pin->flags[0], freq, 0);
170 break;
171 case ICE_DPLL_PIN_TYPE_OUTPUT:
172 flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_FREQ;
173 ret = ice_aq_set_output_pin_cfg(&pf->hw, pin->idx, flags,
174 0, freq, 0);
175 break;
176 default:
177 return -EINVAL;
178 }
179 if (ret) {
180 NL_SET_ERR_MSG_FMT(extack,
181 "err:%d %s failed to set pin freq:%u on pin:%u",
182 ret,
183 libie_aq_str(pf->hw.adminq.sq_last_status),
184 freq, pin->idx);
185 return ret;
186 }
187 pin->freq = freq;
188
189 return 0;
190 }
191
192 /**
193 * ice_dpll_frequency_set - wrapper for pin callback for set frequency
194 * @pin: pointer to a pin
195 * @pin_priv: private data pointer passed on pin registration
196 * @dpll: pointer to dpll
197 * @dpll_priv: private data pointer passed on dpll registration
198 * @frequency: frequency to be set
199 * @extack: error reporting
200 * @pin_type: type of pin being configured
201 *
202 * Wraps internal set frequency command on a pin.
203 *
204 * Context: Acquires pf->dplls.lock
205 * Return:
206 * * 0 - success
207 * * negative - error pin not found or couldn't set in hw
208 */
209 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)210 ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv,
211 const struct dpll_device *dpll, void *dpll_priv,
212 const u32 frequency,
213 struct netlink_ext_ack *extack,
214 enum ice_dpll_pin_type pin_type)
215 {
216 struct ice_dpll_pin *p = pin_priv;
217 struct ice_dpll *d = dpll_priv;
218 struct ice_pf *pf = d->pf;
219 int ret;
220
221 if (ice_dpll_is_reset(pf, extack))
222 return -EBUSY;
223
224 mutex_lock(&pf->dplls.lock);
225 ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency, extack);
226 mutex_unlock(&pf->dplls.lock);
227
228 return ret;
229 }
230
231 /**
232 * ice_dpll_input_frequency_set - input pin callback for set frequency
233 * @pin: pointer to a pin
234 * @pin_priv: private data pointer passed on pin registration
235 * @dpll: pointer to dpll
236 * @dpll_priv: private data pointer passed on dpll registration
237 * @frequency: frequency to be set
238 * @extack: error reporting
239 *
240 * Wraps internal set frequency command on a pin.
241 *
242 * Context: Calls a function which acquires pf->dplls.lock
243 * Return:
244 * * 0 - success
245 * * negative - error pin not found or couldn't set in hw
246 */
247 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)248 ice_dpll_input_frequency_set(const struct dpll_pin *pin, void *pin_priv,
249 const struct dpll_device *dpll, void *dpll_priv,
250 u64 frequency, struct netlink_ext_ack *extack)
251 {
252 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
253 extack, ICE_DPLL_PIN_TYPE_INPUT);
254 }
255
256 /**
257 * ice_dpll_output_frequency_set - output pin callback for set frequency
258 * @pin: pointer to a pin
259 * @pin_priv: private data pointer passed on pin registration
260 * @dpll: pointer to dpll
261 * @dpll_priv: private data pointer passed on dpll registration
262 * @frequency: frequency to be set
263 * @extack: error reporting
264 *
265 * Wraps internal set frequency command on a pin.
266 *
267 * Context: Calls a function which acquires pf->dplls.lock
268 * Return:
269 * * 0 - success
270 * * negative - error pin not found or couldn't set in hw
271 */
272 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)273 ice_dpll_output_frequency_set(const struct dpll_pin *pin, void *pin_priv,
274 const struct dpll_device *dpll, void *dpll_priv,
275 u64 frequency, struct netlink_ext_ack *extack)
276 {
277 return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
278 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
279 }
280
281 /**
282 * ice_dpll_frequency_get - wrapper for pin callback for get frequency
283 * @pin: pointer to a pin
284 * @pin_priv: private data pointer passed on pin registration
285 * @dpll: pointer to dpll
286 * @dpll_priv: private data pointer passed on dpll registration
287 * @frequency: on success holds pin's frequency
288 * @extack: error reporting
289 * @pin_type: type of pin being configured
290 *
291 * Wraps internal get frequency command of a pin.
292 *
293 * Context: Acquires pf->dplls.lock
294 * Return:
295 * * 0 - success
296 * * negative - error pin not found or couldn't get from hw
297 */
298 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)299 ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv,
300 const struct dpll_device *dpll, void *dpll_priv,
301 u64 *frequency, struct netlink_ext_ack *extack,
302 enum ice_dpll_pin_type pin_type)
303 {
304 struct ice_dpll_pin *p = pin_priv;
305 struct ice_dpll *d = dpll_priv;
306 struct ice_pf *pf = d->pf;
307
308 mutex_lock(&pf->dplls.lock);
309 *frequency = p->freq;
310 mutex_unlock(&pf->dplls.lock);
311
312 return 0;
313 }
314
315 /**
316 * ice_dpll_input_frequency_get - input pin callback for get frequency
317 * @pin: pointer to a pin
318 * @pin_priv: private data pointer passed on pin registration
319 * @dpll: pointer to dpll
320 * @dpll_priv: private data pointer passed on dpll registration
321 * @frequency: on success holds pin's frequency
322 * @extack: error reporting
323 *
324 * Wraps internal get frequency command of a input pin.
325 *
326 * Context: Calls a function which acquires pf->dplls.lock
327 * Return:
328 * * 0 - success
329 * * negative - error pin not found or couldn't get from hw
330 */
331 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)332 ice_dpll_input_frequency_get(const struct dpll_pin *pin, void *pin_priv,
333 const struct dpll_device *dpll, void *dpll_priv,
334 u64 *frequency, struct netlink_ext_ack *extack)
335 {
336 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
337 extack, ICE_DPLL_PIN_TYPE_INPUT);
338 }
339
340 /**
341 * ice_dpll_output_frequency_get - output pin callback for get frequency
342 * @pin: pointer to a pin
343 * @pin_priv: private data pointer passed on pin registration
344 * @dpll: pointer to dpll
345 * @dpll_priv: private data pointer passed on dpll registration
346 * @frequency: on success holds pin's frequency
347 * @extack: error reporting
348 *
349 * Wraps internal get frequency command of a pin.
350 *
351 * Context: Calls a function which acquires pf->dplls.lock
352 * Return:
353 * * 0 - success
354 * * negative - error pin not found or couldn't get from hw
355 */
356 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)357 ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv,
358 const struct dpll_device *dpll, void *dpll_priv,
359 u64 *frequency, struct netlink_ext_ack *extack)
360 {
361 return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
362 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
363 }
364
365 /**
366 * ice_dpll_sw_pin_frequency_set - callback to set frequency of SW pin
367 * @pin: pointer to a pin
368 * @pin_priv: private data pointer passed on pin registration
369 * @dpll: pointer to dpll
370 * @dpll_priv: private data pointer passed on dpll registration
371 * @frequency: on success holds pin's frequency
372 * @extack: error reporting
373 *
374 * Calls set frequency command for corresponding and active input/output pin.
375 *
376 * Context: Calls a function which acquires and releases pf->dplls.lock
377 * Return:
378 * * 0 - success
379 * * negative - error pin not active or couldn't get from hw
380 */
381 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)382 ice_dpll_sw_pin_frequency_set(const struct dpll_pin *pin, void *pin_priv,
383 const struct dpll_device *dpll, void *dpll_priv,
384 u64 frequency, struct netlink_ext_ack *extack)
385 {
386 struct ice_dpll_pin *sma = pin_priv;
387 int ret;
388
389 if (!sma->active) {
390 NL_SET_ERR_MSG(extack, "pin is not active");
391 return -EINVAL;
392 }
393 if (sma->direction == DPLL_PIN_DIRECTION_INPUT)
394 ret = ice_dpll_input_frequency_set(NULL, sma->input, dpll,
395 dpll_priv, frequency,
396 extack);
397 else
398 ret = ice_dpll_output_frequency_set(NULL, sma->output, dpll,
399 dpll_priv, frequency,
400 extack);
401
402 return ret;
403 }
404
405 /**
406 * ice_dpll_sw_pin_frequency_get - callback for get frequency of SW pin
407 * @pin: pointer to a pin
408 * @pin_priv: private data pointer passed on pin registration
409 * @dpll: pointer to dpll
410 * @dpll_priv: private data pointer passed on dpll registration
411 * @frequency: on success holds pin's frequency
412 * @extack: error reporting
413 *
414 * Calls get frequency command for corresponding active input/output.
415 *
416 * Context: Calls a function which acquires and releases pf->dplls.lock
417 * Return:
418 * * 0 - success
419 * * negative - error pin not active or couldn't get from hw
420 */
421 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)422 ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv,
423 const struct dpll_device *dpll, void *dpll_priv,
424 u64 *frequency, struct netlink_ext_ack *extack)
425 {
426 struct ice_dpll_pin *sma = pin_priv;
427 int ret;
428
429 if (!sma->active) {
430 *frequency = 0;
431 return 0;
432 }
433 if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
434 ret = ice_dpll_input_frequency_get(NULL, sma->input, dpll,
435 dpll_priv, frequency,
436 extack);
437 } else {
438 ret = ice_dpll_output_frequency_get(NULL, sma->output, dpll,
439 dpll_priv, frequency,
440 extack);
441 }
442
443 return ret;
444 }
445
446 /**
447 * ice_dpll_pin_enable - enable a pin on dplls
448 * @hw: board private hw structure
449 * @pin: pointer to a pin
450 * @dpll_idx: dpll index to connect to output pin
451 * @pin_type: type of pin being enabled
452 * @extack: error reporting
453 *
454 * Enable a pin on both dplls. Store current state in pin->flags.
455 *
456 * Context: Called under pf->dplls.lock
457 * Return:
458 * * 0 - OK
459 * * negative - error
460 */
461 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)462 ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin,
463 u8 dpll_idx, enum ice_dpll_pin_type pin_type,
464 struct netlink_ext_ack *extack)
465 {
466 u8 flags = 0;
467 int ret;
468
469 switch (pin_type) {
470 case ICE_DPLL_PIN_TYPE_INPUT:
471 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
472 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
473 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
474 ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
475 break;
476 case ICE_DPLL_PIN_TYPE_OUTPUT:
477 flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_SRC_SEL;
478 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
479 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
480 flags |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
481 ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, dpll_idx,
482 0, 0);
483 break;
484 default:
485 return -EINVAL;
486 }
487 if (ret)
488 NL_SET_ERR_MSG_FMT(extack,
489 "err:%d %s failed to enable %s pin:%u",
490 ret, libie_aq_str(hw->adminq.sq_last_status),
491 pin_type_name[pin_type], pin->idx);
492
493 return ret;
494 }
495
496 /**
497 * ice_dpll_pin_disable - disable a pin on dplls
498 * @hw: board private hw structure
499 * @pin: pointer to a pin
500 * @pin_type: type of pin being disabled
501 * @extack: error reporting
502 *
503 * Disable a pin on both dplls. Store current state in pin->flags.
504 *
505 * Context: Called under pf->dplls.lock
506 * Return:
507 * * 0 - OK
508 * * negative - error
509 */
510 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)511 ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
512 enum ice_dpll_pin_type pin_type,
513 struct netlink_ext_ack *extack)
514 {
515 u8 flags = 0;
516 int ret;
517
518 switch (pin_type) {
519 case ICE_DPLL_PIN_TYPE_INPUT:
520 if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
521 flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
522 ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
523 break;
524 case ICE_DPLL_PIN_TYPE_OUTPUT:
525 if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
526 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
527 ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0);
528 break;
529 default:
530 return -EINVAL;
531 }
532 if (ret)
533 NL_SET_ERR_MSG_FMT(extack,
534 "err:%d %s failed to disable %s pin:%u",
535 ret, libie_aq_str(hw->adminq.sq_last_status),
536 pin_type_name[pin_type], pin->idx);
537
538 return ret;
539 }
540
541 /**
542 * ice_dpll_pin_store_state - updates the state of pin in SW bookkeeping
543 * @pin: pointer to a pin
544 * @parent: parent pin index
545 * @state: pin state (connected or disconnected)
546 */
547 static void
ice_dpll_pin_store_state(struct ice_dpll_pin * pin,int parent,bool state)548 ice_dpll_pin_store_state(struct ice_dpll_pin *pin, int parent, bool state)
549 {
550 pin->state[parent] = state ? DPLL_PIN_STATE_CONNECTED :
551 DPLL_PIN_STATE_DISCONNECTED;
552 }
553
554 /**
555 * ice_dpll_rclk_update_e825c - updates the state of rclk pin on e825c device
556 * @pf: private board struct
557 * @pin: pointer to a pin
558 *
559 * Update struct holding pin states info, states are separate for each parent
560 *
561 * Context: Called under pf->dplls.lock
562 * Return:
563 * * 0 - OK
564 * * negative - error
565 */
ice_dpll_rclk_update_e825c(struct ice_pf * pf,struct ice_dpll_pin * pin)566 static int ice_dpll_rclk_update_e825c(struct ice_pf *pf,
567 struct ice_dpll_pin *pin)
568 {
569 u8 rclk_bits;
570 int err;
571 u32 reg;
572
573 if (pf->dplls.rclk.num_parents > ICE_SYNCE_CLK_NUM)
574 return -EINVAL;
575
576 err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R10, ®);
577 if (err)
578 return err;
579
580 rclk_bits = FIELD_GET(ICE_CGU_R10_SYNCE_S_REF_CLK, reg);
581 ice_dpll_pin_store_state(pin, ICE_SYNCE_CLK0, rclk_bits ==
582 (pf->ptp.port.port_num + ICE_CGU_BYPASS_MUX_OFFSET_E825C));
583
584 err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R11, ®);
585 if (err)
586 return err;
587
588 rclk_bits = FIELD_GET(ICE_CGU_R11_SYNCE_S_BYP_CLK, reg);
589 ice_dpll_pin_store_state(pin, ICE_SYNCE_CLK1, rclk_bits ==
590 (pf->ptp.port.port_num + ICE_CGU_BYPASS_MUX_OFFSET_E825C));
591
592 return 0;
593 }
594
595 /**
596 * ice_dpll_rclk_update - updates the state of rclk pin on a device
597 * @pf: private board struct
598 * @pin: pointer to a pin
599 * @port_num: port number
600 *
601 * Update struct holding pin states info, states are separate for each parent
602 *
603 * Context: Called under pf->dplls.lock
604 * Return:
605 * * 0 - OK
606 * * negative - error
607 */
ice_dpll_rclk_update(struct ice_pf * pf,struct ice_dpll_pin * pin,u8 port_num)608 static int ice_dpll_rclk_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
609 u8 port_num)
610 {
611 int ret;
612
613 for (u8 parent = 0; parent < pf->dplls.rclk.num_parents; parent++) {
614 u8 p = parent;
615
616 ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &p, &port_num,
617 &pin->flags[parent], NULL);
618 if (ret)
619 return ret;
620
621 ice_dpll_pin_store_state(pin, parent,
622 ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
623 pin->flags[parent]);
624 }
625
626 return 0;
627 }
628
629 /**
630 * ice_dpll_sw_pins_update - update status of all SW pins
631 * @pf: private board struct
632 *
633 * Determine and update pin struct fields (direction/active) of their current
634 * values for all the SW controlled pins.
635 *
636 * Context: Call with pf->dplls.lock held
637 * Return:
638 * * 0 - OK
639 * * negative - error
640 */
641 static int
ice_dpll_sw_pins_update(struct ice_pf * pf)642 ice_dpll_sw_pins_update(struct ice_pf *pf)
643 {
644 struct ice_dplls *d = &pf->dplls;
645 struct ice_dpll_pin *p;
646 u8 data = 0;
647 int ret;
648
649 ret = ice_read_sma_ctrl(&pf->hw, &data);
650 if (ret)
651 return ret;
652 /* no change since last check */
653 if (d->sma_data == data)
654 return 0;
655
656 /*
657 * SMA1/U.FL1 vs SMA2/U.FL2 are using different bit scheme to decide
658 * on their direction and if are active
659 */
660 p = &d->sma[ICE_DPLL_PIN_SW_1_IDX];
661 p->active = true;
662 p->direction = DPLL_PIN_DIRECTION_INPUT;
663 if (data & ICE_SMA1_DIR_EN) {
664 p->direction = DPLL_PIN_DIRECTION_OUTPUT;
665 if (data & ICE_SMA1_TX_EN)
666 p->active = false;
667 }
668
669 p = &d->sma[ICE_DPLL_PIN_SW_2_IDX];
670 p->active = true;
671 p->direction = DPLL_PIN_DIRECTION_INPUT;
672 if ((data & ICE_SMA2_INACTIVE_MASK) == ICE_SMA2_INACTIVE_MASK)
673 p->active = false;
674 else if (data & ICE_SMA2_DIR_EN)
675 p->direction = DPLL_PIN_DIRECTION_OUTPUT;
676
677 p = &d->ufl[ICE_DPLL_PIN_SW_1_IDX];
678 if (!(data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)))
679 p->active = true;
680 else
681 p->active = false;
682
683 p = &d->ufl[ICE_DPLL_PIN_SW_2_IDX];
684 p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_DIS);
685 d->sma_data = data;
686
687 return 0;
688 }
689
690 /**
691 * ice_dpll_pin_state_update - update pin's state
692 * @pf: private board struct
693 * @pin: structure with pin attributes to be updated
694 * @pin_type: type of pin being updated
695 * @extack: error reporting
696 *
697 * Determine pin current state and frequency, then update struct
698 * holding the pin info. For input pin states are separated for each
699 * dpll, for rclk pins states are separated for each parent.
700 *
701 * Context: Called under pf->dplls.lock
702 * Return:
703 * * 0 - OK
704 * * negative - error
705 */
706 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)707 ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
708 enum ice_dpll_pin_type pin_type,
709 struct netlink_ext_ack *extack)
710 {
711 u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
712 int ret;
713
714 switch (pin_type) {
715 case ICE_DPLL_PIN_TYPE_INPUT:
716 ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
717 NULL, NULL, &pin->flags[0],
718 &pin->freq, &pin->phase_adjust);
719 if (ret)
720 goto err;
721 if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
722 if (pin->pin) {
723 pin->state[pf->dplls.eec.dpll_idx] =
724 pin->pin == pf->dplls.eec.active_input ?
725 DPLL_PIN_STATE_CONNECTED :
726 DPLL_PIN_STATE_SELECTABLE;
727 pin->state[pf->dplls.pps.dpll_idx] =
728 pin->pin == pf->dplls.pps.active_input ?
729 DPLL_PIN_STATE_CONNECTED :
730 DPLL_PIN_STATE_SELECTABLE;
731 } else {
732 pin->state[pf->dplls.eec.dpll_idx] =
733 DPLL_PIN_STATE_SELECTABLE;
734 pin->state[pf->dplls.pps.dpll_idx] =
735 DPLL_PIN_STATE_SELECTABLE;
736 }
737 } else {
738 pin->state[pf->dplls.eec.dpll_idx] =
739 DPLL_PIN_STATE_DISCONNECTED;
740 pin->state[pf->dplls.pps.dpll_idx] =
741 DPLL_PIN_STATE_DISCONNECTED;
742 }
743 break;
744 case ICE_DPLL_PIN_TYPE_OUTPUT:
745 ret = ice_aq_get_output_pin_cfg(&pf->hw, pin->idx,
746 &pin->flags[0], &parent,
747 &pin->freq, NULL);
748 if (ret)
749 goto err;
750
751 parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
752 if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
753 pin->state[pf->dplls.eec.dpll_idx] =
754 parent == pf->dplls.eec.dpll_idx ?
755 DPLL_PIN_STATE_CONNECTED :
756 DPLL_PIN_STATE_DISCONNECTED;
757 pin->state[pf->dplls.pps.dpll_idx] =
758 parent == pf->dplls.pps.dpll_idx ?
759 DPLL_PIN_STATE_CONNECTED :
760 DPLL_PIN_STATE_DISCONNECTED;
761 } else {
762 pin->state[pf->dplls.eec.dpll_idx] =
763 DPLL_PIN_STATE_DISCONNECTED;
764 pin->state[pf->dplls.pps.dpll_idx] =
765 DPLL_PIN_STATE_DISCONNECTED;
766 }
767 break;
768 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
769 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
770 ret = ice_dpll_rclk_update_e825c(pf, pin);
771 if (ret)
772 goto err;
773 } else {
774 ret = ice_dpll_rclk_update(pf, pin, port_num);
775 if (ret)
776 goto err;
777 }
778 break;
779 case ICE_DPLL_PIN_TYPE_SOFTWARE:
780 ret = ice_dpll_sw_pins_update(pf);
781 if (ret)
782 goto err;
783 break;
784 default:
785 return -EINVAL;
786 }
787
788 return 0;
789 err:
790 if (extack)
791 NL_SET_ERR_MSG_FMT(extack,
792 "err:%d %s failed to update %s pin:%u",
793 ret,
794 libie_aq_str(pf->hw.adminq.sq_last_status),
795 pin_type_name[pin_type], pin->idx);
796 else if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY)
797 dev_err_ratelimited(ice_pf_to_dev(pf),
798 "err:%d %s failed to update %s pin:%u\n",
799 ret,
800 libie_aq_str(pf->hw.adminq.sq_last_status),
801 pin_type_name[pin_type], pin->idx);
802 return ret;
803 }
804
805 /**
806 * ice_dpll_hw_input_prio_set - set input priority value in hardware
807 * @pf: board private structure
808 * @dpll: ice dpll pointer
809 * @pin: ice pin pointer
810 * @prio: priority value being set on a dpll
811 * @extack: error reporting
812 *
813 * Internal wrapper for setting the priority in the hardware.
814 *
815 * Context: Called under pf->dplls.lock
816 * Return:
817 * * 0 - success
818 * * negative - failure
819 */
820 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)821 ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
822 struct ice_dpll_pin *pin, const u32 prio,
823 struct netlink_ext_ack *extack)
824 {
825 int ret;
826
827 ret = ice_aq_set_cgu_ref_prio(&pf->hw, dpll->dpll_idx, pin->idx,
828 (u8)prio);
829 if (ret)
830 NL_SET_ERR_MSG_FMT(extack,
831 "err:%d %s failed to set pin prio:%u on pin:%u",
832 ret,
833 libie_aq_str(pf->hw.adminq.sq_last_status),
834 prio, pin->idx);
835 else
836 dpll->input_prio[pin->idx] = prio;
837
838 return ret;
839 }
840
841 /**
842 * ice_dpll_lock_status_get - get dpll lock status callback
843 * @dpll: registered dpll pointer
844 * @dpll_priv: private data pointer passed on dpll registration
845 * @status: on success holds dpll's lock status
846 * @status_error: status error value
847 * @extack: error reporting
848 *
849 * Dpll subsystem callback, provides dpll's lock status.
850 *
851 * Context: Acquires pf->dplls.lock
852 * Return:
853 * * 0 - success
854 * * negative - failure
855 */
856 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)857 ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
858 enum dpll_lock_status *status,
859 enum dpll_lock_status_error *status_error,
860 struct netlink_ext_ack *extack)
861 {
862 struct ice_dpll *d = dpll_priv;
863 struct ice_pf *pf = d->pf;
864
865 mutex_lock(&pf->dplls.lock);
866 *status = d->dpll_state;
867 mutex_unlock(&pf->dplls.lock);
868
869 return 0;
870 }
871
872 /**
873 * ice_dpll_mode_get - get dpll's working mode
874 * @dpll: registered dpll pointer
875 * @dpll_priv: private data pointer passed on dpll registration
876 * @mode: on success holds current working mode of dpll
877 * @extack: error reporting
878 *
879 * Dpll subsystem callback. Provides working mode of dpll.
880 *
881 * Context: Acquires pf->dplls.lock
882 * Return:
883 * * 0 - success
884 * * negative - failure
885 */
ice_dpll_mode_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_mode * mode,struct netlink_ext_ack * extack)886 static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
887 enum dpll_mode *mode,
888 struct netlink_ext_ack *extack)
889 {
890 struct ice_dpll *d = dpll_priv;
891 struct ice_pf *pf = d->pf;
892
893 mutex_lock(&pf->dplls.lock);
894 *mode = d->mode;
895 mutex_unlock(&pf->dplls.lock);
896
897 return 0;
898 }
899
900 /**
901 * ice_dpll_phase_offset_monitor_set - set phase offset monitor state
902 * @dpll: registered dpll pointer
903 * @dpll_priv: private data pointer passed on dpll registration
904 * @state: feature state to be set
905 * @extack: error reporting
906 *
907 * Dpll subsystem callback. Enable/disable phase offset monitor feature of dpll.
908 *
909 * Context: Acquires and releases pf->dplls.lock
910 * Return: 0 - success
911 */
ice_dpll_phase_offset_monitor_set(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state state,struct netlink_ext_ack * extack)912 static int ice_dpll_phase_offset_monitor_set(const struct dpll_device *dpll,
913 void *dpll_priv,
914 enum dpll_feature_state state,
915 struct netlink_ext_ack *extack)
916 {
917 struct ice_dpll *d = dpll_priv;
918 struct ice_pf *pf = d->pf;
919
920 mutex_lock(&pf->dplls.lock);
921 if (state == DPLL_FEATURE_STATE_ENABLE)
922 d->phase_offset_monitor_period = ICE_DPLL_PHASE_OFFSET_PERIOD;
923 else
924 d->phase_offset_monitor_period = 0;
925 mutex_unlock(&pf->dplls.lock);
926
927 return 0;
928 }
929
930 /**
931 * ice_dpll_phase_offset_monitor_get - get phase offset monitor state
932 * @dpll: registered dpll pointer
933 * @dpll_priv: private data pointer passed on dpll registration
934 * @state: on success holds current state of phase offset monitor
935 * @extack: error reporting
936 *
937 * Dpll subsystem callback. Provides current state of phase offset monitor
938 * features on dpll device.
939 *
940 * Context: Acquires and releases pf->dplls.lock
941 * Return: 0 - success
942 */
ice_dpll_phase_offset_monitor_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state * state,struct netlink_ext_ack * extack)943 static int ice_dpll_phase_offset_monitor_get(const struct dpll_device *dpll,
944 void *dpll_priv,
945 enum dpll_feature_state *state,
946 struct netlink_ext_ack *extack)
947 {
948 struct ice_dpll *d = dpll_priv;
949 struct ice_pf *pf = d->pf;
950
951 mutex_lock(&pf->dplls.lock);
952 if (d->phase_offset_monitor_period)
953 *state = DPLL_FEATURE_STATE_ENABLE;
954 else
955 *state = DPLL_FEATURE_STATE_DISABLE;
956 mutex_unlock(&pf->dplls.lock);
957
958 return 0;
959 }
960
961 /**
962 * ice_dpll_pin_state_set - set pin's state on dpll
963 * @pin: pointer to a pin
964 * @pin_priv: private data pointer passed on pin registration
965 * @dpll: registered dpll pointer
966 * @dpll_priv: private data pointer passed on dpll registration
967 * @enable: if pin shalll be enabled
968 * @extack: error reporting
969 * @pin_type: type of a pin
970 *
971 * Set pin state on a pin.
972 *
973 * Context: Acquires pf->dplls.lock
974 * Return:
975 * * 0 - OK or no change required
976 * * negative - error
977 */
978 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)979 ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
980 const struct dpll_device *dpll, void *dpll_priv,
981 bool enable, struct netlink_ext_ack *extack,
982 enum ice_dpll_pin_type pin_type)
983 {
984 struct ice_dpll_pin *p = pin_priv;
985 struct ice_dpll *d = dpll_priv;
986 struct ice_pf *pf = d->pf;
987 int ret;
988
989 if (ice_dpll_is_reset(pf, extack))
990 return -EBUSY;
991
992 mutex_lock(&pf->dplls.lock);
993 if (enable)
994 ret = ice_dpll_pin_enable(&pf->hw, p, d->dpll_idx, pin_type,
995 extack);
996 else
997 ret = ice_dpll_pin_disable(&pf->hw, p, pin_type, extack);
998 if (!ret)
999 ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
1000 mutex_unlock(&pf->dplls.lock);
1001
1002 return ret;
1003 }
1004
1005 /**
1006 * ice_dpll_output_state_set - enable/disable output pin on dpll device
1007 * @pin: pointer to a pin
1008 * @pin_priv: private data pointer passed on pin registration
1009 * @dpll: dpll being configured
1010 * @dpll_priv: private data pointer passed on dpll registration
1011 * @state: state of pin to be set
1012 * @extack: error reporting
1013 *
1014 * Dpll subsystem callback. Set given state on output type pin.
1015 *
1016 * Context: Calls a function which acquires pf->dplls.lock
1017 * Return:
1018 * * 0 - successfully enabled mode
1019 * * negative - failed to enable mode
1020 */
1021 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)1022 ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
1023 const struct dpll_device *dpll, void *dpll_priv,
1024 enum dpll_pin_state state,
1025 struct netlink_ext_ack *extack)
1026 {
1027 bool enable = state == DPLL_PIN_STATE_CONNECTED;
1028 struct ice_dpll_pin *p = pin_priv;
1029 struct ice_dpll *d = dpll_priv;
1030
1031 if (state == DPLL_PIN_STATE_SELECTABLE)
1032 return -EINVAL;
1033 if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
1034 return 0;
1035
1036 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
1037 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
1038 }
1039
1040 /**
1041 * ice_dpll_input_state_set - enable/disable input pin on dpll levice
1042 * @pin: pointer to a pin
1043 * @pin_priv: private data pointer passed on pin registration
1044 * @dpll: dpll being configured
1045 * @dpll_priv: private data pointer passed on dpll registration
1046 * @state: state of pin to be set
1047 * @extack: error reporting
1048 *
1049 * Dpll subsystem callback. Enables given mode on input type pin.
1050 *
1051 * Context: Calls a function which acquires pf->dplls.lock
1052 * Return:
1053 * * 0 - successfully enabled mode
1054 * * negative - failed to enable mode
1055 */
1056 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)1057 ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv,
1058 const struct dpll_device *dpll, void *dpll_priv,
1059 enum dpll_pin_state state,
1060 struct netlink_ext_ack *extack)
1061 {
1062 bool enable = state == DPLL_PIN_STATE_SELECTABLE;
1063
1064 return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
1065 extack, ICE_DPLL_PIN_TYPE_INPUT);
1066 }
1067
1068 /**
1069 * ice_dpll_pin_state_get - set pin's state on dpll
1070 * @pin: pointer to a pin
1071 * @pin_priv: private data pointer passed on pin registration
1072 * @dpll: registered dpll pointer
1073 * @dpll_priv: private data pointer passed on dpll registration
1074 * @state: on success holds state of the pin
1075 * @extack: error reporting
1076 * @pin_type: type of questioned pin
1077 *
1078 * Determine pin state set it on a pin.
1079 *
1080 * Context: Acquires pf->dplls.lock
1081 * Return:
1082 * * 0 - success
1083 * * negative - failed to get state
1084 */
1085 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)1086 ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1087 const struct dpll_device *dpll, void *dpll_priv,
1088 enum dpll_pin_state *state,
1089 struct netlink_ext_ack *extack,
1090 enum ice_dpll_pin_type pin_type)
1091 {
1092 struct ice_dpll_pin *p = pin_priv;
1093 struct ice_dpll *d = dpll_priv;
1094 struct ice_pf *pf = d->pf;
1095 int ret;
1096
1097 if (ice_dpll_is_reset(pf, extack))
1098 return -EBUSY;
1099
1100 mutex_lock(&pf->dplls.lock);
1101 ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
1102 if (ret)
1103 goto unlock;
1104 if (pin_type == ICE_DPLL_PIN_TYPE_INPUT ||
1105 pin_type == ICE_DPLL_PIN_TYPE_OUTPUT)
1106 *state = p->state[d->dpll_idx];
1107 ret = 0;
1108 unlock:
1109 mutex_unlock(&pf->dplls.lock);
1110
1111 return ret;
1112 }
1113
1114 /**
1115 * ice_dpll_output_state_get - get output pin state on dpll device
1116 * @pin: pointer to a pin
1117 * @pin_priv: private data pointer passed on pin registration
1118 * @dpll: registered dpll pointer
1119 * @dpll_priv: private data pointer passed on dpll registration
1120 * @state: on success holds state of the pin
1121 * @extack: error reporting
1122 *
1123 * Dpll subsystem callback. Check state of a pin.
1124 *
1125 * Context: Calls a function which acquires pf->dplls.lock
1126 * Return:
1127 * * 0 - success
1128 * * negative - failed to get state
1129 */
1130 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)1131 ice_dpll_output_state_get(const struct dpll_pin *pin, void *pin_priv,
1132 const struct dpll_device *dpll, void *dpll_priv,
1133 enum dpll_pin_state *state,
1134 struct netlink_ext_ack *extack)
1135 {
1136 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1137 extack, ICE_DPLL_PIN_TYPE_OUTPUT);
1138 }
1139
1140 /**
1141 * ice_dpll_input_state_get - get input pin state on dpll device
1142 * @pin: pointer to a pin
1143 * @pin_priv: private data pointer passed on pin registration
1144 * @dpll: registered dpll pointer
1145 * @dpll_priv: private data pointer passed on dpll registration
1146 * @state: on success holds state of the pin
1147 * @extack: error reporting
1148 *
1149 * Dpll subsystem callback. Check state of a input pin.
1150 *
1151 * Context: Calls a function which acquires pf->dplls.lock
1152 * Return:
1153 * * 0 - success
1154 * * negative - failed to get state
1155 */
1156 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)1157 ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
1158 const struct dpll_device *dpll, void *dpll_priv,
1159 enum dpll_pin_state *state,
1160 struct netlink_ext_ack *extack)
1161 {
1162 return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1163 extack, ICE_DPLL_PIN_TYPE_INPUT);
1164 }
1165
1166 /**
1167 * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
1168 * @d: pointer to dplls struct
1169 * @changed: the SW pin that was explicitly changed (already notified by dpll core)
1170 *
1171 * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
1172 * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
1173 * expander, the paired pin's state may also change. Send a change
1174 * notification for the peer pin so userspace consumers monitoring the
1175 * peer via dpll netlink learn about the update.
1176 *
1177 * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
1178 * released. Uses __dpll_pin_change_ntf() because dpll_lock is
1179 * still held by the dpll netlink layer.
1180 */
ice_dpll_sw_pin_notify_peer(struct ice_dplls * d,struct ice_dpll_pin * changed)1181 static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
1182 struct ice_dpll_pin *changed)
1183 {
1184 struct ice_dpll_pin *peer;
1185
1186 peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ?
1187 &d->ufl[changed->idx] : &d->sma[changed->idx];
1188 if (peer->pin)
1189 __dpll_pin_change_ntf(peer->pin);
1190 }
1191
1192 /**
1193 * ice_dpll_sma_direction_set - set direction of SMA pin
1194 * @p: pointer to a pin
1195 * @direction: requested direction of the pin
1196 * @extack: error reporting
1197 *
1198 * Wrapper for dpll subsystem callback. Set direction of a SMA pin.
1199 *
1200 * Context: Call with pf->dplls.lock held
1201 * Return:
1202 * * 0 - success
1203 * * negative - failed to get state
1204 */
ice_dpll_sma_direction_set(struct ice_dpll_pin * p,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1205 static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
1206 enum dpll_pin_direction direction,
1207 struct netlink_ext_ack *extack)
1208 {
1209 struct ice_dplls *d = &p->pf->dplls;
1210 struct ice_dpll_pin *peer;
1211 u8 data;
1212 int ret;
1213
1214 if (p->direction == direction && p->active)
1215 return 0;
1216 ret = ice_read_sma_ctrl(&p->pf->hw, &data);
1217 if (ret)
1218 return ret;
1219
1220 switch (p->idx) {
1221 case ICE_DPLL_PIN_SW_1_IDX:
1222 data &= ~ICE_SMA1_MASK;
1223 if (direction == DPLL_PIN_DIRECTION_OUTPUT)
1224 data |= ICE_SMA1_DIR_EN;
1225 break;
1226 case ICE_DPLL_PIN_SW_2_IDX:
1227 if (direction == DPLL_PIN_DIRECTION_INPUT) {
1228 data &= ~ICE_SMA2_DIR_EN;
1229 data |= ICE_SMA2_UFL2_RX_DIS;
1230 } else {
1231 data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);
1232 data |= ICE_SMA2_DIR_EN;
1233 }
1234 break;
1235 default:
1236 return -EINVAL;
1237 }
1238 ret = ice_write_sma_ctrl(&p->pf->hw, data);
1239 if (!ret)
1240 ret = ice_dpll_pin_state_update(p->pf, p,
1241 ICE_DPLL_PIN_TYPE_SOFTWARE,
1242 extack);
1243 if (ret)
1244 return ret;
1245
1246 /* When a direction change activates the paired U.FL pin, enable
1247 * its backing CGU pin so the pin reports as connected. Without
1248 * this the U.FL routing is correct but the CGU pin stays disabled
1249 * and userspace sees the pin as disconnected. Do not disable the
1250 * backing pin when U.FL becomes inactive because the SMA pin may
1251 * still be using it.
1252 */
1253 peer = &d->ufl[p->idx];
1254 if (peer->active) {
1255 struct ice_dpll_pin *target;
1256 enum ice_dpll_pin_type type;
1257
1258 if (peer->output) {
1259 target = peer->output;
1260 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1261 } else {
1262 target = peer->input;
1263 type = ICE_DPLL_PIN_TYPE_INPUT;
1264 }
1265 ret = ice_dpll_pin_enable(&p->pf->hw, target,
1266 d->eec.dpll_idx, type, extack);
1267 if (!ret)
1268 ret = ice_dpll_pin_state_update(p->pf, target,
1269 type, extack);
1270 }
1271
1272 return ret;
1273 }
1274
1275 /**
1276 * ice_dpll_ufl_pin_state_set - set U.FL pin state on dpll device
1277 * @pin: pointer to a pin
1278 * @pin_priv: private data pointer passed on pin registration
1279 * @dpll: registered dpll pointer
1280 * @dpll_priv: private data pointer passed on dpll registration
1281 * @state: requested state of the pin
1282 * @extack: error reporting
1283 *
1284 * Dpll subsystem callback. Set the state of a pin.
1285 *
1286 * Context: Acquires and releases pf->dplls.lock
1287 * Return:
1288 * * 0 - success
1289 * * negative - error
1290 */
1291 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)1292 ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1293 const struct dpll_device *dpll, void *dpll_priv,
1294 enum dpll_pin_state state,
1295 struct netlink_ext_ack *extack)
1296 {
1297 struct ice_dpll_pin *p = pin_priv, *target;
1298 struct ice_dpll *d = dpll_priv;
1299 enum ice_dpll_pin_type type;
1300 struct ice_pf *pf = p->pf;
1301 struct ice_hw *hw;
1302 bool enable;
1303 u8 data;
1304 int ret;
1305
1306 if (ice_dpll_is_reset(pf, extack))
1307 return -EBUSY;
1308
1309 mutex_lock(&pf->dplls.lock);
1310 hw = &pf->hw;
1311 ret = ice_read_sma_ctrl(hw, &data);
1312 if (ret)
1313 goto unlock;
1314
1315 ret = -EINVAL;
1316 switch (p->idx) {
1317 case ICE_DPLL_PIN_SW_1_IDX:
1318 if (state == DPLL_PIN_STATE_CONNECTED) {
1319 data &= ~ICE_SMA1_MASK;
1320 enable = true;
1321 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1322 /* Skip if U.FL1 is not active, setting TX_EN
1323 * while DIR_EN is set would also deactivate
1324 * the paired SMA1 output.
1325 */
1326 if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) {
1327 ret = 0;
1328 goto unlock;
1329 }
1330 data |= ICE_SMA1_TX_EN;
1331 enable = false;
1332 } else {
1333 goto unlock;
1334 }
1335 target = p->output;
1336 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1337 break;
1338 case ICE_DPLL_PIN_SW_2_IDX:
1339 if (state == DPLL_PIN_STATE_SELECTABLE) {
1340 data |= ICE_SMA2_DIR_EN;
1341 data &= ~ICE_SMA2_UFL2_RX_DIS;
1342 enable = true;
1343 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1344 /* Skip if U.FL2 is not active, setting
1345 * UFL2_RX_DIS could also disable the paired
1346 * SMA2 input.
1347 */
1348 if (!(data & ICE_SMA2_DIR_EN) ||
1349 (data & ICE_SMA2_UFL2_RX_DIS)) {
1350 ret = 0;
1351 goto unlock;
1352 }
1353 data |= ICE_SMA2_UFL2_RX_DIS;
1354 enable = false;
1355 } else {
1356 goto unlock;
1357 }
1358 target = p->input;
1359 type = ICE_DPLL_PIN_TYPE_INPUT;
1360 break;
1361 default:
1362 goto unlock;
1363 }
1364
1365 ret = ice_write_sma_ctrl(hw, data);
1366 if (ret)
1367 goto unlock;
1368 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,
1369 extack);
1370 if (ret)
1371 goto unlock;
1372
1373 if (enable)
1374 ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
1375 else
1376 ret = ice_dpll_pin_disable(hw, target, type, extack);
1377 if (!ret)
1378 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1379
1380 unlock:
1381 mutex_unlock(&pf->dplls.lock);
1382 if (!ret)
1383 ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
1384
1385 return ret;
1386 }
1387
1388 /**
1389 * ice_dpll_sw_pin_state_get - get SW pin state
1390 * @pin: pointer to a pin
1391 * @pin_priv: private data pointer passed on pin registration
1392 * @dpll: registered dpll pointer
1393 * @dpll_priv: private data pointer passed on dpll registration
1394 * @state: on success holds state of the pin
1395 * @extack: error reporting
1396 *
1397 * Dpll subsystem callback. Check state of a SW pin.
1398 *
1399 * Context: Acquires and releases pf->dplls.lock
1400 * Return:
1401 * * 0 - success
1402 * * negative - error
1403 */
1404 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)1405 ice_dpll_sw_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1406 const struct dpll_device *dpll, void *dpll_priv,
1407 enum dpll_pin_state *state,
1408 struct netlink_ext_ack *extack)
1409 {
1410 struct ice_dpll_pin *p = pin_priv;
1411 struct ice_dpll *d = dpll_priv;
1412 struct ice_pf *pf = p->pf;
1413 int ret = 0;
1414
1415 if (ice_dpll_is_reset(pf, extack))
1416 return -EBUSY;
1417 mutex_lock(&pf->dplls.lock);
1418 if (!p->active) {
1419 *state = DPLL_PIN_STATE_DISCONNECTED;
1420 goto unlock;
1421 }
1422
1423 if (p->direction == DPLL_PIN_DIRECTION_INPUT) {
1424 ret = ice_dpll_pin_state_update(pf, p->input,
1425 ICE_DPLL_PIN_TYPE_INPUT,
1426 extack);
1427 if (ret)
1428 goto unlock;
1429 *state = p->input->state[d->dpll_idx];
1430 } else {
1431 ret = ice_dpll_pin_state_update(pf, p->output,
1432 ICE_DPLL_PIN_TYPE_OUTPUT,
1433 extack);
1434 if (ret)
1435 goto unlock;
1436 *state = p->output->state[d->dpll_idx];
1437 }
1438 unlock:
1439 mutex_unlock(&pf->dplls.lock);
1440
1441 return ret;
1442 }
1443
1444 /**
1445 * ice_dpll_sma_pin_state_set - set SMA pin state on dpll device
1446 * @pin: pointer to a pin
1447 * @pin_priv: private data pointer passed on pin registration
1448 * @dpll: registered dpll pointer
1449 * @dpll_priv: private data pointer passed on dpll registration
1450 * @state: requested state of the pin
1451 * @extack: error reporting
1452 *
1453 * Dpll subsystem callback. Set state of a pin.
1454 *
1455 * Context: Acquires and releases pf->dplls.lock
1456 * Return:
1457 * * 0 - success
1458 * * negative - failed to get state
1459 */
1460 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)1461 ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1462 const struct dpll_device *dpll, void *dpll_priv,
1463 enum dpll_pin_state state,
1464 struct netlink_ext_ack *extack)
1465 {
1466 struct ice_dpll_pin *sma = pin_priv, *target;
1467 struct ice_dpll *d = dpll_priv;
1468 struct ice_pf *pf = sma->pf;
1469 enum ice_dpll_pin_type type;
1470 bool enable;
1471 int ret;
1472
1473 if (ice_dpll_is_reset(pf, extack))
1474 return -EBUSY;
1475
1476 mutex_lock(&pf->dplls.lock);
1477 if (!sma->active) {
1478 ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
1479 if (ret)
1480 goto unlock;
1481 }
1482 if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
1483 enable = state == DPLL_PIN_STATE_SELECTABLE;
1484 target = sma->input;
1485 type = ICE_DPLL_PIN_TYPE_INPUT;
1486 } else {
1487 enable = state == DPLL_PIN_STATE_CONNECTED;
1488 target = sma->output;
1489 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1490 }
1491
1492 if (enable)
1493 ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
1494 extack);
1495 else
1496 ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
1497 if (!ret)
1498 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1499
1500 unlock:
1501 mutex_unlock(&pf->dplls.lock);
1502 if (!ret)
1503 ice_dpll_sw_pin_notify_peer(&pf->dplls, sma);
1504
1505 return ret;
1506 }
1507
1508 /**
1509 * ice_dpll_input_prio_get - get dpll's input prio
1510 * @pin: pointer to a pin
1511 * @pin_priv: private data pointer passed on pin registration
1512 * @dpll: registered dpll pointer
1513 * @dpll_priv: private data pointer passed on dpll registration
1514 * @prio: on success - returns input priority on dpll
1515 * @extack: error reporting
1516 *
1517 * Dpll subsystem callback. Handler for getting priority of a input pin.
1518 *
1519 * Context: Acquires pf->dplls.lock
1520 * Return:
1521 * * 0 - success
1522 * * negative - failure
1523 */
1524 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)1525 ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1526 const struct dpll_device *dpll, void *dpll_priv,
1527 u32 *prio, struct netlink_ext_ack *extack)
1528 {
1529 struct ice_dpll_pin *p = pin_priv;
1530 struct ice_dpll *d = dpll_priv;
1531 struct ice_pf *pf = d->pf;
1532
1533 mutex_lock(&pf->dplls.lock);
1534 *prio = d->input_prio[p->idx];
1535 mutex_unlock(&pf->dplls.lock);
1536
1537 return 0;
1538 }
1539
1540 /**
1541 * ice_dpll_input_prio_set - set dpll input prio
1542 * @pin: pointer to a pin
1543 * @pin_priv: private data pointer passed on pin registration
1544 * @dpll: registered dpll pointer
1545 * @dpll_priv: private data pointer passed on dpll registration
1546 * @prio: input priority to be set on dpll
1547 * @extack: error reporting
1548 *
1549 * Dpll subsystem callback. Handler for setting priority of a input pin.
1550 *
1551 * Context: Acquires pf->dplls.lock
1552 * Return:
1553 * * 0 - success
1554 * * negative - failure
1555 */
1556 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)1557 ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1558 const struct dpll_device *dpll, void *dpll_priv,
1559 u32 prio, struct netlink_ext_ack *extack)
1560 {
1561 struct ice_dpll_pin *p = pin_priv;
1562 struct ice_dpll *d = dpll_priv;
1563 struct ice_pf *pf = d->pf;
1564 int ret;
1565
1566 if (ice_dpll_is_reset(pf, extack))
1567 return -EBUSY;
1568
1569 mutex_lock(&pf->dplls.lock);
1570 ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
1571 mutex_unlock(&pf->dplls.lock);
1572
1573 return ret;
1574 }
1575
1576 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)1577 ice_dpll_sw_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1578 const struct dpll_device *dpll, void *dpll_priv,
1579 u32 *prio, struct netlink_ext_ack *extack)
1580 {
1581 struct ice_dpll_pin *p = pin_priv;
1582 struct ice_dpll *d = dpll_priv;
1583 struct ice_pf *pf = d->pf;
1584
1585 mutex_lock(&pf->dplls.lock);
1586 if (p->input && p->direction == DPLL_PIN_DIRECTION_INPUT)
1587 *prio = d->input_prio[p->input->idx];
1588 else
1589 *prio = ICE_DPLL_PIN_PRIO_OUTPUT;
1590 mutex_unlock(&pf->dplls.lock);
1591
1592 return 0;
1593 }
1594
1595 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)1596 ice_dpll_sw_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1597 const struct dpll_device *dpll, void *dpll_priv,
1598 u32 prio, struct netlink_ext_ack *extack)
1599 {
1600 struct ice_dpll_pin *p = pin_priv;
1601 struct ice_dpll *d = dpll_priv;
1602 struct ice_pf *pf = d->pf;
1603 int ret;
1604
1605 if (!p->input || p->direction != DPLL_PIN_DIRECTION_INPUT)
1606 return -EINVAL;
1607 if (ice_dpll_is_reset(pf, extack))
1608 return -EBUSY;
1609
1610 mutex_lock(&pf->dplls.lock);
1611 ret = ice_dpll_hw_input_prio_set(pf, d, p->input, prio, extack);
1612 mutex_unlock(&pf->dplls.lock);
1613
1614 return ret;
1615 }
1616
1617 /**
1618 * ice_dpll_input_direction - callback for get input pin direction
1619 * @pin: pointer to a pin
1620 * @pin_priv: private data pointer passed on pin registration
1621 * @dpll: registered dpll pointer
1622 * @dpll_priv: private data pointer passed on dpll registration
1623 * @direction: holds input pin direction
1624 * @extack: error reporting
1625 *
1626 * Dpll subsystem callback. Handler for getting direction of a input pin.
1627 *
1628 * Return:
1629 * * 0 - success
1630 */
1631 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)1632 ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
1633 const struct dpll_device *dpll, void *dpll_priv,
1634 enum dpll_pin_direction *direction,
1635 struct netlink_ext_ack *extack)
1636 {
1637 *direction = DPLL_PIN_DIRECTION_INPUT;
1638
1639 return 0;
1640 }
1641
1642 /**
1643 * ice_dpll_output_direction - callback for get output pin direction
1644 * @pin: pointer to a pin
1645 * @pin_priv: private data pointer passed on pin registration
1646 * @dpll: registered dpll pointer
1647 * @dpll_priv: private data pointer passed on dpll registration
1648 * @direction: holds output pin direction
1649 * @extack: error reporting
1650 *
1651 * Dpll subsystem callback. Handler for getting direction of an output pin.
1652 *
1653 * Return:
1654 * * 0 - success
1655 */
1656 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)1657 ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
1658 const struct dpll_device *dpll, void *dpll_priv,
1659 enum dpll_pin_direction *direction,
1660 struct netlink_ext_ack *extack)
1661 {
1662 *direction = DPLL_PIN_DIRECTION_OUTPUT;
1663
1664 return 0;
1665 }
1666
1667 /**
1668 * ice_dpll_pin_sma_direction_set - callback for set SMA pin direction
1669 * @pin: pointer to a pin
1670 * @pin_priv: private data pointer passed on pin registration
1671 * @dpll: registered dpll pointer
1672 * @dpll_priv: private data pointer passed on dpll registration
1673 * @direction: requested pin direction
1674 * @extack: error reporting
1675 *
1676 * Dpll subsystem callback. Handler for setting direction of a SMA pin.
1677 *
1678 * Context: Acquires and releases pf->dplls.lock
1679 * Return:
1680 * * 0 - success
1681 * * negative - error
1682 */
1683 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)1684 ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
1685 const struct dpll_device *dpll, void *dpll_priv,
1686 enum dpll_pin_direction direction,
1687 struct netlink_ext_ack *extack)
1688 {
1689 struct ice_dpll_pin *p = pin_priv;
1690 struct ice_pf *pf = p->pf;
1691 int ret;
1692
1693 if (ice_dpll_is_reset(pf, extack))
1694 return -EBUSY;
1695
1696 mutex_lock(&pf->dplls.lock);
1697 ret = ice_dpll_sma_direction_set(p, direction, extack);
1698 mutex_unlock(&pf->dplls.lock);
1699 if (!ret)
1700 ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
1701
1702 return ret;
1703 }
1704
1705 /**
1706 * ice_dpll_pin_sw_direction_get - callback for get SW pin direction
1707 * @pin: pointer to a pin
1708 * @pin_priv: private data pointer passed on pin registration
1709 * @dpll: registered dpll pointer
1710 * @dpll_priv: private data pointer passed on dpll registration
1711 * @direction: on success holds pin direction
1712 * @extack: error reporting
1713 *
1714 * Dpll subsystem callback. Handler for getting direction of a SMA pin.
1715 *
1716 * Context: Acquires and releases pf->dplls.lock
1717 * Return:
1718 * * 0 - success
1719 * * negative - error
1720 */
1721 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)1722 ice_dpll_pin_sw_direction_get(const struct dpll_pin *pin, void *pin_priv,
1723 const struct dpll_device *dpll, void *dpll_priv,
1724 enum dpll_pin_direction *direction,
1725 struct netlink_ext_ack *extack)
1726 {
1727 struct ice_dpll_pin *p = pin_priv;
1728 struct ice_pf *pf = p->pf;
1729
1730 if (ice_dpll_is_reset(pf, extack))
1731 return -EBUSY;
1732 mutex_lock(&pf->dplls.lock);
1733 *direction = p->direction;
1734 mutex_unlock(&pf->dplls.lock);
1735
1736 return 0;
1737 }
1738
1739 /**
1740 * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
1741 * @pin: pointer to a pin
1742 * @pin_priv: private data pointer passed on pin registration
1743 * @dpll: registered dpll pointer
1744 * @dpll_priv: private data pointer passed on dpll registration
1745 * @phase_adjust: on success holds pin phase_adjust value
1746 * @extack: error reporting
1747 *
1748 * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
1749 *
1750 * Context: Acquires pf->dplls.lock
1751 * Return:
1752 * * 0 - success
1753 * * negative - error
1754 */
1755 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)1756 ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1757 const struct dpll_device *dpll, void *dpll_priv,
1758 s32 *phase_adjust,
1759 struct netlink_ext_ack *extack)
1760 {
1761 struct ice_dpll_pin *p = pin_priv;
1762 struct ice_pf *pf = p->pf;
1763
1764 mutex_lock(&pf->dplls.lock);
1765 *phase_adjust = p->phase_adjust;
1766 mutex_unlock(&pf->dplls.lock);
1767
1768 return 0;
1769 }
1770
1771 /**
1772 * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
1773 * @pin: pointer to a pin
1774 * @pin_priv: private data pointer passed on pin registration
1775 * @dpll: registered dpll pointer
1776 * @dpll_priv: private data pointer passed on dpll registration
1777 * @phase_adjust: phase_adjust to be set
1778 * @extack: error reporting
1779 * @type: type of a pin
1780 *
1781 * Helper for dpll subsystem callback. Handler for setting phase adjust value
1782 * of a pin.
1783 *
1784 * Context: Acquires pf->dplls.lock
1785 * Return:
1786 * * 0 - success
1787 * * negative - error
1788 */
1789 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)1790 ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1791 const struct dpll_device *dpll, void *dpll_priv,
1792 s32 phase_adjust,
1793 struct netlink_ext_ack *extack,
1794 enum ice_dpll_pin_type type)
1795 {
1796 struct ice_dpll_pin *p = pin_priv;
1797 struct ice_dpll *d = dpll_priv;
1798 struct ice_pf *pf = d->pf;
1799 u8 flag, flags_en = 0;
1800 int ret;
1801
1802 if (ice_dpll_is_reset(pf, extack))
1803 return -EBUSY;
1804
1805 mutex_lock(&pf->dplls.lock);
1806 switch (type) {
1807 case ICE_DPLL_PIN_TYPE_INPUT:
1808 flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
1809 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
1810 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1811 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
1812 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
1813 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
1814 0, phase_adjust);
1815 break;
1816 case ICE_DPLL_PIN_TYPE_OUTPUT:
1817 flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
1818 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1819 flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1820 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
1821 flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1822 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
1823 phase_adjust);
1824 break;
1825 default:
1826 ret = -EINVAL;
1827 }
1828 if (!ret)
1829 p->phase_adjust = phase_adjust;
1830 mutex_unlock(&pf->dplls.lock);
1831 if (ret)
1832 NL_SET_ERR_MSG_FMT(extack,
1833 "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u",
1834 ret,
1835 libie_aq_str(pf->hw.adminq.sq_last_status),
1836 phase_adjust, p->idx, d->dpll_idx);
1837
1838 return ret;
1839 }
1840
1841 /**
1842 * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
1843 * @pin: pointer to a pin
1844 * @pin_priv: private data pointer passed on pin registration
1845 * @dpll: registered dpll pointer
1846 * @dpll_priv: private data pointer passed on dpll registration
1847 * @phase_adjust: phase_adjust to be set
1848 * @extack: error reporting
1849 *
1850 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
1851 * pin.
1852 *
1853 * Context: Calls a function which acquires and releases pf->dplls.lock
1854 * Return:
1855 * * 0 - success
1856 * * negative - error
1857 */
1858 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)1859 ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1860 const struct dpll_device *dpll, void *dpll_priv,
1861 s32 phase_adjust,
1862 struct netlink_ext_ack *extack)
1863 {
1864 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1865 phase_adjust, extack,
1866 ICE_DPLL_PIN_TYPE_INPUT);
1867 }
1868
1869 /**
1870 * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1871 * @pin: pointer to a pin
1872 * @pin_priv: private data pointer passed on pin registration
1873 * @dpll: registered dpll pointer
1874 * @dpll_priv: private data pointer passed on dpll registration
1875 * @phase_adjust: phase_adjust to be set
1876 * @extack: error reporting
1877 *
1878 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1879 * pin.
1880 *
1881 * Context: Calls a function which acquires pf->dplls.lock
1882 * Return:
1883 * * 0 - success
1884 * * negative - error
1885 */
1886 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)1887 ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1888 const struct dpll_device *dpll, void *dpll_priv,
1889 s32 phase_adjust,
1890 struct netlink_ext_ack *extack)
1891 {
1892 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1893 phase_adjust, extack,
1894 ICE_DPLL_PIN_TYPE_OUTPUT);
1895 }
1896
1897 /**
1898 * ice_dpll_sw_phase_adjust_get - callback for get SW pin phase adjust
1899 * @pin: pointer to a pin
1900 * @pin_priv: private data pointer passed on pin registration
1901 * @dpll: registered dpll pointer
1902 * @dpll_priv: private data pointer passed on dpll registration
1903 * @phase_adjust: on success holds phase adjust value
1904 * @extack: error reporting
1905 *
1906 * Dpll subsystem callback. Wraps a handler for getting phase adjust on sw
1907 * pin.
1908 *
1909 * Context: Calls a function which acquires and releases pf->dplls.lock
1910 * Return:
1911 * * 0 - success
1912 * * negative - error
1913 */
1914 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)1915 ice_dpll_sw_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1916 const struct dpll_device *dpll, void *dpll_priv,
1917 s32 *phase_adjust,
1918 struct netlink_ext_ack *extack)
1919 {
1920 struct ice_dpll_pin *p = pin_priv;
1921
1922 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1923 return ice_dpll_pin_phase_adjust_get(p->input->pin, p->input,
1924 dpll, dpll_priv,
1925 phase_adjust, extack);
1926 else
1927 return ice_dpll_pin_phase_adjust_get(p->output->pin, p->output,
1928 dpll, dpll_priv,
1929 phase_adjust, extack);
1930 }
1931
1932 /**
1933 * ice_dpll_sw_phase_adjust_set - callback for set SW pin phase adjust value
1934 * @pin: pointer to a pin
1935 * @pin_priv: private data pointer passed on pin registration
1936 * @dpll: registered dpll pointer
1937 * @dpll_priv: private data pointer passed on dpll registration
1938 * @phase_adjust: phase_adjust to be set
1939 * @extack: error reporting
1940 *
1941 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1942 * pin.
1943 *
1944 * Context: Calls a function which acquires and releases pf->dplls.lock
1945 * Return:
1946 * * 0 - success
1947 * * negative - error
1948 */
1949 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)1950 ice_dpll_sw_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1951 const struct dpll_device *dpll, void *dpll_priv,
1952 s32 phase_adjust,
1953 struct netlink_ext_ack *extack)
1954 {
1955 struct ice_dpll_pin *p = pin_priv;
1956
1957 if (!p->active) {
1958 NL_SET_ERR_MSG(extack, "pin is not active");
1959 return -EINVAL;
1960 }
1961 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1962 return ice_dpll_pin_phase_adjust_set(p->input->pin, p->input,
1963 dpll, dpll_priv,
1964 phase_adjust, extack,
1965 ICE_DPLL_PIN_TYPE_INPUT);
1966 else
1967 return ice_dpll_pin_phase_adjust_set(p->output->pin, p->output,
1968 dpll, dpll_priv,
1969 phase_adjust, extack,
1970 ICE_DPLL_PIN_TYPE_OUTPUT);
1971 }
1972
1973 #define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1974 #define ICE_DPLL_PHASE_OFFSET_FACTOR \
1975 (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1976 /**
1977 * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1978 * @pin: pointer to a pin
1979 * @pin_priv: private data pointer passed on pin registration
1980 * @dpll: registered dpll pointer
1981 * @dpll_priv: private data pointer passed on dpll registration
1982 * @phase_offset: on success holds pin phase_offset value
1983 * @extack: error reporting
1984 *
1985 * Dpll subsystem callback. Handler for getting phase shift value between
1986 * dpll's input and output.
1987 *
1988 * Context: Acquires pf->dplls.lock
1989 * Return:
1990 * * 0 - success
1991 * * negative - error
1992 */
1993 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)1994 ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1995 const struct dpll_device *dpll, void *dpll_priv,
1996 s64 *phase_offset, struct netlink_ext_ack *extack)
1997 {
1998 struct ice_dpll_pin *p = pin_priv;
1999 struct ice_dpll *d = dpll_priv;
2000 struct ice_pf *pf = d->pf;
2001
2002 mutex_lock(&pf->dplls.lock);
2003 if (d->active_input == pin || (p->input &&
2004 d->active_input == p->input->pin))
2005 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
2006 else if (d->phase_offset_monitor_period)
2007 *phase_offset = (p->input &&
2008 p->direction == DPLL_PIN_DIRECTION_INPUT ?
2009 p->input->phase_offset :
2010 p->phase_offset) * ICE_DPLL_PHASE_OFFSET_FACTOR;
2011 else
2012 *phase_offset = 0;
2013 mutex_unlock(&pf->dplls.lock);
2014
2015 return 0;
2016 }
2017
2018 /**
2019 * ice_dpll_synce_update_e825c - setting PHY recovered clock pins on e825c
2020 * @hw: Pointer to the HW struct
2021 * @ena: true if enable, false in disable
2022 * @port_num: port number
2023 * @output: output pin, we have two in E825C
2024 *
2025 * DPLL subsystem callback. Set proper signals to recover clock from port.
2026 *
2027 * Context: Called under pf->dplls.lock
2028 * Return:
2029 * * 0 - success
2030 * * negative - error
2031 */
ice_dpll_synce_update_e825c(struct ice_hw * hw,bool ena,u32 port_num,enum ice_synce_clk output)2032 static int ice_dpll_synce_update_e825c(struct ice_hw *hw, bool ena,
2033 u32 port_num, enum ice_synce_clk output)
2034 {
2035 int err;
2036
2037 /* configure the mux to deliver proper signal to DPLL from the MUX */
2038 err = ice_tspll_cfg_bypass_mux_e825c(hw, ena, port_num, output);
2039 if (err)
2040 return err;
2041
2042 err = ice_tspll_cfg_synce_ethdiv_e825c(hw, output);
2043 if (err)
2044 return err;
2045
2046 dev_dbg(ice_hw_to_dev(hw), "CLK_SYNCE%u recovered clock: pin %s\n",
2047 output, str_enabled_disabled(ena));
2048
2049 return 0;
2050 }
2051
2052 /**
2053 * ice_dpll_output_esync_set - callback for setting embedded sync
2054 * @pin: pointer to a pin
2055 * @pin_priv: private data pointer passed on pin registration
2056 * @dpll: registered dpll pointer
2057 * @dpll_priv: private data pointer passed on dpll registration
2058 * @freq: requested embedded sync frequency
2059 * @extack: error reporting
2060 *
2061 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2062 * on output pin.
2063 *
2064 * Context: Acquires pf->dplls.lock
2065 * Return:
2066 * * 0 - success
2067 * * negative - error
2068 */
2069 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)2070 ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
2071 const struct dpll_device *dpll, void *dpll_priv,
2072 u64 freq, struct netlink_ext_ack *extack)
2073 {
2074 struct ice_dpll_pin *p = pin_priv;
2075 struct ice_dpll *d = dpll_priv;
2076 struct ice_pf *pf = d->pf;
2077 u8 flags = 0;
2078 int ret;
2079
2080 if (ice_dpll_is_reset(pf, extack))
2081 return -EBUSY;
2082 mutex_lock(&pf->dplls.lock);
2083 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
2084 flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
2085 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
2086 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
2087 ret = 0;
2088 } else {
2089 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
2090 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
2091 0, 0, 0);
2092 }
2093 } else {
2094 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
2095 ret = 0;
2096 } else {
2097 flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
2098 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
2099 0, 0, 0);
2100 }
2101 }
2102 mutex_unlock(&pf->dplls.lock);
2103
2104 return ret;
2105 }
2106
2107 /**
2108 * ice_dpll_output_esync_get - callback for getting embedded sync config
2109 * @pin: pointer to a pin
2110 * @pin_priv: private data pointer passed on pin registration
2111 * @dpll: registered dpll pointer
2112 * @dpll_priv: private data pointer passed on dpll registration
2113 * @esync: on success holds embedded sync pin properties
2114 * @extack: error reporting
2115 *
2116 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2117 * and capabilities on output pin.
2118 *
2119 * Context: Acquires pf->dplls.lock
2120 * Return:
2121 * * 0 - success
2122 * * negative - error
2123 */
2124 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)2125 ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
2126 const struct dpll_device *dpll, void *dpll_priv,
2127 struct dpll_pin_esync *esync,
2128 struct netlink_ext_ack *extack)
2129 {
2130 struct ice_dpll_pin *p = pin_priv;
2131 struct ice_dpll *d = dpll_priv;
2132 struct ice_pf *pf = d->pf;
2133
2134 if (ice_dpll_is_reset(pf, extack))
2135 return -EBUSY;
2136 mutex_lock(&pf->dplls.lock);
2137 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
2138 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2139 mutex_unlock(&pf->dplls.lock);
2140 return -EOPNOTSUPP;
2141 }
2142 esync->range = ice_esync_range;
2143 esync->range_num = ARRAY_SIZE(ice_esync_range);
2144 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
2145 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2146 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2147 } else {
2148 esync->freq = 0;
2149 esync->pulse = 0;
2150 }
2151 mutex_unlock(&pf->dplls.lock);
2152
2153 return 0;
2154 }
2155
2156 /**
2157 * ice_dpll_input_esync_set - callback for setting embedded sync
2158 * @pin: pointer to a pin
2159 * @pin_priv: private data pointer passed on pin registration
2160 * @dpll: registered dpll pointer
2161 * @dpll_priv: private data pointer passed on dpll registration
2162 * @freq: requested embedded sync frequency
2163 * @extack: error reporting
2164 *
2165 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2166 * on input pin.
2167 *
2168 * Context: Acquires pf->dplls.lock
2169 * Return:
2170 * * 0 - success
2171 * * negative - error
2172 */
2173 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)2174 ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
2175 const struct dpll_device *dpll, void *dpll_priv,
2176 u64 freq, struct netlink_ext_ack *extack)
2177 {
2178 struct ice_dpll_pin *p = pin_priv;
2179 struct ice_dpll *d = dpll_priv;
2180 struct ice_pf *pf = d->pf;
2181 u8 flags_en = 0;
2182 int ret;
2183
2184 if (ice_dpll_is_reset(pf, extack))
2185 return -EBUSY;
2186 mutex_lock(&pf->dplls.lock);
2187 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2188 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2189 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
2190 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2191 ret = 0;
2192 } else {
2193 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2194 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2195 flags_en, 0, 0);
2196 }
2197 } else {
2198 if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
2199 ret = 0;
2200 } else {
2201 flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2202 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2203 flags_en, 0, 0);
2204 }
2205 }
2206 mutex_unlock(&pf->dplls.lock);
2207
2208 return ret;
2209 }
2210
2211 /**
2212 * ice_dpll_input_esync_get - callback for getting embedded sync config
2213 * @pin: pointer to a pin
2214 * @pin_priv: private data pointer passed on pin registration
2215 * @dpll: registered dpll pointer
2216 * @dpll_priv: private data pointer passed on dpll registration
2217 * @esync: on success holds embedded sync pin properties
2218 * @extack: error reporting
2219 *
2220 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2221 * and capabilities on input pin.
2222 *
2223 * Context: Acquires pf->dplls.lock
2224 * Return:
2225 * * 0 - success
2226 * * negative - error
2227 */
2228 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)2229 ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
2230 const struct dpll_device *dpll, void *dpll_priv,
2231 struct dpll_pin_esync *esync,
2232 struct netlink_ext_ack *extack)
2233 {
2234 struct ice_dpll_pin *p = pin_priv;
2235 struct ice_dpll *d = dpll_priv;
2236 struct ice_pf *pf = d->pf;
2237
2238 if (ice_dpll_is_reset(pf, extack))
2239 return -EBUSY;
2240 mutex_lock(&pf->dplls.lock);
2241 if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
2242 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2243 mutex_unlock(&pf->dplls.lock);
2244 return -EOPNOTSUPP;
2245 }
2246 esync->range = ice_esync_range;
2247 esync->range_num = ARRAY_SIZE(ice_esync_range);
2248 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2249 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2250 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2251 } else {
2252 esync->freq = 0;
2253 esync->pulse = 0;
2254 }
2255 mutex_unlock(&pf->dplls.lock);
2256
2257 return 0;
2258 }
2259
2260 /**
2261 * ice_dpll_sw_esync_set - callback for setting embedded sync on SW pin
2262 * @pin: pointer to a pin
2263 * @pin_priv: private data pointer passed on pin registration
2264 * @dpll: registered dpll pointer
2265 * @dpll_priv: private data pointer passed on dpll registration
2266 * @freq: requested embedded sync frequency
2267 * @extack: error reporting
2268 *
2269 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2270 * on SW pin.
2271 *
2272 * Context: Calls a function which acquires and releases pf->dplls.lock
2273 * Return:
2274 * * 0 - success
2275 * * negative - error
2276 */
2277 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)2278 ice_dpll_sw_esync_set(const struct dpll_pin *pin, void *pin_priv,
2279 const struct dpll_device *dpll, void *dpll_priv,
2280 u64 freq, struct netlink_ext_ack *extack)
2281 {
2282 struct ice_dpll_pin *p = pin_priv;
2283
2284 if (!p->active) {
2285 NL_SET_ERR_MSG(extack, "pin is not active");
2286 return -EINVAL;
2287 }
2288 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2289 return ice_dpll_input_esync_set(p->input->pin, p->input, dpll,
2290 dpll_priv, freq, extack);
2291 else
2292 return ice_dpll_output_esync_set(p->output->pin, p->output,
2293 dpll, dpll_priv, freq, extack);
2294 }
2295
2296 /**
2297 * ice_dpll_sw_esync_get - callback for getting embedded sync on SW pin
2298 * @pin: pointer to a pin
2299 * @pin_priv: private data pointer passed on pin registration
2300 * @dpll: registered dpll pointer
2301 * @dpll_priv: private data pointer passed on dpll registration
2302 * @esync: on success holds embedded sync frequency and properties
2303 * @extack: error reporting
2304 *
2305 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2306 * of SW pin.
2307 *
2308 * Context: Calls a function which acquires and releases pf->dplls.lock
2309 * Return:
2310 * * 0 - success
2311 * * negative - error
2312 */
2313 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)2314 ice_dpll_sw_esync_get(const struct dpll_pin *pin, void *pin_priv,
2315 const struct dpll_device *dpll, void *dpll_priv,
2316 struct dpll_pin_esync *esync,
2317 struct netlink_ext_ack *extack)
2318 {
2319 struct ice_dpll_pin *p = pin_priv;
2320
2321 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2322 return ice_dpll_input_esync_get(p->input->pin, p->input, dpll,
2323 dpll_priv, esync, extack);
2324 else
2325 return ice_dpll_output_esync_get(p->output->pin, p->output,
2326 dpll, dpll_priv, esync,
2327 extack);
2328 }
2329
2330 /*
2331 * ice_dpll_input_ref_sync_set - callback for setting reference sync feature
2332 * @pin: pointer to a pin
2333 * @pin_priv: private data pointer passed on pin registration
2334 * @ref_pin: pin pointer for reference sync pair
2335 * @ref_pin_priv: private data pointer of ref_pin
2336 * @state: requested state for reference sync for pin pair
2337 * @extack: error reporting
2338 *
2339 * Dpll subsystem callback. Handler for setting reference sync frequency
2340 * feature for input pin.
2341 *
2342 * Context: Acquires and releases pf->dplls.lock
2343 * Return:
2344 * * 0 - success
2345 * * negative - error
2346 */
2347 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)2348 ice_dpll_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2349 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2350 const enum dpll_pin_state state,
2351 struct netlink_ext_ack *extack)
2352 {
2353 struct ice_dpll_pin *p = pin_priv;
2354 struct ice_pf *pf = p->pf;
2355 u8 flags_en = 0;
2356 int ret;
2357
2358 if (ice_dpll_is_reset(pf, extack))
2359 return -EBUSY;
2360 mutex_lock(&pf->dplls.lock);
2361
2362 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2363 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2364 if (state == DPLL_PIN_STATE_CONNECTED)
2365 flags_en |= ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN;
2366 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, flags_en, 0, 0);
2367 if (!ret)
2368 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT,
2369 extack);
2370 mutex_unlock(&pf->dplls.lock);
2371
2372 return ret;
2373 }
2374
2375 /**
2376 * ice_dpll_input_ref_sync_get - callback for getting reference sync config
2377 * @pin: pointer to a pin
2378 * @pin_priv: private data pointer passed on pin registration
2379 * @ref_pin: pin pointer for reference sync pair
2380 * @ref_pin_priv: private data pointer of ref_pin
2381 * @state: on success holds reference sync state for pin pair
2382 * @extack: error reporting
2383 *
2384 * Dpll subsystem callback. Handler for setting reference sync frequency
2385 * feature for input pin.
2386 *
2387 * Context: Acquires and releases pf->dplls.lock
2388 * Return:
2389 * * 0 - success
2390 * * negative - error
2391 */
2392 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)2393 ice_dpll_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2394 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2395 enum dpll_pin_state *state,
2396 struct netlink_ext_ack *extack)
2397 {
2398 struct ice_dpll_pin *p = pin_priv;
2399 struct ice_pf *pf = p->pf;
2400
2401 if (ice_dpll_is_reset(pf, extack))
2402 return -EBUSY;
2403 mutex_lock(&pf->dplls.lock);
2404 if (p->flags[0] & ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN)
2405 *state = DPLL_PIN_STATE_CONNECTED;
2406 else
2407 *state = DPLL_PIN_STATE_DISCONNECTED;
2408 mutex_unlock(&pf->dplls.lock);
2409
2410 return 0;
2411 }
2412
2413 /*
2414 * ice_dpll_sw_input_ref_sync_set - callback for setting reference sync feature
2415 * @pin: pointer to a pin
2416 * @pin_priv: private data pointer passed on pin registration
2417 * @ref_pin: pin pointer for reference sync pair
2418 * @ref_pin_priv: private data pointer of ref_pin
2419 * @state: requested state for reference sync for pin pair
2420 * @extack: error reporting
2421 *
2422 * Dpll subsystem callback. Handler for setting reference sync
2423 * feature for input pins.
2424 *
2425 * Context: Calls a function which acquires and releases pf->dplls.lock
2426 * Return:
2427 * * 0 - success
2428 * * negative - error
2429 */
2430 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)2431 ice_dpll_sw_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2432 const struct dpll_pin *ref_pin,
2433 void *ref_pin_priv,
2434 const enum dpll_pin_state state,
2435 struct netlink_ext_ack *extack)
2436 {
2437 struct ice_dpll_pin *p = pin_priv;
2438
2439 return ice_dpll_input_ref_sync_set(pin, p->input, ref_pin, ref_pin_priv,
2440 state, extack);
2441 }
2442
2443 /**
2444 * ice_dpll_sw_input_ref_sync_get - callback for getting reference sync config
2445 * @pin: pointer to a pin
2446 * @pin_priv: private data pointer passed on pin registration
2447 * @ref_pin: pin pointer for reference sync pair
2448 * @ref_pin_priv: private data pointer of ref_pin
2449 * @state: on success holds reference sync state for pin pair
2450 * @extack: error reporting
2451 *
2452 * Dpll subsystem callback. Handler for setting reference sync feature for
2453 * input pins.
2454 *
2455 * Context: Calls a function which acquires and releases pf->dplls.lock
2456 * Return:
2457 * * 0 - success
2458 * * negative - error
2459 */
2460 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)2461 ice_dpll_sw_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2462 const struct dpll_pin *ref_pin,
2463 void *ref_pin_priv,
2464 enum dpll_pin_state *state,
2465 struct netlink_ext_ack *extack)
2466 {
2467 struct ice_dpll_pin *p = pin_priv;
2468
2469 return ice_dpll_input_ref_sync_get(pin, p->input, ref_pin, ref_pin_priv,
2470 state, extack);
2471 }
2472
2473 static int
ice_dpll_pin_get_parent_num(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2474 ice_dpll_pin_get_parent_num(struct ice_dpll_pin *pin,
2475 const struct dpll_pin *parent)
2476 {
2477 int i;
2478
2479 for (i = 0; i < pin->num_parents; i++)
2480 if (pin->pf->dplls.inputs[pin->parent_idx[i]].pin == parent)
2481 return i;
2482
2483 return -ENOENT;
2484 }
2485
2486 static int
ice_dpll_pin_get_parent_idx(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2487 ice_dpll_pin_get_parent_idx(struct ice_dpll_pin *pin,
2488 const struct dpll_pin *parent)
2489 {
2490 int num = ice_dpll_pin_get_parent_num(pin, parent);
2491
2492 return num < 0 ? num : pin->parent_idx[num];
2493 }
2494
2495 /**
2496 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
2497 * @pin: pointer to a pin
2498 * @pin_priv: private data pointer passed on pin registration
2499 * @parent_pin: pin parent pointer
2500 * @parent_pin_priv: parent private data pointer passed on pin registration
2501 * @state: state to be set on pin
2502 * @extack: error reporting
2503 *
2504 * Dpll subsystem callback, set a state of a rclk pin on a parent pin
2505 *
2506 * Context: Acquires pf->dplls.lock
2507 * Return:
2508 * * 0 - success
2509 * * negative - failure
2510 */
2511 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)2512 ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
2513 const struct dpll_pin *parent_pin,
2514 void *parent_pin_priv,
2515 enum dpll_pin_state state,
2516 struct netlink_ext_ack *extack)
2517 {
2518 bool enable = state == DPLL_PIN_STATE_CONNECTED;
2519 struct ice_dpll_pin *p = pin_priv;
2520 struct ice_pf *pf = p->pf;
2521 struct ice_hw *hw;
2522 int ret = -EINVAL;
2523 int hw_idx;
2524
2525 hw = &pf->hw;
2526
2527 if (ice_dpll_is_reset(pf, extack))
2528 return -EBUSY;
2529
2530 mutex_lock(&pf->dplls.lock);
2531 hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2532 if (hw_idx < 0)
2533 goto unlock;
2534 hw_idx -= pf->dplls.base_rclk_idx;
2535 if (hw_idx >= ICE_DPLL_RCLK_NUM_MAX)
2536 goto unlock;
2537
2538 if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
2539 (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
2540 NL_SET_ERR_MSG_FMT(extack,
2541 "pin:%u state:%u on parent:%u already set",
2542 p->idx, state,
2543 ice_dpll_pin_get_parent_num(p, parent_pin));
2544 goto unlock;
2545 }
2546
2547 ret = hw->mac_type == ICE_MAC_GENERIC_3K_E825 ?
2548 ice_dpll_synce_update_e825c(hw, enable,
2549 pf->ptp.port.port_num,
2550 (enum ice_synce_clk)hw_idx) :
2551 ice_aq_set_phy_rec_clk_out(hw, hw_idx, enable, &p->freq);
2552 if (ret)
2553 NL_SET_ERR_MSG_FMT(extack,
2554 "err:%d %s failed to set pin state:%u for pin:%u on parent:%u",
2555 ret,
2556 libie_aq_str(hw->adminq.sq_last_status),
2557 state, p->idx,
2558 ice_dpll_pin_get_parent_num(p, parent_pin));
2559 unlock:
2560 mutex_unlock(&pf->dplls.lock);
2561
2562 return ret;
2563 }
2564
2565 /**
2566 * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
2567 * @pin: pointer to a pin
2568 * @pin_priv: private data pointer passed on pin registration
2569 * @parent_pin: pin parent pointer
2570 * @parent_pin_priv: pin parent priv data pointer passed on pin registration
2571 * @state: on success holds pin state on parent pin
2572 * @extack: error reporting
2573 *
2574 * dpll subsystem callback, get a state of a recovered clock pin.
2575 *
2576 * Context: Acquires pf->dplls.lock
2577 * Return:
2578 * * 0 - success
2579 * * negative - failure
2580 */
2581 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)2582 ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
2583 const struct dpll_pin *parent_pin,
2584 void *parent_pin_priv,
2585 enum dpll_pin_state *state,
2586 struct netlink_ext_ack *extack)
2587 {
2588 struct ice_dpll_pin *p = pin_priv;
2589 struct ice_pf *pf = p->pf;
2590 int ret = -EINVAL;
2591 int hw_idx;
2592
2593 if (ice_dpll_is_reset(pf, extack))
2594 return -EBUSY;
2595
2596 mutex_lock(&pf->dplls.lock);
2597 hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2598 if (hw_idx < 0)
2599 goto unlock;
2600 hw_idx -= pf->dplls.base_rclk_idx;
2601 if (hw_idx >= ICE_DPLL_RCLK_NUM_MAX)
2602 goto unlock;
2603
2604 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
2605 extack);
2606 if (ret)
2607 goto unlock;
2608
2609 *state = p->state[hw_idx];
2610 ret = 0;
2611 unlock:
2612 mutex_unlock(&pf->dplls.lock);
2613
2614 return ret;
2615 }
2616
2617 /**
2618 * ice_dpll_txclk_work - apply a pending TX reference clock change
2619 * @work: work_struct embedded in struct ice_dplls
2620 *
2621 * This worker executes an outstanding TX reference clock switch request
2622 * that was previously queued via the DPLL TXCLK pin set callback.
2623 *
2624 * The worker performs only the operational part of the switch, issuing
2625 * the necessary firmware commands to request a new TX reference clock
2626 * selection (e.g. triggering an AN restart). It does not verify whether
2627 * the requested clock was ultimately accepted by the hardware.
2628 *
2629 * Hardware verification, software state reconciliation, pin state
2630 * notification, and TXC DPLL lock-status updates are performed later,
2631 * after link-up, by ice_txclk_update_and_notify().
2632 *
2633 * Context:
2634 * - Runs in process context on pf->dplls.wq and may sleep.
2635 * - Serializes access to shared TXCLK state using pf->dplls.lock.
2636 */
ice_dpll_txclk_work(struct work_struct * work)2637 static void ice_dpll_txclk_work(struct work_struct *work)
2638 {
2639 struct ice_dplls *dplls =
2640 container_of(work, struct ice_dplls, txclk_work);
2641 struct ice_pf *pf = container_of(dplls, struct ice_pf, dplls);
2642 struct dpll_pin *old_pin = NULL;
2643 struct dpll_pin *new_pin = NULL;
2644 enum ice_e825c_ref_clk clk;
2645 bool do_switch;
2646 int err;
2647
2648 mutex_lock(&pf->dplls.lock);
2649 do_switch = pf->dplls.txclk_switch_requested;
2650 clk = pf->ptp.port.tx_clk_req;
2651 mutex_unlock(&pf->dplls.lock);
2652
2653 if (!do_switch)
2654 return;
2655
2656 err = ice_txclk_set_clk(pf, clk);
2657
2658 mutex_lock(&pf->dplls.lock);
2659 /* Only clear the request flag if no newer request arrived while
2660 * the lock was dropped. Otherwise leave it set so the re-queued
2661 * worker run picks up the updated tx_clk_req value.
2662 */
2663 if (pf->ptp.port.tx_clk_req == clk)
2664 pf->dplls.txclk_switch_requested = false;
2665 if (err) {
2666 /* Roll back the requested clock to match the current hardware
2667 * state so that ice_txclk_update_and_notify() does not
2668 * misinterpret a future link-up as a failed switch. Only roll
2669 * back if no newer request arrived in the meantime; otherwise
2670 * the re-queued worker run will apply the updated value.
2671 */
2672 dev_err(ice_pf_to_dev(pf),
2673 "TX clock switch to %u failed, err=%d; reverting\n",
2674 clk, err);
2675 if (pf->ptp.port.tx_clk_req == clk) {
2676 /* Capture pins for post-unlock notification so that
2677 * userspace observes the requested pin flipping back
2678 * to DISCONNECTED and the effective pin to CONNECTED.
2679 */
2680 new_pin = ice_txclk_get_pin(pf, clk);
2681 old_pin = ice_txclk_get_pin(pf, pf->ptp.port.tx_clk);
2682 pf->ptp.port.tx_clk_req = pf->ptp.port.tx_clk;
2683 }
2684 }
2685 mutex_unlock(&pf->dplls.lock);
2686
2687 if (old_pin)
2688 dpll_pin_change_ntf(old_pin);
2689 if (new_pin)
2690 dpll_pin_change_ntf(new_pin);
2691 }
2692
2693 /**
2694 * ice_dpll_txclk_state_on_dpll_set - set a state on TX clk pin
2695 * @pin: pointer to a pin
2696 * @pin_priv: private data pointer passed on pin registration
2697 * @dpll: registered dpll pointer
2698 * @dpll_priv: private data pointer passed on dpll registration
2699 * @state: state to be set on pin
2700 * @extack: error reporting
2701 *
2702 * Dpll subsystem callback, set a state of a Tx reference clock pin
2703 *
2704 * Context: Acquires and releases pf->dplls.lock.
2705 * Return:
2706 * * 0 - success
2707 * * negative - failure
2708 */
2709 static int
ice_dpll_txclk_state_on_dpll_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)2710 ice_dpll_txclk_state_on_dpll_set(const struct dpll_pin *pin, void *pin_priv,
2711 const struct dpll_device *dpll,
2712 void *dpll_priv, enum dpll_pin_state state,
2713 struct netlink_ext_ack *extack)
2714 {
2715 struct ice_dpll_pin *p = pin_priv;
2716 struct ice_pf *pf = p->pf;
2717 enum ice_e825c_ref_clk new_clk;
2718 int ret = 0;
2719
2720 if (ice_dpll_is_reset(pf, extack))
2721 return -EBUSY;
2722
2723 if (state != DPLL_PIN_STATE_CONNECTED &&
2724 state != DPLL_PIN_STATE_DISCONNECTED) {
2725 NL_SET_ERR_MSG(extack,
2726 "unsupported pin state for TX reference clock");
2727 return -EINVAL;
2728 }
2729
2730 /* Check ICE_FLAG_DPLL and queue_work() under pf->dplls.lock.
2731 * ice_dpll_deinit() clears the flag under the same lock before
2732 * cancel_work_sync() and wq destruction, so a callback arriving
2733 * after teardown observes the cleared flag and bails out.
2734 */
2735 mutex_lock(&pf->dplls.lock);
2736 if (!test_bit(ICE_FLAG_DPLL, pf->flags)) {
2737 ret = -ENODEV;
2738 goto unlock;
2739 }
2740 if (state == DPLL_PIN_STATE_DISCONNECTED &&
2741 p->tx_ref_src != pf->ptp.port.tx_clk_req)
2742 goto unlock;
2743
2744 new_clk = (state == DPLL_PIN_STATE_DISCONNECTED) ? ICE_REF_CLK_ENET :
2745 p->tx_ref_src;
2746 if (new_clk == pf->ptp.port.tx_clk_req)
2747 goto unlock;
2748
2749 pf->ptp.port.tx_clk_req = new_clk;
2750 pf->dplls.txclk_switch_requested = true;
2751 queue_work(pf->dplls.wq, &pf->dplls.txclk_work);
2752 unlock:
2753 mutex_unlock(&pf->dplls.lock);
2754 return ret;
2755 }
2756
2757 /**
2758 * ice_dpll_txclk_state_on_dpll_get - get a state of Tx clk reference pin
2759 * @pin: pointer to a pin
2760 * @pin_priv: private data pointer passed on pin registration
2761 * @dpll: registered dpll pointer
2762 * @dpll_priv: private data pointer passed on dpll registration
2763 * @state: on success holds pin state on parent pin
2764 * @extack: error reporting
2765 *
2766 * TXCLK DPLL pin state is derived and not stored explicitly.
2767 *
2768 * Only external TX reference clocks (SYNCE, EREF0) are modeled
2769 * as DPLL pins. The internal ENET (TXCO) clock has no pin and,
2770 * when selected, all TXCLK pins are reported DISCONNECTED.
2771 *
2772 * During a pending TXCLK switch, the requested pin may be
2773 * reported as CONNECTED before hardware verification.
2774 * Hardware acceptance and synchronization are reported
2775 * exclusively via TXC DPLL lock-status.
2776 *
2777 * Context: Acquires and releases pf->dplls.lock
2778 * Return:
2779 * * 0 - success
2780 * * negative - failure
2781 */
2782 static int
ice_dpll_txclk_state_on_dpll_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)2783 ice_dpll_txclk_state_on_dpll_get(const struct dpll_pin *pin, void *pin_priv,
2784 const struct dpll_device *dpll,
2785 void *dpll_priv,
2786 enum dpll_pin_state *state,
2787 struct netlink_ext_ack *extack)
2788 {
2789 struct ice_dpll_pin *p = pin_priv;
2790 struct ice_pf *pf = p->pf;
2791
2792 if (ice_dpll_is_reset(pf, extack))
2793 return -EBUSY;
2794
2795 mutex_lock(&pf->dplls.lock);
2796 if (pf->ptp.port.tx_clk_req == p->tx_ref_src)
2797 *state = DPLL_PIN_STATE_CONNECTED;
2798 else
2799 *state = DPLL_PIN_STATE_DISCONNECTED;
2800 mutex_unlock(&pf->dplls.lock);
2801
2802 return 0;
2803 }
2804
2805 static const struct dpll_pin_ops ice_dpll_rclk_ops = {
2806 .state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
2807 .state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
2808 .direction_get = ice_dpll_input_direction,
2809 };
2810
2811 static const struct dpll_pin_ops ice_dpll_txclk_ops = {
2812 .state_on_dpll_set = ice_dpll_txclk_state_on_dpll_set,
2813 .state_on_dpll_get = ice_dpll_txclk_state_on_dpll_get,
2814 .direction_get = ice_dpll_input_direction,
2815 };
2816
2817 static const struct dpll_pin_ops ice_dpll_pin_sma_ops = {
2818 .state_on_dpll_set = ice_dpll_sma_pin_state_set,
2819 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2820 .direction_get = ice_dpll_pin_sw_direction_get,
2821 .direction_set = ice_dpll_pin_sma_direction_set,
2822 .prio_get = ice_dpll_sw_input_prio_get,
2823 .prio_set = ice_dpll_sw_input_prio_set,
2824 .frequency_get = ice_dpll_sw_pin_frequency_get,
2825 .frequency_set = ice_dpll_sw_pin_frequency_set,
2826 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2827 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2828 .phase_offset_get = ice_dpll_phase_offset_get,
2829 .esync_set = ice_dpll_sw_esync_set,
2830 .esync_get = ice_dpll_sw_esync_get,
2831 .ref_sync_set = ice_dpll_sw_input_ref_sync_set,
2832 .ref_sync_get = ice_dpll_sw_input_ref_sync_get,
2833 };
2834
2835 static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
2836 .state_on_dpll_set = ice_dpll_ufl_pin_state_set,
2837 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2838 .direction_get = ice_dpll_pin_sw_direction_get,
2839 .prio_get = ice_dpll_sw_input_prio_get,
2840 .prio_set = ice_dpll_sw_input_prio_set,
2841 .frequency_get = ice_dpll_sw_pin_frequency_get,
2842 .frequency_set = ice_dpll_sw_pin_frequency_set,
2843 .esync_set = ice_dpll_sw_esync_set,
2844 .esync_get = ice_dpll_sw_esync_get,
2845 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2846 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2847 .phase_offset_get = ice_dpll_phase_offset_get,
2848 };
2849
2850 static const struct dpll_pin_ops ice_dpll_input_ops = {
2851 .frequency_get = ice_dpll_input_frequency_get,
2852 .frequency_set = ice_dpll_input_frequency_set,
2853 .state_on_dpll_get = ice_dpll_input_state_get,
2854 .state_on_dpll_set = ice_dpll_input_state_set,
2855 .prio_get = ice_dpll_input_prio_get,
2856 .prio_set = ice_dpll_input_prio_set,
2857 .direction_get = ice_dpll_input_direction,
2858 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2859 .phase_adjust_set = ice_dpll_input_phase_adjust_set,
2860 .phase_offset_get = ice_dpll_phase_offset_get,
2861 .esync_set = ice_dpll_input_esync_set,
2862 .esync_get = ice_dpll_input_esync_get,
2863 .ref_sync_set = ice_dpll_input_ref_sync_set,
2864 .ref_sync_get = ice_dpll_input_ref_sync_get,
2865 };
2866
2867 static const struct dpll_pin_ops ice_dpll_output_ops = {
2868 .frequency_get = ice_dpll_output_frequency_get,
2869 .frequency_set = ice_dpll_output_frequency_set,
2870 .state_on_dpll_get = ice_dpll_output_state_get,
2871 .state_on_dpll_set = ice_dpll_output_state_set,
2872 .direction_get = ice_dpll_output_direction,
2873 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2874 .phase_adjust_set = ice_dpll_output_phase_adjust_set,
2875 .esync_set = ice_dpll_output_esync_set,
2876 .esync_get = ice_dpll_output_esync_get,
2877 };
2878
2879 static const struct dpll_device_ops ice_dpll_ops = {
2880 .lock_status_get = ice_dpll_lock_status_get,
2881 .mode_get = ice_dpll_mode_get,
2882 };
2883
2884 static const struct dpll_device_ops ice_dpll_pom_ops = {
2885 .lock_status_get = ice_dpll_lock_status_get,
2886 .mode_get = ice_dpll_mode_get,
2887 .phase_offset_monitor_set = ice_dpll_phase_offset_monitor_set,
2888 .phase_offset_monitor_get = ice_dpll_phase_offset_monitor_get,
2889 };
2890
2891 /**
2892 * ice_generate_clock_id - generates unique clock_id for registering dpll.
2893 * @pf: board private structure
2894 *
2895 * Generates unique (per board) clock_id for allocation and search of dpll
2896 * devices in Linux dpll subsystem.
2897 *
2898 * Return: generated clock id for the board
2899 */
ice_generate_clock_id(struct ice_pf * pf)2900 static u64 ice_generate_clock_id(struct ice_pf *pf)
2901 {
2902 return pci_get_dsn(pf->pdev);
2903 }
2904
2905 /**
2906 * ice_dpll_pin_ntf - notify pin change including any SW pin wrappers
2907 * @dplls: pointer to dplls struct
2908 * @pin: the dpll_pin that changed
2909 *
2910 * Send a change notification for @pin and for any registered SMA/U.FL pin
2911 * whose backing CGU input matches @pin.
2912 */
ice_dpll_pin_ntf(struct ice_dplls * dplls,struct dpll_pin * pin)2913 static void ice_dpll_pin_ntf(struct ice_dplls *dplls, struct dpll_pin *pin)
2914 {
2915 dpll_pin_change_ntf(pin);
2916 for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
2917 if (dplls->sma[i].pin && dplls->sma[i].input &&
2918 dplls->sma[i].input->pin == pin)
2919 dpll_pin_change_ntf(dplls->sma[i].pin);
2920 if (dplls->ufl[i].pin && dplls->ufl[i].input &&
2921 dplls->ufl[i].input->pin == pin)
2922 dpll_pin_change_ntf(dplls->ufl[i].pin);
2923 }
2924 }
2925
2926 /**
2927 * ice_dpll_notify_changes - notify dpll subsystem about changes
2928 * @d: pointer do dpll
2929 *
2930 * Once change detected appropriate event is submitted to the dpll subsystem.
2931 */
ice_dpll_notify_changes(struct ice_dpll * d)2932 static void ice_dpll_notify_changes(struct ice_dpll *d)
2933 {
2934 struct ice_dplls *dplls = &d->pf->dplls;
2935 bool pin_notified = false;
2936
2937 if (d->prev_dpll_state != d->dpll_state) {
2938 d->prev_dpll_state = d->dpll_state;
2939 dpll_device_change_ntf(d->dpll);
2940 }
2941 if (d->prev_input != d->active_input) {
2942 if (d->prev_input)
2943 ice_dpll_pin_ntf(dplls, d->prev_input);
2944 d->prev_input = d->active_input;
2945 if (d->active_input) {
2946 ice_dpll_pin_ntf(dplls, d->active_input);
2947 pin_notified = true;
2948 }
2949 }
2950 if (d->prev_phase_offset != d->phase_offset) {
2951 d->prev_phase_offset = d->phase_offset;
2952 if (!pin_notified && d->active_input)
2953 ice_dpll_pin_ntf(dplls, d->active_input);
2954 }
2955 }
2956
2957 /**
2958 * ice_dpll_is_pps_phase_monitor - check if dpll capable of phase offset monitor
2959 * @pf: pf private structure
2960 *
2961 * Check if firmware is capable of supporting admin command to provide
2962 * phase offset monitoring on all the input pins on PPS dpll.
2963 *
2964 * Returns:
2965 * * true - PPS dpll phase offset monitoring is supported
2966 * * false - PPS dpll phase offset monitoring is not supported
2967 */
ice_dpll_is_pps_phase_monitor(struct ice_pf * pf)2968 static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
2969 {
2970 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2971 int ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2972 ARRAY_SIZE(meas));
2973
2974 if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_ESRCH)
2975 return false;
2976
2977 return true;
2978 }
2979
2980 /**
2981 * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
2982 * @dplls: pointer to dplls struct
2983 * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
2984 * @pin_num: number of pins
2985 * @phase_offset_ntf_mask: bitmask of pin indexes to notify
2986 *
2987 * Iterate over array of pins and call dpll subsystem pin notify if
2988 * corresponding pin index within bitmask is set.
2989 *
2990 * Context: Must be called while pf->dplls.lock is released.
2991 */
ice_dpll_pins_notify_mask(struct ice_dplls * dplls,struct ice_dpll_pin * pins,u8 pin_num,u32 phase_offset_ntf_mask)2992 static void ice_dpll_pins_notify_mask(struct ice_dplls *dplls,
2993 struct ice_dpll_pin *pins,
2994 u8 pin_num,
2995 u32 phase_offset_ntf_mask)
2996 {
2997 for (int i = 0; i < pin_num; i++)
2998 if (phase_offset_ntf_mask & BIT(i))
2999 ice_dpll_pin_ntf(dplls, pins[i].pin);
3000 }
3001
3002 /**
3003 * ice_dpll_pps_update_phase_offsets - update phase offset measurements
3004 * @pf: pf private structure
3005 * @phase_offset_pins_updated: returns mask of updated input pin indexes
3006 *
3007 * Read phase offset measurements for PPS dpll device and store values in
3008 * input pins array. On success phase_offset_pins_updated - fills bitmask of
3009 * updated input pin indexes, pins shall be notified.
3010 *
3011 * Context: Shall be called with pf->dplls.lock being locked.
3012 * Returns:
3013 * * 0 - success or no data available
3014 * * negative - AQ failure
3015 */
ice_dpll_pps_update_phase_offsets(struct ice_pf * pf,u32 * phase_offset_pins_updated)3016 static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf,
3017 u32 *phase_offset_pins_updated)
3018 {
3019 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
3020 struct ice_dpll_pin *p;
3021 s64 phase_offset, tmp;
3022 int i, j, ret;
3023
3024 *phase_offset_pins_updated = 0;
3025 ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
3026 ARRAY_SIZE(meas));
3027 if (ret && (pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN ||
3028 pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EBUSY)) {
3029 return 0;
3030 } else if (ret) {
3031 dev_err(ice_pf_to_dev(pf),
3032 "failed to get input pin measurements dpll=%d, ret=%d %s\n",
3033 DPLL_TYPE_PPS, ret,
3034 libie_aq_str(pf->hw.adminq.sq_last_status));
3035 return ret;
3036 }
3037 for (i = 0; i < pf->dplls.num_inputs; i++) {
3038 p = &pf->dplls.inputs[i];
3039 phase_offset = 0;
3040 for (j = 0; j < ICE_CGU_INPUT_PHASE_OFFSET_BYTES; j++) {
3041 tmp = meas[i].phase_offset[j];
3042 #ifdef __LITTLE_ENDIAN
3043 phase_offset += tmp << 8 * j;
3044 #else
3045 phase_offset += tmp << 8 *
3046 (ICE_CGU_INPUT_PHASE_OFFSET_BYTES - 1 - j);
3047 #endif
3048 }
3049 phase_offset = sign_extend64(phase_offset, 47);
3050 if (p->phase_offset != phase_offset) {
3051 dev_dbg(ice_pf_to_dev(pf),
3052 "phase offset changed for pin:%d old:%llx, new:%llx\n",
3053 p->idx, p->phase_offset, phase_offset);
3054 p->phase_offset = phase_offset;
3055 *phase_offset_pins_updated |= (1 << i);
3056 }
3057 }
3058
3059 return 0;
3060 }
3061
3062 /**
3063 * ice_dpll_update_state - update dpll state
3064 * @pf: pf private structure
3065 * @d: pointer to queried dpll device
3066 * @init: if function called on initialization of ice dpll
3067 *
3068 * Poll current state of dpll from hw and update ice_dpll struct.
3069 *
3070 * Context: Called by kworker under pf->dplls.lock
3071 * Return:
3072 * * 0 - success
3073 * * negative - AQ failure
3074 */
3075 static int
ice_dpll_update_state(struct ice_pf * pf,struct ice_dpll * d,bool init)3076 ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
3077 {
3078 struct ice_dpll_pin *p = NULL;
3079 int ret;
3080
3081 ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
3082 &d->input_idx, &d->ref_state, &d->eec_mode,
3083 &d->phase_offset, &d->dpll_state);
3084
3085 dev_dbg(ice_pf_to_dev(pf),
3086 "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
3087 d->dpll_idx, d->prev_input_idx, d->input_idx,
3088 d->dpll_state, d->prev_dpll_state, d->mode);
3089 if (ret) {
3090 /* EBUSY is expected during reset recovery, don't log error */
3091 if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY)
3092 dev_err(ice_pf_to_dev(pf),
3093 "update dpll=%d state failed, ret=%d %s\n",
3094 d->dpll_idx, ret,
3095 libie_aq_str(pf->hw.adminq.sq_last_status));
3096 return ret;
3097 }
3098 if (init) {
3099 if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
3100 d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
3101 d->active_input = pf->dplls.inputs[d->input_idx].pin;
3102 p = &pf->dplls.inputs[d->input_idx];
3103 return ice_dpll_pin_state_update(pf, p,
3104 ICE_DPLL_PIN_TYPE_INPUT, NULL);
3105 }
3106 if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
3107 d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
3108 d->active_input = NULL;
3109 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
3110 p = &pf->dplls.inputs[d->input_idx];
3111 d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
3112 d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
3113 if (!p)
3114 return 0;
3115 ret = ice_dpll_pin_state_update(pf, p,
3116 ICE_DPLL_PIN_TYPE_INPUT, NULL);
3117 } else if (d->input_idx != d->prev_input_idx) {
3118 if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
3119 p = &pf->dplls.inputs[d->prev_input_idx];
3120 ice_dpll_pin_state_update(pf, p,
3121 ICE_DPLL_PIN_TYPE_INPUT,
3122 NULL);
3123 }
3124 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
3125 p = &pf->dplls.inputs[d->input_idx];
3126 d->active_input = p->pin;
3127 ice_dpll_pin_state_update(pf, p,
3128 ICE_DPLL_PIN_TYPE_INPUT,
3129 NULL);
3130 }
3131 d->prev_input_idx = d->input_idx;
3132 }
3133
3134 return ret;
3135 }
3136
3137 /**
3138 * ice_dpll_periodic_work - DPLLs periodic worker
3139 * @work: pointer to kthread_work structure
3140 *
3141 * DPLLs periodic worker is responsible for polling state of dpll.
3142 * Context: Holds pf->dplls.lock
3143 */
ice_dpll_periodic_work(struct kthread_work * work)3144 static void ice_dpll_periodic_work(struct kthread_work *work)
3145 {
3146 struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
3147 struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
3148 struct ice_dpll *de = &pf->dplls.eec;
3149 struct ice_dpll *dp = &pf->dplls.pps;
3150 u32 phase_offset_ntf = 0;
3151 int ret = 0;
3152
3153 if (ice_is_reset_in_progress(pf->state))
3154 goto resched;
3155 mutex_lock(&pf->dplls.lock);
3156 d->periodic_counter++;
3157 ret = ice_dpll_update_state(pf, de, false);
3158 if (!ret)
3159 ret = ice_dpll_update_state(pf, dp, false);
3160 if (!ret && dp->phase_offset_monitor_period &&
3161 d->periodic_counter % dp->phase_offset_monitor_period == 0)
3162 ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf);
3163 if (ret) {
3164 /* EBUSY is expected during reset recovery */
3165 if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY)
3166 d->cgu_state_acq_err_num++;
3167 /* stop rescheduling this worker */
3168 if (d->cgu_state_acq_err_num >
3169 ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
3170 dev_err(ice_pf_to_dev(pf),
3171 "EEC/PPS DPLLs periodic work disabled\n");
3172 mutex_unlock(&pf->dplls.lock);
3173 return;
3174 }
3175 }
3176 mutex_unlock(&pf->dplls.lock);
3177 ice_dpll_notify_changes(de);
3178 ice_dpll_notify_changes(dp);
3179 if (phase_offset_ntf)
3180 ice_dpll_pins_notify_mask(d, d->inputs, d->num_inputs,
3181 phase_offset_ntf);
3182
3183 resched:
3184 /* Run twice a second or reschedule if update failed */
3185 kthread_queue_delayed_work(d->kworker, &d->work,
3186 ret ? msecs_to_jiffies(10) :
3187 msecs_to_jiffies(500));
3188 }
3189
3190 /**
3191 * ice_dpll_init_ref_sync_inputs - initialize reference sync pin pairs
3192 * @pf: pf private structure
3193 *
3194 * Read DPLL TLV capabilities and initialize reference sync pin pairs in
3195 * dpll subsystem.
3196 *
3197 * Return:
3198 * * 0 - success or nothing to do (no ref-sync tlv are present)
3199 * * negative - AQ failure
3200 */
ice_dpll_init_ref_sync_inputs(struct ice_pf * pf)3201 static int ice_dpll_init_ref_sync_inputs(struct ice_pf *pf)
3202 {
3203 struct ice_dpll_pin *inputs = pf->dplls.inputs;
3204 struct ice_hw *hw = &pf->hw;
3205 u16 addr, len, end, hdr;
3206 int ret;
3207
3208 ret = ice_get_pfa_module_tlv(hw, &hdr, &len, ICE_SR_PFA_DPLL_DEFAULTS);
3209 if (ret) {
3210 dev_err(ice_pf_to_dev(pf),
3211 "Failed to read PFA dpll defaults TLV ret=%d\n", ret);
3212 return ret;
3213 }
3214 end = hdr + len;
3215
3216 for (addr = hdr + ICE_DPLL_PFA_HEADER_LEN; addr < end;
3217 addr += ICE_DPLL_PFA_ENTRY_LEN) {
3218 unsigned long bit, ul_mask, offset;
3219 u16 pin, mask, buf;
3220 bool valid = false;
3221
3222 ret = ice_read_sr_word(hw, addr, &buf);
3223 if (ret)
3224 return ret;
3225
3226 switch (buf) {
3227 case ICE_DPLL_PFA_REF_SYNC_TYPE:
3228 case ICE_DPLL_PFA_REF_SYNC_TYPE2:
3229 {
3230 u16 mask_addr = addr + ICE_DPLL_PFA_MASK_OFFSET;
3231 u16 val_addr = addr + ICE_DPLL_PFA_VALUE_OFFSET;
3232
3233 ret = ice_read_sr_word(hw, mask_addr, &mask);
3234 if (ret)
3235 return ret;
3236 ret = ice_read_sr_word(hw, val_addr, &pin);
3237 if (ret)
3238 return ret;
3239 if (buf == ICE_DPLL_PFA_REF_SYNC_TYPE)
3240 pin >>= ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S;
3241 valid = true;
3242 break;
3243 }
3244 case ICE_DPLL_PFA_END:
3245 addr = end;
3246 break;
3247 default:
3248 continue;
3249 }
3250 if (!valid)
3251 continue;
3252
3253 ul_mask = mask;
3254 offset = 0;
3255 for_each_set_bit(bit, &ul_mask, BITS_PER_TYPE(u16)) {
3256 int i, j;
3257
3258 if (hw->device_id == ICE_DEV_ID_E810C_SFP &&
3259 pin > ICE_DPLL_E810C_SFP_NC_START)
3260 offset = -ICE_DPLL_E810C_SFP_NC_PINS;
3261 i = pin + offset;
3262 j = bit + offset;
3263 if (i < 0 || j < 0)
3264 return -ERANGE;
3265 inputs[i].ref_sync = j;
3266 }
3267 }
3268
3269 return 0;
3270 }
3271
3272 /**
3273 * ice_dpll_release_pins - release pins resources from dpll subsystem
3274 * @pins: pointer to pins array
3275 * @count: number of pins
3276 *
3277 * Release resources of given pins array in the dpll subsystem.
3278 */
ice_dpll_release_pins(struct ice_dpll_pin * pins,int count)3279 static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
3280 {
3281 int i;
3282
3283 for (i = 0; i < count; i++)
3284 if (!IS_ERR_OR_NULL(pins[i].pin))
3285 dpll_pin_put(pins[i].pin, &pins[i].tracker);
3286 }
3287
3288 /**
3289 * ice_dpll_get_pins - get pins from dpll subsystem
3290 * @pf: board private structure
3291 * @pins: pointer to pins array
3292 * @start_idx: get starts from this pin idx value
3293 * @count: number of pins
3294 * @clock_id: clock_id of dpll device
3295 *
3296 * Get pins - allocate - in dpll subsystem, store them in pin field of given
3297 * pins array.
3298 *
3299 * Return:
3300 * * 0 - success
3301 * * negative - allocation failure reason
3302 */
3303 static int
ice_dpll_get_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx,int count,u64 clock_id)3304 ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3305 int start_idx, int count, u64 clock_id)
3306 {
3307 u32 pin_index;
3308 int i, ret;
3309
3310 for (i = 0; i < count; i++) {
3311 pin_index = start_idx;
3312 if (start_idx != DPLL_PIN_IDX_UNSPEC)
3313 pin_index += i;
3314 pins[i].pin = dpll_pin_get(clock_id, pin_index, THIS_MODULE,
3315 &pins[i].prop, &pins[i].tracker);
3316 if (IS_ERR(pins[i].pin)) {
3317 ret = PTR_ERR(pins[i].pin);
3318 goto release_pins;
3319 }
3320 }
3321
3322 return 0;
3323
3324 release_pins:
3325 while (--i >= 0)
3326 dpll_pin_put(pins[i].pin, &pins[i].tracker);
3327 return ret;
3328 }
3329
3330 /**
3331 * ice_dpll_unregister_pins - unregister pins from a dpll
3332 * @dpll: dpll device pointer
3333 * @pins: pointer to pins array
3334 * @ops: callback ops registered with the pins
3335 * @count: number of pins
3336 *
3337 * Unregister pins of a given array of pins from given dpll device registered in
3338 * dpll subsystem.
3339 */
3340 static void
ice_dpll_unregister_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3341 ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3342 const struct dpll_pin_ops *ops, int count)
3343 {
3344 int i;
3345
3346 for (i = 0; i < count; i++) {
3347 if (pins[i].hidden)
3348 continue;
3349 if (IS_ERR_OR_NULL(pins[i].pin))
3350 continue;
3351 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3352 }
3353 }
3354
3355 /**
3356 * ice_dpll_pin_ref_sync_register - register reference sync pins
3357 * @pins: pointer to pins array
3358 * @count: number of pins
3359 *
3360 * Register reference sync pins in dpll subsystem.
3361 *
3362 * Return:
3363 * * 0 - success
3364 * * negative - registration failure reason
3365 */
3366 static int
ice_dpll_pin_ref_sync_register(struct ice_dpll_pin * pins,int count)3367 ice_dpll_pin_ref_sync_register(struct ice_dpll_pin *pins, int count)
3368 {
3369 int ret, i;
3370
3371 for (i = 0; i < count; i++) {
3372 if (!pins[i].hidden && pins[i].ref_sync) {
3373 int j = pins[i].ref_sync;
3374
3375 ret = dpll_pin_ref_sync_pair_add(pins[i].pin,
3376 pins[j].pin);
3377 if (ret)
3378 return ret;
3379 }
3380 }
3381
3382 return 0;
3383 }
3384
3385 /**
3386 * ice_dpll_register_pins - register pins with a dpll
3387 * @dpll: dpll pointer to register pins with
3388 * @pins: pointer to pins array
3389 * @ops: callback ops registered with the pins
3390 * @count: number of pins
3391 *
3392 * Register pins of a given array with given dpll in dpll subsystem.
3393 *
3394 * Return:
3395 * * 0 - success
3396 * * negative - registration failure reason
3397 */
3398 static int
ice_dpll_register_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3399 ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3400 const struct dpll_pin_ops *ops, int count)
3401 {
3402 int ret, i;
3403
3404 for (i = 0; i < count; i++) {
3405 if (!pins[i].hidden) {
3406 ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]);
3407 if (ret)
3408 goto unregister_pins;
3409 }
3410 }
3411
3412 return 0;
3413
3414 unregister_pins:
3415 while (--i >= 0)
3416 if (!pins[i].hidden)
3417 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3418 return ret;
3419 }
3420
3421 /**
3422 * ice_dpll_deinit_direct_pins - deinitialize direct pins
3423 * @pf: board private structure
3424 * @cgu: if cgu is present and controlled by this NIC
3425 * @pins: pointer to pins array
3426 * @count: number of pins
3427 * @ops: callback ops registered with the pins
3428 * @first: dpll device pointer
3429 * @second: dpll device pointer
3430 *
3431 * If cgu is owned unregister pins from given dplls.
3432 * Release pins resources to the dpll subsystem.
3433 */
3434 static void
ice_dpll_deinit_direct_pins(struct ice_pf * pf,bool cgu,struct ice_dpll_pin * pins,int count,const struct dpll_pin_ops * ops,struct dpll_device * first,struct dpll_device * second)3435 ice_dpll_deinit_direct_pins(struct ice_pf *pf, bool cgu,
3436 struct ice_dpll_pin *pins, int count,
3437 const struct dpll_pin_ops *ops,
3438 struct dpll_device *first,
3439 struct dpll_device *second)
3440 {
3441 if (cgu) {
3442 ice_dpll_unregister_pins(first, pins, ops, count);
3443 ice_dpll_unregister_pins(second, pins, ops, count);
3444 }
3445 ice_dpll_release_pins(pins, count);
3446 }
3447
3448 /**
3449 * ice_dpll_init_direct_pins - initialize direct pins
3450 * @pf: board private structure
3451 * @cgu: if cgu is present and controlled by this NIC
3452 * @pins: pointer to pins array
3453 * @start_idx: on which index shall allocation start in dpll subsystem
3454 * @count: number of pins
3455 * @ops: callback ops registered with the pins
3456 * @first: dpll device pointer
3457 * @second: dpll device pointer
3458 *
3459 * Allocate directly connected pins of a given array in dpll subsystem.
3460 * If cgu is owned register allocated pins with given dplls.
3461 *
3462 * Return:
3463 * * 0 - success
3464 * * negative - registration failure reason
3465 */
3466 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)3467 ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
3468 struct ice_dpll_pin *pins, int start_idx, int count,
3469 const struct dpll_pin_ops *ops,
3470 struct dpll_device *first, struct dpll_device *second)
3471 {
3472 int ret;
3473
3474 ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id);
3475 if (ret)
3476 return ret;
3477 if (cgu) {
3478 ret = ice_dpll_register_pins(first, pins, ops, count);
3479 if (ret)
3480 goto release_pins;
3481 ret = ice_dpll_register_pins(second, pins, ops, count);
3482 if (ret)
3483 goto unregister_first;
3484 }
3485
3486 return 0;
3487
3488 unregister_first:
3489 ice_dpll_unregister_pins(first, pins, ops, count);
3490 release_pins:
3491 ice_dpll_release_pins(pins, count);
3492 return ret;
3493 }
3494
3495 /**
3496 * ice_dpll_deinit_rclk_pin - release rclk pin resources
3497 * @pf: board private structure
3498 *
3499 * Deregister rclk pin from parent pins and release resources in dpll subsystem.
3500 */
ice_dpll_deinit_rclk_pin(struct ice_pf * pf)3501 static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
3502 {
3503 struct ice_dpll_pin *rclk = &pf->dplls.rclk;
3504 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3505 struct ice_dpll_pin *parent;
3506 int i;
3507
3508 for (i = 0; i < rclk->num_parents; i++) {
3509 parent = &pf->dplls.inputs[rclk->parent_idx[i]];
3510 if (IS_ERR_OR_NULL(parent->pin))
3511 continue;
3512 dpll_pin_on_pin_unregister(parent->pin, rclk->pin,
3513 &ice_dpll_rclk_ops, rclk);
3514 }
3515 if (WARN_ON_ONCE(!vsi || !vsi->netdev))
3516 return;
3517 dpll_netdev_pin_clear(vsi->netdev);
3518 dpll_pin_put(rclk->pin, &rclk->tracker);
3519 }
3520
ice_dpll_is_fwnode_pin(struct ice_dpll_pin * pin)3521 static bool ice_dpll_is_fwnode_pin(struct ice_dpll_pin *pin)
3522 {
3523 return !IS_ERR_OR_NULL(pin->fwnode);
3524 }
3525
ice_dpll_fwnode_eq(const struct fwnode_handle * a,const struct fwnode_handle * b)3526 static bool ice_dpll_fwnode_eq(const struct fwnode_handle *a,
3527 const struct fwnode_handle *b)
3528 {
3529 return a && a == b;
3530 }
3531
ice_dpll_pin_notify_work(struct work_struct * work)3532 static void ice_dpll_pin_notify_work(struct work_struct *work)
3533 {
3534 struct ice_dpll_pin_work *w = container_of(work,
3535 struct ice_dpll_pin_work,
3536 work);
3537 struct ice_dpll_pin *pin, *parent = w->pin;
3538 bool is_tx_synce_parent = false;
3539 struct ice_pf *pf = parent->pf;
3540 bool is_rclk_parent = false;
3541 int ret;
3542
3543 wait_for_completion(&pf->dplls.dpll_init);
3544 if (!test_bit(ICE_FLAG_DPLL, pf->flags))
3545 goto out; /* DPLL initialization failed */
3546
3547 /* Decide which parent we are handling, defensively checking FWNs */
3548 for (int i = 0; i < pf->dplls.rclk.num_parents; i++) {
3549 if (ice_dpll_fwnode_eq(parent->fwnode,
3550 pf->dplls.inputs[i].fwnode)) {
3551 is_rclk_parent = true;
3552 break;
3553 }
3554 }
3555
3556 is_tx_synce_parent =
3557 ice_dpll_fwnode_eq(parent->fwnode,
3558 pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX].fwnode);
3559 if (!is_rclk_parent && !is_tx_synce_parent)
3560 goto out;
3561
3562 switch (w->action) {
3563 case DPLL_PIN_CREATED:
3564 if (!IS_ERR_OR_NULL(parent->pin)) {
3565 /* We have already our pin registered */
3566 goto out;
3567 }
3568
3569 /* Grab reference on fwnode pin */
3570 parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3571 &parent->tracker);
3572 if (IS_ERR_OR_NULL(parent->pin)) {
3573 dev_err(ice_pf_to_dev(pf),
3574 "Cannot get fwnode pin reference\n");
3575 goto out;
3576 }
3577
3578 if (is_rclk_parent) {
3579 /* Register rclk pin via on-pin relationship */
3580 pin = &pf->dplls.rclk;
3581 ret = dpll_pin_on_pin_register(parent->pin, pin->pin,
3582 &ice_dpll_rclk_ops, pin);
3583 if (ret) {
3584 dev_err(ice_pf_to_dev(pf),
3585 "RCLK pin register failed: %pe\n",
3586 ERR_PTR(ret));
3587 goto drop_parent_ref;
3588 }
3589 } else if (is_tx_synce_parent) {
3590 /* Register TX-CLK SYNCE pin directly to TXC DPLL */
3591 pin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];
3592 ret = dpll_pin_register(pf->dplls.txc.dpll, pin->pin,
3593 &ice_dpll_txclk_ops, pin);
3594 if (ret) {
3595 dev_err(ice_pf_to_dev(pf),
3596 "TX SYNCE pin register failed: %pe\n",
3597 ERR_PTR(ret));
3598 goto drop_parent_ref;
3599 }
3600 }
3601 break;
3602 case DPLL_PIN_DELETED:
3603 if (IS_ERR_OR_NULL(parent->pin)) {
3604 /* We have already our pin unregistered */
3605 goto out;
3606 }
3607
3608 if (is_rclk_parent) {
3609 /* Unregister rclk pin */
3610 pin = &pf->dplls.rclk;
3611 dpll_pin_on_pin_unregister(parent->pin, pin->pin,
3612 &ice_dpll_rclk_ops, pin);
3613 } else if (is_tx_synce_parent) {
3614 /* Unregister TX-CLK SYNCE pin from TXC DPLL */
3615 pin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];
3616 dpll_pin_unregister(pf->dplls.txc.dpll, pin->pin,
3617 &ice_dpll_txclk_ops, pin);
3618 }
3619 drop_parent_ref:
3620 /* Drop fwnode pin reference */
3621 dpll_pin_put(parent->pin, &parent->tracker);
3622 parent->pin = NULL;
3623 break;
3624 default:
3625 break;
3626 }
3627 out:
3628 kfree(w);
3629 }
3630
ice_dpll_pin_notify(struct notifier_block * nb,unsigned long action,void * data)3631 static int ice_dpll_pin_notify(struct notifier_block *nb, unsigned long action,
3632 void *data)
3633 {
3634 struct ice_dpll_pin *pin = container_of(nb, struct ice_dpll_pin, nb);
3635 struct dpll_pin_notifier_info *info = data;
3636 struct ice_dpll_pin_work *work;
3637
3638 if (action != DPLL_PIN_CREATED && action != DPLL_PIN_DELETED)
3639 return NOTIFY_DONE;
3640
3641 /* Check if the reported pin is this one */
3642 if (pin->fwnode != info->fwnode)
3643 return NOTIFY_DONE; /* Not this pin */
3644
3645 /* Ignore notification which are the outcome of internal pin
3646 * registration/unregistration calls - synce pin case.
3647 */
3648 if (info->src_clock_id == pin->pf->dplls.clock_id)
3649 return NOTIFY_DONE;
3650
3651 work = kzalloc_obj(*work);
3652 if (!work)
3653 return NOTIFY_DONE;
3654
3655 INIT_WORK(&work->work, ice_dpll_pin_notify_work);
3656 work->action = action;
3657 work->pin = pin;
3658
3659 queue_work(pin->pf->dplls.wq, &work->work);
3660
3661 return NOTIFY_OK;
3662 }
3663
3664 /**
3665 * ice_dpll_init_pin_common - initialize pin
3666 * @pf: board private structure
3667 * @pin: pin to register
3668 * @start_idx: on which index shall allocation start in dpll subsystem
3669 * @ops: callback ops registered with the pins
3670 *
3671 * Allocate resource for given pin in dpll subsystem. Register the pin with
3672 * the parents it has in the info.
3673 *
3674 * Return:
3675 * * 0 - success
3676 * * negative - registration failure reason
3677 */
3678 static int
ice_dpll_init_pin_common(struct ice_pf * pf,struct ice_dpll_pin * pin,int start_idx,const struct dpll_pin_ops * ops)3679 ice_dpll_init_pin_common(struct ice_pf *pf, struct ice_dpll_pin *pin,
3680 int start_idx, const struct dpll_pin_ops *ops)
3681 {
3682 struct ice_dpll_pin *parent;
3683 int ret, i;
3684
3685 ret = ice_dpll_get_pins(pf, pin, start_idx, 1, pf->dplls.clock_id);
3686 if (ret)
3687 return ret;
3688
3689 for (i = 0; i < pin->num_parents; i++) {
3690 parent = &pf->dplls.inputs[pin->parent_idx[i]];
3691 if (IS_ERR_OR_NULL(parent->pin)) {
3692 if (!ice_dpll_is_fwnode_pin(parent)) {
3693 ret = -ENODEV;
3694 goto unregister_pins;
3695 }
3696 parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3697 &parent->tracker);
3698 if (IS_ERR_OR_NULL(parent->pin)) {
3699 dev_info(ice_pf_to_dev(pf),
3700 "Mux pin not registered yet\n");
3701 continue;
3702 }
3703 }
3704 ret = dpll_pin_on_pin_register(parent->pin, pin->pin, ops, pin);
3705 if (ret)
3706 goto unregister_pins;
3707 }
3708
3709 return 0;
3710
3711 unregister_pins:
3712 while (i) {
3713 parent = &pf->dplls.inputs[pin->parent_idx[--i]];
3714 if (IS_ERR_OR_NULL(parent->pin))
3715 continue;
3716 dpll_pin_on_pin_unregister(parent->pin, pin->pin, ops, pin);
3717 }
3718 ice_dpll_release_pins(pin, 1);
3719
3720 return ret;
3721 }
3722
3723 /**
3724 * ice_dpll_init_rclk_pin - initialize recovered clock pin
3725 * @pf: board private structure
3726 * @start_idx: on which index shall allocation start in dpll subsystem
3727 * @ops: callback ops registered with the pins
3728 *
3729 * Allocate resource for recovered clock pin in dpll subsystem. Register the
3730 * pin with the parents it has in the info.
3731 *
3732 * Return:
3733 * * 0 - success
3734 * * negative - registration failure reason
3735 */
3736 static int
ice_dpll_init_rclk_pin(struct ice_pf * pf,int start_idx,const struct dpll_pin_ops * ops)3737 ice_dpll_init_rclk_pin(struct ice_pf *pf, int start_idx,
3738 const struct dpll_pin_ops *ops)
3739 {
3740 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3741 int ret;
3742
3743 ret = ice_dpll_init_pin_common(pf, &pf->dplls.rclk, start_idx, ops);
3744 if (ret)
3745 return ret;
3746
3747 dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
3748
3749 return 0;
3750 }
3751
3752 static void
ice_dpll_stop_fwnode_pin_activity(struct ice_dpll_pin * pin,bool flush)3753 ice_dpll_stop_fwnode_pin_activity(struct ice_dpll_pin *pin, bool flush)
3754 {
3755 unregister_dpll_notifier(&pin->nb);
3756 if (flush)
3757 flush_workqueue(pin->pf->dplls.wq);
3758 }
3759
3760 static void
ice_dpll_release_fwnode_pin(struct ice_dpll_pin * pin)3761 ice_dpll_release_fwnode_pin(struct ice_dpll_pin *pin)
3762 {
3763 if (!IS_ERR_OR_NULL(pin->pin)) {
3764 dpll_pin_put(pin->pin, &pin->tracker);
3765 pin->pin = NULL;
3766 }
3767 fwnode_handle_put(pin->fwnode);
3768 pin->fwnode = NULL;
3769 }
3770
3771 static void
ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin * pin)3772 ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin *pin)
3773 {
3774 ice_dpll_stop_fwnode_pin_activity(pin, true);
3775 ice_dpll_release_fwnode_pin(pin);
3776 }
3777
3778 static void
ice_dpll_deinit_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3779 ice_dpll_deinit_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3780 int start_idx)
3781 {
3782 int i;
3783
3784 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
3785 ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3786 destroy_workqueue(pf->dplls.wq);
3787 }
3788
ice_dpll_deinit_txclk_pins(struct ice_pf * pf)3789 static int ice_dpll_deinit_txclk_pins(struct ice_pf *pf)
3790 {
3791 struct ice_dpll_pin *synce_pin = &pf->dplls.txclks[E825_EXT_SYNCE_PIN_IDX];
3792 struct ice_dpll *dt = &pf->dplls.txc;
3793
3794 ice_dpll_stop_fwnode_pin_activity(synce_pin, true);
3795 ice_dpll_unregister_pins(dt->dpll, pf->dplls.txclks,
3796 &ice_dpll_txclk_ops,
3797 ARRAY_SIZE(pf->dplls.txclks));
3798 ice_dpll_release_pins(&pf->dplls.txclks[E825_EXT_EREF_PIN_IDX], 1);
3799 /* ice_dpll_release_pins() puts the pin but does not clear the slot,
3800 * unlike ice_dpll_release_fwnode_pin() used for SYNCE below. NULL it
3801 * so a late ice_txclk_get_pin() returns NULL rather than a dangling
3802 * pointer.
3803 */
3804 pf->dplls.txclks[E825_EXT_EREF_PIN_IDX].pin = NULL;
3805 ice_dpll_release_fwnode_pin(synce_pin);
3806 return 0;
3807 }
3808
3809 /**
3810 * ice_dpll_deinit_pins - deinitialize direct pins
3811 * @pf: board private structure
3812 * @cgu: if cgu is controlled by this pf
3813 *
3814 * If cgu is owned unregister directly connected pins from the dplls.
3815 * Release resources of directly connected pins from the dpll subsystem.
3816 */
ice_dpll_deinit_pins(struct ice_pf * pf,bool cgu)3817 static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
3818 {
3819 struct ice_dpll_pin *outputs = pf->dplls.outputs;
3820 struct ice_dpll_pin *inputs = pf->dplls.inputs;
3821 int num_outputs = pf->dplls.num_outputs;
3822 int num_inputs = pf->dplls.num_inputs;
3823 struct ice_dplls *d = &pf->dplls;
3824 struct ice_dpll *de = &d->eec;
3825 struct ice_dpll *dp = &d->pps;
3826
3827 ice_dpll_deinit_rclk_pin(pf);
3828 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
3829 ice_dpll_deinit_txclk_pins(pf);
3830 ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
3831 }
3832 if (cgu) {
3833 ice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,
3834 num_inputs);
3835 ice_dpll_unregister_pins(de->dpll, inputs, &ice_dpll_input_ops,
3836 num_inputs);
3837 }
3838 ice_dpll_release_pins(inputs, num_inputs);
3839 if (cgu) {
3840 ice_dpll_unregister_pins(dp->dpll, outputs,
3841 &ice_dpll_output_ops, num_outputs);
3842 ice_dpll_unregister_pins(de->dpll, outputs,
3843 &ice_dpll_output_ops, num_outputs);
3844 ice_dpll_release_pins(outputs, num_outputs);
3845 if (!pf->dplls.generic) {
3846 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl,
3847 ICE_DPLL_PIN_SW_NUM,
3848 &ice_dpll_pin_ufl_ops,
3849 pf->dplls.pps.dpll,
3850 pf->dplls.eec.dpll);
3851 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma,
3852 ICE_DPLL_PIN_SW_NUM,
3853 &ice_dpll_pin_sma_ops,
3854 pf->dplls.pps.dpll,
3855 pf->dplls.eec.dpll);
3856 }
3857 }
3858 }
3859
3860 static struct fwnode_handle *
ice_dpll_pin_node_get(struct ice_pf * pf,const char * name)3861 ice_dpll_pin_node_get(struct ice_pf *pf, const char *name)
3862 {
3863 struct fwnode_handle *fwnode = dev_fwnode(ice_pf_to_dev(pf));
3864 int index;
3865
3866 index = fwnode_property_match_string(fwnode, "dpll-pin-names", name);
3867 if (index < 0)
3868 return ERR_PTR(-ENOENT);
3869
3870 return fwnode_find_reference(fwnode, "dpll-pins", index);
3871 }
3872
3873 static int
ice_dpll_init_fwnode_pin(struct ice_dpll_pin * pin,const char * name)3874 ice_dpll_init_fwnode_pin(struct ice_dpll_pin *pin, const char *name)
3875 {
3876 struct ice_pf *pf = pin->pf;
3877 int ret;
3878
3879 pin->fwnode = ice_dpll_pin_node_get(pf, name);
3880 if (IS_ERR(pin->fwnode)) {
3881 dev_err(ice_pf_to_dev(pf),
3882 "Failed to find %s firmware node: %pe\n", name,
3883 pin->fwnode);
3884 pin->fwnode = NULL;
3885 return -ENODEV;
3886 }
3887
3888 dev_dbg(ice_pf_to_dev(pf), "Found fwnode node for %s\n", name);
3889
3890 pin->pin = fwnode_dpll_pin_find(pin->fwnode, &pin->tracker);
3891 if (IS_ERR_OR_NULL(pin->pin)) {
3892 dev_info(ice_pf_to_dev(pf),
3893 "DPLL pin for %pfwp not registered yet\n",
3894 pin->fwnode);
3895 pin->pin = NULL;
3896 }
3897
3898 pin->nb.notifier_call = ice_dpll_pin_notify;
3899 ret = register_dpll_notifier(&pin->nb);
3900 if (ret) {
3901 dev_err(ice_pf_to_dev(pf),
3902 "Failed to subscribe for DPLL notifications\n");
3903
3904 if (!IS_ERR_OR_NULL(pin->pin)) {
3905 dpll_pin_put(pin->pin, &pin->tracker);
3906 pin->pin = NULL;
3907 }
3908 fwnode_handle_put(pin->fwnode);
3909 pin->fwnode = NULL;
3910
3911 return ret;
3912 }
3913
3914 return ret;
3915 }
3916
3917 /**
3918 * ice_dpll_init_fwnode_pins - initialize pins from device tree
3919 * @pf: board private structure
3920 * @pins: pointer to pins array
3921 * @start_idx: starting index for pins
3922 * @count: number of pins to initialize
3923 *
3924 * Initialize input pins for E825 RCLK support. The parent pins (rclk0, rclk1)
3925 * are expected to be defined by the system firmware (ACPI). This function
3926 * allocates them in the dpll subsystem and stores their indices for later
3927 * registration with the rclk pin.
3928 *
3929 * Return:
3930 * * 0 - success
3931 * * negative - initialization failure reason
3932 */
3933 static int
ice_dpll_init_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3934 ice_dpll_init_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3935 int start_idx)
3936 {
3937 char pin_name[16];
3938 int i, ret;
3939
3940 pf->dplls.wq = create_singlethread_workqueue("ice_dpll_wq");
3941 if (!pf->dplls.wq)
3942 return -ENOMEM;
3943
3944 for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
3945 pins[start_idx + i].pf = pf;
3946 snprintf(pin_name, sizeof(pin_name), "rclk%u", i);
3947 ret = ice_dpll_init_fwnode_pin(&pins[start_idx + i], pin_name);
3948 if (ret)
3949 goto error;
3950 }
3951
3952 return 0;
3953 error:
3954 /*
3955 * A notifier worker may already be queued and blocked on dpll_init;
3956 * release it so the per-pin flush below does not deadlock.
3957 */
3958 complete_all(&pf->dplls.dpll_init);
3959 while (i--)
3960 ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3961
3962 destroy_workqueue(pf->dplls.wq);
3963
3964 return ret;
3965 }
3966
ice_dpll_init_txclk_pins(struct ice_pf * pf,int start_idx)3967 static int ice_dpll_init_txclk_pins(struct ice_pf *pf, int start_idx)
3968 {
3969 struct ice_dpll_pin *ref_pin = pf->dplls.txclks;
3970 struct ice_dpll *txc = &pf->dplls.txc;
3971 int ret;
3972
3973 /* Configure EXT_EREF0 pin */
3974 ret = ice_dpll_get_pins(pf, ref_pin, start_idx, 1, pf->dplls.clock_id);
3975 if (ret)
3976 return ret;
3977 ret = dpll_pin_register(txc->dpll, ref_pin->pin, &ice_dpll_txclk_ops,
3978 ref_pin);
3979 if (ret)
3980 goto err_release_ext_eref;
3981
3982 /*
3983 * Configure EXT_SYNCE pin (fwnode-backed).
3984 * The pin may not yet be available; in that case registration
3985 * will be deferred via the notifier path.
3986 */
3987 ref_pin++;
3988 ret = ice_dpll_init_fwnode_pin(ref_pin, ice_dpll_fwnode_ext_synce);
3989 if (ret)
3990 goto err_unregister_ext_eref;
3991
3992 if (IS_ERR_OR_NULL(ref_pin->pin)) {
3993 dev_dbg(ice_pf_to_dev(pf),
3994 "Tx-clk SYNCE pin not registered yet\n");
3995 return 0;
3996 }
3997
3998 ret = dpll_pin_register(txc->dpll, ref_pin->pin, &ice_dpll_txclk_ops,
3999 ref_pin);
4000 if (ret)
4001 goto err_deinit_synce;
4002
4003 return 0;
4004
4005 err_deinit_synce:
4006 /*
4007 * Avoid deadlock against notifier workers blocked on dpll_init.
4008 * The outer init error path will complete dpll_init and flush the
4009 * shared workqueue before destroying it.
4010 */
4011 ice_dpll_stop_fwnode_pin_activity(ref_pin, false);
4012 ice_dpll_release_fwnode_pin(ref_pin);
4013 err_unregister_ext_eref:
4014 dpll_pin_unregister(txc->dpll,
4015 pf->dplls.txclks[E825_EXT_EREF_PIN_IDX].pin,
4016 &ice_dpll_txclk_ops,
4017 &pf->dplls.txclks[E825_EXT_EREF_PIN_IDX]);
4018
4019 err_release_ext_eref:
4020 ice_dpll_release_pins(&pf->dplls.txclks[E825_EXT_EREF_PIN_IDX], 1);
4021
4022 return ret;
4023 }
4024
4025 /**
4026 * ice_dpll_init_pins_e825 - init pins and register pins with a dplls
4027 * @pf: board private structure
4028 * @cgu: if cgu is present and controlled by this NIC
4029 *
4030 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
4031 * subsystem.
4032 *
4033 * Return:
4034 * * 0 - success
4035 * * negative - initialization failure reason
4036 */
ice_dpll_init_pins_e825(struct ice_pf * pf)4037 static int ice_dpll_init_pins_e825(struct ice_pf *pf)
4038 {
4039 int ret;
4040
4041 ret = ice_dpll_init_fwnode_pins(pf, pf->dplls.inputs, 0);
4042 if (ret)
4043 return ret;
4044
4045 ret = ice_dpll_init_rclk_pin(pf, DPLL_PIN_IDX_UNSPEC,
4046 &ice_dpll_rclk_ops);
4047
4048 if (ret)
4049 goto unregister_pins;
4050
4051 ret = ice_dpll_init_txclk_pins(pf, 0);
4052 if (ret)
4053 ice_dpll_deinit_rclk_pin(pf);
4054
4055 unregister_pins:
4056 if (ret) {
4057 /* Inform DPLL notifier works that DPLL init was finished
4058 * unsuccessfully (ICE_DPLL_FLAG not set).
4059 */
4060 complete_all(&pf->dplls.dpll_init);
4061 ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
4062 }
4063
4064 return ret;
4065 }
4066
4067 /**
4068 * ice_dpll_init_pins - init pins and register pins with a dplls
4069 * @pf: board private structure
4070 * @cgu: if cgu is present and controlled by this NIC
4071 *
4072 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
4073 * subsystem.
4074 *
4075 * Return:
4076 * * 0 - success
4077 * * negative - initialization failure reason
4078 */
ice_dpll_init_pins(struct ice_pf * pf,bool cgu)4079 static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
4080 {
4081 const struct dpll_pin_ops *output_ops;
4082 const struct dpll_pin_ops *input_ops;
4083 int ret, count;
4084
4085 input_ops = &ice_dpll_input_ops;
4086 output_ops = &ice_dpll_output_ops;
4087
4088 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0,
4089 pf->dplls.num_inputs, input_ops,
4090 pf->dplls.eec.dpll,
4091 pf->dplls.pps.dpll);
4092 if (ret)
4093 return ret;
4094 count = pf->dplls.num_inputs;
4095 if (cgu) {
4096 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs,
4097 count, pf->dplls.num_outputs,
4098 output_ops, pf->dplls.eec.dpll,
4099 pf->dplls.pps.dpll);
4100 if (ret)
4101 goto deinit_inputs;
4102 count += pf->dplls.num_outputs;
4103 if (!pf->dplls.generic) {
4104 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.sma,
4105 count,
4106 ICE_DPLL_PIN_SW_NUM,
4107 &ice_dpll_pin_sma_ops,
4108 pf->dplls.eec.dpll,
4109 pf->dplls.pps.dpll);
4110 if (ret)
4111 goto deinit_outputs;
4112 count += ICE_DPLL_PIN_SW_NUM;
4113 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.ufl,
4114 count,
4115 ICE_DPLL_PIN_SW_NUM,
4116 &ice_dpll_pin_ufl_ops,
4117 pf->dplls.eec.dpll,
4118 pf->dplls.pps.dpll);
4119 if (ret)
4120 goto deinit_sma;
4121 count += ICE_DPLL_PIN_SW_NUM;
4122 }
4123 ret = ice_dpll_pin_ref_sync_register(pf->dplls.inputs,
4124 pf->dplls.num_inputs);
4125 if (ret)
4126 goto deinit_ufl;
4127 ret = ice_dpll_pin_ref_sync_register(pf->dplls.sma,
4128 ICE_DPLL_PIN_SW_NUM);
4129 if (ret)
4130 goto deinit_ufl;
4131 } else {
4132 count += pf->dplls.num_outputs + 2 * ICE_DPLL_PIN_SW_NUM;
4133 }
4134
4135 ret = ice_dpll_init_rclk_pin(pf, count + pf->ptp.port.port_num,
4136 &ice_dpll_rclk_ops);
4137 if (ret)
4138 goto deinit_ufl;
4139
4140 return 0;
4141 deinit_ufl:
4142 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl, ICE_DPLL_PIN_SW_NUM,
4143 &ice_dpll_pin_ufl_ops, pf->dplls.pps.dpll,
4144 pf->dplls.eec.dpll);
4145 deinit_sma:
4146 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma, ICE_DPLL_PIN_SW_NUM,
4147 &ice_dpll_pin_sma_ops, pf->dplls.pps.dpll,
4148 pf->dplls.eec.dpll);
4149 deinit_outputs:
4150 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.outputs,
4151 pf->dplls.num_outputs,
4152 output_ops, pf->dplls.pps.dpll,
4153 pf->dplls.eec.dpll);
4154 deinit_inputs:
4155 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.inputs,
4156 pf->dplls.num_inputs,
4157 input_ops, pf->dplls.pps.dpll,
4158 pf->dplls.eec.dpll);
4159 return ret;
4160 }
4161
4162 /**
4163 * ice_dpll_deinit_dpll - deinitialize dpll device
4164 * @pf: board private structure
4165 * @d: pointer to ice_dpll
4166 * @cgu: if cgu is present and controlled by this NIC
4167 *
4168 * If cgu is owned, unregister the DPLL from DPLL subsystem.
4169 * Release resources of DPLL device from DPLL subsystem.
4170 */
4171 static void
ice_dpll_deinit_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu)4172 ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
4173 {
4174 if (cgu || pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
4175 dpll_device_unregister(d->dpll, d->ops, d);
4176 dpll_device_put(d->dpll, &d->tracker);
4177 }
4178
4179 /**
4180 * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
4181 * @pf: board private structure
4182 * @d: dpll to be initialized
4183 * @cgu: if cgu is present and controlled by this NIC
4184 * @type: type of dpll being initialized
4185 *
4186 * Allocate DPLL instance for this board in dpll subsystem, if cgu is controlled
4187 * by this NIC, register DPLL with the callback ops.
4188 *
4189 * Return:
4190 * * 0 - success
4191 * * negative - initialization failure reason
4192 */
4193 static int
ice_dpll_init_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu,enum dpll_type type)4194 ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
4195 enum dpll_type type)
4196 {
4197 u64 clock_id = pf->dplls.clock_id;
4198 int ret;
4199
4200 d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE,
4201 &d->tracker);
4202 if (IS_ERR(d->dpll)) {
4203 ret = PTR_ERR(d->dpll);
4204 dev_err(ice_pf_to_dev(pf),
4205 "dpll_device_get failed (%p) err=%d\n", d, ret);
4206 return ret;
4207 }
4208 d->pf = pf;
4209 if (cgu || pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
4210 const struct dpll_device_ops *ops = &ice_dpll_ops;
4211
4212 if (type == DPLL_TYPE_PPS && ice_dpll_is_pps_phase_monitor(pf))
4213 ops = &ice_dpll_pom_ops;
4214 if (cgu)
4215 ice_dpll_update_state(pf, d, true);
4216 ret = dpll_device_register(d->dpll, type, ops, d);
4217 if (ret) {
4218 dpll_device_put(d->dpll, &d->tracker);
4219 d->dpll = NULL;
4220 return ret;
4221 }
4222 d->ops = ops;
4223 }
4224
4225 return 0;
4226 }
4227
4228 /**
4229 * ice_dpll_deinit_worker - deinitialize dpll kworker
4230 * @pf: board private structure
4231 *
4232 * Stop dpll's kworker, release it's resources.
4233 */
ice_dpll_deinit_worker(struct ice_pf * pf)4234 static void ice_dpll_deinit_worker(struct ice_pf *pf)
4235 {
4236 struct ice_dplls *d = &pf->dplls;
4237
4238 kthread_cancel_delayed_work_sync(&d->work);
4239 kthread_destroy_worker(d->kworker);
4240 }
4241
4242 /**
4243 * ice_dpll_init_worker - Initialize DPLLs periodic worker
4244 * @pf: board private structure
4245 *
4246 * Create and start DPLLs periodic worker.
4247 *
4248 * Context: Shall be called after pf->dplls.lock is initialized.
4249 * Return:
4250 * * 0 - success
4251 * * negative - create worker failure
4252 */
ice_dpll_init_worker(struct ice_pf * pf)4253 static int ice_dpll_init_worker(struct ice_pf *pf)
4254 {
4255 struct ice_dplls *d = &pf->dplls;
4256 struct kthread_worker *kworker;
4257
4258 kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
4259 kworker = kthread_run_worker(0, "ice-dplls-%s",
4260 dev_name(ice_pf_to_dev(pf)));
4261 if (IS_ERR(kworker))
4262 return PTR_ERR(kworker);
4263 d->kworker = kworker;
4264 d->cgu_state_acq_err_num = 0;
4265 kthread_queue_delayed_work(d->kworker, &d->work, 0);
4266
4267 return 0;
4268 }
4269
4270 /**
4271 * ice_dpll_phase_range_set - initialize phase adjust range helper
4272 * @range: pointer to phase adjust range struct to be initialized
4273 * @phase_adj: a value to be used as min(-)/max(+) boundary
4274 */
ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range * range,u32 phase_adj)4275 static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
4276 u32 phase_adj)
4277 {
4278 range->min = -phase_adj;
4279 range->max = phase_adj;
4280 }
4281
4282 /**
4283 * ice_dpll_init_info_pins_generic - initializes generic pins info
4284 * @pf: board private structure
4285 * @input: if input pins initialized
4286 *
4287 * Init information for generic pins, cache them in PF's pins structures.
4288 *
4289 * Return:
4290 * * 0 - success
4291 * * negative - init failure reason
4292 */
ice_dpll_init_info_pins_generic(struct ice_pf * pf,bool input)4293 static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
4294 {
4295 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
4296 static const char labels[][sizeof("99")] = {
4297 "0", "1", "2", "3", "4", "5", "6", "7", "8",
4298 "9", "10", "11", "12", "13", "14", "15" };
4299 u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4300 enum ice_dpll_pin_type pin_type;
4301 int i, pin_num, ret = -EINVAL;
4302 struct ice_dpll_pin *pins;
4303 u32 phase_adj_max;
4304
4305 if (input) {
4306 pin_num = pf->dplls.num_inputs;
4307 pins = pf->dplls.inputs;
4308 phase_adj_max = pf->dplls.input_phase_adj_max;
4309 pin_type = ICE_DPLL_PIN_TYPE_INPUT;
4310 cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
4311 } else {
4312 pin_num = pf->dplls.num_outputs;
4313 pins = pf->dplls.outputs;
4314 phase_adj_max = pf->dplls.output_phase_adj_max;
4315 pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
4316 }
4317 if (pin_num > ARRAY_SIZE(labels))
4318 return ret;
4319
4320 for (i = 0; i < pin_num; i++) {
4321 pins[i].idx = i;
4322 pins[i].prop.board_label = labels[i];
4323 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
4324 phase_adj_max);
4325 pins[i].prop.capabilities = cap;
4326 pins[i].pf = pf;
4327 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
4328 if (ret)
4329 break;
4330 if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
4331 pins[i].prop.type = DPLL_PIN_TYPE_MUX;
4332 else
4333 pins[i].prop.type = DPLL_PIN_TYPE_EXT;
4334 if (!input)
4335 continue;
4336 ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
4337 &de->input_prio[i]);
4338 if (ret)
4339 break;
4340 ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
4341 &dp->input_prio[i]);
4342 if (ret)
4343 break;
4344 }
4345
4346 return ret;
4347 }
4348
4349 /**
4350 * ice_dpll_init_info_direct_pins - initializes direct pins info
4351 * @pf: board private structure
4352 * @pin_type: type of pins being initialized
4353 *
4354 * Init information for directly connected pins, cache them in pf's pins
4355 * structures.
4356 *
4357 * Return:
4358 * * 0 - success
4359 * * negative - init failure reason
4360 */
4361 static int
ice_dpll_init_info_direct_pins(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)4362 ice_dpll_init_info_direct_pins(struct ice_pf *pf,
4363 enum ice_dpll_pin_type pin_type)
4364 {
4365 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
4366 int num_pins, i, ret = -EINVAL;
4367 struct ice_hw *hw = &pf->hw;
4368 struct ice_dpll_pin *pins;
4369 unsigned long caps;
4370 u32 phase_adj_max;
4371 u8 freq_supp_num;
4372 bool input;
4373
4374 switch (pin_type) {
4375 case ICE_DPLL_PIN_TYPE_INPUT:
4376 pins = pf->dplls.inputs;
4377 num_pins = pf->dplls.num_inputs;
4378 phase_adj_max = pf->dplls.input_phase_adj_max;
4379 input = true;
4380 break;
4381 case ICE_DPLL_PIN_TYPE_OUTPUT:
4382 pins = pf->dplls.outputs;
4383 num_pins = pf->dplls.num_outputs;
4384 phase_adj_max = pf->dplls.output_phase_adj_max;
4385 input = false;
4386 break;
4387 default:
4388 return -EINVAL;
4389 }
4390 if (num_pins != ice_cgu_get_num_pins(hw, input)) {
4391 pf->dplls.generic = true;
4392 return ice_dpll_init_info_pins_generic(pf, input);
4393 }
4394
4395 for (i = 0; i < num_pins; i++) {
4396 caps = 0;
4397 pins[i].idx = i;
4398 pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
4399 pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
4400 if (input) {
4401 ret = ice_aq_get_cgu_ref_prio(hw, de->dpll_idx, i,
4402 &de->input_prio[i]);
4403 if (ret)
4404 return ret;
4405 ret = ice_aq_get_cgu_ref_prio(hw, dp->dpll_idx, i,
4406 &dp->input_prio[i]);
4407 if (ret)
4408 return ret;
4409 caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4410 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
4411 if (ice_dpll_is_sw_pin(pf, i, true))
4412 pins[i].hidden = true;
4413 } else {
4414 ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
4415 if (ret)
4416 return ret;
4417 if (ice_dpll_is_sw_pin(pf, i, false))
4418 pins[i].hidden = true;
4419 }
4420 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
4421 phase_adj_max);
4422 pins[i].prop.capabilities = caps;
4423 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
4424 if (ret)
4425 return ret;
4426 pins[i].prop.freq_supported =
4427 ice_cgu_get_pin_freq_supp(hw, i, input, &freq_supp_num);
4428 pins[i].prop.freq_supported_num = freq_supp_num;
4429 pins[i].pf = pf;
4430 }
4431 if (input)
4432 ret = ice_dpll_init_ref_sync_inputs(pf);
4433
4434 return ret;
4435 }
4436
4437 /**
4438 * ice_dpll_init_info_pin_on_pin_e825c - initializes rclk pin information
4439 * @pf: board private structure
4440 *
4441 * Init information for rclk pin, cache them in pf->dplls.rclk.
4442 *
4443 * Return:
4444 * * 0 - success
4445 */
ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf * pf)4446 static int ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf *pf)
4447 {
4448 struct ice_dpll_pin *rclk_pin = &pf->dplls.rclk;
4449
4450 rclk_pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
4451 rclk_pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4452 rclk_pin->pf = pf;
4453
4454 return 0;
4455 }
4456
4457 /**
4458 * ice_dpll_init_info_rclk_pin - initializes rclk pin information
4459 * @pf: board private structure
4460 *
4461 * Init information for rclk pin, cache them in pf->dplls.rclk.
4462 *
4463 * Return:
4464 * * 0 - success
4465 * * negative - init failure reason
4466 */
ice_dpll_init_info_rclk_pin(struct ice_pf * pf)4467 static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
4468 {
4469 struct ice_dpll_pin *pin = &pf->dplls.rclk;
4470
4471 pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
4472 pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4473 pin->pf = pf;
4474
4475 return ice_dpll_pin_state_update(pf, pin,
4476 ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
4477 }
4478
4479 /**
4480 * ice_dpll_init_info_sw_pins - initializes software controlled pin information
4481 * @pf: board private structure
4482 *
4483 * Init information for software controlled pins, cache them in
4484 * pf->dplls.sma and pf->dplls.ufl.
4485 *
4486 * Return:
4487 * * 0 - success
4488 * * negative - init failure reason
4489 */
ice_dpll_init_info_sw_pins(struct ice_pf * pf)4490 static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
4491 {
4492 u8 freq_supp_num, pin_abs_idx, input_idx_offset = 0;
4493 struct ice_dplls *d = &pf->dplls;
4494 struct ice_dpll_pin *pin;
4495 u32 phase_adj_max, caps;
4496 int i, ret;
4497 u8 data;
4498
4499 if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
4500 input_idx_offset = ICE_E810_RCLK_PINS_NUM;
4501 phase_adj_max = max(d->input_phase_adj_max, d->output_phase_adj_max);
4502 caps = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4503 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4504 pin = &d->sma[i];
4505 pin->idx = i;
4506 pin->prop.type = DPLL_PIN_TYPE_EXT;
4507 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + input_idx_offset;
4508 pin->prop.freq_supported =
4509 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4510 true, &freq_supp_num);
4511 pin->prop.freq_supported_num = freq_supp_num;
4512 pin->prop.capabilities =
4513 (DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE |
4514 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4515 caps);
4516 pin->pf = pf;
4517 pin->prop.board_label = ice_dpll_sw_pin_sma[i];
4518 pin->input = &d->inputs[pin_abs_idx];
4519 if (pin->input->ref_sync)
4520 pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
4521 pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
4522 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4523 }
4524 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4525 pin = &d->ufl[i];
4526 pin->idx = i;
4527 pin->prop.type = DPLL_PIN_TYPE_EXT;
4528 pin->prop.capabilities = caps;
4529 pin->pf = pf;
4530 pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
4531 if (i == ICE_DPLL_PIN_SW_1_IDX) {
4532 pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
4533 pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
4534 pin->prop.freq_supported =
4535 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4536 false,
4537 &freq_supp_num);
4538 pin->prop.freq_supported_num = freq_supp_num;
4539 pin->input = NULL;
4540 pin->output = &d->outputs[pin_abs_idx];
4541 } else if (i == ICE_DPLL_PIN_SW_2_IDX) {
4542 pin->direction = DPLL_PIN_DIRECTION_INPUT;
4543 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
4544 input_idx_offset;
4545 pin->output = NULL;
4546 pin->input = &d->inputs[pin_abs_idx];
4547 pin->prop.freq_supported =
4548 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4549 true, &freq_supp_num);
4550 pin->prop.freq_supported_num = freq_supp_num;
4551 pin->prop.capabilities =
4552 (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4553 caps);
4554 }
4555 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4556 }
4557
4558 /* Initialize the SMA control register to a known-good default state.
4559 * Without this write the PCA9575 GPIO expander retains its power-on
4560 * default (all outputs high) which makes all SW pins appear inactive.
4561 * Set SMA1 and SMA2 as active inputs, disable U.FL1 output and
4562 * U.FL2 input.
4563 */
4564 ret = ice_read_sma_ctrl(&pf->hw, &data);
4565 if (ret)
4566 return ret;
4567 data &= ~ICE_ALL_SMA_MASK;
4568 data |= ICE_SMA1_TX_EN | ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS;
4569 ret = ice_write_sma_ctrl(&pf->hw, data);
4570 if (ret)
4571 return ret;
4572
4573 ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE,
4574 NULL);
4575 if (ret)
4576 return ret;
4577
4578 return 0;
4579 }
4580
4581 /**
4582 * ice_dpll_init_info_txclk_pins_e825c - initializes tx-clk pins information
4583 * @pf: board private structure
4584 *
4585 * Init information for tx-clks pin, cache them in pf->dplls.txclks
4586 *
4587 * Return:
4588 * * 0 - success
4589 */
ice_dpll_init_info_txclk_pins_e825c(struct ice_pf * pf)4590 static int ice_dpll_init_info_txclk_pins_e825c(struct ice_pf *pf)
4591 {
4592 struct ice_dpll_pin *tx_pin;
4593
4594 for (int i = 0; i < ICE_DPLL_TXCLK_NUM_MAX; i++) {
4595 tx_pin = &pf->dplls.txclks[i];
4596 tx_pin->prop.type = DPLL_PIN_TYPE_EXT;
4597 tx_pin->prop.capabilities |=
4598 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4599 tx_pin->pf = pf;
4600 if (i == E825_EXT_EREF_PIN_IDX) {
4601 tx_pin->prop.board_label = ice_dpll_ext_eref_pin;
4602 tx_pin->tx_ref_src = ICE_REF_CLK_EREF0;
4603 } else if (i == E825_EXT_SYNCE_PIN_IDX) {
4604 tx_pin->tx_ref_src = ICE_REF_CLK_SYNCE;
4605 }
4606 }
4607
4608 return 0;
4609 }
4610
4611 /**
4612 * ice_dpll_init_pins_info - init pins info wrapper
4613 * @pf: board private structure
4614 * @pin_type: type of pins being initialized
4615 *
4616 * Wraps functions for pin initialization.
4617 *
4618 * Return:
4619 * * 0 - success
4620 * * negative - init failure reason
4621 */
4622 static int
ice_dpll_init_pins_info(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)4623 ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
4624 {
4625 switch (pin_type) {
4626 case ICE_DPLL_PIN_TYPE_INPUT:
4627 case ICE_DPLL_PIN_TYPE_OUTPUT:
4628 return ice_dpll_init_info_direct_pins(pf, pin_type);
4629 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
4630 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
4631 return ice_dpll_init_info_pin_on_pin_e825c(pf);
4632 else
4633 return ice_dpll_init_info_rclk_pin(pf);
4634 case ICE_DPLL_PIN_TYPE_SOFTWARE:
4635 return ice_dpll_init_info_sw_pins(pf);
4636
4637 case ICE_DPLL_PIN_TYPE_TXCLK:
4638 return ice_dpll_init_info_txclk_pins_e825c(pf);
4639 default:
4640 return -EINVAL;
4641 }
4642 }
4643
4644 /**
4645 * ice_dpll_deinit_info - release memory allocated for pins info
4646 * @pf: board private structure
4647 *
4648 * Release memory allocated for pins by ice_dpll_init_info function.
4649 */
ice_dpll_deinit_info(struct ice_pf * pf)4650 static void ice_dpll_deinit_info(struct ice_pf *pf)
4651 {
4652 kfree(pf->dplls.inputs);
4653 pf->dplls.inputs = NULL;
4654 kfree(pf->dplls.outputs);
4655 pf->dplls.outputs = NULL;
4656 kfree(pf->dplls.eec.input_prio);
4657 pf->dplls.eec.input_prio = NULL;
4658 kfree(pf->dplls.pps.input_prio);
4659 pf->dplls.pps.input_prio = NULL;
4660 }
4661
4662 /**
4663 * ice_dpll_init_info_e825c - prepare pf's dpll information structure for e825c
4664 * device
4665 * @pf: board private structure
4666 *
4667 * Acquire (from HW) and set basic DPLL information (on pf->dplls struct).
4668 *
4669 * Return:
4670 * * 0 - success
4671 * * negative - init failure reason
4672 */
ice_dpll_init_info_e825c(struct ice_pf * pf)4673 static int ice_dpll_init_info_e825c(struct ice_pf *pf)
4674 {
4675 struct ice_dplls *d = &pf->dplls;
4676 struct ice_dpll *dt = &d->txc;
4677 int ret = 0;
4678 int i;
4679
4680 d->clock_id = ice_generate_clock_id(pf);
4681 d->num_inputs = ICE_SYNCE_CLK_NUM;
4682 dt->dpll_state = ice_txclk_lock_status(pf->ptp.port.tx_clk);
4683 dt->mode = DPLL_MODE_MANUAL;
4684 dt->dpll_idx = pf->ptp.port.port_num;
4685
4686 d->inputs = kzalloc_objs(*d->inputs, d->num_inputs);
4687 if (!d->inputs)
4688 return -ENOMEM;
4689
4690 ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4691 &pf->dplls.rclk.num_parents);
4692 if (ret)
4693 goto deinit_info;
4694
4695 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4696 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4697
4698 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4699 if (ret)
4700 goto deinit_info;
4701
4702 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_TXCLK);
4703 if (ret)
4704 goto deinit_info;
4705
4706 dev_dbg(ice_pf_to_dev(pf),
4707 "%s - success, inputs: %u, outputs: %u, rclk-parents: %u\n",
4708 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4709 return 0;
4710 deinit_info:
4711 ice_dpll_deinit_info(pf);
4712 return ret;
4713 }
4714
4715 /**
4716 * ice_dpll_init_info - prepare pf's dpll information structure
4717 * @pf: board private structure
4718 * @cgu: if cgu is present and controlled by this NIC
4719 *
4720 * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
4721 *
4722 * Return:
4723 * * 0 - success
4724 * * negative - init failure reason
4725 */
ice_dpll_init_info(struct ice_pf * pf,bool cgu)4726 static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
4727 {
4728 struct ice_aqc_get_cgu_abilities abilities;
4729 struct ice_dpll *de = &pf->dplls.eec;
4730 struct ice_dpll *dp = &pf->dplls.pps;
4731 struct ice_dplls *d = &pf->dplls;
4732 struct ice_hw *hw = &pf->hw;
4733 int ret, alloc_size, i;
4734
4735 d->clock_id = ice_generate_clock_id(pf);
4736 ret = ice_aq_get_cgu_abilities(hw, &abilities);
4737 if (ret) {
4738 dev_err(ice_pf_to_dev(pf),
4739 "err:%d %s failed to read cgu abilities\n",
4740 ret, libie_aq_str(hw->adminq.sq_last_status));
4741 return ret;
4742 }
4743
4744 de->dpll_idx = abilities.eec_dpll_idx;
4745 dp->dpll_idx = abilities.pps_dpll_idx;
4746 d->num_inputs = abilities.num_inputs;
4747 d->num_outputs = abilities.num_outputs;
4748 d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
4749 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4750 d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
4751 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4752
4753 alloc_size = sizeof(*d->inputs) * d->num_inputs;
4754 d->inputs = kzalloc(alloc_size, GFP_KERNEL);
4755 if (!d->inputs)
4756 return -ENOMEM;
4757
4758 alloc_size = sizeof(*de->input_prio) * d->num_inputs;
4759 de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4760 if (!de->input_prio) {
4761 ret = -ENOMEM;
4762 goto deinit_info;
4763 }
4764
4765 dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4766 if (!dp->input_prio) {
4767 ret = -ENOMEM;
4768 goto deinit_info;
4769 }
4770
4771 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
4772 if (ret)
4773 goto deinit_info;
4774
4775 if (cgu) {
4776 alloc_size = sizeof(*d->outputs) * d->num_outputs;
4777 d->outputs = kzalloc(alloc_size, GFP_KERNEL);
4778 if (!d->outputs) {
4779 ret = -ENOMEM;
4780 goto deinit_info;
4781 }
4782
4783 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT);
4784 if (ret)
4785 goto deinit_info;
4786 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_SOFTWARE);
4787 if (ret)
4788 goto deinit_info;
4789 }
4790
4791 ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4792 &pf->dplls.rclk.num_parents);
4793 if (ret)
4794 goto deinit_info;
4795 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4796 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4797 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4798 if (ret)
4799 goto deinit_info;
4800 de->mode = DPLL_MODE_AUTOMATIC;
4801 dp->mode = DPLL_MODE_AUTOMATIC;
4802
4803 dev_dbg(ice_pf_to_dev(pf),
4804 "%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
4805 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4806
4807 return 0;
4808
4809 deinit_info:
4810 dev_err(ice_pf_to_dev(pf),
4811 "%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
4812 __func__, d->inputs, de->input_prio,
4813 dp->input_prio, d->outputs);
4814 ice_dpll_deinit_info(pf);
4815 return ret;
4816 }
4817
4818 /**
4819 * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
4820 * the dpll device.
4821 * @pf: board private structure
4822 *
4823 * Handles the cleanup work required after dpll initialization, freeing
4824 * resources and unregistering the dpll, pin and all resources used for
4825 * handling them.
4826 *
4827 * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
4828 */
ice_dpll_deinit(struct ice_pf * pf)4829 void ice_dpll_deinit(struct ice_pf *pf)
4830 {
4831 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4832
4833 /* Clear ICE_FLAG_DPLL under the lock so that any new caller of
4834 * ice_txclk_update_and_notify() observes the cleared flag and
4835 * returns early. In-flight callers that already passed the flag
4836 * check hold txclk_notify_rwsem for read across the out-of-lock
4837 * dpll_*_change_ntf() calls; the down_write/up_write barrier
4838 * below waits for them to finish before pins and the TXC DPLL
4839 * device may be freed.
4840 */
4841 mutex_lock(&pf->dplls.lock);
4842 clear_bit(ICE_FLAG_DPLL, pf->flags);
4843 mutex_unlock(&pf->dplls.lock);
4844
4845 /* Wait for in-flight ice_txclk_update_and_notify() readers */
4846 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
4847 down_write(&pf->dplls.txclk_notify_rwsem);
4848 up_write(&pf->dplls.txclk_notify_rwsem);
4849 }
4850
4851 if (cgu)
4852 ice_dpll_deinit_worker(pf);
4853
4854 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
4855 cancel_work_sync(&pf->dplls.txclk_work);
4856
4857 ice_dpll_deinit_pins(pf, cgu);
4858 if (!IS_ERR_OR_NULL(pf->dplls.pps.dpll))
4859 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4860 if (!IS_ERR_OR_NULL(pf->dplls.eec.dpll))
4861 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4862 if (!IS_ERR_OR_NULL(pf->dplls.txc.dpll))
4863 ice_dpll_deinit_dpll(pf, &pf->dplls.txc, false);
4864
4865 ice_dpll_deinit_info(pf);
4866 mutex_destroy(&pf->dplls.lock);
4867 }
4868
4869 /**
4870 * ice_dpll_init_e825 - initialize support for dpll subsystem
4871 * @pf: board private structure
4872 *
4873 * Set up the device dplls, register them and pins connected within Linux dpll
4874 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4875 * configuration requests.
4876 *
4877 * Context: Initializes pf->dplls.lock mutex.
4878 */
ice_dpll_init_e825(struct ice_pf * pf)4879 static void ice_dpll_init_e825(struct ice_pf *pf)
4880 {
4881 struct ice_dplls *d = &pf->dplls;
4882 int err;
4883
4884 /* E825 sets ICE_F_PHY_RCLK unconditionally, so DPLL may run without
4885 * PTP. Populate the HW-topology fields the TX-clk path divides by,
4886 * otherwise userspace can trigger div-by-zero in ice_txclk_set_clk().
4887 * When PTP is supported, ice_ptp_init() handles this.
4888 */
4889 if (!test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
4890 ice_ptp_init_hw(&pf->hw);
4891 if (pf->hw.lane_num >= 0)
4892 pf->ptp.port.port_num = pf->hw.lane_num;
4893 }
4894
4895 mutex_init(&d->lock);
4896 /* Initialize the txclk worker and its notification rwsem before any
4897 * code path can fail: ice_dpll_deinit() runs unconditionally on
4898 * failure and calls cancel_work_sync() / down_write() on these.
4899 */
4900 INIT_WORK(&d->txclk_work, ice_dpll_txclk_work);
4901 init_rwsem(&d->txclk_notify_rwsem);
4902 init_completion(&d->dpll_init);
4903
4904 err = ice_dpll_init_info_e825c(pf);
4905 if (err)
4906 goto err_exit;
4907 err = ice_dpll_init_dpll(pf, &pf->dplls.txc, false, DPLL_TYPE_GENERIC);
4908 if (err)
4909 goto deinit_info;
4910 err = ice_dpll_init_pins_e825(pf);
4911 if (err)
4912 goto deinit_txclk;
4913 set_bit(ICE_FLAG_DPLL, pf->flags);
4914 complete_all(&d->dpll_init);
4915
4916 return;
4917
4918 deinit_txclk:
4919 ice_dpll_deinit_dpll(pf, &pf->dplls.txc, false);
4920 deinit_info:
4921 ice_dpll_deinit_info(pf);
4922 err_exit:
4923 mutex_destroy(&d->lock);
4924 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4925 }
4926
4927 /**
4928 * ice_dpll_init_e810 - initialize support for dpll subsystem
4929 * @pf: board private structure
4930 *
4931 * Set up the device dplls, register them and pins connected within Linux dpll
4932 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4933 * configuration requests.
4934 *
4935 * Context: Initializes pf->dplls.lock mutex.
4936 */
ice_dpll_init_e810(struct ice_pf * pf)4937 static void ice_dpll_init_e810(struct ice_pf *pf)
4938 {
4939 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4940 struct ice_dplls *d = &pf->dplls;
4941 int err = 0;
4942
4943 mutex_init(&d->lock);
4944 err = ice_dpll_init_info(pf, cgu);
4945 if (err)
4946 goto err_exit;
4947 err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
4948 if (err)
4949 goto deinit_info;
4950 err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
4951 if (err)
4952 goto deinit_eec;
4953 err = ice_dpll_init_pins(pf, cgu);
4954 if (err)
4955 goto deinit_pps;
4956 if (cgu) {
4957 err = ice_dpll_init_worker(pf);
4958 if (err)
4959 goto deinit_pins;
4960 }
4961 set_bit(ICE_FLAG_DPLL, pf->flags);
4962
4963 return;
4964
4965 deinit_pins:
4966 ice_dpll_deinit_pins(pf, cgu);
4967 deinit_pps:
4968 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4969 deinit_eec:
4970 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4971 deinit_info:
4972 ice_dpll_deinit_info(pf);
4973 err_exit:
4974 mutex_destroy(&d->lock);
4975 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4976 }
4977
ice_dpll_init(struct ice_pf * pf)4978 void ice_dpll_init(struct ice_pf *pf)
4979 {
4980 switch (pf->hw.mac_type) {
4981 case ICE_MAC_GENERIC_3K_E825:
4982 ice_dpll_init_e825(pf);
4983 break;
4984 default:
4985 ice_dpll_init_e810(pf);
4986 break;
4987 }
4988 }
4989