Commit 65104599 authored by Arkadiusz Kubalewski's avatar Arkadiusz Kubalewski Committed by Tony Nguyen
Browse files

ice: fix max values for dpll pin phase adjust

Mask admin command returned max phase adjust value for both input and
output pins. Only 31 bits are relevant, last released data sheet wrongly
points that 32 bits are valid - see [1] 3.2.6.4.1 Get CCU Capabilities
Command for reference. Fix of the datasheet itself is in progress.

Fix the min/max assignment logic, previously the value was wrongly
considered as negative value due to most significant bit being set.

Example of previous broken behavior:
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml \
--do pin-get --json '{"id":1}'| grep phase-adjust
 'phase-adjust': 0,
 'phase-adjust-max': 16723,
 'phase-adjust-min': -16723,

Correct behavior with the fix:
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml \
--do pin-get --json '{"id":1}'| grep phase-adjust
 'phase-adjust': 0,
 'phase-adjust-max': 2147466925,
 'phase-adjust-min': -2147466925,

[1] https://cdrdv2.intel.com/v1/dl/getContent/613875?explicitVersion=true



Fixes: 90e1c907 ("ice: dpll: implement phase related callbacks")
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: default avatarArkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent fd48f071
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2264,6 +2264,8 @@ struct ice_aqc_get_pkg_info_resp {
	struct ice_aqc_get_pkg_info pkg_info[];
};

#define ICE_AQC_GET_CGU_MAX_PHASE_ADJ	GENMASK(30, 0)

/* Get CGU abilities command response data structure (indirect 0x0C61) */
struct ice_aqc_get_cgu_abilities {
	u8 num_inputs;
+23 −12
Original line number Diff line number Diff line
@@ -2064,6 +2064,18 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
	return 0;
}

/**
 * ice_dpll_phase_range_set - initialize phase adjust range helper
 * @range: pointer to phase adjust range struct to be initialized
 * @phase_adj: a value to be used as min(-)/max(+) boundary
 */
static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
				     u32 phase_adj)
{
	range->min = -phase_adj;
	range->max = phase_adj;
}

/**
 * ice_dpll_init_info_pins_generic - initializes generic pins info
 * @pf: board private structure
@@ -2105,8 +2117,8 @@ static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
	for (i = 0; i < pin_num; i++) {
		pins[i].idx = i;
		pins[i].prop.board_label = labels[i];
		pins[i].prop.phase_range.min = phase_adj_max;
		pins[i].prop.phase_range.max = -phase_adj_max;
		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
					 phase_adj_max);
		pins[i].prop.capabilities = cap;
		pins[i].pf = pf;
		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
@@ -2152,6 +2164,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
	struct ice_hw *hw = &pf->hw;
	struct ice_dpll_pin *pins;
	unsigned long caps;
	u32 phase_adj_max;
	u8 freq_supp_num;
	bool input;

@@ -2159,11 +2172,13 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
	case ICE_DPLL_PIN_TYPE_INPUT:
		pins = pf->dplls.inputs;
		num_pins = pf->dplls.num_inputs;
		phase_adj_max = pf->dplls.input_phase_adj_max;
		input = true;
		break;
	case ICE_DPLL_PIN_TYPE_OUTPUT:
		pins = pf->dplls.outputs;
		num_pins = pf->dplls.num_outputs;
		phase_adj_max = pf->dplls.output_phase_adj_max;
		input = false;
		break;
	default:
@@ -2188,19 +2203,13 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
				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;
		}
		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
					 phase_adj_max);
		pins[i].prop.capabilities = caps;
		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
		if (ret)
@@ -2308,8 +2317,10 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
	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);
	d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
	d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;

	alloc_size = sizeof(*d->inputs) * d->num_inputs;
	d->inputs = kzalloc(alloc_size, GFP_KERNEL);