// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022, Intel Corporation. */

#include "ice.h"
#include "ice_lib.h"
#include "ice_trace.h"
#include <linux/dpll.h>

#define ICE_CGU_STATE_ACQ_ERR_THRESHOLD		50
#define ICE_DPLL_PIN_IDX_INVALID		0xff
#define ICE_DPLL_RCLK_NUM_PER_PF		1

/**
 * enum ice_dpll_pin_type - enumerate ice pin types:
 * @ICE_DPLL_PIN_INVALID: invalid pin type
 * @ICE_DPLL_PIN_TYPE_INPUT: input pin
 * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
 * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
 */
enum ice_dpll_pin_type {
	ICE_DPLL_PIN_INVALID,
	ICE_DPLL_PIN_TYPE_INPUT,
	ICE_DPLL_PIN_TYPE_OUTPUT,
	ICE_DPLL_PIN_TYPE_RCLK_INPUT,
};

static const char * const pin_type_name[] = {
	[ICE_DPLL_PIN_TYPE_INPUT] = "input",
	[ICE_DPLL_PIN_TYPE_OUTPUT] = "output",
	[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
};

/**
 * ice_dpll_is_reset - check if reset is in progress
 * @pf: private board structure
 * @extack: error reporting
 *
 * If reset is in progress, fill extack with error.
 *
 * Return:
 * * false - no reset in progress
 * * true - reset in progress
 */
static bool ice_dpll_is_reset(struct ice_pf *pf, struct netlink_ext_ack *extack)
{
	if (ice_is_reset_in_progress(pf->state)) {
		NL_SET_ERR_MSG(extack, "PF reset in progress");
		return true;
	}
	return false;
}

/**
 * ice_dpll_pin_freq_set - set pin's frequency
 * @pf: private board structure
 * @pin: pointer to a pin
 * @pin_type: type of pin being configured
 * @freq: frequency to be set
 * @extack: error reporting
 *
 * Set requested frequency on a pin.
 *
 * Context: Called under pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error on AQ or wrong pin type given
 */
static int
ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin,
		      enum ice_dpll_pin_type pin_type, const u32 freq,
		      struct netlink_ext_ack *extack)
{
	u8 flags;
	int ret;

	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		flags = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ;
		ret = ice_aq_set_input_pin_cfg(&pf->hw, pin->idx, flags,
					       pin->flags[0], freq, 0);
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_FREQ;
		ret = ice_aq_set_output_pin_cfg(&pf->hw, pin->idx, flags,
						0, freq, 0);
		break;
	default:
		return -EINVAL;
	}
	if (ret) {
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to set pin freq:%u on pin:%u\n",
				   ret,
				   ice_aq_str(pf->hw.adminq.sq_last_status),
				   freq, pin->idx);
		return ret;
	}
	pin->freq = freq;

	return 0;
}

/**
 * ice_dpll_frequency_set - wrapper for pin callback for set frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: frequency to be set
 * @extack: error reporting
 * @pin_type: type of pin being configured
 *
 * Wraps internal set frequency command on a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't set in hw
 */
static int
ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv,
		       const struct dpll_device *dpll, void *dpll_priv,
		       const u32 frequency,
		       struct netlink_ext_ack *extack,
		       enum ice_dpll_pin_type pin_type)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;
	int ret;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency, extack);
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

/**
 * ice_dpll_input_frequency_set - input pin callback for set frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: frequency to be set
 * @extack: error reporting
 *
 * Wraps internal set frequency command on a pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't set in hw
 */
static int
ice_dpll_input_frequency_set(const struct dpll_pin *pin, void *pin_priv,
			     const struct dpll_device *dpll, void *dpll_priv,
			     u64 frequency, struct netlink_ext_ack *extack)
{
	return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
				      extack, ICE_DPLL_PIN_TYPE_INPUT);
}

/**
 * ice_dpll_output_frequency_set - output pin callback for set frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: frequency to be set
 * @extack: error reporting
 *
 * Wraps internal set frequency command on a pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't set in hw
 */
static int
ice_dpll_output_frequency_set(const struct dpll_pin *pin, void *pin_priv,
			      const struct dpll_device *dpll, void *dpll_priv,
			      u64 frequency, struct netlink_ext_ack *extack)
{
	return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
}

/**
 * ice_dpll_frequency_get - wrapper for pin callback for get frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: on success holds pin's frequency
 * @extack: error reporting
 * @pin_type: type of pin being configured
 *
 * Wraps internal get frequency command of a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't get from hw
 */
static int
ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv,
		       const struct dpll_device *dpll, void *dpll_priv,
		       u64 *frequency, struct netlink_ext_ack *extack,
		       enum ice_dpll_pin_type pin_type)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;

	mutex_lock(&pf->dplls.lock);
	*frequency = p->freq;
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_input_frequency_get - input pin callback for get frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: on success holds pin's frequency
 * @extack: error reporting
 *
 * Wraps internal get frequency command of a input pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't get from hw
 */
static int
ice_dpll_input_frequency_get(const struct dpll_pin *pin, void *pin_priv,
			     const struct dpll_device *dpll, void *dpll_priv,
			     u64 *frequency, struct netlink_ext_ack *extack)
{
	return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
				      extack, ICE_DPLL_PIN_TYPE_INPUT);
}

/**
 * ice_dpll_output_frequency_get - output pin callback for get frequency
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: pointer to dpll
 * @dpll_priv: private data pointer passed on dpll registration
 * @frequency: on success holds pin's frequency
 * @extack: error reporting
 *
 * Wraps internal get frequency command of a pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error pin not found or couldn't get from hw
 */
static int
ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv,
			      const struct dpll_device *dpll, void *dpll_priv,
			      u64 *frequency, struct netlink_ext_ack *extack)
{
	return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
}

/**
 * ice_dpll_pin_enable - enable a pin on dplls
 * @hw: board private hw structure
 * @pin: pointer to a pin
 * @dpll_idx: dpll index to connect to output pin
 * @pin_type: type of pin being enabled
 * @extack: error reporting
 *
 * Enable a pin on both dplls. Store current state in pin->flags.
 *
 * Context: Called under pf->dplls.lock
 * Return:
 * * 0 - OK
 * * negative - error
 */
