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