File Index
Files and directories
Sign in
FILE

ice_dpll.c

File preview with syntax highlighting.

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