static int
ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin,
		    u8 dpll_idx, enum ice_dpll_pin_type pin_type,
		    struct netlink_ext_ack *extack)
{
	u8 flags = 0;
	int ret;

	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
			flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
		flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
		ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_SRC_SEL;
		if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
		flags |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
		ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, dpll_idx,
						0, 0);
		break;
	default:
		return -EINVAL;
	}
	if (ret)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to enable %s pin:%u\n",
				   ret, ice_aq_str(hw->adminq.sq_last_status),
				   pin_type_name[pin_type], pin->idx);

	return ret;
}

/**
 * ice_dpll_pin_disable - disable a pin on dplls
 * @hw: board private hw structure
 * @pin: pointer to a pin
 * @pin_type: type of pin being disabled
 * @extack: error reporting
 *
 * Disable a pin on both dplls. Store current state in pin->flags.
 *
 * Context: Called under pf->dplls.lock
 * Return:
 * * 0 - OK
 * * negative - error
 */
static int
ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
		     enum ice_dpll_pin_type pin_type,
		     struct netlink_ext_ack *extack)
{
	u8 flags = 0;
	int ret;

	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
			flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
		ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
		ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0);
		break;
	default:
		return -EINVAL;
	}
	if (ret)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to disable %s pin:%u\n",
				   ret, ice_aq_str(hw->adminq.sq_last_status),
				   pin_type_name[pin_type], pin->idx);

	return ret;
}

/**
 * ice_dpll_pin_state_update - update pin's state
 * @pf: private board struct
 * @pin: structure with pin attributes to be updated
 * @pin_type: type of pin being updated
 * @extack: error reporting
 *
 * Determine pin current state and frequency, then update struct
 * holding the pin info. For input pin states are separated for each
 * dpll, for rclk pins states are separated for each parent.
 *
 * Context: Called under pf->dplls.lock
 * Return:
 * * 0 - OK
 * * negative - error
 */
static int
ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
			  enum ice_dpll_pin_type pin_type,
			  struct netlink_ext_ack *extack)
{
	u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
	int ret;

	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, NULL, NULL,
					       NULL, &pin->flags[0],
					       &pin->freq, &pin->phase_adjust);
		if (ret)
			goto err;
		if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
			if (pin->pin) {
				pin->state[pf->dplls.eec.dpll_idx] =
					pin->pin == pf->dplls.eec.active_input ?
					DPLL_PIN_STATE_CONNECTED :
					DPLL_PIN_STATE_SELECTABLE;
				pin->state[pf->dplls.pps.dpll_idx] =
					pin->pin == pf->dplls.pps.active_input ?
					DPLL_PIN_STATE_CONNECTED :
					DPLL_PIN_STATE_SELECTABLE;
			} else {
				pin->state[pf->dplls.eec.dpll_idx] =
					DPLL_PIN_STATE_SELECTABLE;
				pin->state[pf->dplls.pps.dpll_idx] =
					DPLL_PIN_STATE_SELECTABLE;
			}
		} else {
			pin->state[pf->dplls.eec.dpll_idx] =
				DPLL_PIN_STATE_DISCONNECTED;
			pin->state[pf->dplls.pps.dpll_idx] =
				DPLL_PIN_STATE_DISCONNECTED;
		}
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		ret = ice_aq_get_output_pin_cfg(&pf->hw, pin->idx,
						&pin->flags[0], &parent,
						&pin->freq, NULL);
		if (ret)
			goto err;

		parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
		if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
			pin->state[pf->dplls.eec.dpll_idx] =
				parent == pf->dplls.eec.dpll_idx ?
				DPLL_PIN_STATE_CONNECTED :
				DPLL_PIN_STATE_DISCONNECTED;
			pin->state[pf->dplls.pps.dpll_idx] =
				parent == pf->dplls.pps.dpll_idx ?
				DPLL_PIN_STATE_CONNECTED :
				DPLL_PIN_STATE_DISCONNECTED;
		} else {
			pin->state[pf->dplls.eec.dpll_idx] =
				DPLL_PIN_STATE_DISCONNECTED;
			pin->state[pf->dplls.pps.dpll_idx] =
				DPLL_PIN_STATE_DISCONNECTED;
		}
		break;
	case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
		for (parent = 0; parent < pf->dplls.rclk.num_parents;
		     parent++) {
			u8 p = parent;

			ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &p,
							 &port_num,
							 &pin->flags[parent],
							 NULL);
			if (ret)
				goto err;
			if (ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
			    pin->flags[parent])
				pin->state[parent] = DPLL_PIN_STATE_CONNECTED;
			else
				pin->state[parent] =
					DPLL_PIN_STATE_DISCONNECTED;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
err:
	if (extack)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to update %s pin:%u\n",
				   ret,
				   ice_aq_str(pf->hw.adminq.sq_last_status),
				   pin_type_name[pin_type], pin->idx);
	else
		dev_err_ratelimited(ice_pf_to_dev(pf),
				    "err:%d %s failed to update %s pin:%u\n",
				    ret,
				    ice_aq_str(pf->hw.adminq.sq_last_status),
				    pin_type_name[pin_type], pin->idx);
	return ret;
}

/**
 * ice_dpll_hw_input_prio_set - set input priority value in hardware
 * @pf: board private structure
 * @dpll: ice dpll pointer
 * @pin: ice pin pointer
 * @prio: priority value being set on a dpll
 * @extack: error reporting
 *
 * Internal wrapper for setting the priority in the hardware.
 *
 * Context: Called under pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
			   struct ice_dpll_pin *pin, const u32 prio,
			   struct netlink_ext_ack *extack)
{
	int ret;

	ret = ice_aq_set_cgu_ref_prio(&pf->hw, dpll->dpll_idx, pin->idx,
				      (u8)prio);
	if (ret)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to set pin prio:%u on pin:%u\n",
				   ret,
				   ice_aq_str(pf->hw.adminq.sq_last_status),
				   prio, pin->idx);
	else
		dpll->input_prio[pin->idx] = prio;

	return ret;
}

/**
 * ice_dpll_lock_status_get - get dpll lock status callback
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @status: on success holds dpll's lock status
 * @status_error: status error value
 * @extack: error reporting
 *
 * Dpll subsystem callback, provides dpll's lock status.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
			 enum dpll_lock_status *status,
			 enum dpll_lock_status_error *status_error,
			 struct netlink_ext_ack *extack)
{
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;

	mutex_lock(&pf->dplls.lock);
	*status = d->dpll_state;
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_mode_get - get dpll's working mode
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @mode: on success holds current working mode of dpll
 * @extack: error reporting
 *
 * Dpll subsystem callback. Provides working mode of dpll.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
			     enum dpll_mode *mode,
			     struct netlink_ext_ack *extack)
{
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;

	mutex_lock(&pf->dplls.lock);
	*mode = d->mode;
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_pin_state_set - set pin's state on dpll
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @enable: if pin shalll be enabled
 * @extack: error reporting
 * @pin_type: type of a pin
 *
 * Set pin state on a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - OK or no change required
 * * negative - error
 */
