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_sma_direction_set - set direction of SMA pin
1159 * @p: pointer to a pin
1160 * @direction: requested direction of the pin
1161 * @extack: error reporting
1162 *
1163 * Wrapper for dpll subsystem callback. Set direction of a SMA pin.
1164 *
1165 * Context: Call with pf->dplls.lock held
1166 * Return:
1167 * * 0 - success
1168 * * negative - failed to get state
1169 */
ice_dpll_sma_direction_set(struct ice_dpll_pin * p,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1170 static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
1171 enum dpll_pin_direction direction,
1172 struct netlink_ext_ack *extack)
1173 {
1174 u8 data;
1175 int ret;
1176
1177 if (p->direction == direction && p->active)
1178 return 0;
1179 ret = ice_read_sma_ctrl(&p->pf->hw, &data);
1180 if (ret)
1181 return ret;
1182
1183 switch (p->idx) {
1184 case ICE_DPLL_PIN_SW_1_IDX:
1185 data &= ~ICE_SMA1_MASK;
1186 if (direction == DPLL_PIN_DIRECTION_OUTPUT)
1187 data |= ICE_SMA1_DIR_EN;
1188 break;
1189 case ICE_DPLL_PIN_SW_2_IDX:
1190 if (direction == DPLL_PIN_DIRECTION_INPUT) {
1191 data &= ~ICE_SMA2_DIR_EN;
1192 } else {
1193 data &= ~ICE_SMA2_TX_EN;
1194 data |= ICE_SMA2_DIR_EN;
1195 }
1196 break;
1197 default:
1198 return -EINVAL;
1199 }
1200 ret = ice_write_sma_ctrl(&p->pf->hw, data);
1201 if (!ret)
1202 ret = ice_dpll_pin_state_update(p->pf, p,
1203 ICE_DPLL_PIN_TYPE_SOFTWARE,
1204 extack);
1205
1206 return ret;
1207 }
1208
1209 /**
1210 * ice_dpll_ufl_pin_state_set - set U.FL pin state on dpll device
1211 * @pin: pointer to a pin
1212 * @pin_priv: private data pointer passed on pin registration
1213 * @dpll: registered dpll pointer
1214 * @dpll_priv: private data pointer passed on dpll registration
1215 * @state: requested state of the pin
1216 * @extack: error reporting
1217 *
1218 * Dpll subsystem callback. Set the state of a pin.
1219 *
1220 * Context: Acquires and releases pf->dplls.lock
1221 * Return:
1222 * * 0 - success
1223 * * negative - error
1224 */
1225 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)1226 ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1227 const struct dpll_device *dpll, void *dpll_priv,
1228 enum dpll_pin_state state,
1229 struct netlink_ext_ack *extack)
1230 {
1231 struct ice_dpll_pin *p = pin_priv, *target;
1232 struct ice_dpll *d = dpll_priv;
1233 enum ice_dpll_pin_type type;
1234 struct ice_pf *pf = p->pf;
1235 struct ice_hw *hw;
1236 bool enable;
1237 u8 data;
1238 int ret;
1239
1240 if (ice_dpll_is_reset(pf, extack))
1241 return -EBUSY;
1242
1243 mutex_lock(&pf->dplls.lock);
1244 hw = &pf->hw;
1245 ret = ice_read_sma_ctrl(hw, &data);
1246 if (ret)
1247 goto unlock;
1248
1249 ret = -EINVAL;
1250 switch (p->idx) {
1251 case ICE_DPLL_PIN_SW_1_IDX:
1252 if (state == DPLL_PIN_STATE_CONNECTED) {
1253 data &= ~ICE_SMA1_MASK;
1254 enable = true;
1255 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1256 data |= ICE_SMA1_TX_EN;
1257 enable = false;
1258 } else {
1259 goto unlock;
1260 }
1261 target = p->output;
1262 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1263 break;
1264 case ICE_DPLL_PIN_SW_2_IDX:
1265 if (state == DPLL_PIN_STATE_SELECTABLE) {
1266 data |= ICE_SMA2_DIR_EN;
1267 data &= ~ICE_SMA2_UFL2_RX_DIS;
1268 enable = true;
1269 } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1270 data |= ICE_SMA2_UFL2_RX_DIS;
1271 enable = false;
1272 } else {
1273 goto unlock;
1274 }
1275 target = p->input;
1276 type = ICE_DPLL_PIN_TYPE_INPUT;
1277 break;
1278 default:
1279 goto unlock;
1280 }
1281
1282 ret = ice_write_sma_ctrl(hw, data);
1283 if (ret)
1284 goto unlock;
1285 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,
1286 extack);
1287 if (ret)
1288 goto unlock;
1289
1290 if (enable)
1291 ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
1292 else
1293 ret = ice_dpll_pin_disable(hw, target, type, extack);
1294 if (!ret)
1295 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1296
1297 unlock:
1298 mutex_unlock(&pf->dplls.lock);
1299
1300 return ret;
1301 }
1302
1303 /**
1304 * ice_dpll_sw_pin_state_get - get SW pin state
1305 * @pin: pointer to a pin
1306 * @pin_priv: private data pointer passed on pin registration
1307 * @dpll: registered dpll pointer
1308 * @dpll_priv: private data pointer passed on dpll registration
1309 * @state: on success holds state of the pin
1310 * @extack: error reporting
1311 *
1312 * Dpll subsystem callback. Check state of a SW pin.
1313 *
1314 * Context: Acquires and releases pf->dplls.lock
1315 * Return:
1316 * * 0 - success
1317 * * negative - error
1318 */
1319 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)1320 ice_dpll_sw_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1321 const struct dpll_device *dpll, void *dpll_priv,
1322 enum dpll_pin_state *state,
1323 struct netlink_ext_ack *extack)
1324 {
1325 struct ice_dpll_pin *p = pin_priv;
1326 struct ice_dpll *d = dpll_priv;
1327 struct ice_pf *pf = p->pf;
1328 int ret = 0;
1329
1330 if (ice_dpll_is_reset(pf, extack))
1331 return -EBUSY;
1332 mutex_lock(&pf->dplls.lock);
1333 if (!p->active) {
1334 *state = DPLL_PIN_STATE_DISCONNECTED;
1335 goto unlock;
1336 }
1337
1338 if (p->direction == DPLL_PIN_DIRECTION_INPUT) {
1339 ret = ice_dpll_pin_state_update(pf, p->input,
1340 ICE_DPLL_PIN_TYPE_INPUT,
1341 extack);
1342 if (ret)
1343 goto unlock;
1344 *state = p->input->state[d->dpll_idx];
1345 } else {
1346 ret = ice_dpll_pin_state_update(pf, p->output,
1347 ICE_DPLL_PIN_TYPE_OUTPUT,
1348 extack);
1349 if (ret)
1350 goto unlock;
1351 *state = p->output->state[d->dpll_idx];
1352 }
1353 unlock:
1354 mutex_unlock(&pf->dplls.lock);
1355
1356 return ret;
1357 }
1358
1359 /**
1360 * ice_dpll_sma_pin_state_set - set SMA pin state on dpll device
1361 * @pin: pointer to a pin
1362 * @pin_priv: private data pointer passed on pin registration
1363 * @dpll: registered dpll pointer
1364 * @dpll_priv: private data pointer passed on dpll registration
1365 * @state: requested state of the pin
1366 * @extack: error reporting
1367 *
1368 * Dpll subsystem callback. Set state of a pin.
1369 *
1370 * Context: Acquires and releases pf->dplls.lock
1371 * Return:
1372 * * 0 - success
1373 * * negative - failed to get state
1374 */
1375 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)1376 ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1377 const struct dpll_device *dpll, void *dpll_priv,
1378 enum dpll_pin_state state,
1379 struct netlink_ext_ack *extack)
1380 {
1381 struct ice_dpll_pin *sma = pin_priv, *target;
1382 struct ice_dpll *d = dpll_priv;
1383 struct ice_pf *pf = sma->pf;
1384 enum ice_dpll_pin_type type;
1385 bool enable;
1386 int ret;
1387
1388 if (ice_dpll_is_reset(pf, extack))
1389 return -EBUSY;
1390
1391 mutex_lock(&pf->dplls.lock);
1392 if (!sma->active) {
1393 ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
1394 if (ret)
1395 goto unlock;
1396 }
1397 if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
1398 enable = state == DPLL_PIN_STATE_SELECTABLE;
1399 target = sma->input;
1400 type = ICE_DPLL_PIN_TYPE_INPUT;
1401 } else {
1402 enable = state == DPLL_PIN_STATE_CONNECTED;
1403 target = sma->output;
1404 type = ICE_DPLL_PIN_TYPE_OUTPUT;
1405 }
1406
1407 if (enable)
1408 ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
1409 extack);
1410 else
1411 ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
1412 if (!ret)
1413 ret = ice_dpll_pin_state_update(pf, target, type, extack);
1414
1415 unlock:
1416 mutex_unlock(&pf->dplls.lock);
1417
1418 return ret;
1419 }
1420
1421 /**
1422 * ice_dpll_input_prio_get - get dpll's input prio
1423 * @pin: pointer to a pin
1424 * @pin_priv: private data pointer passed on pin registration
1425 * @dpll: registered dpll pointer
1426 * @dpll_priv: private data pointer passed on dpll registration
1427 * @prio: on success - returns input priority on dpll
1428 * @extack: error reporting
1429 *
1430 * Dpll subsystem callback. Handler for getting priority of a input pin.
1431 *
1432 * Context: Acquires pf->dplls.lock
1433 * Return:
1434 * * 0 - success
1435 * * negative - failure
1436 */
1437 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)1438 ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1439 const struct dpll_device *dpll, void *dpll_priv,
1440 u32 *prio, struct netlink_ext_ack *extack)
1441 {
1442 struct ice_dpll_pin *p = pin_priv;
1443 struct ice_dpll *d = dpll_priv;
1444 struct ice_pf *pf = d->pf;
1445
1446 mutex_lock(&pf->dplls.lock);
1447 *prio = d->input_prio[p->idx];
1448 mutex_unlock(&pf->dplls.lock);
1449
1450 return 0;
1451 }
1452
1453 /**
1454 * ice_dpll_input_prio_set - set dpll input prio
1455 * @pin: pointer to a pin
1456 * @pin_priv: private data pointer passed on pin registration
1457 * @dpll: registered dpll pointer
1458 * @dpll_priv: private data pointer passed on dpll registration
1459 * @prio: input priority to be set on dpll
1460 * @extack: error reporting
1461 *
1462 * Dpll subsystem callback. Handler for setting priority of a input pin.
1463 *
1464 * Context: Acquires pf->dplls.lock
1465 * Return:
1466 * * 0 - success
1467 * * negative - failure
1468 */
1469 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)1470 ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1471 const struct dpll_device *dpll, void *dpll_priv,
1472 u32 prio, struct netlink_ext_ack *extack)
1473 {
1474 struct ice_dpll_pin *p = pin_priv;
1475 struct ice_dpll *d = dpll_priv;
1476 struct ice_pf *pf = d->pf;
1477 int ret;
1478
1479 if (ice_dpll_is_reset(pf, extack))
1480 return -EBUSY;
1481
1482 mutex_lock(&pf->dplls.lock);
1483 ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
1484 mutex_unlock(&pf->dplls.lock);
1485
1486 return ret;
1487 }
1488
1489 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)1490 ice_dpll_sw_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1491 const struct dpll_device *dpll, void *dpll_priv,
1492 u32 *prio, struct netlink_ext_ack *extack)
1493 {
1494 struct ice_dpll_pin *p = pin_priv;
1495 struct ice_dpll *d = dpll_priv;
1496 struct ice_pf *pf = d->pf;
1497
1498 mutex_lock(&pf->dplls.lock);
1499 if (p->input && p->direction == DPLL_PIN_DIRECTION_INPUT)
1500 *prio = d->input_prio[p->input->idx];
1501 else
1502 *prio = ICE_DPLL_PIN_PRIO_OUTPUT;
1503 mutex_unlock(&pf->dplls.lock);
1504
1505 return 0;
1506 }
1507
1508 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)1509 ice_dpll_sw_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1510 const struct dpll_device *dpll, void *dpll_priv,
1511 u32 prio, struct netlink_ext_ack *extack)
1512 {
1513 struct ice_dpll_pin *p = pin_priv;
1514 struct ice_dpll *d = dpll_priv;
1515 struct ice_pf *pf = d->pf;
1516 int ret;
1517
1518 if (!p->input || p->direction != DPLL_PIN_DIRECTION_INPUT)
1519 return -EINVAL;
1520 if (ice_dpll_is_reset(pf, extack))
1521 return -EBUSY;
1522
1523 mutex_lock(&pf->dplls.lock);
1524 ret = ice_dpll_hw_input_prio_set(pf, d, p->input, prio, extack);
1525 mutex_unlock(&pf->dplls.lock);
1526
1527 return ret;
1528 }
1529
1530 /**
1531 * ice_dpll_input_direction - callback for get input pin direction
1532 * @pin: pointer to a pin
1533 * @pin_priv: private data pointer passed on pin registration
1534 * @dpll: registered dpll pointer
1535 * @dpll_priv: private data pointer passed on dpll registration
1536 * @direction: holds input pin direction
1537 * @extack: error reporting
1538 *
1539 * Dpll subsystem callback. Handler for getting direction of a input pin.
1540 *
1541 * Return:
1542 * * 0 - success
1543 */
1544 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)1545 ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
1546 const struct dpll_device *dpll, void *dpll_priv,
1547 enum dpll_pin_direction *direction,
1548 struct netlink_ext_ack *extack)
1549 {
1550 *direction = DPLL_PIN_DIRECTION_INPUT;
1551
1552 return 0;
1553 }
1554
1555 /**
1556 * ice_dpll_output_direction - callback for get output pin direction
1557 * @pin: pointer to a pin
1558 * @pin_priv: private data pointer passed on pin registration
1559 * @dpll: registered dpll pointer
1560 * @dpll_priv: private data pointer passed on dpll registration
1561 * @direction: holds output pin direction
1562 * @extack: error reporting
1563 *
1564 * Dpll subsystem callback. Handler for getting direction of an output pin.
1565 *
1566 * Return:
1567 * * 0 - success
1568 */
1569 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)1570 ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
1571 const struct dpll_device *dpll, void *dpll_priv,
1572 enum dpll_pin_direction *direction,
1573 struct netlink_ext_ack *extack)
1574 {
1575 *direction = DPLL_PIN_DIRECTION_OUTPUT;
1576
1577 return 0;
1578 }
1579
1580 /**
1581 * ice_dpll_pin_sma_direction_set - callback for set SMA pin direction
1582 * @pin: pointer to a pin
1583 * @pin_priv: private data pointer passed on pin registration
1584 * @dpll: registered dpll pointer
1585 * @dpll_priv: private data pointer passed on dpll registration
1586 * @direction: requested pin direction
1587 * @extack: error reporting
1588 *
1589 * Dpll subsystem callback. Handler for setting direction of a SMA pin.
1590 *
1591 * Context: Acquires and releases pf->dplls.lock
1592 * Return:
1593 * * 0 - success
1594 * * negative - error
1595 */
1596 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)1597 ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
1598 const struct dpll_device *dpll, void *dpll_priv,
1599 enum dpll_pin_direction direction,
1600 struct netlink_ext_ack *extack)
1601 {
1602 struct ice_dpll_pin *p = pin_priv;
1603 struct ice_pf *pf = p->pf;
1604 int ret;
1605
1606 if (ice_dpll_is_reset(pf, extack))
1607 return -EBUSY;
1608
1609 mutex_lock(&pf->dplls.lock);
1610 ret = ice_dpll_sma_direction_set(p, direction, extack);
1611 mutex_unlock(&pf->dplls.lock);
1612
1613 return ret;
1614 }
1615
1616 /**
1617 * ice_dpll_pin_sw_direction_get - callback for get SW pin direction
1618 * @pin: pointer to a pin
1619 * @pin_priv: private data pointer passed on pin registration
1620 * @dpll: registered dpll pointer
1621 * @dpll_priv: private data pointer passed on dpll registration
1622 * @direction: on success holds pin direction
1623 * @extack: error reporting
1624 *
1625 * Dpll subsystem callback. Handler for getting direction of a SMA pin.
1626 *
1627 * Context: Acquires and releases pf->dplls.lock
1628 * Return:
1629 * * 0 - success
1630 * * negative - error
1631 */
1632 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)1633 ice_dpll_pin_sw_direction_get(const struct dpll_pin *pin, void *pin_priv,
1634 const struct dpll_device *dpll, void *dpll_priv,
1635 enum dpll_pin_direction *direction,
1636 struct netlink_ext_ack *extack)
1637 {
1638 struct ice_dpll_pin *p = pin_priv;
1639 struct ice_pf *pf = p->pf;
1640
1641 if (ice_dpll_is_reset(pf, extack))
1642 return -EBUSY;
1643 mutex_lock(&pf->dplls.lock);
1644 *direction = p->direction;
1645 mutex_unlock(&pf->dplls.lock);
1646
1647 return 0;
1648 }
1649
1650 /**
1651 * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
1652 * @pin: pointer to a pin
1653 * @pin_priv: private data pointer passed on pin registration
1654 * @dpll: registered dpll pointer
1655 * @dpll_priv: private data pointer passed on dpll registration
1656 * @phase_adjust: on success holds pin phase_adjust value
1657 * @extack: error reporting
1658 *
1659 * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
1660 *
1661 * Context: Acquires pf->dplls.lock
1662 * Return:
1663 * * 0 - success
1664 * * negative - error
1665 */
1666 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)1667 ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1668 const struct dpll_device *dpll, void *dpll_priv,
1669 s32 *phase_adjust,
1670 struct netlink_ext_ack *extack)
1671 {
1672 struct ice_dpll_pin *p = pin_priv;
1673 struct ice_pf *pf = p->pf;
1674
1675 mutex_lock(&pf->dplls.lock);
1676 *phase_adjust = p->phase_adjust;
1677 mutex_unlock(&pf->dplls.lock);
1678
1679 return 0;
1680 }
1681
1682 /**
1683 * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
1684 * @pin: pointer to a pin
1685 * @pin_priv: private data pointer passed on pin registration
1686 * @dpll: registered dpll pointer
1687 * @dpll_priv: private data pointer passed on dpll registration
1688 * @phase_adjust: phase_adjust to be set
1689 * @extack: error reporting
1690 * @type: type of a pin
1691 *
1692 * Helper for dpll subsystem callback. Handler for setting phase adjust value
1693 * of a pin.
1694 *
1695 * Context: Acquires pf->dplls.lock
1696 * Return:
1697 * * 0 - success
1698 * * negative - error
1699 */
1700 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)1701 ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1702 const struct dpll_device *dpll, void *dpll_priv,
1703 s32 phase_adjust,
1704 struct netlink_ext_ack *extack,
1705 enum ice_dpll_pin_type type)
1706 {
1707 struct ice_dpll_pin *p = pin_priv;
1708 struct ice_dpll *d = dpll_priv;
1709 struct ice_pf *pf = d->pf;
1710 u8 flag, flags_en = 0;
1711 int ret;
1712
1713 if (ice_dpll_is_reset(pf, extack))
1714 return -EBUSY;
1715
1716 mutex_lock(&pf->dplls.lock);
1717 switch (type) {
1718 case ICE_DPLL_PIN_TYPE_INPUT:
1719 flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
1720 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
1721 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1722 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
1723 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
1724 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
1725 0, phase_adjust);
1726 break;
1727 case ICE_DPLL_PIN_TYPE_OUTPUT:
1728 flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
1729 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1730 flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1731 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
1732 flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1733 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
1734 phase_adjust);
1735 break;
1736 default:
1737 ret = -EINVAL;
1738 }
1739 if (!ret)
1740 p->phase_adjust = phase_adjust;
1741 mutex_unlock(&pf->dplls.lock);
1742 if (ret)
1743 NL_SET_ERR_MSG_FMT(extack,
1744 "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u",
1745 ret,
1746 libie_aq_str(pf->hw.adminq.sq_last_status),
1747 phase_adjust, p->idx, d->dpll_idx);
1748
1749 return ret;
1750 }
1751
1752 /**
1753 * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
1754 * @pin: pointer to a pin
1755 * @pin_priv: private data pointer passed on pin registration
1756 * @dpll: registered dpll pointer
1757 * @dpll_priv: private data pointer passed on dpll registration
1758 * @phase_adjust: phase_adjust to be set
1759 * @extack: error reporting
1760 *
1761 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
1762 * pin.
1763 *
1764 * Context: Calls a function which acquires and releases pf->dplls.lock
1765 * Return:
1766 * * 0 - success
1767 * * negative - error
1768 */
1769 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)1770 ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1771 const struct dpll_device *dpll, void *dpll_priv,
1772 s32 phase_adjust,
1773 struct netlink_ext_ack *extack)
1774 {
1775 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1776 phase_adjust, extack,
1777 ICE_DPLL_PIN_TYPE_INPUT);
1778 }
1779
1780 /**
1781 * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1782 * @pin: pointer to a pin
1783 * @pin_priv: private data pointer passed on pin registration
1784 * @dpll: registered dpll pointer
1785 * @dpll_priv: private data pointer passed on dpll registration
1786 * @phase_adjust: phase_adjust to be set
1787 * @extack: error reporting
1788 *
1789 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1790 * pin.
1791 *
1792 * Context: Calls a function which acquires pf->dplls.lock
1793 * Return:
1794 * * 0 - success
1795 * * negative - error
1796 */
1797 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)1798 ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1799 const struct dpll_device *dpll, void *dpll_priv,
1800 s32 phase_adjust,
1801 struct netlink_ext_ack *extack)
1802 {
1803 return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1804 phase_adjust, extack,
1805 ICE_DPLL_PIN_TYPE_OUTPUT);
1806 }
1807
1808 /**
1809 * ice_dpll_sw_phase_adjust_get - callback for get SW pin phase adjust
1810 * @pin: pointer to a pin
1811 * @pin_priv: private data pointer passed on pin registration
1812 * @dpll: registered dpll pointer
1813 * @dpll_priv: private data pointer passed on dpll registration
1814 * @phase_adjust: on success holds phase adjust value
1815 * @extack: error reporting
1816 *
1817 * Dpll subsystem callback. Wraps a handler for getting phase adjust on sw
1818 * pin.
1819 *
1820 * Context: Calls a function which acquires and releases pf->dplls.lock
1821 * Return:
1822 * * 0 - success
1823 * * negative - error
1824 */
1825 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)1826 ice_dpll_sw_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1827 const struct dpll_device *dpll, void *dpll_priv,
1828 s32 *phase_adjust,
1829 struct netlink_ext_ack *extack)
1830 {
1831 struct ice_dpll_pin *p = pin_priv;
1832
1833 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1834 return ice_dpll_pin_phase_adjust_get(p->input->pin, p->input,
1835 dpll, dpll_priv,
1836 phase_adjust, extack);
1837 else
1838 return ice_dpll_pin_phase_adjust_get(p->output->pin, p->output,
1839 dpll, dpll_priv,
1840 phase_adjust, extack);
1841 }
1842
1843 /**
1844 * ice_dpll_sw_phase_adjust_set - callback for set SW pin phase adjust value
1845 * @pin: pointer to a pin
1846 * @pin_priv: private data pointer passed on pin registration
1847 * @dpll: registered dpll pointer
1848 * @dpll_priv: private data pointer passed on dpll registration
1849 * @phase_adjust: phase_adjust to be set
1850 * @extack: error reporting
1851 *
1852 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1853 * pin.
1854 *
1855 * Context: Calls a function which acquires and releases pf->dplls.lock
1856 * Return:
1857 * * 0 - success
1858 * * negative - error
1859 */
1860 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)1861 ice_dpll_sw_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1862 const struct dpll_device *dpll, void *dpll_priv,
1863 s32 phase_adjust,
1864 struct netlink_ext_ack *extack)
1865 {
1866 struct ice_dpll_pin *p = pin_priv;
1867
1868 if (!p->active) {
1869 NL_SET_ERR_MSG(extack, "pin is not active");
1870 return -EINVAL;
1871 }
1872 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1873 return ice_dpll_pin_phase_adjust_set(p->input->pin, p->input,
1874 dpll, dpll_priv,
1875 phase_adjust, extack,
1876 ICE_DPLL_PIN_TYPE_INPUT);
1877 else
1878 return ice_dpll_pin_phase_adjust_set(p->output->pin, p->output,
1879 dpll, dpll_priv,
1880 phase_adjust, extack,
1881 ICE_DPLL_PIN_TYPE_OUTPUT);
1882 }
1883
1884 #define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1885 #define ICE_DPLL_PHASE_OFFSET_FACTOR \
1886 (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1887 /**
1888 * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1889 * @pin: pointer to a pin
1890 * @pin_priv: private data pointer passed on pin registration
1891 * @dpll: registered dpll pointer
1892 * @dpll_priv: private data pointer passed on dpll registration
1893 * @phase_offset: on success holds pin phase_offset value
1894 * @extack: error reporting
1895 *
1896 * Dpll subsystem callback. Handler for getting phase shift value between
1897 * dpll's input and output.
1898 *
1899 * Context: Acquires pf->dplls.lock
1900 * Return:
1901 * * 0 - success
1902 * * negative - error
1903 */
1904 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)1905 ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1906 const struct dpll_device *dpll, void *dpll_priv,
1907 s64 *phase_offset, struct netlink_ext_ack *extack)
1908 {
1909 struct ice_dpll_pin *p = pin_priv;
1910 struct ice_dpll *d = dpll_priv;
1911 struct ice_pf *pf = d->pf;
1912
1913 mutex_lock(&pf->dplls.lock);
1914 if (d->active_input == pin || (p->input &&
1915 d->active_input == p->input->pin))
1916 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1917 else if (d->phase_offset_monitor_period)
1918 *phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1919 else
1920 *phase_offset = 0;
1921 mutex_unlock(&pf->dplls.lock);
1922
1923 return 0;
1924 }
1925
1926 /**
1927 * ice_dpll_synce_update_e825c - setting PHY recovered clock pins on e825c
1928 * @hw: Pointer to the HW struct
1929 * @ena: true if enable, false in disable
1930 * @port_num: port number
1931 * @output: output pin, we have two in E825C
1932 *
1933 * DPLL subsystem callback. Set proper signals to recover clock from port.
1934 *
1935 * Context: Called under pf->dplls.lock
1936 * Return:
1937 * * 0 - success
1938 * * negative - error
1939 */
ice_dpll_synce_update_e825c(struct ice_hw * hw,bool ena,u32 port_num,enum ice_synce_clk output)1940 static int ice_dpll_synce_update_e825c(struct ice_hw *hw, bool ena,
1941 u32 port_num, enum ice_synce_clk output)
1942 {
1943 int err;
1944
1945 /* configure the mux to deliver proper signal to DPLL from the MUX */
1946 err = ice_tspll_cfg_bypass_mux_e825c(hw, ena, port_num, output);
1947 if (err)
1948 return err;
1949
1950 err = ice_tspll_cfg_synce_ethdiv_e825c(hw, output);
1951 if (err)
1952 return err;
1953
1954 dev_dbg(ice_hw_to_dev(hw), "CLK_SYNCE%u recovered clock: pin %s\n",
1955 output, str_enabled_disabled(ena));
1956
1957 return 0;
1958 }
1959
1960 /**
1961 * ice_dpll_output_esync_set - callback for setting embedded sync
1962 * @pin: pointer to a pin
1963 * @pin_priv: private data pointer passed on pin registration
1964 * @dpll: registered dpll pointer
1965 * @dpll_priv: private data pointer passed on dpll registration
1966 * @freq: requested embedded sync frequency
1967 * @extack: error reporting
1968 *
1969 * Dpll subsystem callback. Handler for setting embedded sync frequency value
1970 * on output pin.
1971 *
1972 * Context: Acquires pf->dplls.lock
1973 * Return:
1974 * * 0 - success
1975 * * negative - error
1976 */
1977 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)1978 ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
1979 const struct dpll_device *dpll, void *dpll_priv,
1980 u64 freq, struct netlink_ext_ack *extack)
1981 {
1982 struct ice_dpll_pin *p = pin_priv;
1983 struct ice_dpll *d = dpll_priv;
1984 struct ice_pf *pf = d->pf;
1985 u8 flags = 0;
1986 int ret;
1987
1988 if (ice_dpll_is_reset(pf, extack))
1989 return -EBUSY;
1990 mutex_lock(&pf->dplls.lock);
1991 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1992 flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1993 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
1994 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
1995 ret = 0;
1996 } else {
1997 flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1998 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
1999 0, 0, 0);
2000 }
2001 } else {
2002 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
2003 ret = 0;
2004 } else {
2005 flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
2006 ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
2007 0, 0, 0);
2008 }
2009 }
2010 mutex_unlock(&pf->dplls.lock);
2011
2012 return ret;
2013 }
2014
2015 /**
2016 * ice_dpll_output_esync_get - callback for getting embedded sync config
2017 * @pin: pointer to a pin
2018 * @pin_priv: private data pointer passed on pin registration
2019 * @dpll: registered dpll pointer
2020 * @dpll_priv: private data pointer passed on dpll registration
2021 * @esync: on success holds embedded sync pin properties
2022 * @extack: error reporting
2023 *
2024 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2025 * and capabilities on output pin.
2026 *
2027 * Context: Acquires pf->dplls.lock
2028 * Return:
2029 * * 0 - success
2030 * * negative - error
2031 */
2032 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)2033 ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
2034 const struct dpll_device *dpll, void *dpll_priv,
2035 struct dpll_pin_esync *esync,
2036 struct netlink_ext_ack *extack)
2037 {
2038 struct ice_dpll_pin *p = pin_priv;
2039 struct ice_dpll *d = dpll_priv;
2040 struct ice_pf *pf = d->pf;
2041
2042 if (ice_dpll_is_reset(pf, extack))
2043 return -EBUSY;
2044 mutex_lock(&pf->dplls.lock);
2045 if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
2046 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2047 mutex_unlock(&pf->dplls.lock);
2048 return -EOPNOTSUPP;
2049 }
2050 esync->range = ice_esync_range;
2051 esync->range_num = ARRAY_SIZE(ice_esync_range);
2052 if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
2053 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2054 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2055 } else {
2056 esync->freq = 0;
2057 esync->pulse = 0;
2058 }
2059 mutex_unlock(&pf->dplls.lock);
2060
2061 return 0;
2062 }
2063
2064 /**
2065 * ice_dpll_input_esync_set - callback for setting embedded sync
2066 * @pin: pointer to a pin
2067 * @pin_priv: private data pointer passed on pin registration
2068 * @dpll: registered dpll pointer
2069 * @dpll_priv: private data pointer passed on dpll registration
2070 * @freq: requested embedded sync frequency
2071 * @extack: error reporting
2072 *
2073 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2074 * on input pin.
2075 *
2076 * Context: Acquires pf->dplls.lock
2077 * Return:
2078 * * 0 - success
2079 * * negative - error
2080 */
2081 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)2082 ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
2083 const struct dpll_device *dpll, void *dpll_priv,
2084 u64 freq, struct netlink_ext_ack *extack)
2085 {
2086 struct ice_dpll_pin *p = pin_priv;
2087 struct ice_dpll *d = dpll_priv;
2088 struct ice_pf *pf = d->pf;
2089 u8 flags_en = 0;
2090 int ret;
2091
2092 if (ice_dpll_is_reset(pf, extack))
2093 return -EBUSY;
2094 mutex_lock(&pf->dplls.lock);
2095 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2096 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2097 if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
2098 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2099 ret = 0;
2100 } else {
2101 flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2102 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2103 flags_en, 0, 0);
2104 }
2105 } else {
2106 if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
2107 ret = 0;
2108 } else {
2109 flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2110 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2111 flags_en, 0, 0);
2112 }
2113 }
2114 mutex_unlock(&pf->dplls.lock);
2115
2116 return ret;
2117 }
2118
2119 /**
2120 * ice_dpll_input_esync_get - callback for getting embedded sync config
2121 * @pin: pointer to a pin
2122 * @pin_priv: private data pointer passed on pin registration
2123 * @dpll: registered dpll pointer
2124 * @dpll_priv: private data pointer passed on dpll registration
2125 * @esync: on success holds embedded sync pin properties
2126 * @extack: error reporting
2127 *
2128 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2129 * and capabilities on input pin.
2130 *
2131 * Context: Acquires pf->dplls.lock
2132 * Return:
2133 * * 0 - success
2134 * * negative - error
2135 */
2136 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)2137 ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
2138 const struct dpll_device *dpll, void *dpll_priv,
2139 struct dpll_pin_esync *esync,
2140 struct netlink_ext_ack *extack)
2141 {
2142 struct ice_dpll_pin *p = pin_priv;
2143 struct ice_dpll *d = dpll_priv;
2144 struct ice_pf *pf = d->pf;
2145
2146 if (ice_dpll_is_reset(pf, extack))
2147 return -EBUSY;
2148 mutex_lock(&pf->dplls.lock);
2149 if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
2150 p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2151 mutex_unlock(&pf->dplls.lock);
2152 return -EOPNOTSUPP;
2153 }
2154 esync->range = ice_esync_range;
2155 esync->range_num = ARRAY_SIZE(ice_esync_range);
2156 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2157 esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2158 esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2159 } else {
2160 esync->freq = 0;
2161 esync->pulse = 0;
2162 }
2163 mutex_unlock(&pf->dplls.lock);
2164
2165 return 0;
2166 }
2167
2168 /**
2169 * ice_dpll_sw_esync_set - callback for setting embedded sync on SW pin
2170 * @pin: pointer to a pin
2171 * @pin_priv: private data pointer passed on pin registration
2172 * @dpll: registered dpll pointer
2173 * @dpll_priv: private data pointer passed on dpll registration
2174 * @freq: requested embedded sync frequency
2175 * @extack: error reporting
2176 *
2177 * Dpll subsystem callback. Handler for setting embedded sync frequency value
2178 * on SW pin.
2179 *
2180 * Context: Calls a function which acquires and releases pf->dplls.lock
2181 * Return:
2182 * * 0 - success
2183 * * negative - error
2184 */
2185 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)2186 ice_dpll_sw_esync_set(const struct dpll_pin *pin, void *pin_priv,
2187 const struct dpll_device *dpll, void *dpll_priv,
2188 u64 freq, struct netlink_ext_ack *extack)
2189 {
2190 struct ice_dpll_pin *p = pin_priv;
2191
2192 if (!p->active) {
2193 NL_SET_ERR_MSG(extack, "pin is not active");
2194 return -EINVAL;
2195 }
2196 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2197 return ice_dpll_input_esync_set(p->input->pin, p->input, dpll,
2198 dpll_priv, freq, extack);
2199 else
2200 return ice_dpll_output_esync_set(p->output->pin, p->output,
2201 dpll, dpll_priv, freq, extack);
2202 }
2203
2204 /**
2205 * ice_dpll_sw_esync_get - callback for getting embedded sync on SW pin
2206 * @pin: pointer to a pin
2207 * @pin_priv: private data pointer passed on pin registration
2208 * @dpll: registered dpll pointer
2209 * @dpll_priv: private data pointer passed on dpll registration
2210 * @esync: on success holds embedded sync frequency and properties
2211 * @extack: error reporting
2212 *
2213 * Dpll subsystem callback. Handler for getting embedded sync frequency value
2214 * of SW pin.
2215 *
2216 * Context: Calls a function which acquires and releases pf->dplls.lock
2217 * Return:
2218 * * 0 - success
2219 * * negative - error
2220 */
2221 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)2222 ice_dpll_sw_esync_get(const struct dpll_pin *pin, void *pin_priv,
2223 const struct dpll_device *dpll, void *dpll_priv,
2224 struct dpll_pin_esync *esync,
2225 struct netlink_ext_ack *extack)
2226 {
2227 struct ice_dpll_pin *p = pin_priv;
2228
2229 if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2230 return ice_dpll_input_esync_get(p->input->pin, p->input, dpll,
2231 dpll_priv, esync, extack);
2232 else
2233 return ice_dpll_output_esync_get(p->output->pin, p->output,
2234 dpll, dpll_priv, esync,
2235 extack);
2236 }
2237
2238 /*
2239 * ice_dpll_input_ref_sync_set - callback for setting reference sync feature
2240 * @pin: pointer to a pin
2241 * @pin_priv: private data pointer passed on pin registration
2242 * @ref_pin: pin pointer for reference sync pair
2243 * @ref_pin_priv: private data pointer of ref_pin
2244 * @state: requested state for reference sync for pin pair
2245 * @extack: error reporting
2246 *
2247 * Dpll subsystem callback. Handler for setting reference sync frequency
2248 * feature for input pin.
2249 *
2250 * Context: Acquires and releases pf->dplls.lock
2251 * Return:
2252 * * 0 - success
2253 * * negative - error
2254 */
2255 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)2256 ice_dpll_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2257 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2258 const enum dpll_pin_state state,
2259 struct netlink_ext_ack *extack)
2260 {
2261 struct ice_dpll_pin *p = pin_priv;
2262 struct ice_pf *pf = p->pf;
2263 u8 flags_en = 0;
2264 int ret;
2265
2266 if (ice_dpll_is_reset(pf, extack))
2267 return -EBUSY;
2268 mutex_lock(&pf->dplls.lock);
2269
2270 if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2271 flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2272 if (state == DPLL_PIN_STATE_CONNECTED)
2273 flags_en |= ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN;
2274 ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, flags_en, 0, 0);
2275 if (!ret)
2276 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT,
2277 extack);
2278 mutex_unlock(&pf->dplls.lock);
2279
2280 return ret;
2281 }
2282
2283 /**
2284 * ice_dpll_input_ref_sync_get - callback for getting reference sync config
2285 * @pin: pointer to a pin
2286 * @pin_priv: private data pointer passed on pin registration
2287 * @ref_pin: pin pointer for reference sync pair
2288 * @ref_pin_priv: private data pointer of ref_pin
2289 * @state: on success holds reference sync state for pin pair
2290 * @extack: error reporting
2291 *
2292 * Dpll subsystem callback. Handler for setting reference sync frequency
2293 * feature for input pin.
2294 *
2295 * Context: Acquires and releases pf->dplls.lock
2296 * Return:
2297 * * 0 - success
2298 * * negative - error
2299 */
2300 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)2301 ice_dpll_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2302 const struct dpll_pin *ref_pin, void *ref_pin_priv,
2303 enum dpll_pin_state *state,
2304 struct netlink_ext_ack *extack)
2305 {
2306 struct ice_dpll_pin *p = pin_priv;
2307 struct ice_pf *pf = p->pf;
2308
2309 if (ice_dpll_is_reset(pf, extack))
2310 return -EBUSY;
2311 mutex_lock(&pf->dplls.lock);
2312 if (p->flags[0] & ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN)
2313 *state = DPLL_PIN_STATE_CONNECTED;
2314 else
2315 *state = DPLL_PIN_STATE_DISCONNECTED;
2316 mutex_unlock(&pf->dplls.lock);
2317
2318 return 0;
2319 }
2320
2321 /*
2322 * ice_dpll_sw_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
2331 * feature for input pins.
2332 *
2333 * Context: Calls a function which acquires and releases pf->dplls.lock
2334 * Return:
2335 * * 0 - success
2336 * * negative - error
2337 */
2338 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)2339 ice_dpll_sw_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2340 const struct dpll_pin *ref_pin,
2341 void *ref_pin_priv,
2342 const enum dpll_pin_state state,
2343 struct netlink_ext_ack *extack)
2344 {
2345 struct ice_dpll_pin *p = pin_priv;
2346
2347 return ice_dpll_input_ref_sync_set(pin, p->input, ref_pin, ref_pin_priv,
2348 state, extack);
2349 }
2350
2351 /**
2352 * ice_dpll_sw_input_ref_sync_get - callback for getting reference sync config
2353 * @pin: pointer to a pin
2354 * @pin_priv: private data pointer passed on pin registration
2355 * @ref_pin: pin pointer for reference sync pair
2356 * @ref_pin_priv: private data pointer of ref_pin
2357 * @state: on success holds reference sync state for pin pair
2358 * @extack: error reporting
2359 *
2360 * Dpll subsystem callback. Handler for setting reference sync feature for
2361 * input pins.
2362 *
2363 * Context: Calls a function which acquires and releases pf->dplls.lock
2364 * Return:
2365 * * 0 - success
2366 * * negative - error
2367 */
2368 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)2369 ice_dpll_sw_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2370 const struct dpll_pin *ref_pin,
2371 void *ref_pin_priv,
2372 enum dpll_pin_state *state,
2373 struct netlink_ext_ack *extack)
2374 {
2375 struct ice_dpll_pin *p = pin_priv;
2376
2377 return ice_dpll_input_ref_sync_get(pin, p->input, ref_pin, ref_pin_priv,
2378 state, extack);
2379 }
2380
2381 static int
ice_dpll_pin_get_parent_num(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2382 ice_dpll_pin_get_parent_num(struct ice_dpll_pin *pin,
2383 const struct dpll_pin *parent)
2384 {
2385 int i;
2386
2387 for (i = 0; i < pin->num_parents; i++)
2388 if (pin->pf->dplls.inputs[pin->parent_idx[i]].pin == parent)
2389 return i;
2390
2391 return -ENOENT;
2392 }
2393
2394 static int
ice_dpll_pin_get_parent_idx(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2395 ice_dpll_pin_get_parent_idx(struct ice_dpll_pin *pin,
2396 const struct dpll_pin *parent)
2397 {
2398 int num = ice_dpll_pin_get_parent_num(pin, parent);
2399
2400 return num < 0 ? num : pin->parent_idx[num];
2401 }
2402
2403 /**
2404 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
2405 * @pin: pointer to a pin
2406 * @pin_priv: private data pointer passed on pin registration
2407 * @parent_pin: pin parent pointer
2408 * @parent_pin_priv: parent private data pointer passed on pin registration
2409 * @state: state to be set on pin
2410 * @extack: error reporting
2411 *
2412 * Dpll subsystem callback, set a state of a rclk pin on a parent pin
2413 *
2414 * Context: Acquires pf->dplls.lock
2415 * Return:
2416 * * 0 - success
2417 * * negative - failure
2418 */
2419 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)2420 ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
2421 const struct dpll_pin *parent_pin,
2422 void *parent_pin_priv,
2423 enum dpll_pin_state state,
2424 struct netlink_ext_ack *extack)
2425 {
2426 bool enable = state == DPLL_PIN_STATE_CONNECTED;
2427 struct ice_dpll_pin *p = pin_priv;
2428 struct ice_pf *pf = p->pf;
2429 struct ice_hw *hw;
2430 int ret = -EINVAL;
2431 int hw_idx;
2432
2433 hw = &pf->hw;
2434
2435 if (ice_dpll_is_reset(pf, extack))
2436 return -EBUSY;
2437
2438 mutex_lock(&pf->dplls.lock);
2439 hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2440 if (hw_idx < 0)
2441 goto unlock;
2442 hw_idx -= pf->dplls.base_rclk_idx;
2443
2444 if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
2445 (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
2446 NL_SET_ERR_MSG_FMT(extack,
2447 "pin:%u state:%u on parent:%u already set",
2448 p->idx, state,
2449 ice_dpll_pin_get_parent_num(p, parent_pin));
2450 goto unlock;
2451 }
2452
2453 ret = hw->mac_type == ICE_MAC_GENERIC_3K_E825 ?
2454 ice_dpll_synce_update_e825c(hw, enable,
2455 pf->ptp.port.port_num,
2456 (enum ice_synce_clk)hw_idx) :
2457 ice_aq_set_phy_rec_clk_out(hw, hw_idx, enable, &p->freq);
2458 if (ret)
2459 NL_SET_ERR_MSG_FMT(extack,
2460 "err:%d %s failed to set pin state:%u for pin:%u on parent:%u",
2461 ret,
2462 libie_aq_str(hw->adminq.sq_last_status),
2463 state, p->idx,
2464 ice_dpll_pin_get_parent_num(p, parent_pin));
2465 unlock:
2466 mutex_unlock(&pf->dplls.lock);
2467
2468 return ret;
2469 }
2470
2471 /**
2472 * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
2473 * @pin: pointer to a pin
2474 * @pin_priv: private data pointer passed on pin registration
2475 * @parent_pin: pin parent pointer
2476 * @parent_pin_priv: pin parent priv data pointer passed on pin registration
2477 * @state: on success holds pin state on parent pin
2478 * @extack: error reporting
2479 *
2480 * dpll subsystem callback, get a state of a recovered clock pin.
2481 *
2482 * Context: Acquires pf->dplls.lock
2483 * Return:
2484 * * 0 - success
2485 * * negative - failure
2486 */
2487 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)2488 ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
2489 const struct dpll_pin *parent_pin,
2490 void *parent_pin_priv,
2491 enum dpll_pin_state *state,
2492 struct netlink_ext_ack *extack)
2493 {
2494 struct ice_dpll_pin *p = pin_priv;
2495 struct ice_pf *pf = p->pf;
2496 int ret = -EINVAL;
2497 int hw_idx;
2498
2499 if (ice_dpll_is_reset(pf, extack))
2500 return -EBUSY;
2501
2502 mutex_lock(&pf->dplls.lock);
2503 hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2504 if (hw_idx < 0)
2505 goto unlock;
2506
2507 ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
2508 extack);
2509 if (ret)
2510 goto unlock;
2511
2512 *state = p->state[hw_idx];
2513 ret = 0;
2514 unlock:
2515 mutex_unlock(&pf->dplls.lock);
2516
2517 return ret;
2518 }
2519
2520 static const struct dpll_pin_ops ice_dpll_rclk_ops = {
2521 .state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
2522 .state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
2523 .direction_get = ice_dpll_input_direction,
2524 };
2525
2526 static const struct dpll_pin_ops ice_dpll_pin_sma_ops = {
2527 .state_on_dpll_set = ice_dpll_sma_pin_state_set,
2528 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2529 .direction_get = ice_dpll_pin_sw_direction_get,
2530 .direction_set = ice_dpll_pin_sma_direction_set,
2531 .prio_get = ice_dpll_sw_input_prio_get,
2532 .prio_set = ice_dpll_sw_input_prio_set,
2533 .frequency_get = ice_dpll_sw_pin_frequency_get,
2534 .frequency_set = ice_dpll_sw_pin_frequency_set,
2535 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2536 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2537 .phase_offset_get = ice_dpll_phase_offset_get,
2538 .esync_set = ice_dpll_sw_esync_set,
2539 .esync_get = ice_dpll_sw_esync_get,
2540 .ref_sync_set = ice_dpll_sw_input_ref_sync_set,
2541 .ref_sync_get = ice_dpll_sw_input_ref_sync_get,
2542 };
2543
2544 static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
2545 .state_on_dpll_set = ice_dpll_ufl_pin_state_set,
2546 .state_on_dpll_get = ice_dpll_sw_pin_state_get,
2547 .direction_get = ice_dpll_pin_sw_direction_get,
2548 .frequency_get = ice_dpll_sw_pin_frequency_get,
2549 .frequency_set = ice_dpll_sw_pin_frequency_set,
2550 .esync_set = ice_dpll_sw_esync_set,
2551 .esync_get = ice_dpll_sw_esync_get,
2552 .phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2553 .phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2554 .phase_offset_get = ice_dpll_phase_offset_get,
2555 };
2556
2557 static const struct dpll_pin_ops ice_dpll_input_ops = {
2558 .frequency_get = ice_dpll_input_frequency_get,
2559 .frequency_set = ice_dpll_input_frequency_set,
2560 .state_on_dpll_get = ice_dpll_input_state_get,
2561 .state_on_dpll_set = ice_dpll_input_state_set,
2562 .prio_get = ice_dpll_input_prio_get,
2563 .prio_set = ice_dpll_input_prio_set,
2564 .direction_get = ice_dpll_input_direction,
2565 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2566 .phase_adjust_set = ice_dpll_input_phase_adjust_set,
2567 .phase_offset_get = ice_dpll_phase_offset_get,
2568 .esync_set = ice_dpll_input_esync_set,
2569 .esync_get = ice_dpll_input_esync_get,
2570 .ref_sync_set = ice_dpll_input_ref_sync_set,
2571 .ref_sync_get = ice_dpll_input_ref_sync_get,
2572 };
2573
2574 static const struct dpll_pin_ops ice_dpll_output_ops = {
2575 .frequency_get = ice_dpll_output_frequency_get,
2576 .frequency_set = ice_dpll_output_frequency_set,
2577 .state_on_dpll_get = ice_dpll_output_state_get,
2578 .state_on_dpll_set = ice_dpll_output_state_set,
2579 .direction_get = ice_dpll_output_direction,
2580 .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2581 .phase_adjust_set = ice_dpll_output_phase_adjust_set,
2582 .esync_set = ice_dpll_output_esync_set,
2583 .esync_get = ice_dpll_output_esync_get,
2584 };
2585
2586 static const struct dpll_device_ops ice_dpll_ops = {
2587 .lock_status_get = ice_dpll_lock_status_get,
2588 .mode_get = ice_dpll_mode_get,
2589 };
2590
2591 static const struct dpll_device_ops ice_dpll_pom_ops = {
2592 .lock_status_get = ice_dpll_lock_status_get,
2593 .mode_get = ice_dpll_mode_get,
2594 .phase_offset_monitor_set = ice_dpll_phase_offset_monitor_set,
2595 .phase_offset_monitor_get = ice_dpll_phase_offset_monitor_get,
2596 };
2597
2598 /**
2599 * ice_generate_clock_id - generates unique clock_id for registering dpll.
2600 * @pf: board private structure
2601 *
2602 * Generates unique (per board) clock_id for allocation and search of dpll
2603 * devices in Linux dpll subsystem.
2604 *
2605 * Return: generated clock id for the board
2606 */
ice_generate_clock_id(struct ice_pf * pf)2607 static u64 ice_generate_clock_id(struct ice_pf *pf)
2608 {
2609 return pci_get_dsn(pf->pdev);
2610 }
2611
2612 /**
2613 * ice_dpll_notify_changes - notify dpll subsystem about changes
2614 * @d: pointer do dpll
2615 *
2616 * Once change detected appropriate event is submitted to the dpll subsystem.
2617 */
ice_dpll_notify_changes(struct ice_dpll * d)2618 static void ice_dpll_notify_changes(struct ice_dpll *d)
2619 {
2620 bool pin_notified = false;
2621
2622 if (d->prev_dpll_state != d->dpll_state) {
2623 d->prev_dpll_state = d->dpll_state;
2624 dpll_device_change_ntf(d->dpll);
2625 }
2626 if (d->prev_input != d->active_input) {
2627 if (d->prev_input)
2628 dpll_pin_change_ntf(d->prev_input);
2629 d->prev_input = d->active_input;
2630 if (d->active_input) {
2631 dpll_pin_change_ntf(d->active_input);
2632 pin_notified = true;
2633 }
2634 }
2635 if (d->prev_phase_offset != d->phase_offset) {
2636 d->prev_phase_offset = d->phase_offset;
2637 if (!pin_notified && d->active_input)
2638 dpll_pin_change_ntf(d->active_input);
2639 }
2640 }
2641
2642 /**
2643 * ice_dpll_is_pps_phase_monitor - check if dpll capable of phase offset monitor
2644 * @pf: pf private structure
2645 *
2646 * Check if firmware is capable of supporting admin command to provide
2647 * phase offset monitoring on all the input pins on PPS dpll.
2648 *
2649 * Returns:
2650 * * true - PPS dpll phase offset monitoring is supported
2651 * * false - PPS dpll phase offset monitoring is not supported
2652 */
ice_dpll_is_pps_phase_monitor(struct ice_pf * pf)2653 static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
2654 {
2655 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2656 int ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2657 ARRAY_SIZE(meas));
2658
2659 if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_ESRCH)
2660 return false;
2661
2662 return true;
2663 }
2664
2665 /**
2666 * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
2667 * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
2668 * @pin_num: number of pins
2669 * @phase_offset_ntf_mask: bitmask of pin indexes to notify
2670 *
2671 * Iterate over array of pins and call dpll subsystem pin notify if
2672 * corresponding pin index within bitmask is set.
2673 *
2674 * Context: Must be called while pf->dplls.lock is released.
2675 */
ice_dpll_pins_notify_mask(struct ice_dpll_pin * pins,u8 pin_num,u32 phase_offset_ntf_mask)2676 static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
2677 u8 pin_num,
2678 u32 phase_offset_ntf_mask)
2679 {
2680 int i = 0;
2681
2682 for (i = 0; i < pin_num; i++)
2683 if (phase_offset_ntf_mask & (1 << i))
2684 dpll_pin_change_ntf(pins[i].pin);
2685 }
2686
2687 /**
2688 * ice_dpll_pps_update_phase_offsets - update phase offset measurements
2689 * @pf: pf private structure
2690 * @phase_offset_pins_updated: returns mask of updated input pin indexes
2691 *
2692 * Read phase offset measurements for PPS dpll device and store values in
2693 * input pins array. On success phase_offset_pins_updated - fills bitmask of
2694 * updated input pin indexes, pins shall be notified.
2695 *
2696 * Context: Shall be called with pf->dplls.lock being locked.
2697 * Returns:
2698 * * 0 - success or no data available
2699 * * negative - AQ failure
2700 */
ice_dpll_pps_update_phase_offsets(struct ice_pf * pf,u32 * phase_offset_pins_updated)2701 static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf,
2702 u32 *phase_offset_pins_updated)
2703 {
2704 struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2705 struct ice_dpll_pin *p;
2706 s64 phase_offset, tmp;
2707 int i, j, ret;
2708
2709 *phase_offset_pins_updated = 0;
2710 ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2711 ARRAY_SIZE(meas));
2712 if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN) {
2713 return 0;
2714 } else if (ret) {
2715 dev_err(ice_pf_to_dev(pf),
2716 "failed to get input pin measurements dpll=%d, ret=%d %s\n",
2717 DPLL_TYPE_PPS, ret,
2718 libie_aq_str(pf->hw.adminq.sq_last_status));
2719 return ret;
2720 }
2721 for (i = 0; i < pf->dplls.num_inputs; i++) {
2722 p = &pf->dplls.inputs[i];
2723 phase_offset = 0;
2724 for (j = 0; j < ICE_CGU_INPUT_PHASE_OFFSET_BYTES; j++) {
2725 tmp = meas[i].phase_offset[j];
2726 #ifdef __LITTLE_ENDIAN
2727 phase_offset += tmp << 8 * j;
2728 #else
2729 phase_offset += tmp << 8 *
2730 (ICE_CGU_INPUT_PHASE_OFFSET_BYTES - 1 - j);
2731 #endif
2732 }
2733 phase_offset = sign_extend64(phase_offset, 47);
2734 if (p->phase_offset != phase_offset) {
2735 dev_dbg(ice_pf_to_dev(pf),
2736 "phase offset changed for pin:%d old:%llx, new:%llx\n",
2737 p->idx, p->phase_offset, phase_offset);
2738 p->phase_offset = phase_offset;
2739 *phase_offset_pins_updated |= (1 << i);
2740 }
2741 }
2742
2743 return 0;
2744 }
2745
2746 /**
2747 * ice_dpll_update_state - update dpll state
2748 * @pf: pf private structure
2749 * @d: pointer to queried dpll device
2750 * @init: if function called on initialization of ice dpll
2751 *
2752 * Poll current state of dpll from hw and update ice_dpll struct.
2753 *
2754 * Context: Called by kworker under pf->dplls.lock
2755 * Return:
2756 * * 0 - success
2757 * * negative - AQ failure
2758 */
2759 static int
ice_dpll_update_state(struct ice_pf * pf,struct ice_dpll * d,bool init)2760 ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
2761 {
2762 struct ice_dpll_pin *p = NULL;
2763 int ret;
2764
2765 ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
2766 &d->input_idx, &d->ref_state, &d->eec_mode,
2767 &d->phase_offset, &d->dpll_state);
2768
2769 dev_dbg(ice_pf_to_dev(pf),
2770 "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
2771 d->dpll_idx, d->prev_input_idx, d->input_idx,
2772 d->dpll_state, d->prev_dpll_state, d->mode);
2773 if (ret) {
2774 dev_err(ice_pf_to_dev(pf),
2775 "update dpll=%d state failed, ret=%d %s\n",
2776 d->dpll_idx, ret,
2777 libie_aq_str(pf->hw.adminq.sq_last_status));
2778 return ret;
2779 }
2780 if (init) {
2781 if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
2782 d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
2783 d->active_input = pf->dplls.inputs[d->input_idx].pin;
2784 p = &pf->dplls.inputs[d->input_idx];
2785 return ice_dpll_pin_state_update(pf, p,
2786 ICE_DPLL_PIN_TYPE_INPUT, NULL);
2787 }
2788 if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
2789 d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
2790 d->active_input = NULL;
2791 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
2792 p = &pf->dplls.inputs[d->input_idx];
2793 d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
2794 d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
2795 if (!p)
2796 return 0;
2797 ret = ice_dpll_pin_state_update(pf, p,
2798 ICE_DPLL_PIN_TYPE_INPUT, NULL);
2799 } else if (d->input_idx != d->prev_input_idx) {
2800 if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2801 p = &pf->dplls.inputs[d->prev_input_idx];
2802 ice_dpll_pin_state_update(pf, p,
2803 ICE_DPLL_PIN_TYPE_INPUT,
2804 NULL);
2805 }
2806 if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2807 p = &pf->dplls.inputs[d->input_idx];
2808 d->active_input = p->pin;
2809 ice_dpll_pin_state_update(pf, p,
2810 ICE_DPLL_PIN_TYPE_INPUT,
2811 NULL);
2812 }
2813 d->prev_input_idx = d->input_idx;
2814 }
2815
2816 return ret;
2817 }
2818
2819 /**
2820 * ice_dpll_periodic_work - DPLLs periodic worker
2821 * @work: pointer to kthread_work structure
2822 *
2823 * DPLLs periodic worker is responsible for polling state of dpll.
2824 * Context: Holds pf->dplls.lock
2825 */
ice_dpll_periodic_work(struct kthread_work * work)2826 static void ice_dpll_periodic_work(struct kthread_work *work)
2827 {
2828 struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
2829 struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
2830 struct ice_dpll *de = &pf->dplls.eec;
2831 struct ice_dpll *dp = &pf->dplls.pps;
2832 u32 phase_offset_ntf = 0;
2833 int ret = 0;
2834
2835 if (ice_is_reset_in_progress(pf->state))
2836 goto resched;
2837 mutex_lock(&pf->dplls.lock);
2838 d->periodic_counter++;
2839 ret = ice_dpll_update_state(pf, de, false);
2840 if (!ret)
2841 ret = ice_dpll_update_state(pf, dp, false);
2842 if (!ret && dp->phase_offset_monitor_period &&
2843 d->periodic_counter % dp->phase_offset_monitor_period == 0)
2844 ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf);
2845 if (ret) {
2846 d->cgu_state_acq_err_num++;
2847 /* stop rescheduling this worker */
2848 if (d->cgu_state_acq_err_num >
2849 ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
2850 dev_err(ice_pf_to_dev(pf),
2851 "EEC/PPS DPLLs periodic work disabled\n");
2852 mutex_unlock(&pf->dplls.lock);
2853 return;
2854 }
2855 }
2856 mutex_unlock(&pf->dplls.lock);
2857 ice_dpll_notify_changes(de);
2858 ice_dpll_notify_changes(dp);
2859 if (phase_offset_ntf)
2860 ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
2861 phase_offset_ntf);
2862
2863 resched:
2864 /* Run twice a second or reschedule if update failed */
2865 kthread_queue_delayed_work(d->kworker, &d->work,
2866 ret ? msecs_to_jiffies(10) :
2867 msecs_to_jiffies(500));
2868 }
2869
2870 /**
2871 * ice_dpll_init_ref_sync_inputs - initialize reference sync pin pairs
2872 * @pf: pf private structure
2873 *
2874 * Read DPLL TLV capabilities and initialize reference sync pin pairs in
2875 * dpll subsystem.
2876 *
2877 * Return:
2878 * * 0 - success or nothing to do (no ref-sync tlv are present)
2879 * * negative - AQ failure
2880 */
ice_dpll_init_ref_sync_inputs(struct ice_pf * pf)2881 static int ice_dpll_init_ref_sync_inputs(struct ice_pf *pf)
2882 {
2883 struct ice_dpll_pin *inputs = pf->dplls.inputs;
2884 struct ice_hw *hw = &pf->hw;
2885 u16 addr, len, end, hdr;
2886 int ret;
2887
2888 ret = ice_get_pfa_module_tlv(hw, &hdr, &len, ICE_SR_PFA_DPLL_DEFAULTS);
2889 if (ret) {
2890 dev_err(ice_pf_to_dev(pf),
2891 "Failed to read PFA dpll defaults TLV ret=%d\n", ret);
2892 return ret;
2893 }
2894 end = hdr + len;
2895
2896 for (addr = hdr + ICE_DPLL_PFA_HEADER_LEN; addr < end;
2897 addr += ICE_DPLL_PFA_ENTRY_LEN) {
2898 unsigned long bit, ul_mask, offset;
2899 u16 pin, mask, buf;
2900 bool valid = false;
2901
2902 ret = ice_read_sr_word(hw, addr, &buf);
2903 if (ret)
2904 return ret;
2905
2906 switch (buf) {
2907 case ICE_DPLL_PFA_REF_SYNC_TYPE:
2908 case ICE_DPLL_PFA_REF_SYNC_TYPE2:
2909 {
2910 u16 mask_addr = addr + ICE_DPLL_PFA_MASK_OFFSET;
2911 u16 val_addr = addr + ICE_DPLL_PFA_VALUE_OFFSET;
2912
2913 ret = ice_read_sr_word(hw, mask_addr, &mask);
2914 if (ret)
2915 return ret;
2916 ret = ice_read_sr_word(hw, val_addr, &pin);
2917 if (ret)
2918 return ret;
2919 if (buf == ICE_DPLL_PFA_REF_SYNC_TYPE)
2920 pin >>= ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S;
2921 valid = true;
2922 break;
2923 }
2924 case ICE_DPLL_PFA_END:
2925 addr = end;
2926 break;
2927 default:
2928 continue;
2929 }
2930 if (!valid)
2931 continue;
2932
2933 ul_mask = mask;
2934 offset = 0;
2935 for_each_set_bit(bit, &ul_mask, BITS_PER_TYPE(u16)) {
2936 int i, j;
2937
2938 if (hw->device_id == ICE_DEV_ID_E810C_SFP &&
2939 pin > ICE_DPLL_E810C_SFP_NC_START)
2940 offset = -ICE_DPLL_E810C_SFP_NC_PINS;
2941 i = pin + offset;
2942 j = bit + offset;
2943 if (i < 0 || j < 0)
2944 return -ERANGE;
2945 inputs[i].ref_sync = j;
2946 }
2947 }
2948
2949 return 0;
2950 }
2951
2952 /**
2953 * ice_dpll_release_pins - release pins resources from dpll subsystem
2954 * @pins: pointer to pins array
2955 * @count: number of pins
2956 *
2957 * Release resources of given pins array in the dpll subsystem.
2958 */
ice_dpll_release_pins(struct ice_dpll_pin * pins,int count)2959 static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
2960 {
2961 int i;
2962
2963 for (i = 0; i < count; i++)
2964 if (!IS_ERR_OR_NULL(pins[i].pin))
2965 dpll_pin_put(pins[i].pin, &pins[i].tracker);
2966 }
2967
2968 /**
2969 * ice_dpll_get_pins - get pins from dpll subsystem
2970 * @pf: board private structure
2971 * @pins: pointer to pins array
2972 * @start_idx: get starts from this pin idx value
2973 * @count: number of pins
2974 * @clock_id: clock_id of dpll device
2975 *
2976 * Get pins - allocate - in dpll subsystem, store them in pin field of given
2977 * pins array.
2978 *
2979 * Return:
2980 * * 0 - success
2981 * * negative - allocation failure reason
2982 */
2983 static int
ice_dpll_get_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx,int count,u64 clock_id)2984 ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
2985 int start_idx, int count, u64 clock_id)
2986 {
2987 u32 pin_index;
2988 int i, ret;
2989
2990 for (i = 0; i < count; i++) {
2991 pin_index = start_idx;
2992 if (start_idx != DPLL_PIN_IDX_UNSPEC)
2993 pin_index += i;
2994 pins[i].pin = dpll_pin_get(clock_id, pin_index, THIS_MODULE,
2995 &pins[i].prop, &pins[i].tracker);
2996 if (IS_ERR(pins[i].pin)) {
2997 ret = PTR_ERR(pins[i].pin);
2998 goto release_pins;
2999 }
3000 }
3001
3002 return 0;
3003
3004 release_pins:
3005 while (--i >= 0)
3006 dpll_pin_put(pins[i].pin, &pins[i].tracker);
3007 return ret;
3008 }
3009
3010 /**
3011 * ice_dpll_unregister_pins - unregister pins from a dpll
3012 * @dpll: dpll device pointer
3013 * @pins: pointer to pins array
3014 * @ops: callback ops registered with the pins
3015 * @count: number of pins
3016 *
3017 * Unregister pins of a given array of pins from given dpll device registered in
3018 * dpll subsystem.
3019 */
3020 static void
ice_dpll_unregister_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3021 ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3022 const struct dpll_pin_ops *ops, int count)
3023 {
3024 int i;
3025
3026 for (i = 0; i < count; i++)
3027 if (!pins[i].hidden)
3028 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3029 }
3030
3031 /**
3032 * ice_dpll_pin_ref_sync_register - register reference sync pins
3033 * @pins: pointer to pins array
3034 * @count: number of pins
3035 *
3036 * Register reference sync pins in dpll subsystem.
3037 *
3038 * Return:
3039 * * 0 - success
3040 * * negative - registration failure reason
3041 */
3042 static int
ice_dpll_pin_ref_sync_register(struct ice_dpll_pin * pins,int count)3043 ice_dpll_pin_ref_sync_register(struct ice_dpll_pin *pins, int count)
3044 {
3045 int ret, i;
3046
3047 for (i = 0; i < count; i++) {
3048 if (!pins[i].hidden && pins[i].ref_sync) {
3049 int j = pins[i].ref_sync;
3050
3051 ret = dpll_pin_ref_sync_pair_add(pins[i].pin,
3052 pins[j].pin);
3053 if (ret)
3054 return ret;
3055 }
3056 }
3057
3058 return 0;
3059 }
3060
3061 /**
3062 * ice_dpll_register_pins - register pins with a dpll
3063 * @dpll: dpll pointer to register pins with
3064 * @pins: pointer to pins array
3065 * @ops: callback ops registered with the pins
3066 * @count: number of pins
3067 *
3068 * Register pins of a given array with given dpll in dpll subsystem.
3069 *
3070 * Return:
3071 * * 0 - success
3072 * * negative - registration failure reason
3073 */
3074 static int
ice_dpll_register_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3075 ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3076 const struct dpll_pin_ops *ops, int count)
3077 {
3078 int ret, i;
3079
3080 for (i = 0; i < count; i++) {
3081 if (!pins[i].hidden) {
3082 ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]);
3083 if (ret)
3084 goto unregister_pins;
3085 }
3086 }
3087
3088 return 0;
3089
3090 unregister_pins:
3091 while (--i >= 0)
3092 if (!pins[i].hidden)
3093 dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3094 return ret;
3095 }
3096
3097 /**
3098 * ice_dpll_deinit_direct_pins - deinitialize direct pins
3099 * @pf: board private structure
3100 * @cgu: if cgu is present and controlled by this NIC
3101 * @pins: pointer to pins array
3102 * @count: number of pins
3103 * @ops: callback ops registered with the pins
3104 * @first: dpll device pointer
3105 * @second: dpll device pointer
3106 *
3107 * If cgu is owned unregister pins from given dplls.
3108 * Release pins resources to the dpll subsystem.
3109 */
3110 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)3111 ice_dpll_deinit_direct_pins(struct ice_pf *pf, bool cgu,
3112 struct ice_dpll_pin *pins, int count,
3113 const struct dpll_pin_ops *ops,
3114 struct dpll_device *first,
3115 struct dpll_device *second)
3116 {
3117 if (cgu) {
3118 ice_dpll_unregister_pins(first, pins, ops, count);
3119 ice_dpll_unregister_pins(second, pins, ops, count);
3120 }
3121 ice_dpll_release_pins(pins, count);
3122 }
3123
3124 /**
3125 * ice_dpll_init_direct_pins - initialize direct pins
3126 * @pf: board private structure
3127 * @cgu: if cgu is present and controlled by this NIC
3128 * @pins: pointer to pins array
3129 * @start_idx: on which index shall allocation start in dpll subsystem
3130 * @count: number of pins
3131 * @ops: callback ops registered with the pins
3132 * @first: dpll device pointer
3133 * @second: dpll device pointer
3134 *
3135 * Allocate directly connected pins of a given array in dpll subsystem.
3136 * If cgu is owned register allocated pins with given dplls.
3137 *
3138 * Return:
3139 * * 0 - success
3140 * * negative - registration failure reason
3141 */
3142 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)3143 ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
3144 struct ice_dpll_pin *pins, int start_idx, int count,
3145 const struct dpll_pin_ops *ops,
3146 struct dpll_device *first, struct dpll_device *second)
3147 {
3148 int ret;
3149
3150 ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id);
3151 if (ret)
3152 return ret;
3153 if (cgu) {
3154 ret = ice_dpll_register_pins(first, pins, ops, count);
3155 if (ret)
3156 goto release_pins;
3157 ret = ice_dpll_register_pins(second, pins, ops, count);
3158 if (ret)
3159 goto unregister_first;
3160 }
3161
3162 return 0;
3163
3164 unregister_first:
3165 ice_dpll_unregister_pins(first, pins, ops, count);
3166 release_pins:
3167 ice_dpll_release_pins(pins, count);
3168 return ret;
3169 }
3170
3171 /**
3172 * ice_dpll_deinit_rclk_pin - release rclk pin resources
3173 * @pf: board private structure
3174 *
3175 * Deregister rclk pin from parent pins and release resources in dpll subsystem.
3176 */
ice_dpll_deinit_rclk_pin(struct ice_pf * pf)3177 static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
3178 {
3179 struct ice_dpll_pin *rclk = &pf->dplls.rclk;
3180 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3181 struct ice_dpll_pin *parent;
3182 int i;
3183
3184 for (i = 0; i < rclk->num_parents; i++) {
3185 parent = &pf->dplls.inputs[rclk->parent_idx[i]];
3186 if (IS_ERR_OR_NULL(parent->pin))
3187 continue;
3188 dpll_pin_on_pin_unregister(parent->pin, rclk->pin,
3189 &ice_dpll_rclk_ops, rclk);
3190 }
3191 if (WARN_ON_ONCE(!vsi || !vsi->netdev))
3192 return;
3193 dpll_netdev_pin_clear(vsi->netdev);
3194 dpll_pin_put(rclk->pin, &rclk->tracker);
3195 }
3196
ice_dpll_is_fwnode_pin(struct ice_dpll_pin * pin)3197 static bool ice_dpll_is_fwnode_pin(struct ice_dpll_pin *pin)
3198 {
3199 return !IS_ERR_OR_NULL(pin->fwnode);
3200 }
3201
ice_dpll_pin_notify_work(struct work_struct * work)3202 static void ice_dpll_pin_notify_work(struct work_struct *work)
3203 {
3204 struct ice_dpll_pin_work *w = container_of(work,
3205 struct ice_dpll_pin_work,
3206 work);
3207 struct ice_dpll_pin *pin, *parent = w->pin;
3208 struct ice_pf *pf = parent->pf;
3209 int ret;
3210
3211 wait_for_completion(&pf->dplls.dpll_init);
3212 if (!test_bit(ICE_FLAG_DPLL, pf->flags))
3213 goto out; /* DPLL initialization failed */
3214
3215 switch (w->action) {
3216 case DPLL_PIN_CREATED:
3217 if (!IS_ERR_OR_NULL(parent->pin)) {
3218 /* We have already our pin registered */
3219 goto out;
3220 }
3221
3222 /* Grab reference on fwnode pin */
3223 parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3224 &parent->tracker);
3225 if (IS_ERR_OR_NULL(parent->pin)) {
3226 dev_err(ice_pf_to_dev(pf),
3227 "Cannot get fwnode pin reference\n");
3228 goto out;
3229 }
3230
3231 /* Register rclk pin */
3232 pin = &pf->dplls.rclk;
3233 ret = dpll_pin_on_pin_register(parent->pin, pin->pin,
3234 &ice_dpll_rclk_ops, pin);
3235 if (ret) {
3236 dev_err(ice_pf_to_dev(pf),
3237 "Failed to register pin: %pe\n", ERR_PTR(ret));
3238 dpll_pin_put(parent->pin, &parent->tracker);
3239 parent->pin = NULL;
3240 goto out;
3241 }
3242 break;
3243 case DPLL_PIN_DELETED:
3244 if (IS_ERR_OR_NULL(parent->pin)) {
3245 /* We have already our pin unregistered */
3246 goto out;
3247 }
3248
3249 /* Unregister rclk pin */
3250 pin = &pf->dplls.rclk;
3251 dpll_pin_on_pin_unregister(parent->pin, pin->pin,
3252 &ice_dpll_rclk_ops, pin);
3253
3254 /* Drop fwnode pin reference */
3255 dpll_pin_put(parent->pin, &parent->tracker);
3256 parent->pin = NULL;
3257 break;
3258 default:
3259 break;
3260 }
3261 out:
3262 kfree(w);
3263 }
3264
ice_dpll_pin_notify(struct notifier_block * nb,unsigned long action,void * data)3265 static int ice_dpll_pin_notify(struct notifier_block *nb, unsigned long action,
3266 void *data)
3267 {
3268 struct ice_dpll_pin *pin = container_of(nb, struct ice_dpll_pin, nb);
3269 struct dpll_pin_notifier_info *info = data;
3270 struct ice_dpll_pin_work *work;
3271
3272 if (action != DPLL_PIN_CREATED && action != DPLL_PIN_DELETED)
3273 return NOTIFY_DONE;
3274
3275 /* Check if the reported pin is this one */
3276 if (pin->fwnode != info->fwnode)
3277 return NOTIFY_DONE; /* Not this pin */
3278
3279 work = kzalloc_obj(*work);
3280 if (!work)
3281 return NOTIFY_DONE;
3282
3283 INIT_WORK(&work->work, ice_dpll_pin_notify_work);
3284 work->action = action;
3285 work->pin = pin;
3286
3287 queue_work(pin->pf->dplls.wq, &work->work);
3288
3289 return NOTIFY_OK;
3290 }
3291
3292 /**
3293 * ice_dpll_init_pin_common - initialize pin
3294 * @pf: board private structure
3295 * @pin: pin to register
3296 * @start_idx: on which index shall allocation start in dpll subsystem
3297 * @ops: callback ops registered with the pins
3298 *
3299 * Allocate resource for given pin in dpll subsystem. Register the pin with
3300 * the parents it has in the info.
3301 *
3302 * Return:
3303 * * 0 - success
3304 * * negative - registration failure reason
3305 */
3306 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)3307 ice_dpll_init_pin_common(struct ice_pf *pf, struct ice_dpll_pin *pin,
3308 int start_idx, const struct dpll_pin_ops *ops)
3309 {
3310 struct ice_dpll_pin *parent;
3311 int ret, i;
3312
3313 ret = ice_dpll_get_pins(pf, pin, start_idx, 1, pf->dplls.clock_id);
3314 if (ret)
3315 return ret;
3316
3317 for (i = 0; i < pin->num_parents; i++) {
3318 parent = &pf->dplls.inputs[pin->parent_idx[i]];
3319 if (IS_ERR_OR_NULL(parent->pin)) {
3320 if (!ice_dpll_is_fwnode_pin(parent)) {
3321 ret = -ENODEV;
3322 goto unregister_pins;
3323 }
3324 parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3325 &parent->tracker);
3326 if (IS_ERR_OR_NULL(parent->pin)) {
3327 dev_info(ice_pf_to_dev(pf),
3328 "Mux pin not registered yet\n");
3329 continue;
3330 }
3331 }
3332 ret = dpll_pin_on_pin_register(parent->pin, pin->pin, ops, pin);
3333 if (ret)
3334 goto unregister_pins;
3335 }
3336
3337 return 0;
3338
3339 unregister_pins:
3340 while (i) {
3341 parent = &pf->dplls.inputs[pin->parent_idx[--i]];
3342 if (IS_ERR_OR_NULL(parent->pin))
3343 continue;
3344 dpll_pin_on_pin_unregister(parent->pin, pin->pin, ops, pin);
3345 }
3346 ice_dpll_release_pins(pin, 1);
3347
3348 return ret;
3349 }
3350
3351 /**
3352 * ice_dpll_init_rclk_pin - initialize recovered clock pin
3353 * @pf: board private structure
3354 * @start_idx: on which index shall allocation start in dpll subsystem
3355 * @ops: callback ops registered with the pins
3356 *
3357 * Allocate resource for recovered clock pin in dpll subsystem. Register the
3358 * pin with the parents it has in the info.
3359 *
3360 * Return:
3361 * * 0 - success
3362 * * negative - registration failure reason
3363 */
3364 static int
ice_dpll_init_rclk_pin(struct ice_pf * pf,int start_idx,const struct dpll_pin_ops * ops)3365 ice_dpll_init_rclk_pin(struct ice_pf *pf, int start_idx,
3366 const struct dpll_pin_ops *ops)
3367 {
3368 struct ice_vsi *vsi = ice_get_main_vsi(pf);
3369 int ret;
3370
3371 ret = ice_dpll_init_pin_common(pf, &pf->dplls.rclk, start_idx, ops);
3372 if (ret)
3373 return ret;
3374
3375 dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
3376
3377 return 0;
3378 }
3379
3380 static void
ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin * pin)3381 ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin *pin)
3382 {
3383 unregister_dpll_notifier(&pin->nb);
3384 flush_workqueue(pin->pf->dplls.wq);
3385 if (!IS_ERR_OR_NULL(pin->pin)) {
3386 dpll_pin_put(pin->pin, &pin->tracker);
3387 pin->pin = NULL;
3388 }
3389 fwnode_handle_put(pin->fwnode);
3390 pin->fwnode = NULL;
3391 }
3392
3393 static void
ice_dpll_deinit_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3394 ice_dpll_deinit_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3395 int start_idx)
3396 {
3397 int i;
3398
3399 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
3400 ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3401 destroy_workqueue(pf->dplls.wq);
3402 }
3403
3404 /**
3405 * ice_dpll_deinit_pins - deinitialize direct pins
3406 * @pf: board private structure
3407 * @cgu: if cgu is controlled by this pf
3408 *
3409 * If cgu is owned unregister directly connected pins from the dplls.
3410 * Release resources of directly connected pins from the dpll subsystem.
3411 */
ice_dpll_deinit_pins(struct ice_pf * pf,bool cgu)3412 static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
3413 {
3414 struct ice_dpll_pin *outputs = pf->dplls.outputs;
3415 struct ice_dpll_pin *inputs = pf->dplls.inputs;
3416 int num_outputs = pf->dplls.num_outputs;
3417 int num_inputs = pf->dplls.num_inputs;
3418 struct ice_dplls *d = &pf->dplls;
3419 struct ice_dpll *de = &d->eec;
3420 struct ice_dpll *dp = &d->pps;
3421
3422 ice_dpll_deinit_rclk_pin(pf);
3423 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
3424 ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
3425 if (cgu) {
3426 ice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,
3427 num_inputs);
3428 ice_dpll_unregister_pins(de->dpll, inputs, &ice_dpll_input_ops,
3429 num_inputs);
3430 }
3431 ice_dpll_release_pins(inputs, num_inputs);
3432 if (cgu) {
3433 ice_dpll_unregister_pins(dp->dpll, outputs,
3434 &ice_dpll_output_ops, num_outputs);
3435 ice_dpll_unregister_pins(de->dpll, outputs,
3436 &ice_dpll_output_ops, num_outputs);
3437 ice_dpll_release_pins(outputs, num_outputs);
3438 if (!pf->dplls.generic) {
3439 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl,
3440 ICE_DPLL_PIN_SW_NUM,
3441 &ice_dpll_pin_ufl_ops,
3442 pf->dplls.pps.dpll,
3443 pf->dplls.eec.dpll);
3444 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma,
3445 ICE_DPLL_PIN_SW_NUM,
3446 &ice_dpll_pin_sma_ops,
3447 pf->dplls.pps.dpll,
3448 pf->dplls.eec.dpll);
3449 }
3450 }
3451 }
3452
3453 static struct fwnode_handle *
ice_dpll_pin_node_get(struct ice_pf * pf,const char * name)3454 ice_dpll_pin_node_get(struct ice_pf *pf, const char *name)
3455 {
3456 struct fwnode_handle *fwnode = dev_fwnode(ice_pf_to_dev(pf));
3457 int index;
3458
3459 index = fwnode_property_match_string(fwnode, "dpll-pin-names", name);
3460 if (index < 0)
3461 return ERR_PTR(-ENOENT);
3462
3463 return fwnode_find_reference(fwnode, "dpll-pins", index);
3464 }
3465
3466 static int
ice_dpll_init_fwnode_pin(struct ice_dpll_pin * pin,const char * name)3467 ice_dpll_init_fwnode_pin(struct ice_dpll_pin *pin, const char *name)
3468 {
3469 struct ice_pf *pf = pin->pf;
3470 int ret;
3471
3472 pin->fwnode = ice_dpll_pin_node_get(pf, name);
3473 if (IS_ERR(pin->fwnode)) {
3474 dev_err(ice_pf_to_dev(pf),
3475 "Failed to find %s firmware node: %pe\n", name,
3476 pin->fwnode);
3477 pin->fwnode = NULL;
3478 return -ENODEV;
3479 }
3480
3481 dev_dbg(ice_pf_to_dev(pf), "Found fwnode node for %s\n", name);
3482
3483 pin->pin = fwnode_dpll_pin_find(pin->fwnode, &pin->tracker);
3484 if (IS_ERR_OR_NULL(pin->pin)) {
3485 dev_info(ice_pf_to_dev(pf),
3486 "DPLL pin for %pfwp not registered yet\n",
3487 pin->fwnode);
3488 pin->pin = NULL;
3489 }
3490
3491 pin->nb.notifier_call = ice_dpll_pin_notify;
3492 ret = register_dpll_notifier(&pin->nb);
3493 if (ret) {
3494 dev_err(ice_pf_to_dev(pf),
3495 "Failed to subscribe for DPLL notifications\n");
3496
3497 if (!IS_ERR_OR_NULL(pin->pin)) {
3498 dpll_pin_put(pin->pin, &pin->tracker);
3499 pin->pin = NULL;
3500 }
3501 fwnode_handle_put(pin->fwnode);
3502 pin->fwnode = NULL;
3503
3504 return ret;
3505 }
3506
3507 return ret;
3508 }
3509
3510 /**
3511 * ice_dpll_init_fwnode_pins - initialize pins from device tree
3512 * @pf: board private structure
3513 * @pins: pointer to pins array
3514 * @start_idx: starting index for pins
3515 * @count: number of pins to initialize
3516 *
3517 * Initialize input pins for E825 RCLK support. The parent pins (rclk0, rclk1)
3518 * are expected to be defined by the system firmware (ACPI). This function
3519 * allocates them in the dpll subsystem and stores their indices for later
3520 * registration with the rclk pin.
3521 *
3522 * Return:
3523 * * 0 - success
3524 * * negative - initialization failure reason
3525 */
3526 static int
ice_dpll_init_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3527 ice_dpll_init_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3528 int start_idx)
3529 {
3530 char pin_name[8];
3531 int i, ret;
3532
3533 pf->dplls.wq = create_singlethread_workqueue("ice_dpll_wq");
3534 if (!pf->dplls.wq)
3535 return -ENOMEM;
3536
3537 for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
3538 pins[start_idx + i].pf = pf;
3539 snprintf(pin_name, sizeof(pin_name), "rclk%u", i);
3540 ret = ice_dpll_init_fwnode_pin(&pins[start_idx + i], pin_name);
3541 if (ret)
3542 goto error;
3543 }
3544
3545 return 0;
3546 error:
3547 while (i--)
3548 ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3549
3550 destroy_workqueue(pf->dplls.wq);
3551
3552 return ret;
3553 }
3554
3555 /**
3556 * ice_dpll_init_pins_e825 - init pins and register pins with a dplls
3557 * @pf: board private structure
3558 * @cgu: if cgu is present and controlled by this NIC
3559 *
3560 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
3561 * subsystem.
3562 *
3563 * Return:
3564 * * 0 - success
3565 * * negative - initialization failure reason
3566 */
ice_dpll_init_pins_e825(struct ice_pf * pf)3567 static int ice_dpll_init_pins_e825(struct ice_pf *pf)
3568 {
3569 int ret;
3570
3571 ret = ice_dpll_init_fwnode_pins(pf, pf->dplls.inputs, 0);
3572 if (ret)
3573 return ret;
3574
3575 ret = ice_dpll_init_rclk_pin(pf, DPLL_PIN_IDX_UNSPEC,
3576 &ice_dpll_rclk_ops);
3577 if (ret) {
3578 /* Inform DPLL notifier works that DPLL init was finished
3579 * unsuccessfully (ICE_DPLL_FLAG not set).
3580 */
3581 complete_all(&pf->dplls.dpll_init);
3582 ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
3583 }
3584
3585 return ret;
3586 }
3587
3588 /**
3589 * ice_dpll_init_pins - init pins and register pins with a dplls
3590 * @pf: board private structure
3591 * @cgu: if cgu is present and controlled by this NIC
3592 *
3593 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
3594 * subsystem.
3595 *
3596 * Return:
3597 * * 0 - success
3598 * * negative - initialization failure reason
3599 */
ice_dpll_init_pins(struct ice_pf * pf,bool cgu)3600 static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
3601 {
3602 const struct dpll_pin_ops *output_ops;
3603 const struct dpll_pin_ops *input_ops;
3604 int ret, count;
3605
3606 input_ops = &ice_dpll_input_ops;
3607 output_ops = &ice_dpll_output_ops;
3608
3609 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0,
3610 pf->dplls.num_inputs, input_ops,
3611 pf->dplls.eec.dpll,
3612 pf->dplls.pps.dpll);
3613 if (ret)
3614 return ret;
3615 count = pf->dplls.num_inputs;
3616 if (cgu) {
3617 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs,
3618 count, pf->dplls.num_outputs,
3619 output_ops, pf->dplls.eec.dpll,
3620 pf->dplls.pps.dpll);
3621 if (ret)
3622 goto deinit_inputs;
3623 count += pf->dplls.num_outputs;
3624 if (!pf->dplls.generic) {
3625 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.sma,
3626 count,
3627 ICE_DPLL_PIN_SW_NUM,
3628 &ice_dpll_pin_sma_ops,
3629 pf->dplls.eec.dpll,
3630 pf->dplls.pps.dpll);
3631 if (ret)
3632 goto deinit_outputs;
3633 count += ICE_DPLL_PIN_SW_NUM;
3634 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.ufl,
3635 count,
3636 ICE_DPLL_PIN_SW_NUM,
3637 &ice_dpll_pin_ufl_ops,
3638 pf->dplls.eec.dpll,
3639 pf->dplls.pps.dpll);
3640 if (ret)
3641 goto deinit_sma;
3642 count += ICE_DPLL_PIN_SW_NUM;
3643 }
3644 ret = ice_dpll_pin_ref_sync_register(pf->dplls.inputs,
3645 pf->dplls.num_inputs);
3646 if (ret)
3647 goto deinit_ufl;
3648 ret = ice_dpll_pin_ref_sync_register(pf->dplls.sma,
3649 ICE_DPLL_PIN_SW_NUM);
3650 if (ret)
3651 goto deinit_ufl;
3652 } else {
3653 count += pf->dplls.num_outputs + 2 * ICE_DPLL_PIN_SW_NUM;
3654 }
3655
3656 ret = ice_dpll_init_rclk_pin(pf, count + pf->ptp.port.port_num,
3657 &ice_dpll_rclk_ops);
3658 if (ret)
3659 goto deinit_ufl;
3660
3661 return 0;
3662 deinit_ufl:
3663 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl, ICE_DPLL_PIN_SW_NUM,
3664 &ice_dpll_pin_ufl_ops, pf->dplls.pps.dpll,
3665 pf->dplls.eec.dpll);
3666 deinit_sma:
3667 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma, ICE_DPLL_PIN_SW_NUM,
3668 &ice_dpll_pin_sma_ops, pf->dplls.pps.dpll,
3669 pf->dplls.eec.dpll);
3670 deinit_outputs:
3671 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.outputs,
3672 pf->dplls.num_outputs,
3673 output_ops, pf->dplls.pps.dpll,
3674 pf->dplls.eec.dpll);
3675 deinit_inputs:
3676 ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.inputs,
3677 pf->dplls.num_inputs,
3678 input_ops, pf->dplls.pps.dpll,
3679 pf->dplls.eec.dpll);
3680 return ret;
3681 }
3682
3683 /**
3684 * ice_dpll_deinit_dpll - deinitialize dpll device
3685 * @pf: board private structure
3686 * @d: pointer to ice_dpll
3687 * @cgu: if cgu is present and controlled by this NIC
3688 *
3689 * If cgu is owned, unregister the DPLL from DPLL subsystem.
3690 * Release resources of DPLL device from DPLL subsystem.
3691 */
3692 static void
ice_dpll_deinit_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu)3693 ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
3694 {
3695 if (cgu)
3696 dpll_device_unregister(d->dpll, d->ops, d);
3697 dpll_device_put(d->dpll, &d->tracker);
3698 }
3699
3700 /**
3701 * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
3702 * @pf: board private structure
3703 * @d: dpll to be initialized
3704 * @cgu: if cgu is present and controlled by this NIC
3705 * @type: type of dpll being initialized
3706 *
3707 * Allocate DPLL instance for this board in dpll subsystem, if cgu is controlled
3708 * by this NIC, register DPLL with the callback ops.
3709 *
3710 * Return:
3711 * * 0 - success
3712 * * negative - initialization failure reason
3713 */
3714 static int
ice_dpll_init_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu,enum dpll_type type)3715 ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
3716 enum dpll_type type)
3717 {
3718 u64 clock_id = pf->dplls.clock_id;
3719 int ret;
3720
3721 d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE,
3722 &d->tracker);
3723 if (IS_ERR(d->dpll)) {
3724 ret = PTR_ERR(d->dpll);
3725 dev_err(ice_pf_to_dev(pf),
3726 "dpll_device_get failed (%p) err=%d\n", d, ret);
3727 return ret;
3728 }
3729 d->pf = pf;
3730 if (cgu) {
3731 const struct dpll_device_ops *ops = &ice_dpll_ops;
3732
3733 if (type == DPLL_TYPE_PPS && ice_dpll_is_pps_phase_monitor(pf))
3734 ops = &ice_dpll_pom_ops;
3735 ice_dpll_update_state(pf, d, true);
3736 ret = dpll_device_register(d->dpll, type, ops, d);
3737 if (ret) {
3738 dpll_device_put(d->dpll, &d->tracker);
3739 d->dpll = NULL;
3740 return ret;
3741 }
3742 d->ops = ops;
3743 }
3744
3745 return 0;
3746 }
3747
3748 /**
3749 * ice_dpll_deinit_worker - deinitialize dpll kworker
3750 * @pf: board private structure
3751 *
3752 * Stop dpll's kworker, release it's resources.
3753 */
ice_dpll_deinit_worker(struct ice_pf * pf)3754 static void ice_dpll_deinit_worker(struct ice_pf *pf)
3755 {
3756 struct ice_dplls *d = &pf->dplls;
3757
3758 kthread_cancel_delayed_work_sync(&d->work);
3759 kthread_destroy_worker(d->kworker);
3760 }
3761
3762 /**
3763 * ice_dpll_init_worker - Initialize DPLLs periodic worker
3764 * @pf: board private structure
3765 *
3766 * Create and start DPLLs periodic worker.
3767 *
3768 * Context: Shall be called after pf->dplls.lock is initialized.
3769 * Return:
3770 * * 0 - success
3771 * * negative - create worker failure
3772 */
ice_dpll_init_worker(struct ice_pf * pf)3773 static int ice_dpll_init_worker(struct ice_pf *pf)
3774 {
3775 struct ice_dplls *d = &pf->dplls;
3776 struct kthread_worker *kworker;
3777
3778 kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
3779 kworker = kthread_run_worker(0, "ice-dplls-%s",
3780 dev_name(ice_pf_to_dev(pf)));
3781 if (IS_ERR(kworker))
3782 return PTR_ERR(kworker);
3783 d->kworker = kworker;
3784 d->cgu_state_acq_err_num = 0;
3785 kthread_queue_delayed_work(d->kworker, &d->work, 0);
3786
3787 return 0;
3788 }
3789
3790 /**
3791 * ice_dpll_phase_range_set - initialize phase adjust range helper
3792 * @range: pointer to phase adjust range struct to be initialized
3793 * @phase_adj: a value to be used as min(-)/max(+) boundary
3794 */
ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range * range,u32 phase_adj)3795 static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
3796 u32 phase_adj)
3797 {
3798 range->min = -phase_adj;
3799 range->max = phase_adj;
3800 }
3801
3802 /**
3803 * ice_dpll_init_info_pins_generic - initializes generic pins info
3804 * @pf: board private structure
3805 * @input: if input pins initialized
3806 *
3807 * Init information for generic pins, cache them in PF's pins structures.
3808 *
3809 * Return:
3810 * * 0 - success
3811 * * negative - init failure reason
3812 */
ice_dpll_init_info_pins_generic(struct ice_pf * pf,bool input)3813 static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
3814 {
3815 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3816 static const char labels[][sizeof("99")] = {
3817 "0", "1", "2", "3", "4", "5", "6", "7", "8",
3818 "9", "10", "11", "12", "13", "14", "15" };
3819 u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3820 enum ice_dpll_pin_type pin_type;
3821 int i, pin_num, ret = -EINVAL;
3822 struct ice_dpll_pin *pins;
3823 u32 phase_adj_max;
3824
3825 if (input) {
3826 pin_num = pf->dplls.num_inputs;
3827 pins = pf->dplls.inputs;
3828 phase_adj_max = pf->dplls.input_phase_adj_max;
3829 pin_type = ICE_DPLL_PIN_TYPE_INPUT;
3830 cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
3831 } else {
3832 pin_num = pf->dplls.num_outputs;
3833 pins = pf->dplls.outputs;
3834 phase_adj_max = pf->dplls.output_phase_adj_max;
3835 pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
3836 }
3837 if (pin_num > ARRAY_SIZE(labels))
3838 return ret;
3839
3840 for (i = 0; i < pin_num; i++) {
3841 pins[i].idx = i;
3842 pins[i].prop.board_label = labels[i];
3843 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3844 phase_adj_max);
3845 pins[i].prop.capabilities = cap;
3846 pins[i].pf = pf;
3847 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3848 if (ret)
3849 break;
3850 if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
3851 pins[i].prop.type = DPLL_PIN_TYPE_MUX;
3852 else
3853 pins[i].prop.type = DPLL_PIN_TYPE_EXT;
3854 if (!input)
3855 continue;
3856 ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
3857 &de->input_prio[i]);
3858 if (ret)
3859 break;
3860 ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
3861 &dp->input_prio[i]);
3862 if (ret)
3863 break;
3864 }
3865
3866 return ret;
3867 }
3868
3869 /**
3870 * ice_dpll_init_info_direct_pins - initializes direct pins info
3871 * @pf: board private structure
3872 * @pin_type: type of pins being initialized
3873 *
3874 * Init information for directly connected pins, cache them in pf's pins
3875 * structures.
3876 *
3877 * Return:
3878 * * 0 - success
3879 * * negative - init failure reason
3880 */
3881 static int
ice_dpll_init_info_direct_pins(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)3882 ice_dpll_init_info_direct_pins(struct ice_pf *pf,
3883 enum ice_dpll_pin_type pin_type)
3884 {
3885 struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3886 int num_pins, i, ret = -EINVAL;
3887 struct ice_hw *hw = &pf->hw;
3888 struct ice_dpll_pin *pins;
3889 unsigned long caps;
3890 u32 phase_adj_max;
3891 u8 freq_supp_num;
3892 bool input;
3893
3894 switch (pin_type) {
3895 case ICE_DPLL_PIN_TYPE_INPUT:
3896 pins = pf->dplls.inputs;
3897 num_pins = pf->dplls.num_inputs;
3898 phase_adj_max = pf->dplls.input_phase_adj_max;
3899 input = true;
3900 break;
3901 case ICE_DPLL_PIN_TYPE_OUTPUT:
3902 pins = pf->dplls.outputs;
3903 num_pins = pf->dplls.num_outputs;
3904 phase_adj_max = pf->dplls.output_phase_adj_max;
3905 input = false;
3906 break;
3907 default:
3908 return -EINVAL;
3909 }
3910 if (num_pins != ice_cgu_get_num_pins(hw, input)) {
3911 pf->dplls.generic = true;
3912 return ice_dpll_init_info_pins_generic(pf, input);
3913 }
3914
3915 for (i = 0; i < num_pins; i++) {
3916 caps = 0;
3917 pins[i].idx = i;
3918 pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
3919 pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
3920 if (input) {
3921 ret = ice_aq_get_cgu_ref_prio(hw, de->dpll_idx, i,
3922 &de->input_prio[i]);
3923 if (ret)
3924 return ret;
3925 ret = ice_aq_get_cgu_ref_prio(hw, dp->dpll_idx, i,
3926 &dp->input_prio[i]);
3927 if (ret)
3928 return ret;
3929 caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
3930 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
3931 if (ice_dpll_is_sw_pin(pf, i, true))
3932 pins[i].hidden = true;
3933 } else {
3934 ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
3935 if (ret)
3936 return ret;
3937 if (ice_dpll_is_sw_pin(pf, i, false))
3938 pins[i].hidden = true;
3939 }
3940 ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3941 phase_adj_max);
3942 pins[i].prop.capabilities = caps;
3943 ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3944 if (ret)
3945 return ret;
3946 pins[i].prop.freq_supported =
3947 ice_cgu_get_pin_freq_supp(hw, i, input, &freq_supp_num);
3948 pins[i].prop.freq_supported_num = freq_supp_num;
3949 pins[i].pf = pf;
3950 }
3951 if (input)
3952 ret = ice_dpll_init_ref_sync_inputs(pf);
3953
3954 return ret;
3955 }
3956
3957 /**
3958 * ice_dpll_init_info_pin_on_pin_e825c - initializes rclk pin information
3959 * @pf: board private structure
3960 *
3961 * Init information for rclk pin, cache them in pf->dplls.rclk.
3962 *
3963 * Return:
3964 * * 0 - success
3965 */
ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf * pf)3966 static int ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf *pf)
3967 {
3968 struct ice_dpll_pin *rclk_pin = &pf->dplls.rclk;
3969
3970 rclk_pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
3971 rclk_pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3972 rclk_pin->pf = pf;
3973
3974 return 0;
3975 }
3976
3977 /**
3978 * ice_dpll_init_info_rclk_pin - initializes rclk pin information
3979 * @pf: board private structure
3980 *
3981 * Init information for rclk pin, cache them in pf->dplls.rclk.
3982 *
3983 * Return:
3984 * * 0 - success
3985 * * negative - init failure reason
3986 */
ice_dpll_init_info_rclk_pin(struct ice_pf * pf)3987 static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
3988 {
3989 struct ice_dpll_pin *pin = &pf->dplls.rclk;
3990
3991 pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
3992 pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3993 pin->pf = pf;
3994
3995 return ice_dpll_pin_state_update(pf, pin,
3996 ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
3997 }
3998
3999 /**
4000 * ice_dpll_init_info_sw_pins - initializes software controlled pin information
4001 * @pf: board private structure
4002 *
4003 * Init information for software controlled pins, cache them in
4004 * pf->dplls.sma and pf->dplls.ufl.
4005 *
4006 * Return:
4007 * * 0 - success
4008 * * negative - init failure reason
4009 */
ice_dpll_init_info_sw_pins(struct ice_pf * pf)4010 static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
4011 {
4012 u8 freq_supp_num, pin_abs_idx, input_idx_offset = 0;
4013 struct ice_dplls *d = &pf->dplls;
4014 struct ice_dpll_pin *pin;
4015 u32 phase_adj_max, caps;
4016 int i, ret;
4017
4018 if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
4019 input_idx_offset = ICE_E810_RCLK_PINS_NUM;
4020 phase_adj_max = max(d->input_phase_adj_max, d->output_phase_adj_max);
4021 caps = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4022 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4023 pin = &d->sma[i];
4024 pin->idx = i;
4025 pin->prop.type = DPLL_PIN_TYPE_EXT;
4026 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + input_idx_offset;
4027 pin->prop.freq_supported =
4028 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4029 true, &freq_supp_num);
4030 pin->prop.freq_supported_num = freq_supp_num;
4031 pin->prop.capabilities =
4032 (DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE |
4033 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4034 caps);
4035 pin->pf = pf;
4036 pin->prop.board_label = ice_dpll_sw_pin_sma[i];
4037 pin->input = &d->inputs[pin_abs_idx];
4038 if (pin->input->ref_sync)
4039 pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
4040 pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
4041 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4042 }
4043 for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4044 pin = &d->ufl[i];
4045 pin->idx = i;
4046 pin->prop.type = DPLL_PIN_TYPE_EXT;
4047 pin->prop.capabilities = caps;
4048 pin->pf = pf;
4049 pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
4050 if (i == ICE_DPLL_PIN_SW_1_IDX) {
4051 pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
4052 pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
4053 pin->prop.freq_supported =
4054 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4055 false,
4056 &freq_supp_num);
4057 pin->prop.freq_supported_num = freq_supp_num;
4058 pin->input = NULL;
4059 pin->output = &d->outputs[pin_abs_idx];
4060 } else if (i == ICE_DPLL_PIN_SW_2_IDX) {
4061 pin->direction = DPLL_PIN_DIRECTION_INPUT;
4062 pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
4063 input_idx_offset;
4064 pin->output = NULL;
4065 pin->input = &d->inputs[pin_abs_idx];
4066 pin->prop.freq_supported =
4067 ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4068 true, &freq_supp_num);
4069 pin->prop.freq_supported_num = freq_supp_num;
4070 pin->prop.capabilities =
4071 (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4072 caps);
4073 }
4074 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4075 }
4076 ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE,
4077 NULL);
4078 if (ret)
4079 return ret;
4080
4081 return 0;
4082 }
4083
4084 /**
4085 * ice_dpll_init_pins_info - init pins info wrapper
4086 * @pf: board private structure
4087 * @pin_type: type of pins being initialized
4088 *
4089 * Wraps functions for pin initialization.
4090 *
4091 * Return:
4092 * * 0 - success
4093 * * negative - init failure reason
4094 */
4095 static int
ice_dpll_init_pins_info(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)4096 ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
4097 {
4098 switch (pin_type) {
4099 case ICE_DPLL_PIN_TYPE_INPUT:
4100 case ICE_DPLL_PIN_TYPE_OUTPUT:
4101 return ice_dpll_init_info_direct_pins(pf, pin_type);
4102 case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
4103 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
4104 return ice_dpll_init_info_pin_on_pin_e825c(pf);
4105 else
4106 return ice_dpll_init_info_rclk_pin(pf);
4107 case ICE_DPLL_PIN_TYPE_SOFTWARE:
4108 return ice_dpll_init_info_sw_pins(pf);
4109 default:
4110 return -EINVAL;
4111 }
4112 }
4113
4114 /**
4115 * ice_dpll_deinit_info - release memory allocated for pins info
4116 * @pf: board private structure
4117 *
4118 * Release memory allocated for pins by ice_dpll_init_info function.
4119 */
ice_dpll_deinit_info(struct ice_pf * pf)4120 static void ice_dpll_deinit_info(struct ice_pf *pf)
4121 {
4122 kfree(pf->dplls.inputs);
4123 kfree(pf->dplls.outputs);
4124 kfree(pf->dplls.eec.input_prio);
4125 kfree(pf->dplls.pps.input_prio);
4126 }
4127
4128 /**
4129 * ice_dpll_init_info_e825c - prepare pf's dpll information structure for e825c
4130 * device
4131 * @pf: board private structure
4132 *
4133 * Acquire (from HW) and set basic DPLL information (on pf->dplls struct).
4134 *
4135 * Return:
4136 * * 0 - success
4137 * * negative - init failure reason
4138 */
ice_dpll_init_info_e825c(struct ice_pf * pf)4139 static int ice_dpll_init_info_e825c(struct ice_pf *pf)
4140 {
4141 struct ice_dplls *d = &pf->dplls;
4142 int ret = 0;
4143 int i;
4144
4145 d->clock_id = ice_generate_clock_id(pf);
4146 d->num_inputs = ICE_SYNCE_CLK_NUM;
4147
4148 d->inputs = kzalloc_objs(*d->inputs, d->num_inputs);
4149 if (!d->inputs)
4150 return -ENOMEM;
4151
4152 ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4153 &pf->dplls.rclk.num_parents);
4154 if (ret)
4155 goto deinit_info;
4156
4157 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4158 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4159
4160 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4161 if (ret)
4162 goto deinit_info;
4163 dev_dbg(ice_pf_to_dev(pf),
4164 "%s - success, inputs: %u, outputs: %u, rclk-parents: %u\n",
4165 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4166 return 0;
4167 deinit_info:
4168 ice_dpll_deinit_info(pf);
4169 return ret;
4170 }
4171
4172 /**
4173 * ice_dpll_init_info - prepare pf's dpll information structure
4174 * @pf: board private structure
4175 * @cgu: if cgu is present and controlled by this NIC
4176 *
4177 * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
4178 *
4179 * Return:
4180 * * 0 - success
4181 * * negative - init failure reason
4182 */
ice_dpll_init_info(struct ice_pf * pf,bool cgu)4183 static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
4184 {
4185 struct ice_aqc_get_cgu_abilities abilities;
4186 struct ice_dpll *de = &pf->dplls.eec;
4187 struct ice_dpll *dp = &pf->dplls.pps;
4188 struct ice_dplls *d = &pf->dplls;
4189 struct ice_hw *hw = &pf->hw;
4190 int ret, alloc_size, i;
4191
4192 d->clock_id = ice_generate_clock_id(pf);
4193 ret = ice_aq_get_cgu_abilities(hw, &abilities);
4194 if (ret) {
4195 dev_err(ice_pf_to_dev(pf),
4196 "err:%d %s failed to read cgu abilities\n",
4197 ret, libie_aq_str(hw->adminq.sq_last_status));
4198 return ret;
4199 }
4200
4201 de->dpll_idx = abilities.eec_dpll_idx;
4202 dp->dpll_idx = abilities.pps_dpll_idx;
4203 d->num_inputs = abilities.num_inputs;
4204 d->num_outputs = abilities.num_outputs;
4205 d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
4206 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4207 d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
4208 ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4209
4210 alloc_size = sizeof(*d->inputs) * d->num_inputs;
4211 d->inputs = kzalloc(alloc_size, GFP_KERNEL);
4212 if (!d->inputs)
4213 return -ENOMEM;
4214
4215 alloc_size = sizeof(*de->input_prio) * d->num_inputs;
4216 de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4217 if (!de->input_prio)
4218 return -ENOMEM;
4219
4220 dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4221 if (!dp->input_prio)
4222 return -ENOMEM;
4223
4224 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
4225 if (ret)
4226 goto deinit_info;
4227
4228 if (cgu) {
4229 alloc_size = sizeof(*d->outputs) * d->num_outputs;
4230 d->outputs = kzalloc(alloc_size, GFP_KERNEL);
4231 if (!d->outputs) {
4232 ret = -ENOMEM;
4233 goto deinit_info;
4234 }
4235
4236 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT);
4237 if (ret)
4238 goto deinit_info;
4239 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_SOFTWARE);
4240 if (ret)
4241 goto deinit_info;
4242 }
4243
4244 ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4245 &pf->dplls.rclk.num_parents);
4246 if (ret)
4247 return ret;
4248 for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4249 pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4250 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4251 if (ret)
4252 return ret;
4253 de->mode = DPLL_MODE_AUTOMATIC;
4254 dp->mode = DPLL_MODE_AUTOMATIC;
4255
4256 dev_dbg(ice_pf_to_dev(pf),
4257 "%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
4258 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4259
4260 return 0;
4261
4262 deinit_info:
4263 dev_err(ice_pf_to_dev(pf),
4264 "%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
4265 __func__, d->inputs, de->input_prio,
4266 dp->input_prio, d->outputs);
4267 ice_dpll_deinit_info(pf);
4268 return ret;
4269 }
4270
4271 /**
4272 * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
4273 * the dpll device.
4274 * @pf: board private structure
4275 *
4276 * Handles the cleanup work required after dpll initialization, freeing
4277 * resources and unregistering the dpll, pin and all resources used for
4278 * handling them.
4279 *
4280 * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
4281 */
ice_dpll_deinit(struct ice_pf * pf)4282 void ice_dpll_deinit(struct ice_pf *pf)
4283 {
4284 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4285
4286 clear_bit(ICE_FLAG_DPLL, pf->flags);
4287 if (cgu)
4288 ice_dpll_deinit_worker(pf);
4289
4290 ice_dpll_deinit_pins(pf, cgu);
4291 if (!IS_ERR_OR_NULL(pf->dplls.pps.dpll))
4292 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4293 if (!IS_ERR_OR_NULL(pf->dplls.eec.dpll))
4294 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4295 ice_dpll_deinit_info(pf);
4296 mutex_destroy(&pf->dplls.lock);
4297 }
4298
4299 /**
4300 * ice_dpll_init_e825 - initialize support for dpll subsystem
4301 * @pf: board private structure
4302 *
4303 * Set up the device dplls, register them and pins connected within Linux dpll
4304 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4305 * configuration requests.
4306 *
4307 * Context: Initializes pf->dplls.lock mutex.
4308 */
ice_dpll_init_e825(struct ice_pf * pf)4309 static void ice_dpll_init_e825(struct ice_pf *pf)
4310 {
4311 struct ice_dplls *d = &pf->dplls;
4312 int err;
4313
4314 mutex_init(&d->lock);
4315 init_completion(&d->dpll_init);
4316
4317 err = ice_dpll_init_info_e825c(pf);
4318 if (err)
4319 goto err_exit;
4320 err = ice_dpll_init_pins_e825(pf);
4321 if (err)
4322 goto deinit_info;
4323 set_bit(ICE_FLAG_DPLL, pf->flags);
4324 complete_all(&d->dpll_init);
4325
4326 return;
4327
4328 deinit_info:
4329 ice_dpll_deinit_info(pf);
4330 err_exit:
4331 mutex_destroy(&d->lock);
4332 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4333 }
4334
4335 /**
4336 * ice_dpll_init_e810 - initialize support for dpll subsystem
4337 * @pf: board private structure
4338 *
4339 * Set up the device dplls, register them and pins connected within Linux dpll
4340 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4341 * configuration requests.
4342 *
4343 * Context: Initializes pf->dplls.lock mutex.
4344 */
ice_dpll_init_e810(struct ice_pf * pf)4345 static void ice_dpll_init_e810(struct ice_pf *pf)
4346 {
4347 bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4348 struct ice_dplls *d = &pf->dplls;
4349 int err = 0;
4350
4351 mutex_init(&d->lock);
4352 err = ice_dpll_init_info(pf, cgu);
4353 if (err)
4354 goto err_exit;
4355 err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
4356 if (err)
4357 goto deinit_info;
4358 err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
4359 if (err)
4360 goto deinit_eec;
4361 err = ice_dpll_init_pins(pf, cgu);
4362 if (err)
4363 goto deinit_pps;
4364 if (cgu) {
4365 err = ice_dpll_init_worker(pf);
4366 if (err)
4367 goto deinit_pins;
4368 }
4369 set_bit(ICE_FLAG_DPLL, pf->flags);
4370
4371 return;
4372
4373 deinit_pins:
4374 ice_dpll_deinit_pins(pf, cgu);
4375 deinit_pps:
4376 ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4377 deinit_eec:
4378 ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4379 deinit_info:
4380 ice_dpll_deinit_info(pf);
4381 err_exit:
4382 mutex_destroy(&d->lock);
4383 dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4384 }
4385
ice_dpll_init(struct ice_pf * pf)4386 void ice_dpll_init(struct ice_pf *pf)
4387 {
4388 switch (pf->hw.mac_type) {
4389 case ICE_MAC_GENERIC_3K_E825:
4390 ice_dpll_init_e825(pf);
4391 break;
4392 default:
4393 ice_dpll_init_e810(pf);
4394 break;
4395 }
4396 }
4397