static int
ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
		       const struct dpll_device *dpll, void *dpll_priv,
		       bool enable, struct netlink_ext_ack *extack,
		       enum ice_dpll_pin_type pin_type)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;
	int ret;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	if (enable)
		ret = ice_dpll_pin_enable(&pf->hw, p, d->dpll_idx, pin_type,
					  extack);
	else
		ret = ice_dpll_pin_disable(&pf->hw, p, pin_type, extack);
	if (!ret)
		ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

/**
 * ice_dpll_output_state_set - enable/disable output pin on dpll device
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: dpll being configured
 * @dpll_priv: private data pointer passed on dpll registration
 * @state: state of pin to be set
 * @extack: error reporting
 *
 * Dpll subsystem callback. Set given state on output type pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - successfully enabled mode
 * * negative - failed to enable mode
 */
static int
ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
			  const struct dpll_device *dpll, void *dpll_priv,
			  enum dpll_pin_state state,
			  struct netlink_ext_ack *extack)
{
	bool enable = state == DPLL_PIN_STATE_CONNECTED;
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;

	if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
		return 0;

	return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
}

/**
 * ice_dpll_input_state_set - enable/disable input pin on dpll levice
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: dpll being configured
 * @dpll_priv: private data pointer passed on dpll registration
 * @state: state of pin to be set
 * @extack: error reporting
 *
 * Dpll subsystem callback. Enables given mode on input type pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - successfully enabled mode
 * * negative - failed to enable mode
 */
static int
ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv,
			 const struct dpll_device *dpll, void *dpll_priv,
			 enum dpll_pin_state state,
			 struct netlink_ext_ack *extack)
{
	bool enable = state == DPLL_PIN_STATE_SELECTABLE;

	return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
				      extack, ICE_DPLL_PIN_TYPE_INPUT);
}

/**
 * ice_dpll_pin_state_get - set pin's state on dpll
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @state: on success holds state of the pin
 * @extack: error reporting
 * @pin_type: type of questioned pin
 *
 * Determine pin state set it on a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failed to get state
 */
static int
ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
		       const struct dpll_device *dpll, void *dpll_priv,
		       enum dpll_pin_state *state,
		       struct netlink_ext_ack *extack,
		       enum ice_dpll_pin_type pin_type)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;
	int ret;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
	if (ret)
		goto unlock;
	if (pin_type == ICE_DPLL_PIN_TYPE_INPUT ||
	    pin_type == ICE_DPLL_PIN_TYPE_OUTPUT)
		*state = p->state[d->dpll_idx];
	ret = 0;
unlock:
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

/**
 * ice_dpll_output_state_get - get output pin state on dpll device
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @state: on success holds state of the pin
 * @extack: error reporting
 *
 * Dpll subsystem callback. Check state of a pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failed to get state
 */
static int
ice_dpll_output_state_get(const struct dpll_pin *pin, void *pin_priv,
			  const struct dpll_device *dpll, void *dpll_priv,
			  enum dpll_pin_state *state,
			  struct netlink_ext_ack *extack)
{
	return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
}

/**
 * ice_dpll_input_state_get - get input pin state on dpll device
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @state: on success holds state of the pin
 * @extack: error reporting
 *
 * Dpll subsystem callback. Check state of a input pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failed to get state
 */
static int
ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
			 const struct dpll_device *dpll, void *dpll_priv,
			 enum dpll_pin_state *state,
			 struct netlink_ext_ack *extack)
{
	return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
				      extack, ICE_DPLL_PIN_TYPE_INPUT);
}

/**
 * ice_dpll_input_prio_get - get dpll's input prio
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @prio: on success - returns input priority on dpll
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for getting priority of a input pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
			const struct dpll_device *dpll, void *dpll_priv,
			u32 *prio, struct netlink_ext_ack *extack)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;

	mutex_lock(&pf->dplls.lock);
	*prio = d->input_prio[p->idx];
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_input_prio_set - set dpll input prio
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @prio: input priority to be set on dpll
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for setting priority of a input pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
			const struct dpll_device *dpll, void *dpll_priv,
			u32 prio, struct netlink_ext_ack *extack)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;
	int ret;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

/**
 * ice_dpll_input_direction - callback for get input pin direction
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @direction: holds input pin direction
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for getting direction of a input pin.
 *
 * Return:
 * * 0 - success
 */
static int
ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
			 const struct dpll_device *dpll, void *dpll_priv,
			 enum dpll_pin_direction *direction,
			 struct netlink_ext_ack *extack)
{
	*direction = DPLL_PIN_DIRECTION_INPUT;

	return 0;
}

/**
 * ice_dpll_output_direction - callback for get output pin direction
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @direction: holds output pin direction
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for getting direction of an output pin.
 *
 * Return:
 * * 0 - success
 */
static int
ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
			  const struct dpll_device *dpll, void *dpll_priv,
			  enum dpll_pin_direction *direction,
			  struct netlink_ext_ack *extack)
{
	*direction = DPLL_PIN_DIRECTION_OUTPUT;

	return 0;
}

/**
 * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @phase_adjust: on success holds pin phase_adjust value
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error
 */
static int
ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
			      const struct dpll_device *dpll, void *dpll_priv,
			      s32 *phase_adjust,
			      struct netlink_ext_ack *extack)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_pf *pf = p->pf;

	mutex_lock(&pf->dplls.lock);
	*phase_adjust = p->phase_adjust;
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @phase_adjust: phase_adjust to be set
 * @extack: error reporting
 * @type: type of a pin
 *
 * Helper for dpll subsystem callback. Handler for setting phase adjust value
 * of a pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error
 */
static int
ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
			      const struct dpll_device *dpll, void *dpll_priv,
			      s32 phase_adjust,
			      struct netlink_ext_ack *extack,
			      enum ice_dpll_pin_type type)
{
	struct ice_dpll_pin *p = pin_priv;
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;
	u8 flag, flags_en = 0;
	int ret;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	switch (type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
		ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
					       0, phase_adjust);
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
			flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
			flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
		ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
						phase_adjust);
		break;
	default:
		ret = -EINVAL;
	}
	if (!ret)
		p->phase_adjust = phase_adjust;
	mutex_unlock(&pf->dplls.lock);
	if (ret)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n",
				   ret,
				   ice_aq_str(pf->hw.adminq.sq_last_status),
				   phase_adjust, p->idx, d->dpll_idx);

	return ret;
}

/**
 * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @phase_adjust: phase_adjust to be set
 * @extack: error reporting
 *
 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
 * pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error
 */
static int
ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
				const struct dpll_device *dpll, void *dpll_priv,
				s32 phase_adjust,
				struct netlink_ext_ack *extack)
{
	return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
					     phase_adjust, extack,
					     ICE_DPLL_PIN_TYPE_INPUT);
}

/**
 * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @phase_adjust: phase_adjust to be set
 * @extack: error reporting
 *
 * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
 * pin.
 *
 * Context: Calls a function which acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error
 */
static int
ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
				 const struct dpll_device *dpll, void *dpll_priv,
				 s32 phase_adjust,
				 struct netlink_ext_ack *extack)
{
	return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
					     phase_adjust, extack,
					     ICE_DPLL_PIN_TYPE_OUTPUT);
}

#define ICE_DPLL_PHASE_OFFSET_DIVIDER	100
#define ICE_DPLL_PHASE_OFFSET_FACTOR		\
	(DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
/**
 * ice_dpll_phase_offset_get - callback for get dpll phase shift value
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @dpll: registered dpll pointer
 * @dpll_priv: private data pointer passed on dpll registration
 * @phase_offset: on success holds pin phase_offset value
 * @extack: error reporting
 *
 * Dpll subsystem callback. Handler for getting phase shift value between
 * dpll's input and output.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - error
 */
static int
ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
			  const struct dpll_device *dpll, void *dpll_priv,
			  s64 *phase_offset, struct netlink_ext_ack *extack)
{
	struct ice_dpll *d = dpll_priv;
	struct ice_pf *pf = d->pf;

	mutex_lock(&pf->dplls.lock);
	if (d->active_input == pin)
		*phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
	else
		*phase_offset = 0;
	mutex_unlock(&pf->dplls.lock);

	return 0;
}

/**
 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @parent_pin: pin parent pointer
 * @parent_pin_priv: parent private data pointer passed on pin registration
 * @state: state to be set on pin
 * @extack: error reporting
 *
 * Dpll subsystem callback, set a state of a rclk pin on a parent pin
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
			       const struct dpll_pin *parent_pin,
			       void *parent_pin_priv,
			       enum dpll_pin_state state,
			       struct netlink_ext_ack *extack)
{
	struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
	bool enable = state == DPLL_PIN_STATE_CONNECTED;
	struct ice_pf *pf = p->pf;
	int ret = -EINVAL;
	u32 hw_idx;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	hw_idx = parent->idx - pf->dplls.base_rclk_idx;
	if (hw_idx >= pf->dplls.num_inputs)
		goto unlock;

	if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
	    (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
		NL_SET_ERR_MSG_FMT(extack,
				   "pin:%u state:%u on parent:%u already set",
				   p->idx, state, parent->idx);
		goto unlock;
	}
	ret = ice_aq_set_phy_rec_clk_out(&pf->hw, hw_idx, enable,
					 &p->freq);
	if (ret)
		NL_SET_ERR_MSG_FMT(extack,
				   "err:%d %s failed to set pin state:%u for pin:%u on parent:%u\n",
				   ret,
				   ice_aq_str(pf->hw.adminq.sq_last_status),
				   state, p->idx, parent->idx);
unlock:
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

/**
 * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
 * @pin: pointer to a pin
 * @pin_priv: private data pointer passed on pin registration
 * @parent_pin: pin parent pointer
 * @parent_pin_priv: pin parent priv data pointer passed on pin registration
 * @state: on success holds pin state on parent pin
 * @extack: error reporting
 *
 * dpll subsystem callback, get a state of a recovered clock pin.
 *
 * Context: Acquires pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - failure
 */
static int
ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
			       const struct dpll_pin *parent_pin,
			       void *parent_pin_priv,
			       enum dpll_pin_state *state,
			       struct netlink_ext_ack *extack)
{
	struct ice_dpll_pin *p = pin_priv, *parent = parent_pin_priv;
	struct ice_pf *pf = p->pf;
	int ret = -EINVAL;
	u32 hw_idx;

	if (ice_dpll_is_reset(pf, extack))
		return -EBUSY;

	mutex_lock(&pf->dplls.lock);
	hw_idx = parent->idx - pf->dplls.base_rclk_idx;
	if (hw_idx >= pf->dplls.num_inputs)
		goto unlock;

	ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
					extack);
	if (ret)
		goto unlock;

	*state = p->state[hw_idx];
	ret = 0;
unlock:
	mutex_unlock(&pf->dplls.lock);

	return ret;
}

static const struct dpll_pin_ops ice_dpll_rclk_ops = {
	.state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
	.state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
	.direction_get = ice_dpll_input_direction,
};

static const struct dpll_pin_ops ice_dpll_input_ops = {
	.frequency_get = ice_dpll_input_frequency_get,
	.frequency_set = ice_dpll_input_frequency_set,
	.state_on_dpll_get = ice_dpll_input_state_get,
	.state_on_dpll_set = ice_dpll_input_state_set,
	.prio_get = ice_dpll_input_prio_get,
	.prio_set = ice_dpll_input_prio_set,
	.direction_get = ice_dpll_input_direction,
	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
	.phase_adjust_set = ice_dpll_input_phase_adjust_set,
	.phase_offset_get = ice_dpll_phase_offset_get,
};

static const struct dpll_pin_ops ice_dpll_output_ops = {
	.frequency_get = ice_dpll_output_frequency_get,
	.frequency_set = ice_dpll_output_frequency_set,
	.state_on_dpll_get = ice_dpll_output_state_get,
	.state_on_dpll_set = ice_dpll_output_state_set,
	.direction_get = ice_dpll_output_direction,
	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
	.phase_adjust_set = ice_dpll_output_phase_adjust_set,
};

static const struct dpll_device_ops ice_dpll_ops = {
	.lock_status_get = ice_dpll_lock_status_get,
	.mode_get = ice_dpll_mode_get,
};

/**
 * ice_generate_clock_id - generates unique clock_id for registering dpll.
 * @pf: board private structure
 *
 * Generates unique (per board) clock_id for allocation and search of dpll
 * devices in Linux dpll subsystem.
 *
 * Return: generated clock id for the board
 */
static u64 ice_generate_clock_id(struct ice_pf *pf)
{
	return pci_get_dsn(pf->pdev);
}

/**
 * ice_dpll_notify_changes - notify dpll subsystem about changes
 * @d: pointer do dpll
 *
 * Once change detected appropriate event is submitted to the dpll subsystem.
 */
static void ice_dpll_notify_changes(struct ice_dpll *d)
{
	bool pin_notified = false;

	if (d->prev_dpll_state != d->dpll_state) {
		d->prev_dpll_state = d->dpll_state;
		dpll_device_change_ntf(d->dpll);
	}
	if (d->prev_input != d->active_input) {
		if (d->prev_input)
			dpll_pin_change_ntf(d->prev_input);
		d->prev_input = d->active_input;
		if (d->active_input) {
			dpll_pin_change_ntf(d->active_input);
			pin_notified = true;
		}
	}
	if (d->prev_phase_offset != d->phase_offset) {
		d->prev_phase_offset = d->phase_offset;
		if (!pin_notified && d->active_input)
			dpll_pin_change_ntf(d->active_input);
	}
}

/**
 * ice_dpll_update_state - update dpll state
 * @pf: pf private structure
 * @d: pointer to queried dpll device
 * @init: if function called on initialization of ice dpll
 *
 * Poll current state of dpll from hw and update ice_dpll struct.
 *
 * Context: Called by kworker under pf->dplls.lock
 * Return:
 * * 0 - success
 * * negative - AQ failure
 */
static int
ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
{
	struct ice_dpll_pin *p = NULL;
	int ret;

	ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
				&d->input_idx, &d->ref_state, &d->eec_mode,
				&d->phase_offset, &d->dpll_state);

	dev_dbg(ice_pf_to_dev(pf),
		"update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
		d->dpll_idx, d->prev_input_idx, d->input_idx,
		d->dpll_state, d->prev_dpll_state, d->mode);
	if (ret) {
		dev_err(ice_pf_to_dev(pf),
			"update dpll=%d state failed, ret=%d %s\n",
			d->dpll_idx, ret,
			ice_aq_str(pf->hw.adminq.sq_last_status));
		return ret;
	}
	if (init) {
		if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
		    d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
			d->active_input = pf->dplls.inputs[d->input_idx].pin;
		p = &pf->dplls.inputs[d->input_idx];
		return ice_dpll_pin_state_update(pf, p,
						 ICE_DPLL_PIN_TYPE_INPUT, NULL);
	}
	if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
	    d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
		d->active_input = NULL;
		if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
			p = &pf->dplls.inputs[d->input_idx];
		d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
		d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
		if (!p)
			return 0;
		ret = ice_dpll_pin_state_update(pf, p,
						ICE_DPLL_PIN_TYPE_INPUT, NULL);
	} else if (d->input_idx != d->prev_input_idx) {
		if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
			p = &pf->dplls.inputs[d->prev_input_idx];
			ice_dpll_pin_state_update(pf, p,
						  ICE_DPLL_PIN_TYPE_INPUT,
						  NULL);
		}
		if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
			p = &pf->dplls.inputs[d->input_idx];
			d->active_input = p->pin;
			ice_dpll_pin_state_update(pf, p,
						  ICE_DPLL_PIN_TYPE_INPUT,
						  NULL);
		}
		d->prev_input_idx = d->input_idx;
	}

	return ret;
}

/**
 * ice_dpll_periodic_work - DPLLs periodic worker
 * @work: pointer to kthread_work structure
 *
 * DPLLs periodic worker is responsible for polling state of dpll.
 * Context: Holds pf->dplls.lock
 */
static void ice_dpll_periodic_work(struct kthread_work *work)
{
	struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
	struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
	struct ice_dpll *de = &pf->dplls.eec;
	struct ice_dpll *dp = &pf->dplls.pps;
	int ret = 0;

	if (ice_is_reset_in_progress(pf->state))
		goto resched;
	mutex_lock(&pf->dplls.lock);
	ret = ice_dpll_update_state(pf, de, false);
	if (!ret)
		ret = ice_dpll_update_state(pf, dp, false);
	if (ret) {
		d->cgu_state_acq_err_num++;
		/* stop rescheduling this worker */
		if (d->cgu_state_acq_err_num >
		    ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
			dev_err(ice_pf_to_dev(pf),
				"EEC/PPS DPLLs periodic work disabled\n");
			mutex_unlock(&pf->dplls.lock);
			return;
		}
	}
	mutex_unlock(&pf->dplls.lock);
	ice_dpll_notify_changes(de);
	ice_dpll_notify_changes(dp);

resched:
	/* Run twice a second or reschedule if update failed */
	kthread_queue_delayed_work(d->kworker, &d->work,
				   ret ? msecs_to_jiffies(10) :
				   msecs_to_jiffies(500));
}

/**
 * ice_dpll_release_pins - release pins resources from dpll subsystem
 * @pins: pointer to pins array
 * @count: number of pins
 *
 * Release resources of given pins array in the dpll subsystem.
 */
static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
{
	int i;

	for (i = 0; i < count; i++)
		dpll_pin_put(pins[i].pin);
}

/**
 * ice_dpll_get_pins - get pins from dpll subsystem
 * @pf: board private structure
 * @pins: pointer to pins array
 * @start_idx: get starts from this pin idx value
 * @count: number of pins
 * @clock_id: clock_id of dpll device
 *
 * Get pins - allocate - in dpll subsystem, store them in pin field of given
 * pins array.
 *
 * Return:
 * * 0 - success
 * * negative - allocation failure reason
 */
static int
ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
		  int start_idx, int count, u64 clock_id)
{
	int i, ret;

	for (i = 0; i < count; i++) {
		pins[i].pin = dpll_pin_get(clock_id, i + start_idx, THIS_MODULE,
					   &pins[i].prop);
		if (IS_ERR(pins[i].pin)) {
			ret = PTR_ERR(pins[i].pin);
			goto release_pins;
		}
	}

	return 0;

release_pins:
	while (--i >= 0)
		dpll_pin_put(pins[i].pin);
	return ret;
}

/**
 * ice_dpll_unregister_pins - unregister pins from a dpll
 * @dpll: dpll device pointer
 * @pins: pointer to pins array
 * @ops: callback ops registered with the pins
 * @count: number of pins
 *
 * Unregister pins of a given array of pins from given dpll device registered in
 * dpll subsystem.
 */
static void
ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
			 const struct dpll_pin_ops *ops, int count)
{
	int i;

	for (i = 0; i < count; i++)
		dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
}

/**
 * ice_dpll_register_pins - register pins with a dpll
 * @dpll: dpll pointer to register pins with
 * @pins: pointer to pins array
 * @ops: callback ops registered with the pins
 * @count: number of pins
 *
 * Register pins of a given array with given dpll in dpll subsystem.
 *
 * Return:
 * * 0 - success
 * * negative - registration failure reason
 */
static int
ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
		       const struct dpll_pin_ops *ops, int count)
{
	int ret, i;

	for (i = 0; i < count; i++) {
		ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]);
		if (ret)
			goto unregister_pins;
	}

	return 0;

unregister_pins:
	while (--i >= 0)
		dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
	return ret;
}

/**
 * ice_dpll_deinit_direct_pins - deinitialize direct pins
 * @cgu: if cgu is present and controlled by this NIC
 * @pins: pointer to pins array
 * @count: number of pins
 * @ops: callback ops registered with the pins
 * @first: dpll device pointer
 * @second: dpll device pointer
 *
 * If cgu is owned unregister pins from given dplls.
 * Release pins resources to the dpll subsystem.
 */
static void
ice_dpll_deinit_direct_pins(bool cgu, struct ice_dpll_pin *pins, int count,
			    const struct dpll_pin_ops *ops,
			    struct dpll_device *first,
			    struct dpll_device *second)
{
	if (cgu) {
		ice_dpll_unregister_pins(first, pins, ops, count);
		ice_dpll_unregister_pins(second, pins, ops, count);
	}
	ice_dpll_release_pins(pins, count);
}

/**
 * ice_dpll_init_direct_pins - initialize direct pins
 * @pf: board private structure
 * @cgu: if cgu is present and controlled by this NIC
 * @pins: pointer to pins array
 * @start_idx: on which index shall allocation start in dpll subsystem
 * @count: number of pins
 * @ops: callback ops registered with the pins
 * @first: dpll device pointer
 * @second: dpll device pointer
 *
 * Allocate directly connected pins of a given array in dpll subsystem.
 * If cgu is owned register allocated pins with given dplls.
 *
 * Return:
 * * 0 - success
 * * negative - registration failure reason
 */
static int
ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
			  struct ice_dpll_pin *pins, int start_idx, int count,
			  const struct dpll_pin_ops *ops,
			  struct dpll_device *first, struct dpll_device *second)
{
	int ret;

	ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id);
	if (ret)
		return ret;
	if (cgu) {
		ret = ice_dpll_register_pins(first, pins, ops, count);
		if (ret)
			goto release_pins;
		ret = ice_dpll_register_pins(second, pins, ops, count);
		if (ret)
			goto unregister_first;
	}

	return 0;

unregister_first:
	ice_dpll_unregister_pins(first, pins, ops, count);
release_pins:
	ice_dpll_release_pins(pins, count);
	return ret;
}

/**
 * ice_dpll_deinit_rclk_pin - release rclk pin resources
 * @pf: board private structure
 *
 * Deregister rclk pin from parent pins and release resources in dpll subsystem.
 */
static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
{
	struct ice_dpll_pin *rclk = &pf->dplls.rclk;
	struct ice_vsi *vsi = ice_get_main_vsi(pf);
	struct dpll_pin *parent;
	int i;

	for (i = 0; i < rclk->num_parents; i++) {
		parent = pf->dplls.inputs[rclk->parent_idx[i]].pin;
		if (!parent)
			continue;
		dpll_pin_on_pin_unregister(parent, rclk->pin,
					   &ice_dpll_rclk_ops, rclk);
	}
	if (WARN_ON_ONCE(!vsi || !vsi->netdev))
		return;
	dpll_netdev_pin_clear(vsi->netdev);
	dpll_pin_put(rclk->pin);
}

/**
 * ice_dpll_init_rclk_pins - initialize recovered clock pin
 * @pf: board private structure
 * @pin: pin to register
 * @start_idx: on which index shall allocation start in dpll subsystem
 * @ops: callback ops registered with the pins
 *
 * Allocate resource for recovered clock pin in dpll subsystem. Register the
 * pin with the parents it has in the info. Register pin with the pf's main vsi
 * netdev.
 *
 * Return:
 * * 0 - success
 * * negative - registration failure reason
 */
static int
ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
			int start_idx, const struct dpll_pin_ops *ops)
{
	struct ice_vsi *vsi = ice_get_main_vsi(pf);
	struct dpll_pin *parent;
	int ret, i;

	ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
				pf->dplls.clock_id);
	if (ret)
		return ret;
	for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
		parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[i]].pin;
		if (!parent) {
			ret = -ENODEV;
			goto unregister_pins;
		}
		ret = dpll_pin_on_pin_register(parent, pf->dplls.rclk.pin,
					       ops, &pf->dplls.rclk);
		if (ret)
			goto unregister_pins;
	}
	if (WARN_ON((!vsi || !vsi->netdev)))
		return -EINVAL;
	dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);

	return 0;

unregister_pins:
	while (i) {
		parent = pf->dplls.inputs[pf->dplls.rclk.parent_idx[--i]].pin;
		dpll_pin_on_pin_unregister(parent, pf->dplls.rclk.pin,
					   &ice_dpll_rclk_ops, &pf->dplls.rclk);
	}
	ice_dpll_release_pins(pin, ICE_DPLL_RCLK_NUM_PER_PF);
	return ret;
}

/**
 * ice_dpll_deinit_pins - deinitialize direct pins
 * @pf: board private structure
 * @cgu: if cgu is controlled by this pf
 *
 * If cgu is owned unregister directly connected pins from the dplls.
 * Release resources of directly connected pins from the dpll subsystem.
 */
static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
{
	struct ice_dpll_pin *outputs = pf->dplls.outputs;
	struct ice_dpll_pin *inputs = pf->dplls.inputs;
	int num_outputs = pf->dplls.num_outputs;
	int num_inputs = pf->dplls.num_inputs;
	struct ice_dplls *d = &pf->dplls;
	struct ice_dpll *de = &d->eec;
	struct ice_dpll *dp = &d->pps;

	ice_dpll_deinit_rclk_pin(pf);
	if (cgu) {
		ice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,
					 num_inputs);
		ice_dpll_unregister_pins(de->dpll, inputs, &ice_dpll_input_ops,
					 num_inputs);
	}
	ice_dpll_release_pins(inputs, num_inputs);
	if (cgu) {
		ice_dpll_unregister_pins(dp->dpll, outputs,
					 &ice_dpll_output_ops, num_outputs);
		ice_dpll_unregister_pins(de->dpll, outputs,
					 &ice_dpll_output_ops, num_outputs);
		ice_dpll_release_pins(outputs, num_outputs);
	}
}

/**
 * ice_dpll_init_pins - init pins and register pins with a dplls
 * @pf: board private structure
 * @cgu: if cgu is present and controlled by this NIC
 *
 * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
 * subsystem.
 *
 * Return:
 * * 0 - success
 * * negative - initialization failure reason
 */
static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
{
	u32 rclk_idx;
	int ret;

	ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0,
					pf->dplls.num_inputs,
					&ice_dpll_input_ops,
					pf->dplls.eec.dpll, pf->dplls.pps.dpll);
	if (ret)
		return ret;
	if (cgu) {
		ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs,
						pf->dplls.num_inputs,
						pf->dplls.num_outputs,
						&ice_dpll_output_ops,
						pf->dplls.eec.dpll,
						pf->dplls.pps.dpll);
		if (ret)
			goto deinit_inputs;
	}
	rclk_idx = pf->dplls.num_inputs + pf->dplls.num_outputs + pf->hw.pf_id;
	ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, rclk_idx,
				      &ice_dpll_rclk_ops);
	if (ret)
		goto deinit_outputs;

	return 0;
deinit_outputs:
	ice_dpll_deinit_direct_pins(cgu, pf->dplls.outputs,
				    pf->dplls.num_outputs,
				    &ice_dpll_output_ops, pf->dplls.pps.dpll,
				    pf->dplls.eec.dpll);
deinit_inputs:
	ice_dpll_deinit_direct_pins(cgu, pf->dplls.inputs, pf->dplls.num_inputs,
				    &ice_dpll_input_ops, pf->dplls.pps.dpll,
				    pf->dplls.eec.dpll);
	return ret;
}

/**
 * ice_dpll_deinit_dpll - deinitialize dpll device
 * @pf: board private structure
 * @d: pointer to ice_dpll
 * @cgu: if cgu is present and controlled by this NIC
 *
 * If cgu is owned unregister the dpll from dpll subsystem.
 * Release resources of dpll device from dpll subsystem.
 */
static void
ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
{
	if (cgu)
		dpll_device_unregister(d->dpll, &ice_dpll_ops, d);
	dpll_device_put(d->dpll);
}

/**
 * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
 * @pf: board private structure
 * @d: dpll to be initialized
 * @cgu: if cgu is present and controlled by this NIC
 * @type: type of dpll being initialized
 *
 * Allocate dpll instance for this board in dpll subsystem, if cgu is controlled
 * by this NIC, register dpll with the callback ops.
 *
 * Return:
 * * 0 - success
 * * negative - initialization failure reason
 */
static int
ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
		   enum dpll_type type)
{
	u64 clock_id = pf->dplls.clock_id;
	int ret;

	d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE);
	if (IS_ERR(d->dpll)) {
		ret = PTR_ERR(d->dpll);
		dev_err(ice_pf_to_dev(pf),
			"dpll_device_get failed (%p) err=%d\n", d, ret);
		return ret;
	}
	d->pf = pf;
	if (cgu) {
		ice_dpll_update_state(pf, d, true);
		ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d);
		if (ret) {
			dpll_device_put(d->dpll);
			return ret;
		}
	}

	return 0;
}

/**
 * ice_dpll_deinit_worker - deinitialize dpll kworker
 * @pf: board private structure
 *
 * Stop dpll's kworker, release it's resources.
 */
static void ice_dpll_deinit_worker(struct ice_pf *pf)
{
	struct ice_dplls *d = &pf->dplls;

	kthread_cancel_delayed_work_sync(&d->work);
	kthread_destroy_worker(d->kworker);
}

/**
 * ice_dpll_init_worker - Initialize DPLLs periodic worker
 * @pf: board private structure
 *
 * Create and start DPLLs periodic worker.
 *
 * Context: Shall be called after pf->dplls.lock is initialized.
 * Return:
 * * 0 - success
 * * negative - create worker failure
 */
static int ice_dpll_init_worker(struct ice_pf *pf)
{
	struct ice_dplls *d = &pf->dplls;
	struct kthread_worker *kworker;

	kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
	kworker = kthread_create_worker(0, "ice-dplls-%s",
					dev_name(ice_pf_to_dev(pf)));
	if (IS_ERR(kworker))
		return PTR_ERR(kworker);
	d->kworker = kworker;
	d->cgu_state_acq_err_num = 0;
	kthread_queue_delayed_work(d->kworker, &d->work, 0);

	return 0;
}

/**
 * ice_dpll_init_info_direct_pins - initializes direct pins info
 * @pf: board private structure
 * @pin_type: type of pins being initialized
 *
 * Init information for directly connected pins, cache them in pf's pins
 * structures.
 *
 * Return:
 * * 0 - success
 * * negative - init failure reason
 */
static int
ice_dpll_init_info_direct_pins(struct ice_pf *pf,
			       enum ice_dpll_pin_type pin_type)
{
	struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
	int num_pins, i, ret = -EINVAL;
	struct ice_hw *hw = &pf->hw;
	struct ice_dpll_pin *pins;
	unsigned long caps;
	u8 freq_supp_num;
	bool input;

	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
		pins = pf->dplls.inputs;
		num_pins = pf->dplls.num_inputs;
		input = true;
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		pins = pf->dplls.outputs;
		num_pins = pf->dplls.num_outputs;
		input = false;
		break;
	default:
		return -EINVAL;
	}

	for (i = 0; i < num_pins; i++) {
		caps = 0;
		pins[i].idx = i;
		pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
		pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
		if (input) {
			ret = ice_aq_get_cgu_ref_prio(hw, de->dpll_idx, i,
						      &de->input_prio[i]);
			if (ret)
				return ret;
			ret = ice_aq_get_cgu_ref_prio(hw, dp->dpll_idx, i,
						      &dp->input_prio[i]);
			if (ret)
				return ret;
			caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
				 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
			pins[i].prop.phase_range.min =
				pf->dplls.input_phase_adj_max;
			pins[i].prop.phase_range.max =
				-pf->dplls.input_phase_adj_max;
		} else {
			pins[i].prop.phase_range.min =
				pf->dplls.output_phase_adj_max;
			pins[i].prop.phase_range.max =
				-pf->dplls.output_phase_adj_max;
			ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
			if (ret)
				return ret;
		}
		pins[i].prop.capabilities = caps;
		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
		if (ret)
			return ret;
		pins[i].prop.freq_supported =
			ice_cgu_get_pin_freq_supp(hw, i, input, &freq_supp_num);
		pins[i].prop.freq_supported_num = freq_supp_num;
		pins[i].pf = pf;
	}

	return ret;
}

/**
 * ice_dpll_init_info_rclk_pin - initializes rclk pin information
 * @pf: board private structure
 *
 * Init information for rclk pin, cache them in pf->dplls.rclk.
 *
 * Return:
 * * 0 - success
 * * negative - init failure reason
 */
static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
{
	struct ice_dpll_pin *pin = &pf->dplls.rclk;

	pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
	pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
	pin->pf = pf;

	return ice_dpll_pin_state_update(pf, pin,
					 ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
}

/**
 * ice_dpll_init_pins_info - init pins info wrapper
 * @pf: board private structure
 * @pin_type: type of pins being initialized
 *
 * Wraps functions for pin initialization.
 *
 * Return:
 * * 0 - success
 * * negative - init failure reason
 */
static int
ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
{
	switch (pin_type) {
	case ICE_DPLL_PIN_TYPE_INPUT:
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		return ice_dpll_init_info_direct_pins(pf, pin_type);
	case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
		return ice_dpll_init_info_rclk_pin(pf);
	default:
		return -EINVAL;
	}
}

/**
 * ice_dpll_deinit_info - release memory allocated for pins info
 * @pf: board private structure
 *
 * Release memory allocated for pins by ice_dpll_init_info function.
 */
static void ice_dpll_deinit_info(struct ice_pf *pf)
{
	kfree(pf->dplls.inputs);
	kfree(pf->dplls.outputs);
	kfree(pf->dplls.eec.input_prio);
	kfree(pf->dplls.pps.input_prio);
}

/**
 * ice_dpll_init_info - prepare pf's dpll information structure
 * @pf: board private structure
 * @cgu: if cgu is present and controlled by this NIC
 *
 * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
 *
 * Return:
 * * 0 - success
 * * negative - init failure reason
 */
static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
{
	struct ice_aqc_get_cgu_abilities abilities;
	struct ice_dpll *de = &pf->dplls.eec;
	struct ice_dpll *dp = &pf->dplls.pps;
	struct ice_dplls *d = &pf->dplls;
	struct ice_hw *hw = &pf->hw;
	int ret, alloc_size, i;

	d->clock_id = ice_generate_clock_id(pf);
	ret = ice_aq_get_cgu_abilities(hw, &abilities);
	if (ret) {
		dev_err(ice_pf_to_dev(pf),
			"err:%d %s failed to read cgu abilities\n",
			ret, ice_aq_str(hw->adminq.sq_last_status));
		return ret;
	}

	de->dpll_idx = abilities.eec_dpll_idx;
	dp->dpll_idx = abilities.pps_dpll_idx;
	d->num_inputs = abilities.num_inputs;
	d->num_outputs = abilities.num_outputs;
	d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj);
	d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj);

	alloc_size = sizeof(*d->inputs) * d->num_inputs;
	d->inputs = kzalloc(alloc_size, GFP_KERNEL);
	if (!d->inputs)
		return -ENOMEM;

	alloc_size = sizeof(*de->input_prio) * d->num_inputs;
	de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
	if (!de->input_prio)
		return -ENOMEM;

	dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
	if (!dp->input_prio)
		return -ENOMEM;

	ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
	if (ret)
		goto deinit_info;

	if (cgu) {
		alloc_size = sizeof(*d->outputs) * d->num_outputs;
		d->outputs = kzalloc(alloc_size, GFP_KERNEL);
		if (!d->outputs) {
			ret = -ENOMEM;
			goto deinit_info;
		}

		ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT);
		if (ret)
			goto deinit_info;
	}

	ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
					&pf->dplls.rclk.num_parents);
	if (ret)
		return ret;
	for (i = 0; i < pf->dplls.rclk.num_parents; i++)
		pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
	ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
	if (ret)
		return ret;
	de->mode = DPLL_MODE_AUTOMATIC;
	dp->mode = DPLL_MODE_AUTOMATIC;

	dev_dbg(ice_pf_to_dev(pf),
		"%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
		__func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);

	return 0;

deinit_info:
	dev_err(ice_pf_to_dev(pf),
		"%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
		__func__, d->inputs, de->input_prio,
		dp->input_prio, d->outputs);
	ice_dpll_deinit_info(pf);
	return ret;
}

/**
 * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
 * the dpll device.
 * @pf: board private structure
 *
 * Handles the cleanup work required after dpll initialization, freeing
 * resources and unregistering the dpll, pin and all resources used for
 * handling them.
 *
 * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
 */
void ice_dpll_deinit(struct ice_pf *pf)
{
	bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);

	clear_bit(ICE_FLAG_DPLL, pf->flags);
	if (cgu)
		ice_dpll_deinit_worker(pf);

	ice_dpll_deinit_pins(pf, cgu);
	ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
	ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
	ice_dpll_deinit_info(pf);
	mutex_destroy(&pf->dplls.lock);
}

/**
 * ice_dpll_init - initialize support for dpll subsystem
 * @pf: board private structure
 *
 * Set up the device dplls, register them and pins connected within Linux dpll
 * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
 * configuration requests.
 *
 * Context: Initializes pf->dplls.lock mutex.
 */
void ice_dpll_init(struct ice_pf *pf)
{
	bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
	struct ice_dplls *d = &pf->dplls;
	int err = 0;

	mutex_init(&d->lock);
	err = ice_dpll_init_info(pf, cgu);
	if (err)
		goto err_exit;
	err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
	if (err)
		goto deinit_info;
	err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
	if (err)
		goto deinit_eec;
	err = ice_dpll_init_pins(pf, cgu);
	if (err)
		goto deinit_pps;
	if (cgu) {
		err = ice_dpll_init_worker(pf);
		if (err)
			goto deinit_pins;
	}
	set_bit(ICE_FLAG_DPLL, pf->flags);

	return;

deinit_pins:
	ice_dpll_deinit_pins(pf, cgu);
deinit_pps:
	ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
deinit_eec:
	ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
deinit_info:
	ice_dpll_deinit_info(pf);
err_exit:
	mutex_destroy(&d->lock);
	dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
}
