From patchwork Tue Jul 2 13:41:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719667 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 668301B4C4B for ; Tue, 2 Jul 2024 13:44:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927901; cv=none; b=sv655MwNUA1TV7amuAVtBamtZU/Rwsimd+Ae96qrmfWJVfwH0qSlFSpbvH82Mw4Wpq47yjK6RXHpP1pEmdtkcojGHsE1RXlYq6WQ98k4pZgMz9i8dzALZOoTfIT1YyuBckKGxLSVWnJG/kRXx8vl6uANJDzZny+RBWo+V1yN4qQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927901; c=relaxed/simple; bh=Zoqb0wp7gLBUseSp+sNgDg0zZdEf4PQzXtJ3jWGe194=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MqSo8SXXxrecOa46HmTcB0+p4mE9pVC2lHA73uIU/g/IqNarLAa31C0HT/QlcwYflNuJW0R1jSQGEERULU+wlefhTbIGo+JOK8F4XIko6GN5vS4asq92BYAgDM31a1Bvu3g7PDDwTV7jgavxGVoTiWzyIQrRQ83mR+HtG4zJCus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=HRT8V2Vz; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="HRT8V2Vz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927899; x=1751463899; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Zoqb0wp7gLBUseSp+sNgDg0zZdEf4PQzXtJ3jWGe194=; b=HRT8V2VzZmSqOnMbiANHFIzum1VP2tF8yM+xclwo7aXScti6BvBut/CM rriHE8vpcpL0zZ2wkUUaaqvqiap5xHyGOkH4D4Pu6wNvAd3ETZYjiG+X5 an3L6QYSfCBhxam9568PgiTBoqDuCwjWr01dbQ01tG+73JmBc8FbpqtXB fGyQapvNc/hmNVAhxsBPViYdJxgFHk6zT+l5CKQuv87PYygfM/tKHeqQm izUfGZ7JJJlCRZbptRk9UqviePgwQ7+sgwBmeB1WnrGmEwjdgDh8qqZd/ E22wZRAI9av8+3KhF2vHxmS/KBO8+ekf3euqJejxv1xsT3K4xlBsFXUS1 g==; X-CSE-ConnectionGUID: ZOCtgHdqQAqtvUfV7Hjm3g== X-CSE-MsgGUID: w4ZQ1vLyQeOnCj9PmiLqtA== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826401" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826401" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:44:59 -0700 X-CSE-ConnectionGUID: 3dfK99JjR3i2GYx5V2QPVg== X-CSE-MsgGUID: 4CoOishVTj+9dGCpvfssqw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460501" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:44:57 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Karol Kolacinski , Arkadiusz Kubalewski Subject: [PATCH v2 iwl-next 1/7] ice: Implement ice_ptp_pin_desc Date: Tue, 2 Jul 2024 15:41:30 +0200 Message-ID: <20240702134448.132374-10-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Add a new internal structure describing PTP pins. Use the new structure for all non-E810T products. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: Removed unused err variable drivers/net/ethernet/intel/ice/ice_ptp.c | 270 +++++++++++++++-------- drivers/net/ethernet/intel/ice/ice_ptp.h | 65 ++++-- 2 files changed, 228 insertions(+), 107 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index b652a3e25619..030e55a39ef5 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -5,6 +5,30 @@ #include "ice_lib.h" #include "ice_trace.h" +static const char ice_pin_names[][64] = { + "SDP0", + "SDP1", + "SDP2", + "SDP3", + "TIME_SYNC", + "1PPS" +}; + +static const struct ice_ptp_pin_desc ice_pin_desc_e82x[] = { + /* name, gpio */ + { TIME_SYNC, { -1, 4 }}, + { ONE_PPS, { 5, -1 }}, +}; + +static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = { + /* name, gpio */ + { SDP0, { 0, 0 }}, + { SDP1, { 1, 1 }}, + { SDP2, { 2, 2 }}, + { SDP3, { 3, 3 }}, + { ONE_PPS, { 5, -1 }}, +}; + #define E810_OUT_PROP_DELAY_NS 1 static const struct ptp_pin_desc ice_pin_desc_e810t[] = { @@ -16,6 +40,29 @@ static const struct ptp_pin_desc ice_pin_desc_e810t[] = { { "U.FL2", UFL2, PTP_PF_NONE, 2, { 0, } }, }; +/** + * ice_ptp_find_pin_idx - Find pin index in ptp_pin_desc + * @pf: Board private structure + * @func: Pin function + * @chan: GPIO channel + * + * Return: positive pin number when pin is present, -1 otherwise + */ +static int ice_ptp_find_pin_idx(struct ice_pf *pf, enum ptp_pin_function func, + unsigned int chan) +{ + const struct ptp_clock_info *info = &pf->ptp.info; + int i; + + for (i = 0; i < info->n_pins; i++) { + if (info->pin_config[i].func == func && + info->pin_config[i].chan == chan) + return i; + } + + return -1; +} + /** * ice_get_sma_config_e810t * @hw: pointer to the hw struct @@ -1906,14 +1953,14 @@ static void ice_ptp_enable_all_clkout(struct ice_pf *pf) } /** - * ice_ptp_gpio_enable_e810 - Enable/disable ancillary features of PHC + * ice_ptp_gpio_enable_e810t - Enable/disable ancillary features of PHC * @info: the driver's PTP info structure * @rq: The requested feature to change * @on: Enable/disable flag */ static int -ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, - struct ptp_clock_request *rq, int on) +ice_ptp_gpio_enable_e810t(struct ptp_clock_info *info, + struct ptp_clock_request *rq, int on) { struct ice_pf *pf = ptp_info_to_pf(info); bool sma_pres = false; @@ -1936,22 +1983,18 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, clk_cfg.gpio_pin = GPIO_22; else return -1; - } else if (ice_is_e810t(&pf->hw)) { + } else { if (chan == 0) clk_cfg.gpio_pin = GPIO_20; else clk_cfg.gpio_pin = GPIO_22; - } else if (chan == PPS_CLK_GEN_CHAN) { - clk_cfg.gpio_pin = PPS_PIN_INDEX; - } else { - clk_cfg.gpio_pin = chan; } clk_cfg.flags = rq->perout.flags; - clk_cfg.period = ((rq->perout.period.sec * NSEC_PER_SEC) + - rq->perout.period.nsec); - clk_cfg.start_time = ((rq->perout.start.sec * NSEC_PER_SEC) + - rq->perout.start.nsec); + clk_cfg.period = rq->perout.period.sec * NSEC_PER_SEC + + rq->perout.period.nsec; + clk_cfg.start_time = rq->perout.start.sec * NSEC_PER_SEC + + rq->perout.start.nsec; clk_cfg.ena = !!on; return ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true); @@ -1966,13 +2009,11 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, gpio_pin = GPIO_21; else gpio_pin = GPIO_23; - } else if (ice_is_e810t(&pf->hw)) { + } else { if (chan == 0) gpio_pin = GPIO_21; else gpio_pin = GPIO_23; - } else { - gpio_pin = chan; } extts_cfg.flags = rq->extts.flags; @@ -1987,34 +2028,89 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, } /** - * ice_ptp_gpio_enable_e823 - Enable/disable ancillary features of PHC + * ice_verify_pin - verify if pin supports requested pin function * @info: the driver's PTP info structure + * @pin: Pin index + * @func: Assigned function + * @chan: Assigned channel + * + * Return: 0 on success, -EOPNOTSUPP when function is not supported. + */ +static int ice_verify_pin(struct ptp_clock_info *info, unsigned int pin, + enum ptp_pin_function func, unsigned int chan) +{ + struct ice_pf *pf = ptp_info_to_pf(info); + const struct ice_ptp_pin_desc *pin_desc; + + pin_desc = &pf->ptp.ice_pin_desc[pin]; + + /* Is assigned function allowed? */ + switch (func) { + case PTP_PF_EXTTS: + if (pin_desc->gpio[0] < 0) + return -EOPNOTSUPP; + break; + case PTP_PF_PEROUT: + if (pin_desc->gpio[1] < 0) + return -EOPNOTSUPP; + break; + case PTP_PF_NONE: + break; + case PTP_PF_PHYSYNC: + default: + return -EOPNOTSUPP; + } + + return 0; +} + +/** + * ice_ptp_gpio_enable - Enable/disable ancillary features of PHC + * @info: The driver's PTP info structure * @rq: The requested feature to change * @on: Enable/disable flag + * + * Return: 0 on success, -EOPNOTSUPP when request type is not supported */ -static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info, - struct ptp_clock_request *rq, int on) +static int ice_ptp_gpio_enable(struct ptp_clock_info *info, + struct ptp_clock_request *rq, int on) { struct ice_pf *pf = ptp_info_to_pf(info); switch (rq->type) { - case PTP_CLK_REQ_PPS: + case PTP_CLK_REQ_PEROUT: { - struct ice_perout_channel clk_cfg = {}; + struct ice_perout_channel clk_cfg; + int pin_desc_idx; + + pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT, + rq->perout.index); + if (pin_desc_idx < 0) + return -EIO; + clk_cfg.flags = rq->perout.flags; - clk_cfg.gpio_pin = PPS_PIN_INDEX; - clk_cfg.period = NSEC_PER_SEC; + clk_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[1]; + clk_cfg.period = rq->perout.period.sec * NSEC_PER_SEC + + rq->perout.period.nsec; + clk_cfg.start_time = rq->perout.start.sec * NSEC_PER_SEC + + rq->perout.start.nsec; clk_cfg.ena = !!on; - return ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true); + return ice_ptp_cfg_clkout(pf, rq->perout.index, &clk_cfg, true); } case PTP_CLK_REQ_EXTTS: { struct ice_extts_channel extts_cfg = {}; + int pin_desc_idx; + + pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, + rq->extts.index); + if (pin_desc_idx < 0) + return -EIO; extts_cfg.flags = rq->extts.flags; - extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX; + extts_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[0]; extts_cfg.ena = !!on; return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true); @@ -2409,6 +2505,40 @@ u64 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc, return ts_ns; } +/** + * ice_ptp_setup_pin_cfg - setup PTP pin_config structure + * @pf: Board private structure + */ +static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) +{ + uint extts_chans = 0; + uint po_chans = 0; + uint i; + + for (i = 0; i < pf->ptp.info.n_pins; i++) { + const struct ice_ptp_pin_desc *desc = &pf->ptp.ice_pin_desc[i]; + struct ptp_pin_desc *pin = &pf->ptp.pin_desc[i]; + const char *name = NULL; + + name = ice_pin_names[desc->name_idx]; + strscpy(pin->name, name, sizeof(pin->name)); + + pin->index = i; + if (desc->gpio[0] >= 0 && desc->gpio[1] < 0) { + pin->func = PTP_PF_EXTTS; + pin->chan = extts_chans++; + } else if (desc->gpio[1] >= 0 && desc->gpio[0] < 0) { + pin->func = PTP_PF_PEROUT; + pin->chan = po_chans++; + } else { + pin->func = PTP_PF_NONE; + pin->chan = 0; + } + } + + pf->ptp.info.pin_config = pf->ptp.pin_desc; +} + /** * ice_ptp_disable_sma_pins_e810t - Disable E810-T SMA pins * @pf: pointer to the PF structure @@ -2462,61 +2592,41 @@ ice_ptp_setup_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) } /** - * ice_ptp_setup_pins_e810 - Setup PTP pins in sysfs - * @pf: pointer to the PF instance - * @info: PTP clock capabilities - */ -static void -ice_ptp_setup_pins_e810(struct ice_pf *pf, struct ptp_clock_info *info) -{ - if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { - info->n_ext_ts = N_EXT_TS_E810; - info->n_per_out = N_PER_OUT_E810T; - info->n_pins = NUM_PTP_PINS_E810T; - info->verify = ice_verify_pin_e810t; - - /* Complete setup of the SMA pins */ - ice_ptp_setup_sma_pins_e810t(pf, info); - } else if (ice_is_e810t(&pf->hw)) { - info->n_ext_ts = N_EXT_TS_NO_SMA_E810T; - info->n_per_out = N_PER_OUT_NO_SMA_E810T; - } else { - info->n_per_out = N_PER_OUT_E810; - info->n_ext_ts = N_EXT_TS_E810; - } -} - -/** - * ice_ptp_setup_pins_e823 - Setup PTP pins in sysfs + * ice_ptp_setup_pins_e810t - Setup PTP pins in sysfs * @pf: pointer to the PF instance - * @info: PTP clock capabilities */ -static void -ice_ptp_setup_pins_e823(struct ice_pf *pf, struct ptp_clock_info *info) +static void ice_ptp_setup_pins_e810t(struct ice_pf *pf) { - info->pps = 1; - info->n_per_out = 0; - info->n_ext_ts = 1; + pf->ptp.info.enable = ice_ptp_gpio_enable_e810t; + pf->ptp.info.n_pins = NUM_PTP_PINS_E810T; + pf->ptp.info.verify = ice_verify_pin_e810t; + + /* Complete setup of the SMA pins */ + ice_ptp_setup_sma_pins_e810t(pf, &pf->ptp.info); } /** - * ice_ptp_set_funcs_e82x - Set specialized functions for E82x support + * ice_ptp_set_funcs_e82x - Set specialized functions for E82X support * @pf: Board private structure - * @info: PTP info to fill * - * Assign functions to the PTP capabiltiies structure for E82x devices. + * Assign functions to the PTP capabilities structure for E82X devices. * Functions which operate across all device families should be set directly - * in ice_ptp_set_caps. Only add functions here which are distinct for E82x + * in ice_ptp_set_caps. Only add functions here which are distinct for E82X * devices. */ -static void -ice_ptp_set_funcs_e82x(struct ice_pf *pf, struct ptp_clock_info *info) +static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) { #ifdef CONFIG_ICE_HWTS if (boot_cpu_has(X86_FEATURE_ART) && boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) - info->getcrosststamp = ice_ptp_getcrosststamp_e82x; + pf->ptp.info.getcrosststamp = ice_ptp_getcrosststamp_e82x; + #endif /* CONFIG_ICE_HWTS */ + pf->ptp.info.enable = ice_ptp_gpio_enable; + pf->ptp.info.verify = ice_verify_pin; + pf->ptp.ice_pin_desc = ice_pin_desc_e82x; + pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x); + ice_ptp_setup_pin_cfg(pf); } /** @@ -2532,27 +2642,15 @@ ice_ptp_set_funcs_e82x(struct ice_pf *pf, struct ptp_clock_info *info) static void ice_ptp_set_funcs_e810(struct ice_pf *pf, struct ptp_clock_info *info) { - info->enable = ice_ptp_gpio_enable_e810; - ice_ptp_setup_pins_e810(pf, info); -} - -/** - * ice_ptp_set_funcs_e823 - Set specialized functions for E823 support - * @pf: Board private structure - * @info: PTP info to fill - * - * Assign functions to the PTP capabiltiies structure for E823 devices. - * Functions which operate across all device families should be set directly - * in ice_ptp_set_caps. Only add functions here which are distinct for e823 - * devices. - */ -static void -ice_ptp_set_funcs_e823(struct ice_pf *pf, struct ptp_clock_info *info) -{ - ice_ptp_set_funcs_e82x(pf, info); + if (ice_is_e810t(&pf->hw) && + ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { + ice_ptp_setup_pins_e810t(pf); + return; + } - info->enable = ice_ptp_gpio_enable_e823; - ice_ptp_setup_pins_e823(pf, info); + pf->ptp.ice_pin_desc = ice_pin_desc_e810; + pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810); + ice_ptp_setup_pin_cfg(pf); } /** @@ -2572,13 +2670,13 @@ static void ice_ptp_set_caps(struct ice_pf *pf) info->adjfine = ice_ptp_adjfine; info->gettimex64 = ice_ptp_gettimex64; info->settime64 = ice_ptp_settime64; + info->n_per_out = GLTSYN_TGT_H_IDX_MAX; + info->n_ext_ts = GLTSYN_EVNT_H_IDX_MAX; if (ice_is_e810(&pf->hw)) ice_ptp_set_funcs_e810(pf, info); - else if (ice_is_e823(&pf->hw)) - ice_ptp_set_funcs_e823(pf, info); else - ice_ptp_set_funcs_e82x(pf, info); + ice_ptp_set_funcs_e82x(pf); } /** diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 1d87dd67284d..982769dba832 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -221,6 +221,46 @@ enum ice_ptp_state { ICE_PTP_ERROR, }; +enum ice_ptp_pin { + SDP0 = 0, + SDP1, + SDP2, + SDP3, + TIME_SYNC, + ONE_PPS +}; + +/* Per-channel register definitions */ +#define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8)) +#define GLTSYN_AUX_IN(_chan, _idx) (GLTSYN_AUX_IN_0(_idx) + ((_chan) * 8)) +#define GLTSYN_CLKO(_chan, _idx) (GLTSYN_CLKO_0(_idx) + ((_chan) * 8)) +#define GLTSYN_TGT_L(_chan, _idx) (GLTSYN_TGT_L_0(_idx) + ((_chan) * 16)) +#define GLTSYN_TGT_H(_chan, _idx) (GLTSYN_TGT_H_0(_idx) + ((_chan) * 16)) +#define GLTSYN_EVNT_L(_chan, _idx) (GLTSYN_EVNT_L_0(_idx) + ((_chan) * 16)) +#define GLTSYN_EVNT_H(_chan, _idx) (GLTSYN_EVNT_H_0(_idx) + ((_chan) * 16)) +#define GLTSYN_EVNT_H_IDX_MAX 3 + +/* Pin definitions for PTP */ +#define PPS_CLK_GEN_CHAN 3 +#define PPS_PIN_INDEX 5 +#define ICE_N_PINS_MAX 6 +#define ICE_PIN_DESC_ARR_LEN(_arr) (sizeof(_arr) / \ + sizeof(struct ice_ptp_pin_desc)) + +/** + * struct ice_ptp_pin_desc - hardware pin description data + * @name_idx: index of the name of pin in ice_pin_names + * @gpio: the associated GPIO input and output pins + * + * Structure describing a PTP-capable GPIO pin that extends ptp_pin_desc array + * for the device. Device families have separate sets of available pins with + * varying restrictions. + */ +struct ice_ptp_pin_desc { + int name_idx; + int gpio[2]; +}; + /** * struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK * @state: current state of PTP state machine @@ -232,6 +272,8 @@ enum ice_ptp_state { * @cached_phc_jiffies: jiffies when cached_phc_time was last updated * @ext_ts_chan: the external timestamp channel in use * @ext_ts_irq: the external timestamp IRQ in use + * @pin_desc: structure defining pins + * @ice_pin_desc: internal structure describing pin relations * @kworker: kwork thread for handling periodic work * @perout_channels: periodic output data * @extts_channels: channels for external timestamps @@ -257,6 +299,8 @@ struct ice_ptp { u8 ext_ts_chan; u8 ext_ts_irq; struct kthread_worker *kworker; + struct ptp_pin_desc pin_desc[ICE_N_PINS_MAX]; + const struct ice_ptp_pin_desc *ice_pin_desc; struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX]; struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX]; struct ptp_clock_info info; @@ -290,27 +334,6 @@ struct ice_ptp { #define FIFO_EMPTY BIT(2) #define FIFO_OK 0xFF #define ICE_PTP_FIFO_NUM_CHECKS 5 -/* Per-channel register definitions */ -#define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8)) -#define GLTSYN_AUX_IN(_chan, _idx) (GLTSYN_AUX_IN_0(_idx) + ((_chan) * 8)) -#define GLTSYN_CLKO(_chan, _idx) (GLTSYN_CLKO_0(_idx) + ((_chan) * 8)) -#define GLTSYN_TGT_L(_chan, _idx) (GLTSYN_TGT_L_0(_idx) + ((_chan) * 16)) -#define GLTSYN_TGT_H(_chan, _idx) (GLTSYN_TGT_H_0(_idx) + ((_chan) * 16)) -#define GLTSYN_EVNT_L(_chan, _idx) (GLTSYN_EVNT_L_0(_idx) + ((_chan) * 16)) -#define GLTSYN_EVNT_H(_chan, _idx) (GLTSYN_EVNT_H_0(_idx) + ((_chan) * 16)) -#define GLTSYN_EVNT_H_IDX_MAX 3 - -/* Pin definitions for PTP PPS out */ -#define PPS_CLK_GEN_CHAN 3 -#define PPS_CLK_SRC_CHAN 2 -#define PPS_PIN_INDEX 5 -#define TIME_SYNC_PIN_INDEX 4 -#define N_EXT_TS_E810 3 -#define N_PER_OUT_E810 4 -#define N_PER_OUT_E810T 3 -#define N_PER_OUT_NO_SMA_E810T 2 -#define N_EXT_TS_NO_SMA_E810T 2 -#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4)) #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) int ice_ptp_clock_index(struct ice_pf *pf); From patchwork Tue Jul 2 13:41:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719668 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 462561B4C41 for ; Tue, 2 Jul 2024 13:45:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927902; cv=none; b=D4/wOZI5n1we38Bv4Y4R9fZ4qU1166Ffbpr5PFpKMNMZl1zLnNh8AHd+NVwEENLmHZLEgObUR1qBFTqgYSgjOAP5o15x6rl7v83qlxErZtf4k2M8FC7xoMPd1qo8N/fpXkJw11+6J7cT+zvHGma7wF4sRhKh7PMmgoZhwGehbEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927902; c=relaxed/simple; bh=TksVP2DYBRUrQNbmSt8x5N5u/CVzkVSpIvGDTb+oyQ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l8wqCm/4it5LMnbTQmxZZsOH1nOADWxKaRe6eot1/sXDOmTlFQ4918zeKqqTlazp7bQAqZarYUiv13zn/ikQNgUfuyeG3e9JEoJtBY+hKVQUEGP/2pAw6R6VMxBGDp0vrqiaJupL/8RfqcovuHgMRpbxoXWjEGoe+g+ddeXrnqQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FH0feRO6; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FH0feRO6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927901; x=1751463901; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TksVP2DYBRUrQNbmSt8x5N5u/CVzkVSpIvGDTb+oyQ8=; b=FH0feRO671lLZn7jc6vG9/1ybRnJgTiH31u0YR7zqv8bLJy9x/BAp5Nx hRFrXx84j6FhEbCvp3p+JN83fqYyBGPZLgKMYE3eL0XYklBQ9ic1lALvS 7dz4xMoq4dF6AQY9VpjkrpwbA5uZcL7wPcFAxVc4hOObn7cqlO6nZTgZ6 CuB/n3dhLoeqndvX+vOZAKvsH48mEH0uD0EMW48f9fVMh/DI+S3ltywXV D/nZ+wItj0A0Q1Pbh/kLSW7VvrlQTrJYNcEXNDxeurLPT+hZxV3epipO0 6s31jDSXPbUbn2yMgJUmuVKgdTbSOclSJw4g/tVX1fwphr6l+cpIYFWEA Q==; X-CSE-ConnectionGUID: c78jD229Sf2XRj339Pwn4g== X-CSE-MsgGUID: IyVUD4QgSsirvhaJ8QqU7g== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826407" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826407" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:01 -0700 X-CSE-ConnectionGUID: RMd3SVy+SjKZ3rnfDiU2FQ== X-CSE-MsgGUID: /MhW94SjQqGuI49TpXZCMQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460512" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:44:59 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Karol Kolacinski , Arkadiusz Kubalewski Subject: [PATCH v2 iwl-next 2/7] ice: Add SDPs support for E825C Date: Tue, 2 Jul 2024 15:41:31 +0200 Message-ID: <20240702134448.132374-11-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Add support of PTP SDPs (Software Definable Pins) for E825C products. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: Removed redundant n_pins assignment and enable and verify move drivers/net/ethernet/intel/ice/ice_ptp.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 030e55a39ef5..392b0d2fa61f 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -20,6 +20,16 @@ static const struct ice_ptp_pin_desc ice_pin_desc_e82x[] = { { ONE_PPS, { 5, -1 }}, }; +static const struct ice_ptp_pin_desc ice_pin_desc_e825c[] = { + /* name, gpio */ + { SDP0, { 0, 0 }}, + { SDP1, { 1, 1 }}, + { SDP2, { 2, 2 }}, + { SDP3, { 3, 3 }}, + { TIME_SYNC, { -1, 4 }}, + { ONE_PPS, { 5, -1 }}, +}; + static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = { /* name, gpio */ { SDP0, { 0, 0 }}, @@ -2624,8 +2634,14 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) #endif /* CONFIG_ICE_HWTS */ pf->ptp.info.enable = ice_ptp_gpio_enable; pf->ptp.info.verify = ice_verify_pin; - pf->ptp.ice_pin_desc = ice_pin_desc_e82x; - pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x); + + if (ice_is_e825c(&pf->hw)) { + pf->ptp.ice_pin_desc = ice_pin_desc_e825c; + pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e825c); + } else { + pf->ptp.ice_pin_desc = ice_pin_desc_e82x; + pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x); + } ice_ptp_setup_pin_cfg(pf); } From patchwork Tue Jul 2 13:41:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719669 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF92B1B4C31 for ; Tue, 2 Jul 2024 13:45:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927906; cv=none; b=megdYpOVOR+CxgZ7zozAk9pp6BNtuxfzQj9Rjaci0oiCJWUtB9bwDgjOHkXBcstZSy9SAQPGmUt9ly1w6RTCTwxN/EGJZlZ0uvyQWMZrbozkGF2DaCP7D3JRZfY890p/5vJwou+wa5p6Gdmh87HajK5Ley4g9EfTU5J1HjeJiHw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927906; c=relaxed/simple; bh=YA0oPsE119IIkMJUVxvXaGmH7u+9CAMmLUnnzRjy9So=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fqsEjuGUlsSTpSGmL7MvTUUejpQn1di4D/JB8GqwmipM4Ucm9NZGcXmlITFIrMhgtWlvJXsItagtmcxrsPwfpl7ziJaN6hkmgMYHMC5uk0WCezyt+No5hyd+RMl8GegJ+JOXIVsFmQV+MoevY3UrPAuiRDD2ZVurex7CdAu1fdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=GRfTDHtY; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="GRfTDHtY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927904; x=1751463904; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YA0oPsE119IIkMJUVxvXaGmH7u+9CAMmLUnnzRjy9So=; b=GRfTDHtYDLVAF1mA6oCyD+pe8xJ/CNLh5TSnJ3XpOjqal8CbtJ5EMUNt hbIQtZIEWpGztacybonngmIZvIkc8ou3rgqsQtcu7PRcDXgcL8vBDQKF4 PdWHKWtsDXv1oiitIsRjvaf/hpY/d4/01hwpAe1sYIZjeMjWaDK4YAcnv 8xpdkgdNNqKhasFO7EnaK0EQJs7bFAXUiVPk1iFmUVX/MtazVjOSiVohl T3l9CA78BwDozLpILw+DdlC+iw+AUUUrYF1ydpc5tNqk3MCfn59z5YSpA NwQ9kajhiXphM3sFz5BBNzqcws8GtUzYiFB9G6EhBw048Zgf6af+4UTbb g==; X-CSE-ConnectionGUID: zgylLTvFQAahpVJBa3jSOQ== X-CSE-MsgGUID: UzCB+oNaT3uUn08mQr784Q== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826414" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826414" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:03 -0700 X-CSE-ConnectionGUID: jrhg7T+OQBuZzVYolNPf4Q== X-CSE-MsgGUID: Flsl7d/aRQWDjgmPRHePTA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460537" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:45:01 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Karol Kolacinski , Arkadiusz Kubalewski Subject: [PATCH v2 iwl-next 3/7] ice: Align E810T GPIO to other products Date: Tue, 2 Jul 2024 15:41:32 +0200 Message-ID: <20240702134448.132374-12-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Instead of having separate PTP GPIO implementation for E810T, use existing one from all other products. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: restored blank line and moved enable and verify assignment drivers/net/ethernet/intel/ice/ice_gnss.c | 4 +- drivers/net/ethernet/intel/ice/ice_ptp.c | 464 +++++--------------- drivers/net/ethernet/intel/ice/ice_ptp.h | 29 +- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 20 +- drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 43 +- 5 files changed, 155 insertions(+), 405 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c index c8ea1af51ad3..f02e8ca55375 100644 --- a/drivers/net/ethernet/intel/ice/ice_gnss.c +++ b/drivers/net/ethernet/intel/ice/ice_gnss.c @@ -397,8 +397,8 @@ bool ice_gnss_is_gps_present(struct ice_hw *hw) int err; u8 data; - err = ice_read_pca9575_reg_e810t(hw, ICE_PCA9575_P0_IN, &data); - if (err || !!(data & ICE_E810T_P0_GNSS_PRSNT_N)) + err = ice_read_pca9575_reg(hw, ICE_PCA9575_P0_IN, &data); + if (err || !!(data & ICE_P0_GNSS_PRSNT_N)) return false; } else { return false; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 392b0d2fa61f..df0ae9faf948 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -39,15 +39,21 @@ static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = { { ONE_PPS, { 5, -1 }}, }; -#define E810_OUT_PROP_DELAY_NS 1 - -static const struct ptp_pin_desc ice_pin_desc_e810t[] = { - /* name idx func chan */ - { "GNSS", GNSS, PTP_PF_EXTTS, 0, { 0, } }, - { "SMA1", SMA1, PTP_PF_NONE, 1, { 0, } }, - { "U.FL1", UFL1, PTP_PF_NONE, 1, { 0, } }, - { "SMA2", SMA2, PTP_PF_NONE, 2, { 0, } }, - { "U.FL2", UFL2, PTP_PF_NONE, 2, { 0, } }, +static const char ice_pin_names_e810t[][64] = { + "GNSS", + "SMA1", + "U.FL1", + "SMA2", + "U.FL2", +}; + +static const struct ice_ptp_pin_desc ice_pin_desc_e810t[] = { + /* name, gpio */ + { GNSS, { -1, 1 }}, + { SMA1, { 0, 1 }}, + { UFL1, { 0, -1 }}, + { SMA2, { 2, 3 }}, + { UFL2, { -1, 3 }}, }; /** @@ -74,240 +80,98 @@ static int ice_ptp_find_pin_idx(struct ice_pf *pf, enum ptp_pin_function func, } /** - * ice_get_sma_config_e810t - * @hw: pointer to the hw struct - * @ptp_pins: pointer to the ptp_pin_desc struture - * - * Read the configuration of the SMA control logic and put it into the - * ptp_pin_desc structure + * ice_ptp_update_sma_data - update SMA pins data according to pins setup + * @pf: Board private structure + * @sma_pins: parsed SMA pins status + * @data: SMA data to update */ -static int -ice_get_sma_config_e810t(struct ice_hw *hw, struct ptp_pin_desc *ptp_pins) +static void ice_ptp_update_sma_data(struct ice_pf *pf, uint sma_pins[], + u8 *data) { - u8 data, i; - int status; + const char *state1, *state2; - /* Read initial pin state */ - status = ice_read_sma_ctrl_e810t(hw, &data); - if (status) - return status; - - /* initialize with defaults */ - for (i = 0; i < NUM_PTP_PINS_E810T; i++) { - strscpy(ptp_pins[i].name, ice_pin_desc_e810t[i].name, - sizeof(ptp_pins[i].name)); - ptp_pins[i].index = ice_pin_desc_e810t[i].index; - ptp_pins[i].func = ice_pin_desc_e810t[i].func; - ptp_pins[i].chan = ice_pin_desc_e810t[i].chan; - } - - /* Parse SMA1/UFL1 */ - switch (data & ICE_SMA1_MASK_E810T) { - case ICE_SMA1_MASK_E810T: - default: - ptp_pins[SMA1].func = PTP_PF_NONE; - ptp_pins[UFL1].func = PTP_PF_NONE; - break; - case ICE_SMA1_DIR_EN_E810T: - ptp_pins[SMA1].func = PTP_PF_PEROUT; - ptp_pins[UFL1].func = PTP_PF_NONE; - break; - case ICE_SMA1_TX_EN_E810T: - ptp_pins[SMA1].func = PTP_PF_EXTTS; - ptp_pins[UFL1].func = PTP_PF_NONE; - break; - case 0: - ptp_pins[SMA1].func = PTP_PF_EXTTS; - ptp_pins[UFL1].func = PTP_PF_PEROUT; - break; + /* Set the right state based on the desired configuration. + * When bit is set, functionality is disabled. + */ + *data &= ~ICE_ALL_SMA_MASK; + if (!sma_pins[UFL1 - 1]) { + if (sma_pins[SMA1 - 1] == PTP_PF_EXTTS) { + state1 = "SMA1 Rx, U.FL1 disabled"; + *data |= ICE_SMA1_TX_EN; + } else if (sma_pins[SMA1 - 1] == PTP_PF_PEROUT) { + state1 = "SMA1 Tx U.FL1 disabled"; + *data |= ICE_SMA1_DIR_EN; + } else { + state1 = "SMA1 disabled, U.FL1 disabled"; + *data |= ICE_SMA1_MASK; + } + } else { + /* U.FL1 Tx will always enable SMA1 Rx */ + state1 = "SMA1 Rx, U.FL1 Tx"; } - /* Parse SMA2/UFL2 */ - switch (data & ICE_SMA2_MASK_E810T) { - case ICE_SMA2_MASK_E810T: - default: - ptp_pins[SMA2].func = PTP_PF_NONE; - ptp_pins[UFL2].func = PTP_PF_NONE; - break; - case (ICE_SMA2_TX_EN_E810T | ICE_SMA2_UFL2_RX_DIS_E810T): - ptp_pins[SMA2].func = PTP_PF_EXTTS; - ptp_pins[UFL2].func = PTP_PF_NONE; - break; - case (ICE_SMA2_DIR_EN_E810T | ICE_SMA2_UFL2_RX_DIS_E810T): - ptp_pins[SMA2].func = PTP_PF_PEROUT; - ptp_pins[UFL2].func = PTP_PF_NONE; - break; - case (ICE_SMA2_DIR_EN_E810T | ICE_SMA2_TX_EN_E810T): - ptp_pins[SMA2].func = PTP_PF_NONE; - ptp_pins[UFL2].func = PTP_PF_EXTTS; - break; - case ICE_SMA2_DIR_EN_E810T: - ptp_pins[SMA2].func = PTP_PF_PEROUT; - ptp_pins[UFL2].func = PTP_PF_EXTTS; - break; + if (!sma_pins[UFL2 - 1]) { + if (sma_pins[SMA2 - 1] == PTP_PF_EXTTS) { + state2 = "SMA2 Rx, U.FL2 disabled"; + *data |= ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS; + } else if (sma_pins[SMA2 - 1] == PTP_PF_PEROUT) { + state2 = "SMA2 Tx, U.FL2 disabled"; + *data |= ICE_SMA2_DIR_EN | ICE_SMA2_UFL2_RX_DIS; + } else { + state2 = "SMA2 disabled, U.FL2 disabled"; + *data |= ICE_SMA2_MASK; + } + } else { + if (!sma_pins[SMA2 - 1]) { + state2 = "SMA2 disabled, U.FL2 Rx"; + *data |= ICE_SMA2_DIR_EN | ICE_SMA2_TX_EN; + } else { + state2 = "SMA2 Tx, U.FL2 Rx"; + *data |= ICE_SMA2_DIR_EN; + } } - return 0; + dev_dbg(ice_pf_to_dev(pf), "%s, %s\n", state1, state2); } /** - * ice_ptp_set_sma_config_e810t - * @hw: pointer to the hw struct - * @ptp_pins: pointer to the ptp_pin_desc struture + * ice_ptp_set_sma_cfg - set the configuration of the SMA control logic + * @pf: Board private structure * - * Set the configuration of the SMA control logic based on the configuration in - * num_pins parameter + * Return: 0 on success, negative error code otherwise */ -static int -ice_ptp_set_sma_config_e810t(struct ice_hw *hw, - const struct ptp_pin_desc *ptp_pins) +static int ice_ptp_set_sma_cfg(struct ice_pf *pf) { - int status; + const struct ice_ptp_pin_desc *ice_pins = pf->ptp.ice_pin_desc; + struct ptp_pin_desc *pins = pf->ptp.pin_desc; + uint sma_pins[ICE_SMA_PINS_NUM] = {}; + int err; u8 data; - /* SMA1 and UFL1 cannot be set to TX at the same time */ - if (ptp_pins[SMA1].func == PTP_PF_PEROUT && - ptp_pins[UFL1].func == PTP_PF_PEROUT) - return -EINVAL; - - /* SMA2 and UFL2 cannot be set to RX at the same time */ - if (ptp_pins[SMA2].func == PTP_PF_EXTTS && - ptp_pins[UFL2].func == PTP_PF_EXTTS) - return -EINVAL; - /* Read initial pin state value */ - status = ice_read_sma_ctrl_e810t(hw, &data); - if (status) - return status; - - /* Set the right sate based on the desired configuration */ - data &= ~ICE_SMA1_MASK_E810T; - if (ptp_pins[SMA1].func == PTP_PF_NONE && - ptp_pins[UFL1].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA1 + U.FL1 disabled"); - data |= ICE_SMA1_MASK_E810T; - } else if (ptp_pins[SMA1].func == PTP_PF_EXTTS && - ptp_pins[UFL1].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA1 RX"); - data |= ICE_SMA1_TX_EN_E810T; - } else if (ptp_pins[SMA1].func == PTP_PF_NONE && - ptp_pins[UFL1].func == PTP_PF_PEROUT) { - /* U.FL 1 TX will always enable SMA 1 RX */ - dev_info(ice_hw_to_dev(hw), "SMA1 RX + U.FL1 TX"); - } else if (ptp_pins[SMA1].func == PTP_PF_EXTTS && - ptp_pins[UFL1].func == PTP_PF_PEROUT) { - dev_info(ice_hw_to_dev(hw), "SMA1 RX + U.FL1 TX"); - } else if (ptp_pins[SMA1].func == PTP_PF_PEROUT && - ptp_pins[UFL1].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA1 TX"); - data |= ICE_SMA1_DIR_EN_E810T; - } - - data &= ~ICE_SMA2_MASK_E810T; - if (ptp_pins[SMA2].func == PTP_PF_NONE && - ptp_pins[UFL2].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA2 + U.FL2 disabled"); - data |= ICE_SMA2_MASK_E810T; - } else if (ptp_pins[SMA2].func == PTP_PF_EXTTS && - ptp_pins[UFL2].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA2 RX"); - data |= (ICE_SMA2_TX_EN_E810T | - ICE_SMA2_UFL2_RX_DIS_E810T); - } else if (ptp_pins[SMA2].func == PTP_PF_NONE && - ptp_pins[UFL2].func == PTP_PF_EXTTS) { - dev_info(ice_hw_to_dev(hw), "UFL2 RX"); - data |= (ICE_SMA2_DIR_EN_E810T | ICE_SMA2_TX_EN_E810T); - } else if (ptp_pins[SMA2].func == PTP_PF_PEROUT && - ptp_pins[UFL2].func == PTP_PF_NONE) { - dev_info(ice_hw_to_dev(hw), "SMA2 TX"); - data |= (ICE_SMA2_DIR_EN_E810T | - ICE_SMA2_UFL2_RX_DIS_E810T); - } else if (ptp_pins[SMA2].func == PTP_PF_PEROUT && - ptp_pins[UFL2].func == PTP_PF_EXTTS) { - dev_info(ice_hw_to_dev(hw), "SMA2 TX + U.FL2 RX"); - data |= ICE_SMA2_DIR_EN_E810T; - } - - return ice_write_sma_ctrl_e810t(hw, data); -} - -/** - * ice_ptp_set_sma_e810t - * @info: the driver's PTP info structure - * @pin: pin index in kernel structure - * @func: Pin function to be set (PTP_PF_NONE, PTP_PF_EXTTS or PTP_PF_PEROUT) - * - * Set the configuration of a single SMA pin - */ -static int -ice_ptp_set_sma_e810t(struct ptp_clock_info *info, unsigned int pin, - enum ptp_pin_function func) -{ - struct ptp_pin_desc ptp_pins[NUM_PTP_PINS_E810T]; - struct ice_pf *pf = ptp_info_to_pf(info); - struct ice_hw *hw = &pf->hw; - int err; - - if (pin < SMA1 || func > PTP_PF_PEROUT) - return -EOPNOTSUPP; - - err = ice_get_sma_config_e810t(hw, ptp_pins); + err = ice_read_sma_ctrl(&pf->hw, &data); if (err) return err; - /* Disable the same function on the other pin sharing the channel */ - if (pin == SMA1 && ptp_pins[UFL1].func == func) - ptp_pins[UFL1].func = PTP_PF_NONE; - if (pin == UFL1 && ptp_pins[SMA1].func == func) - ptp_pins[SMA1].func = PTP_PF_NONE; - - if (pin == SMA2 && ptp_pins[UFL2].func == func) - ptp_pins[UFL2].func = PTP_PF_NONE; - if (pin == UFL2 && ptp_pins[SMA2].func == func) - ptp_pins[SMA2].func = PTP_PF_NONE; - - /* Set up new pin function in the temp table */ - ptp_pins[pin].func = func; - - return ice_ptp_set_sma_config_e810t(hw, ptp_pins); -} - -/** - * ice_verify_pin_e810t - * @info: the driver's PTP info structure - * @pin: Pin index - * @func: Assigned function - * @chan: Assigned channel - * - * Verify if pin supports requested pin function. If the Check pins consistency. - * Reconfigure the SMA logic attached to the given pin to enable its - * desired functionality - */ -static int -ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin, - enum ptp_pin_function func, unsigned int chan) -{ - /* Don't allow channel reassignment */ - if (chan != ice_pin_desc_e810t[pin].chan) - return -EOPNOTSUPP; - - /* Check if functions are properly assigned */ - switch (func) { - case PTP_PF_NONE: - break; - case PTP_PF_EXTTS: - if (pin == UFL1) - return -EOPNOTSUPP; - break; - case PTP_PF_PEROUT: - if (pin == UFL2 || pin == GNSS) - return -EOPNOTSUPP; - break; - case PTP_PF_PHYSYNC: - return -EOPNOTSUPP; - } + /* Get SMA/U.FL pins states */ + for (int i = 0; i < pf->ptp.info.n_pins; i++) + if (pins[i].func) { + int name_idx = ice_pins[i].name_idx; + + switch (name_idx) { + case SMA1: + case UFL1: + case SMA2: + case UFL2: + sma_pins[name_idx - 1] = pins[i].func; + break; + default: + continue; + } + } - return ice_ptp_set_sma_e810t(info, pin, func); + ice_ptp_update_sma_data(pf, sma_pins, &data); + return ice_write_sma_ctrl(&pf->hw, data); } /** @@ -1962,81 +1826,6 @@ static void ice_ptp_enable_all_clkout(struct ice_pf *pf) false); } -/** - * ice_ptp_gpio_enable_e810t - Enable/disable ancillary features of PHC - * @info: the driver's PTP info structure - * @rq: The requested feature to change - * @on: Enable/disable flag - */ -static int -ice_ptp_gpio_enable_e810t(struct ptp_clock_info *info, - struct ptp_clock_request *rq, int on) -{ - struct ice_pf *pf = ptp_info_to_pf(info); - bool sma_pres = false; - unsigned int chan; - u32 gpio_pin; - - if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) - sma_pres = true; - - switch (rq->type) { - case PTP_CLK_REQ_PEROUT: - { - struct ice_perout_channel clk_cfg = {}; - - chan = rq->perout.index; - if (sma_pres) { - if (chan == ice_pin_desc_e810t[SMA1].chan) - clk_cfg.gpio_pin = GPIO_20; - else if (chan == ice_pin_desc_e810t[SMA2].chan) - clk_cfg.gpio_pin = GPIO_22; - else - return -1; - } else { - if (chan == 0) - clk_cfg.gpio_pin = GPIO_20; - else - clk_cfg.gpio_pin = GPIO_22; - } - - clk_cfg.flags = rq->perout.flags; - clk_cfg.period = rq->perout.period.sec * NSEC_PER_SEC + - rq->perout.period.nsec; - clk_cfg.start_time = rq->perout.start.sec * NSEC_PER_SEC + - rq->perout.start.nsec; - clk_cfg.ena = !!on; - - return ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true); - } - case PTP_CLK_REQ_EXTTS: - { - struct ice_extts_channel extts_cfg = {}; - - chan = rq->extts.index; - if (sma_pres) { - if (chan < ice_pin_desc_e810t[SMA2].chan) - gpio_pin = GPIO_21; - else - gpio_pin = GPIO_23; - } else { - if (chan == 0) - gpio_pin = GPIO_21; - else - gpio_pin = GPIO_23; - } - - extts_cfg.flags = rq->extts.flags; - extts_cfg.gpio_pin = gpio_pin; - extts_cfg.ena = !!on; - - return ice_ptp_cfg_extts(pf, chan, &extts_cfg, true); - } - default: - return -EOPNOTSUPP; - } -} - /** * ice_verify_pin - verify if pin supports requested pin function * @info: the driver's PTP info structure @@ -2530,8 +2319,12 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) struct ptp_pin_desc *pin = &pf->ptp.pin_desc[i]; const char *name = NULL; - name = ice_pin_names[desc->name_idx]; - strscpy(pin->name, name, sizeof(pin->name)); + if (!ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) + name = ice_pin_names[desc->name_idx]; + else + name = ice_pin_names_e810t[desc->name_idx]; + if (name) + strscpy(pin->name, name, sizeof(pin->name)); pin->index = i; if (desc->gpio[0] >= 0 && desc->gpio[1] < 0) { @@ -2550,20 +2343,17 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) } /** - * ice_ptp_disable_sma_pins_e810t - Disable E810-T SMA pins + * ice_ptp_disable_sma_pins - Disable SMA pins * @pf: pointer to the PF structure - * @info: PTP clock info structure * * Disable the OS access to the SMA pins. Called to clear out the OS - * indications of pin support when we fail to setup the E810-T SMA control - * register. + * indications of pin support when we fail to setup the SMA control register. */ -static void -ice_ptp_disable_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) +static void ice_ptp_disable_sma_pins(struct ice_pf *pf) { - struct device *dev = ice_pf_to_dev(pf); + struct ptp_clock_info *info = &pf->ptp.info; - dev_warn(dev, "Failed to configure E810-T SMA pin control\n"); + dev_warn(ice_pf_to_dev(pf), "Failed to configure SMA pin control\n"); info->enable = NULL; info->verify = NULL; @@ -2572,47 +2362,24 @@ ice_ptp_disable_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) info->n_per_out = 0; } -/** - * ice_ptp_setup_sma_pins_e810t - Setup the SMA pins - * @pf: pointer to the PF structure - * @info: PTP clock info structure - * - * Finish setting up the SMA pins by allocating pin_config, and setting it up - * according to the current status of the SMA. On failure, disable all of the - * extended SMA pin support. - */ -static void -ice_ptp_setup_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) -{ - struct device *dev = ice_pf_to_dev(pf); - int err; - - /* Allocate memory for kernel pins interface */ - info->pin_config = devm_kcalloc(dev, info->n_pins, - sizeof(*info->pin_config), GFP_KERNEL); - if (!info->pin_config) { - ice_ptp_disable_sma_pins_e810t(pf, info); - return; - } - - /* Read current SMA status */ - err = ice_get_sma_config_e810t(&pf->hw, info->pin_config); - if (err) - ice_ptp_disable_sma_pins_e810t(pf, info); -} - /** * ice_ptp_setup_pins_e810t - Setup PTP pins in sysfs * @pf: pointer to the PF instance */ static void ice_ptp_setup_pins_e810t(struct ice_pf *pf) { - pf->ptp.info.enable = ice_ptp_gpio_enable_e810t; - pf->ptp.info.n_pins = NUM_PTP_PINS_E810T; - pf->ptp.info.verify = ice_verify_pin_e810t; + struct ice_ptp *ptp = &pf->ptp; + int err; + + ptp->ice_pin_desc = ice_pin_desc_e810t; + ptp->info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810t); + ptp->info.pin_config = ptp->pin_desc; + ice_ptp_setup_pin_cfg(pf); - /* Complete setup of the SMA pins */ - ice_ptp_setup_sma_pins_e810t(pf, &pf->ptp.info); + /* Clear SMA status */ + err = ice_ptp_set_sma_cfg(pf); + if (err) + ice_ptp_disable_sma_pins(pf); } /** @@ -2632,9 +2399,6 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) pf->ptp.info.getcrosststamp = ice_ptp_getcrosststamp_e82x; #endif /* CONFIG_ICE_HWTS */ - pf->ptp.info.enable = ice_ptp_gpio_enable; - pf->ptp.info.verify = ice_verify_pin; - if (ice_is_e825c(&pf->hw)) { pf->ptp.ice_pin_desc = ice_pin_desc_e825c; pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e825c); @@ -2648,15 +2412,13 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) /** * ice_ptp_set_funcs_e810 - Set specialized functions for E810 support * @pf: Board private structure - * @info: PTP info to fill * * Assign functions to the PTP capabiltiies structure for E810 devices. * Functions which operate across all device families should be set directly - * in ice_ptp_set_caps. Only add functions here which are distinct for e810 + * in ice_ptp_set_caps. Only add functions here which are distinct for E810 * devices. */ -static void -ice_ptp_set_funcs_e810(struct ice_pf *pf, struct ptp_clock_info *info) +static void ice_ptp_set_funcs_e810(struct ice_pf *pf) { if (ice_is_e810t(&pf->hw) && ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { @@ -2688,9 +2450,11 @@ static void ice_ptp_set_caps(struct ice_pf *pf) info->settime64 = ice_ptp_settime64; info->n_per_out = GLTSYN_TGT_H_IDX_MAX; info->n_ext_ts = GLTSYN_EVNT_H_IDX_MAX; + info->enable = ice_ptp_gpio_enable; + info->verify = ice_verify_pin; if (ice_is_e810(&pf->hw)) - ice_ptp_set_funcs_e810(pf, info); + ice_ptp_set_funcs_e810(pf); else ice_ptp_set_funcs_e82x(pf); } diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 982769dba832..449a0eaf904f 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -8,24 +8,6 @@ #include #include "ice_ptp_hw.h" - -enum ice_ptp_pin_e810 { - GPIO_20 = 0, - GPIO_21, - GPIO_22, - GPIO_23, - NUM_PTP_PIN_E810 -}; - -enum ice_ptp_pin_e810t { - GNSS = 0, - SMA1, - UFL1, - SMA2, - UFL2, - NUM_PTP_PINS_E810T -}; - struct ice_perout_channel { bool ena; u32 gpio_pin; @@ -230,6 +212,14 @@ enum ice_ptp_pin { ONE_PPS }; +enum ice_ptp_pin_e810t { + GNSS = 0, + SMA1, + UFL1, + SMA2, + UFL2 +}; + /* Per-channel register definitions */ #define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8)) #define GLTSYN_AUX_IN(_chan, _idx) (GLTSYN_AUX_IN_0(_idx) + ((_chan) * 8)) @@ -241,9 +231,8 @@ enum ice_ptp_pin { #define GLTSYN_EVNT_H_IDX_MAX 3 /* Pin definitions for PTP */ -#define PPS_CLK_GEN_CHAN 3 -#define PPS_PIN_INDEX 5 #define ICE_N_PINS_MAX 6 +#define ICE_SMA_PINS_NUM 4 #define ICE_PIN_DESC_ARR_LEN(_arr) (sizeof(_arr) / \ sizeof(struct ice_ptp_pin_desc)) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index 3a33e6b9b313..3c314f3d8107 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -5150,9 +5150,9 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready) return 0; } -/* E810T SMA functions +/* E810 SMA functions * - * The following functions operate specifically on E810T hardware and are used + * The following functions operate specifically on E810 hardware and are used * to access the extended GPIOs available. */ @@ -5219,14 +5219,14 @@ ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle) } /** - * ice_read_sma_ctrl_e810t + * ice_read_sma_ctrl * @hw: pointer to the hw struct * @data: pointer to data to be read from the GPIO controller * * Read the SMA controller state. It is connected to pins 3-7 of Port 1 of the * PCA9575 expander, so only bits 3-7 in data are valid. */ -int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data) +int ice_read_sma_ctrl(struct ice_hw *hw, u8 *data) { int status; u16 handle; @@ -5238,7 +5238,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data) *data = 0; - for (i = ICE_SMA_MIN_BIT_E810T; i <= ICE_SMA_MAX_BIT_E810T; i++) { + for (i = ICE_SMA_MIN_BIT; i <= ICE_SMA_MAX_BIT; i++) { bool pin; status = ice_aq_get_gpio(hw, handle, i + ICE_PCA9575_P1_OFFSET, @@ -5252,14 +5252,14 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data) } /** - * ice_write_sma_ctrl_e810t + * ice_write_sma_ctrl * @hw: pointer to the hw struct * @data: data to be written to the GPIO controller * * Write the data to the SMA controller. It is connected to pins 3-7 of Port 1 * of the PCA9575 expander, so only bits 3-7 in data are valid. */ -int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data) +int ice_write_sma_ctrl(struct ice_hw *hw, u8 data) { int status; u16 handle; @@ -5269,7 +5269,7 @@ int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data) if (status) return status; - for (i = ICE_SMA_MIN_BIT_E810T; i <= ICE_SMA_MAX_BIT_E810T; i++) { + for (i = ICE_SMA_MIN_BIT; i <= ICE_SMA_MAX_BIT; i++) { bool pin; pin = !(data & (1 << i)); @@ -5283,14 +5283,14 @@ int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data) } /** - * ice_read_pca9575_reg_e810t + * ice_read_pca9575_reg * @hw: pointer to the hw struct * @offset: GPIO controller register offset * @data: pointer to data to be read from the GPIO controller * * Read the register from the GPIO controller */ -int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data) +int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data) { struct ice_aqc_link_topo_addr link_topo; __le16 addr; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index 0852a34ade91..264b290392d7 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -400,9 +400,9 @@ int ice_phy_cfg_rx_offset_e82x(struct ice_hw *hw, u8 port); int ice_phy_cfg_intr_e82x(struct ice_hw *hw, u8 quad, bool ena, u8 threshold); /* E810 family functions */ -int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data); -int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data); -int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data); +int ice_read_sma_ctrl(struct ice_hw *hw, u8 *data); +int ice_write_sma_ctrl(struct ice_hw *hw, u8 data); +int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data); bool ice_is_pca9575_present(struct ice_hw *hw); enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input); struct dpll_pin_frequency * @@ -688,30 +688,27 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw) #define LOW_TX_MEMORY_BANK_START 0x03090000 #define HIGH_TX_MEMORY_BANK_START 0x03090004 -/* E810T SMA controller pin control */ -#define ICE_SMA1_DIR_EN_E810T BIT(4) -#define ICE_SMA1_TX_EN_E810T BIT(5) -#define ICE_SMA2_UFL2_RX_DIS_E810T BIT(3) -#define ICE_SMA2_DIR_EN_E810T BIT(6) -#define ICE_SMA2_TX_EN_E810T BIT(7) - -#define ICE_SMA1_MASK_E810T (ICE_SMA1_DIR_EN_E810T | \ - ICE_SMA1_TX_EN_E810T) -#define ICE_SMA2_MASK_E810T (ICE_SMA2_UFL2_RX_DIS_E810T | \ - ICE_SMA2_DIR_EN_E810T | \ - ICE_SMA2_TX_EN_E810T) -#define ICE_ALL_SMA_MASK_E810T (ICE_SMA1_MASK_E810T | \ - ICE_SMA2_MASK_E810T) - -#define ICE_SMA_MIN_BIT_E810T 3 -#define ICE_SMA_MAX_BIT_E810T 7 +/* SMA controller pin control */ +#define ICE_SMA1_DIR_EN BIT(4) +#define ICE_SMA1_TX_EN BIT(5) +#define ICE_SMA2_UFL2_RX_DIS BIT(3) +#define ICE_SMA2_DIR_EN BIT(6) +#define ICE_SMA2_TX_EN BIT(7) + +#define ICE_SMA1_MASK (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN) +#define ICE_SMA2_MASK (ICE_SMA2_UFL2_RX_DIS | ICE_SMA2_DIR_EN | \ + ICE_SMA2_TX_EN) +#define ICE_ALL_SMA_MASK (ICE_SMA1_MASK | ICE_SMA2_MASK) + +#define ICE_SMA_MIN_BIT 3 +#define ICE_SMA_MAX_BIT 7 #define ICE_PCA9575_P1_OFFSET 8 -/* E810T PCA9575 IO controller registers */ +/* PCA9575 IO controller registers */ #define ICE_PCA9575_P0_IN 0x0 -/* E810T PCA9575 IO controller pin control */ -#define ICE_E810T_P0_GNSS_PRSNT_N BIT(4) +/* PCA9575 IO controller pin control */ +#define ICE_P0_GNSS_PRSNT_N BIT(4) /* ETH56G PHY register addresses */ /* Timestamp PHY incval registers */ From patchwork Tue Jul 2 13:41:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719670 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 672991B4C4A for ; Tue, 2 Jul 2024 13:45:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927909; cv=none; b=FjdV66ueAzI9EfszYWEF2AtGnioVRBrzRE9vdvxGaoPwMo5DP5eQqJgQVynREHvMd8i4nJKeSlwzFa/6jxnRFR8LXt4ILAsFlUwma+GmhE3eZfhYwYDeKKJjm6GKrU4itENich7KPOQZIdaStrR/2GlKTE2jiBKuo/YstgRUMTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927909; c=relaxed/simple; bh=mWoOMf8Agvy0MJPoTp95C8rESRwDiZEFe5dlmutIl6s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YFteN4vDKTrOzFRL59ifhzm8ijRXWnKpYPRpSCsEYGCH8ra56Uyj0Dska4CCsoMVYDbLPBZRkIG19qoz05OPnrR/R1VgEA5ionHIW4PydmoI/BCoe/yBhHVv+j48mo+ytUZqrDw+sdF+DtmyxnfOeFiMPSsA4mTtj6ajnydAlWs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=J3yRydKg; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="J3yRydKg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927906; x=1751463906; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mWoOMf8Agvy0MJPoTp95C8rESRwDiZEFe5dlmutIl6s=; b=J3yRydKgp+CzTl81kAjmw5DMDz6RYoSpj2rZfZg9ZR30pVVOajgB3kcW ySNc6mnYgrmpNvUrzuM6hErtLuif/lGBlpkdCoCwiPRxpBjDiuq/xrIvE 3zh9Enb8qXapdcFPvjTyHc8zl6rwBdNS/XmI9pm9PwMHRryI4M6Qo5nPQ 7vA1Ojyy3n25NHRl265irAyqzBlP9zRi9Xtr3RYQDDBzQ7I/uSDmq7iz7 RAzOcFLZ5gjmSi9cxzAKkXc1u6WlJHKRSMRpb5yTxzydc+6OwbbrM07VN Wn7ZVjHUHO5Tuz17ogaVMRsJ3kV5rR8SZM9R4Ozw19FcSwqGnUNYgnUbt w==; X-CSE-ConnectionGUID: i+uaL3J2QXK9p6Yeuguvqw== X-CSE-MsgGUID: IfZRJIPST/KrFfJPdtkyFw== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826426" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826426" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:06 -0700 X-CSE-ConnectionGUID: NYtEfDtfQlW1kr/zXgMcyA== X-CSE-MsgGUID: zwt74bHgRya6eQyVhUz41Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460552" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:45:04 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Karol Kolacinski , Arkadiusz Kubalewski Subject: [PATCH v2 iwl-next 4/7] ice: Cache perout/extts requests and check flags Date: Tue, 2 Jul 2024 15:41:33 +0200 Message-ID: <20240702134448.132374-13-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Cache original PTP GPIO requests instead of saving each parameter in internal structures for periodic output or external timestamp request. Factor out all periodic output register writes from ice_ptp_cfg_clkout to a separate function to improve readability. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: Fixed unresolved merge conflict drivers/net/ethernet/intel/ice/ice_ptp.c | 354 +++++++++--------- drivers/net/ethernet/intel/ice/ice_ptp.h | 27 +- .../net/ethernet/intel/ice/ice_ptp_consts.h | 2 +- drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 27 +- 4 files changed, 213 insertions(+), 197 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index df0ae9faf948..82a198f28d3c 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -1577,33 +1577,41 @@ void ice_ptp_extts_event(struct ice_pf *pf) /** * ice_ptp_cfg_extts - Configure EXTTS pin and channel * @pf: Board private structure - * @chan: GPIO channel (0-3) - * @config: desired EXTTS configuration. - * @store: If set to true, the values will be stored + * @rq: External timestamp request + * @on: Enable/disable flag * * Configure an external timestamp event on the requested channel. * - * Return: 0 on success, -EOPNOTUSPP on unsupported flags + * Return: 0 on success, negative error code otherwise */ -static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan, - struct ice_extts_channel *config, bool store) +static int ice_ptp_cfg_extts(struct ice_pf *pf, struct ptp_extts_request *rq, + int on) { - u32 func, aux_reg, gpio_reg, irq_reg; + u32 aux_reg, gpio_reg, irq_reg; struct ice_hw *hw = &pf->hw; + uint chan, gpio_pin; + int pin_desc_idx; u8 tmr_idx; /* Reject requests with unsupported flags */ - if (config->flags & ~(PTP_ENABLE_FEATURE | - PTP_RISING_EDGE | - PTP_FALLING_EDGE | - PTP_STRICT_FLAGS)) + + if (rq->flags & ~(PTP_ENABLE_FEATURE | + PTP_RISING_EDGE | + PTP_FALLING_EDGE | + PTP_STRICT_FLAGS)) return -EOPNOTSUPP; tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + chan = rq->index; + pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, chan); + if (pin_desc_idx < 0) + return -EIO; + + gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[0]; irq_reg = rd32(hw, PFINT_OICR_ENA); - if (config->ena) { + if (on) { /* Enable the interrupt */ irq_reg |= PFINT_OICR_TSYN_EVNT_M; aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M; @@ -1612,33 +1620,39 @@ static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan, #define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1) /* set event level to requested edge */ - if (config->flags & PTP_FALLING_EDGE) + if (rq->flags & PTP_FALLING_EDGE) aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE; - if (config->flags & PTP_RISING_EDGE) + if (rq->flags & PTP_RISING_EDGE) aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE; /* Write GPIO CTL reg. * 0x1 is input sampled by EVENT register(channel) * + num_in_channels * tmr_idx */ - func = 1 + chan + (tmr_idx * 3); - gpio_reg = FIELD_PREP(GLGEN_GPIO_CTL_PIN_FUNC_M, func); - pf->ptp.ext_ts_chan |= (1 << chan); + gpio_reg = FIELD_PREP(GLGEN_GPIO_CTL_PIN_FUNC_M, + 1 + chan + (tmr_idx * 3)); } else { + bool last_enabled = true; + uint i; + /* clear the values we set to reset defaults */ aux_reg = 0; gpio_reg = 0; - pf->ptp.ext_ts_chan &= ~(1 << chan); - if (!pf->ptp.ext_ts_chan) + + for (i = 0; i < pf->ptp.info.n_ext_ts; i++) + if ((pf->ptp.extts_rqs[i].flags & + PTP_ENABLE_FEATURE) && + i != chan) { + last_enabled = false; + } + + if (last_enabled) irq_reg &= ~PFINT_OICR_TSYN_EVNT_M; } wr32(hw, PFINT_OICR_ENA, irq_reg); wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg); - wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg); - - if (store) - memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config)); + wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg); return 0; } @@ -1649,16 +1663,12 @@ static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan, */ static void ice_ptp_disable_all_extts(struct ice_pf *pf) { - struct ice_extts_channel extts_cfg = {}; - int i; + uint i; - for (i = 0; i < pf->ptp.info.n_ext_ts; i++) { - if (pf->ptp.extts_channels[i].ena) { - extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin; - extts_cfg.ena = false; - ice_ptp_cfg_extts(pf, i, &extts_cfg, false); - } - } + for (i = 0; i < pf->ptp.info.n_ext_ts ; i++) + if (pf->ptp.extts_rqs[i].flags & PTP_ENABLE_FEATURE) + ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[i], + false); synchronize_irq(pf->oicr_irq.virq); } @@ -1671,159 +1681,175 @@ static void ice_ptp_disable_all_extts(struct ice_pf *pf) */ static void ice_ptp_enable_all_extts(struct ice_pf *pf) { - int i; + uint i; - for (i = 0; i < pf->ptp.info.n_ext_ts; i++) { - if (pf->ptp.extts_channels[i].ena) { - ice_ptp_cfg_extts(pf, i, &pf->ptp.extts_channels[i], - false); - } - } + for (i = 0; i < pf->ptp.info.n_ext_ts ; i++) + if (pf->ptp.extts_rqs[i].flags & PTP_ENABLE_FEATURE) + ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[i], + true); } /** - * ice_ptp_cfg_clkout - Configure clock to generate periodic wave - * @pf: Board private structure - * @chan: GPIO channel (0-3) - * @config: desired periodic clk configuration. NULL will disable channel - * @store: If set to true the values will be stored + * ice_ptp_write_perout - Write periodic wave parameters to HW + * @hw: pointer to the HW struct + * @chan: target channel + * @gpio_pin: target GPIO pin + * @start: target time to start periodic output + * @period: target period * - * Configure the internal clock generator modules to generate the clock wave of - * specified period. + * Return: 0 on success, negative error code otherwise */ -static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan, - struct ice_perout_channel *config, bool store) +static int ice_ptp_write_perout(struct ice_hw *hw, unsigned int chan, + unsigned int gpio_pin, u64 start, u64 period) { - u64 current_time, period, start_time, phase; - struct ice_hw *hw = &pf->hw; - u32 func, val, gpio_pin; - u8 tmr_idx; - if (config && config->flags & ~PTP_PEROUT_PHASE) - return -EOPNOTSUPP; - - tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + u8 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + u32 val = 0; /* 0. Reset mode & out_en in AUX_OUT */ wr32(hw, GLTSYN_AUX_OUT(chan, tmr_idx), 0); - /* If we're disabling the output, clear out CLKO and TGT and keep - * output level low + /* 1. Write perout with half of required period value. + * HW toggles output when source clock hits the TGT and then adds + * GLTSYN_CLKO value to the target, so it ends up with 50% duty cycle. */ - if (!config || !config->ena) { - wr32(hw, GLTSYN_CLKO(chan, tmr_idx), 0); - wr32(hw, GLTSYN_TGT_L(chan, tmr_idx), 0); - wr32(hw, GLTSYN_TGT_H(chan, tmr_idx), 0); - - val = GLGEN_GPIO_CTL_PIN_DIR_M; - gpio_pin = pf->ptp.perout_channels[chan].gpio_pin; - wr32(hw, GLGEN_GPIO_CTL(gpio_pin), val); - - /* Store the value if requested */ - if (store) - memset(&pf->ptp.perout_channels[chan], 0, - sizeof(struct ice_perout_channel)); - - return 0; - } - period = config->period; - start_time = config->start_time; - div64_u64_rem(start_time, period, &phase); - gpio_pin = config->gpio_pin; - - /* 1. Write clkout with half of required period value */ - if (period & 0x1) { - dev_err(ice_pf_to_dev(pf), "CLK Period must be an even value\n"); - goto err; - } - period >>= 1; - /* For proper operation, the GLTSYN_CLKO must be larger than clock tick + /* For proper operation, GLTSYN_CLKO must be larger than clock tick and + * period has to fit in 32 bit register. */ #define MIN_PULSE 3 - if (period <= MIN_PULSE || period > U32_MAX) { - dev_err(ice_pf_to_dev(pf), "CLK Period must be > %d && < 2^33", - MIN_PULSE * 2); - goto err; + if (!!period && (period <= MIN_PULSE || period > U32_MAX)) { + dev_err(ice_hw_to_dev(hw), "CLK period ticks must be >= %d && <= 2^32", + MIN_PULSE); + return -EIO; } wr32(hw, GLTSYN_CLKO(chan, tmr_idx), lower_32_bits(period)); - /* Allow time for programming before start_time is hit */ - current_time = ice_ptp_read_src_clk_reg(pf, NULL); - - /* if start time is in the past start the timer at the nearest second - * maintaining phase - */ - if (start_time < current_time) - start_time = roundup_u64(current_time, NSEC_PER_SEC) + phase; - - if (ice_is_e810(hw)) - start_time -= E810_OUT_PROP_DELAY_NS; - else - start_time -= ice_e82x_pps_delay(ice_e82x_time_ref(hw)); - /* 2. Write TARGET time */ - wr32(hw, GLTSYN_TGT_L(chan, tmr_idx), lower_32_bits(start_time)); - wr32(hw, GLTSYN_TGT_H(chan, tmr_idx), upper_32_bits(start_time)); + wr32(hw, GLTSYN_TGT_L(chan, tmr_idx), lower_32_bits(start)); + wr32(hw, GLTSYN_TGT_H(chan, tmr_idx), upper_32_bits(start)); /* 3. Write AUX_OUT register */ - val = GLTSYN_AUX_OUT_0_OUT_ENA_M | GLTSYN_AUX_OUT_0_OUTMOD_M; + if (!!period) + val = GLTSYN_AUX_OUT_0_OUT_ENA_M | GLTSYN_AUX_OUT_0_OUTMOD_M; wr32(hw, GLTSYN_AUX_OUT(chan, tmr_idx), val); /* 4. write GPIO CTL reg */ - func = 8 + chan + (tmr_idx * 4); - val = GLGEN_GPIO_CTL_PIN_DIR_M | - FIELD_PREP(GLGEN_GPIO_CTL_PIN_FUNC_M, func); + val = GLGEN_GPIO_CTL_PIN_DIR_M; + if (!!period) + val |= FIELD_PREP(GLGEN_GPIO_CTL_PIN_FUNC_M, + 8 + chan + (tmr_idx * 4)); + wr32(hw, GLGEN_GPIO_CTL(gpio_pin), val); - /* Store the value if requested */ - if (store) { - memcpy(&pf->ptp.perout_channels[chan], config, - sizeof(struct ice_perout_channel)); - pf->ptp.perout_channels[chan].start_time = phase; + return 0; +} + +/** + * ice_ptp_cfg_perout - Configure clock to generate periodic wave + * @pf: Board private structure + * @rq: Periodic output request + * @on: Enable/disable flag + * + * Configure the internal clock generator modules to generate the clock wave of + * specified period. + * + * Return: 0 on success, negative error code otherwise + */ +static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq, + int on) +{ + u64 clk, period, start, phase; + struct ice_hw *hw = &pf->hw; + int pin_desc_idx; + uint gpio_pin; + + if (rq->flags & ~PTP_PEROUT_PHASE) + return -EOPNOTSUPP; + + pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT, rq->index); + if (pin_desc_idx < 0) + return -EIO; + + gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[1]; + period = rq->period.sec * NSEC_PER_SEC + rq->period.nsec; + + /* If we're disabling the output or period is 0, clear out CLKO and TGT + * and keep output level low. + */ + if (!on || !period) + return ice_ptp_write_perout(hw, rq->index, gpio_pin, 0, 0); + + if (strncmp(pf->ptp.pin_desc[pin_desc_idx].name, "1PPS", 64) == 0 && + period != NSEC_PER_SEC && hw->ptp.phy_model == ICE_PHY_E82X) { + dev_err(ice_pf_to_dev(pf), "1PPS pin supports only 1 s period\n"); + return -EOPNOTSUPP; } - return 0; -err: - dev_err(ice_pf_to_dev(pf), "PTP failed to cfg per_clk\n"); - return -EFAULT; + if (period & 0x1) { + dev_err(ice_pf_to_dev(pf), "CLK Period must be an even value\n"); + return -EIO; + } + + start = rq->start.sec * NSEC_PER_SEC + rq->start.nsec; + + /* If PTP_PEROUT_PHASE is set, rq has phase instead of start time */ + if (rq->flags & PTP_PEROUT_PHASE) + phase = start; + else + div64_u64_rem(start, period, &phase); + + /* If we have only phase or start time is in the past, start the timer + * at the next multiple of period, maintaining phase. + */ + clk = ice_ptp_read_src_clk_reg(pf, NULL); + if (rq->flags & PTP_PEROUT_PHASE || start <= clk - ice_prop_delay(hw)) + start = div64_u64(clk + period - 1, period) * period + phase; + + /* Compensate for propagation delay from the generator to the pin. */ + start -= ice_prop_delay(hw); + + return ice_ptp_write_perout(hw, rq->index, gpio_pin, start, period); } /** - * ice_ptp_disable_all_clkout - Disable all currently configured outputs - * @pf: pointer to the PF structure + * ice_ptp_disable_all_perout - Disable all currently configured outputs + * @pf: Board private structure * * Disable all currently configured clock outputs. This is necessary before - * certain changes to the PTP hardware clock. Use ice_ptp_enable_all_clkout to + * certain changes to the PTP hardware clock. Use ice_ptp_enable_all_perout to * re-enable the clocks again. */ -static void ice_ptp_disable_all_clkout(struct ice_pf *pf) +static void ice_ptp_disable_all_perout(struct ice_pf *pf) { uint i; for (i = 0; i < pf->ptp.info.n_per_out; i++) - if (pf->ptp.perout_channels[i].ena) - ice_ptp_cfg_clkout(pf, i, NULL, false); + if (pf->ptp.perout_rqs[i].period.sec || + pf->ptp.perout_rqs[i].period.nsec) + ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[i], + false); } /** - * ice_ptp_enable_all_clkout - Enable all configured periodic clock outputs - * @pf: pointer to the PF structure + * ice_ptp_enable_all_perout - Enable all configured periodic clock outputs + * @pf: Board private structure * * Enable all currently configured clock outputs. Use this after - * ice_ptp_disable_all_clkout to reconfigure the output signals according to + * ice_ptp_disable_all_perout to reconfigure the output signals according to * their configuration. */ -static void ice_ptp_enable_all_clkout(struct ice_pf *pf) +static void ice_ptp_enable_all_perout(struct ice_pf *pf) { uint i; for (i = 0; i < pf->ptp.info.n_per_out; i++) - if (pf->ptp.perout_channels[i].ena) - ice_ptp_cfg_clkout(pf, i, &pf->ptp.perout_channels[i], - false); + if (pf->ptp.perout_rqs[i].period.sec || + pf->ptp.perout_rqs[i].period.nsec) + ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[i], + true); } /** @@ -1869,50 +1895,40 @@ static int ice_verify_pin(struct ptp_clock_info *info, unsigned int pin, * @rq: The requested feature to change * @on: Enable/disable flag * - * Return: 0 on success, -EOPNOTSUPP when request type is not supported + * Return: 0 on success, negative error code otherwise */ static int ice_ptp_gpio_enable(struct ptp_clock_info *info, struct ptp_clock_request *rq, int on) { struct ice_pf *pf = ptp_info_to_pf(info); + int err; switch (rq->type) { case PTP_CLK_REQ_PEROUT: { - struct ice_perout_channel clk_cfg; - int pin_desc_idx; - - pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT, - rq->perout.index); - if (pin_desc_idx < 0) - return -EIO; + struct ptp_perout_request *cached = + &pf->ptp.perout_rqs[rq->perout.index]; - - clk_cfg.flags = rq->perout.flags; - clk_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[1]; - clk_cfg.period = rq->perout.period.sec * NSEC_PER_SEC + - rq->perout.period.nsec; - clk_cfg.start_time = rq->perout.start.sec * NSEC_PER_SEC + - rq->perout.start.nsec; - clk_cfg.ena = !!on; - - return ice_ptp_cfg_clkout(pf, rq->perout.index, &clk_cfg, true); + err = ice_ptp_cfg_perout(pf, &rq->perout, on); + if (!err) { + *cached = rq->perout; + } else { + cached->period.sec = 0; + cached->period.nsec = 0; + } + return err; } case PTP_CLK_REQ_EXTTS: { - struct ice_extts_channel extts_cfg = {}; - int pin_desc_idx; - - pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, - rq->extts.index); - if (pin_desc_idx < 0) - return -EIO; + struct ptp_extts_request *cached = + &pf->ptp.extts_rqs[rq->extts.index]; - extts_cfg.flags = rq->extts.flags; - extts_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[0]; - extts_cfg.ena = !!on; - - return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true); + err = ice_ptp_cfg_extts(pf, &rq->extts, on); + if (!err) + *cached = rq->extts; + else + cached->flags &= ~PTP_ENABLE_FEATURE; + return err; } default: return -EOPNOTSUPP; @@ -1972,7 +1988,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts) } /* Disable periodic outputs */ - ice_ptp_disable_all_clkout(pf); + ice_ptp_disable_all_perout(pf); err = ice_ptp_write_init(pf, &ts64); ice_ptp_unlock(hw); @@ -1981,7 +1997,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts) ice_ptp_reset_cached_phctime(pf); /* Reenable periodic outputs */ - ice_ptp_enable_all_clkout(pf); + ice_ptp_enable_all_perout(pf); /* Recalibrate and re-enable timestamp blocks for E822/E823 */ if (hw->ptp.phy_model == ICE_PHY_E82X) @@ -2043,12 +2059,12 @@ static int ice_ptp_adjtime(struct ptp_clock_info *info, s64 delta) } /* Disable periodic outputs */ - ice_ptp_disable_all_clkout(pf); + ice_ptp_disable_all_perout(pf); err = ice_ptp_write_adj(pf, delta); /* Reenable periodic outputs */ - ice_ptp_enable_all_clkout(pf); + ice_ptp_enable_all_perout(pf); ice_ptp_unlock(hw); @@ -2658,7 +2674,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx); /* Disable periodic outputs */ - ice_ptp_disable_all_clkout(pf); + ice_ptp_disable_all_perout(pf); src_tmr = ice_get_ptp_src_clock_index(&pf->hw); @@ -2735,7 +2751,7 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf) } /* Re-enable all periodic outputs and external timestamp events */ - ice_ptp_enable_all_clkout(pf); + ice_ptp_enable_all_perout(pf); ice_ptp_enable_all_extts(pf); return 0; @@ -3315,7 +3331,7 @@ void ice_ptp_release(struct ice_pf *pf) return; /* Disable periodic outputs */ - ice_ptp_disable_all_clkout(pf); + ice_ptp_disable_all_perout(pf); ptp_clock_unregister(pf->ptp.clock); pf->ptp.clock = NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 449a0eaf904f..27b32da999df 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -8,19 +8,6 @@ #include #include "ice_ptp_hw.h" -struct ice_perout_channel { - bool ena; - u32 gpio_pin; - u32 flags; - u64 period; - u64 start_time; -}; - -struct ice_extts_channel { - bool ena; - u32 gpio_pin; - u32 flags; -}; /* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp * is stored in a buffer of registers. Depending on the specific hardware, @@ -259,13 +246,12 @@ struct ice_ptp_pin_desc { * @work: delayed work function for periodic tasks * @cached_phc_time: a cached copy of the PHC time for timestamp extension * @cached_phc_jiffies: jiffies when cached_phc_time was last updated - * @ext_ts_chan: the external timestamp channel in use + * @kworker: kwork thread for handling periodic work * @ext_ts_irq: the external timestamp IRQ in use * @pin_desc: structure defining pins * @ice_pin_desc: internal structure describing pin relations - * @kworker: kwork thread for handling periodic work - * @perout_channels: periodic output data - * @extts_channels: channels for external timestamps + * @perout_rqs: cached periodic output requests + * @extts_rqs: cached external timestamp requests * @info: structure defining PTP hardware capabilities * @clock: pointer to registered PTP clock device * @tstamp_config: hardware timestamping configuration @@ -285,13 +271,12 @@ struct ice_ptp { struct kthread_delayed_work work; u64 cached_phc_time; unsigned long cached_phc_jiffies; - u8 ext_ts_chan; - u8 ext_ts_irq; struct kthread_worker *kworker; + u8 ext_ts_irq; struct ptp_pin_desc pin_desc[ICE_N_PINS_MAX]; const struct ice_ptp_pin_desc *ice_pin_desc; - struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX]; - struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX]; + struct ptp_perout_request perout_rqs[GLTSYN_TGT_H_IDX_MAX]; + struct ptp_extts_request extts_rqs[GLTSYN_EVNT_H_IDX_MAX]; struct ptp_clock_info info; struct ptp_clock *clock; struct hwtstamp_config tstamp_config; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h index e6980b94a6c1..585ce200c60f 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h @@ -334,7 +334,7 @@ struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = { * reference. See the struct ice_time_ref_info_e82x for information about the * meaning of each constant. */ -const struct ice_time_ref_info_e82x e822_time_ref[NUM_ICE_TIME_REF_FREQ] = { +const struct ice_time_ref_info_e82x e82x_time_ref[NUM_ICE_TIME_REF_FREQ] = { /* ICE_TIME_REF_FREQ_25_000 -> 25 MHz */ { /* pll_freq */ diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index 264b290392d7..c42831449787 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -316,7 +316,7 @@ ice_cgu_pll_params_e825c e825c_cgu_params[NUM_ICE_TIME_REF_FREQ]; extern const struct ice_phy_reg_info_eth56g eth56g_phy_res[NUM_ETH56G_PHY_RES]; /* Table of constants related to possible TIME_REF sources */ -extern const struct ice_time_ref_info_e82x e822_time_ref[NUM_ICE_TIME_REF_FREQ]; +extern const struct ice_time_ref_info_e82x e82x_time_ref[NUM_ICE_TIME_REF_FREQ]; /* Table of constants for Vernier calibration on E822 */ extern const struct ice_vernier_info_e82x e822_vernier[NUM_ICE_PTP_LNK_SPD]; @@ -326,7 +326,8 @@ extern const struct ice_vernier_info_e82x e822_vernier[NUM_ICE_PTP_LNK_SPD]; */ #define ICE_E810_PLL_FREQ 812500000 #define ICE_PTP_NOMINAL_INCVAL_E810 0x13b13b13bULL -#define E810_OUT_PROP_DELAY_NS 1 +#define ICE_E810_OUT_PROP_DELAY_NS 1 +#define ICE_E825C_OUT_PROP_DELAY_NS 11 /* Device agnostic functions */ u8 ice_get_ptp_src_clock_index(struct ice_hw *hw); @@ -358,7 +359,7 @@ void ice_ptp_reset_ts_memory_quad_e82x(struct ice_hw *hw, u8 quad); * * Returns the current TIME_REF from the capabilities structure. */ -static inline enum ice_time_ref_freq ice_e82x_time_ref(struct ice_hw *hw) +static inline enum ice_time_ref_freq ice_e82x_time_ref(const struct ice_hw *hw) { return hw->func_caps.ts_func_info.time_ref; } @@ -379,17 +380,17 @@ ice_set_e82x_time_ref(struct ice_hw *hw, enum ice_time_ref_freq time_ref) static inline u64 ice_e82x_pll_freq(enum ice_time_ref_freq time_ref) { - return e822_time_ref[time_ref].pll_freq; + return e82x_time_ref[time_ref].pll_freq; } static inline u64 ice_e82x_nominal_incval(enum ice_time_ref_freq time_ref) { - return e822_time_ref[time_ref].nominal_incval; + return e82x_time_ref[time_ref].nominal_incval; } static inline u64 ice_e82x_pps_delay(enum ice_time_ref_freq time_ref) { - return e822_time_ref[time_ref].pps_delay; + return e82x_time_ref[time_ref].pps_delay; } /* E822 Vernier calibration functions */ @@ -431,6 +432,20 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port); #define ICE_ETH56G_NOMINAL_THRESH4 0x7777 #define ICE_ETH56G_NOMINAL_TX_THRESH 0x6 +static inline u64 ice_prop_delay(const struct ice_hw *hw) +{ + switch (hw->ptp.phy_model) { + case ICE_PHY_ETH56G: + return ICE_E825C_OUT_PROP_DELAY_NS; + case ICE_PHY_E810: + return ICE_E810_OUT_PROP_DELAY_NS; + case ICE_PHY_E82X: + return ice_e82x_pps_delay(ice_e82x_time_ref(hw)); + default: + return 0; + } +} + /** * ice_get_base_incval - Get base clock increment value * @hw: pointer to the HW struct From patchwork Tue Jul 2 13:41:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719671 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D28BA1B47DC for ; Tue, 2 Jul 2024 13:45:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927909; cv=none; b=T/YhDRfAZuxmwIj7w6hhZ4JaoRXr/saMM0vWxHseshXbF9l6TqeDnwWWJtYb46v6S53RdHq9zGN21s9qpDdQh87m5hY7+/oa6rUWHiO/lv9gR8ZbnCZfZqnqfGXwGbHzSQSpdDxMKUwnZ1+PAurX5uCBKIwh0hE1u7LycZ5QStA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927909; c=relaxed/simple; bh=CpqYtCIpwSmhP7EXWw0mfhxzEtWgoFkbm2G25RlGZJc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KAAQRVoWxF/I4BVIQl37IsJ1dr2Ctxhk1ekNdgQfR9yW/DuEIyb7kLZjCf9H29pmguMxDkA6IHeRZVl9wilWgIFFkkUr+6sS5IFlTvIvg4eKQYwxkhoM/a0hUslAQjHAVklLmY8tKV0hI3mF/4Ya95uQZUeYjsQ5BxSrxwJAZ9s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=D2lNQNMg; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="D2lNQNMg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927908; x=1751463908; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CpqYtCIpwSmhP7EXWw0mfhxzEtWgoFkbm2G25RlGZJc=; b=D2lNQNMgEvPjH6Gc37gWiILyD13MpyCq7R9tP5MHYmwnGs2rqfYjUbAG kxwv/zO/wp1WLQYDSTkHU+km8l7F5hzAwylLZ5aNYcvbIoYXUpsqyBehP 1Lh0bCJUTp+bMTqBupS+/igA1OQChjHBAs+nPSP8TYGGwBL16gb6ET8D2 UfE+6Gzy3fnpbY1f6d7kmzgEyXxl3qeZus2CzPmDV6wgi9/B/ZhMRvnYi OP3yQNvwT6S2zh06L6BFAFBDAqqzXi5bvcPoJFXfjA+wuxeFgbOYjQYrW gJ6KkzLScVyAH0iusMbxGYRX23C09oqpnLbhQEbibm5POHy7MzVbQwtrF A==; X-CSE-ConnectionGUID: bvryJFOfS8qy9cy0wy10nQ== X-CSE-MsgGUID: KYBpG4nORk+uO6p9DdIFbw== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826439" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826439" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:07 -0700 X-CSE-ConnectionGUID: sHmNrADzS769r/JDMtujsQ== X-CSE-MsgGUID: M4uU9VOaQDatgexeqBJt1g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460560" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:45:06 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Karol Kolacinski , Arkadiusz Kubalewski Subject: [PATCH v2 iwl-next 5/7] ice: Disable shared pin on E810 on setfunc Date: Tue, 2 Jul 2024 15:41:34 +0200 Message-ID: <20240702134448.132374-14-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org When setting a new supported function for a pin on E810, disable other enabled pin that shares the same GPIO. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: Fixed incorrect call to ice_ptp_set_sma_cfg_e810t() drivers/net/ethernet/intel/ice/ice_ptp.c | 65 ++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 82a198f28d3c..1594d10a0858 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -1852,6 +1852,63 @@ static void ice_ptp_enable_all_perout(struct ice_pf *pf) true); } +/** + * ice_ptp_disable_shared_pin - Disable enabled pin that shares GPIO + * @pf: Board private structure + * @pin: Pin index + * @func: Assigned function + * + * Return: 0 on success, negative error code otherwise + */ +static int ice_ptp_disable_shared_pin(struct ice_pf *pf, unsigned int pin, + enum ptp_pin_function func) +{ + uint gpio_pin, i; + + switch (func) { + case PTP_PF_PEROUT: + gpio_pin = pf->ptp.ice_pin_desc[pin].gpio[1]; + break; + case PTP_PF_EXTTS: + gpio_pin = pf->ptp.ice_pin_desc[pin].gpio[0]; + break; + default: + return -EOPNOTSUPP; + } + + for (i = 0; i < pf->ptp.info.n_pins; i++) { + struct ptp_pin_desc *pin_desc = &pf->ptp.pin_desc[i]; + uint chan = pin_desc->chan; + + /* Skip pin idx from the request */ + if (i == pin) + continue; + + if (pin_desc->func == PTP_PF_PEROUT && + pf->ptp.ice_pin_desc[i].gpio[1] == gpio_pin) { + pf->ptp.perout_rqs[chan].period.sec = 0; + pf->ptp.perout_rqs[chan].period.nsec = 0; + pin_desc->func = PTP_PF_NONE; + pin_desc->chan = 0; + dev_dbg(ice_pf_to_dev(pf), "Disabling pin %u with shared output GPIO pin %u\n", + i, gpio_pin); + return ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[chan], + false); + } else if (pf->ptp.pin_desc->func == PTP_PF_EXTTS && + pf->ptp.ice_pin_desc[i].gpio[0] == gpio_pin) { + pf->ptp.extts_rqs[chan].flags &= ~PTP_ENABLE_FEATURE; + pin_desc->func = PTP_PF_NONE; + pin_desc->chan = 0; + dev_dbg(ice_pf_to_dev(pf), "Disabling pin %u with shared input GPIO pin %u\n", + i, gpio_pin); + return ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[chan], + false); + } + } + + return 0; +} + /** * ice_verify_pin - verify if pin supports requested pin function * @info: the driver's PTP info structure @@ -1886,6 +1943,14 @@ static int ice_verify_pin(struct ptp_clock_info *info, unsigned int pin, return -EOPNOTSUPP; } + /* On adapters with SMA_CTRL disable other pins that share same GPIO */ + if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { + ice_ptp_disable_shared_pin(pf, pin, func); + pf->ptp.pin_desc[pin].func = func; + pf->ptp.pin_desc[pin].chan = chan; + return ice_ptp_set_sma_cfg(pf); + } + return 0; } From patchwork Tue Jul 2 13:41:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719672 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3596F1B581A for ; Tue, 2 Jul 2024 13:45:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927913; cv=none; b=M7wwcstKe7lB8u4tHsKEB0VJLMGt3f3vZmUywq0sd1EB4nc0uL7uh2RHKUpRvfYBsLcz91WD8Pp2jWzpTyxY1PXZHyvSD5D09ezVBNQ/j95zXnEQbS82WXeVR9JkdRlTmVv6WxO7hANyon7IyNi4Pdb1SO8iIvEfkZQBRK+FIz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927913; c=relaxed/simple; bh=cjWNrCtX/PrnW2hIrF9mN7MD3DfyGqd1VfF53tDk2VI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BeGpn96OwwzPdyhdynG13HWS0/0eVcf5BQCKvSuE+W7Vy/cwn+Y+I570/s9BiG5+MxjlvAxPFiiEQPJSyyBUIyNUCJ0/kSFCVNQRq36X4NsPueu09q4qvD/OjRf8W5Z2GiqtySpW1n1u3OcbKIcQmpMJNq6LHq5+aSKQwsJd9Ms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Oh9FO3Xh; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Oh9FO3Xh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927911; x=1751463911; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cjWNrCtX/PrnW2hIrF9mN7MD3DfyGqd1VfF53tDk2VI=; b=Oh9FO3Xheo7FK5EGU2g+MHEIVtjmmet+uMD8g5QpmscOXtwqTDd7bJgN qi89DqaBqvgaTMjoTwTklwDXL+31A/7Da55Y+ckg8du/evMxPLXl4wdKT hnvaO4K4RoLRnZ+THV+0aQXN/PhwMoV2mEuNPH5JzMrqoDmukb55AmQMG sCN7sov0cnMYHbTf6xy/0bN0WvVGAv3k7PmBNP2eevAMTn7pJJh9DaaLS rkhFRmbjjS4SthTQLPZNm2sLD5k9w9a90ahWx3kpCgVYh0WUjG7Jmx/ny 37ntfZr8pPmX7IKQscwb0cNFvzwcP7nqnqaj7VVH/LHIgE9fK46RmDz04 Q==; X-CSE-ConnectionGUID: rumzQ3jpToaEqj3XR3kWIQ== X-CSE-MsgGUID: XjHUV6DOSnq9CDLn7qkQGQ== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826448" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826448" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:10 -0700 X-CSE-ConnectionGUID: c5ew5pijQnWwJdmFO8LnKw== X-CSE-MsgGUID: PT19IWTxSQypd/ghE3pmcw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460573" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:45:08 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Yochai Hagvi , Arkadiusz Kubalewski , Karol Kolacinski Subject: [PATCH v2 iwl-next 6/7] ice: Read SDP section from NVM for pin definitions Date: Tue, 2 Jul 2024 15:41:35 +0200 Message-ID: <20240702134448.132374-15-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Yochai Hagvi PTP pins assignment and their related SDPs (Software Definable Pins) are currently hardcoded. Fix that by reading NVM section instead on products supporting this, which are E810 products. If SDP section is not defined in NVM, the driver continues to use the hardcoded table. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Yochai Hagvi Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- .../net/ethernet/intel/ice/ice_adminq_cmd.h | 9 ++ drivers/net/ethernet/intel/ice/ice_ptp.c | 138 ++++++++++++++---- drivers/net/ethernet/intel/ice/ice_ptp.h | 6 +- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 60 ++++++++ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 + 5 files changed, 186 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h index 66f02988d549..a710ce4e4482 100644 --- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h @@ -1742,6 +1742,15 @@ struct ice_aqc_nvm { }; #define ICE_AQC_NVM_START_POINT 0 +#define ICE_AQC_NVM_SECTOR_UNIT 4096 +#define ICE_AQC_NVM_SDP_AC_PTR_OFFSET 0xD8 +#define ICE_AQC_NVM_SDP_AC_PTR_M GENMASK(14, 0) +#define ICE_AQC_NVM_SDP_AC_PTR_INVAL 0x7FFF +#define ICE_AQC_NVM_SDP_AC_PTR_TYPE_M BIT(15) +#define ICE_AQC_NVM_SDP_AC_SDP_NUM_M GENMASK(2, 0) +#define ICE_AQC_NVM_SDP_AC_DIR_M BIT(3) +#define ICE_AQC_NVM_SDP_AC_PIN_M GENMASK(15, 6) +#define ICE_AQC_NVM_SDP_AC_MAX_SIZE 7 #define ICE_AQC_NVM_TX_TOPO_MOD_ID 0x14B diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 1594d10a0858..e324d96c34c6 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -39,7 +39,7 @@ static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = { { ONE_PPS, { 5, -1 }}, }; -static const char ice_pin_names_e810t[][64] = { +static const char ice_pin_names_nvm[][64] = { "GNSS", "SMA1", "U.FL1", @@ -47,7 +47,7 @@ static const char ice_pin_names_e810t[][64] = { "U.FL2", }; -static const struct ice_ptp_pin_desc ice_pin_desc_e810t[] = { +static const struct ice_ptp_pin_desc ice_pin_desc_e810_sma[] = { /* name, gpio */ { GNSS, { -1, 1 }}, { SMA1, { 0, 1 }}, @@ -2402,8 +2402,8 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) if (!ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) name = ice_pin_names[desc->name_idx]; - else - name = ice_pin_names_e810t[desc->name_idx]; + else if (desc->name_idx != GPIO_NA) + name = ice_pin_names_nvm[desc->name_idx]; if (name) strscpy(pin->name, name, sizeof(pin->name)); @@ -2424,17 +2424,17 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) } /** - * ice_ptp_disable_sma_pins - Disable SMA pins + * ice_ptp_disable_pins - Disable PTP pins * @pf: pointer to the PF structure * * Disable the OS access to the SMA pins. Called to clear out the OS * indications of pin support when we fail to setup the SMA control register. */ -static void ice_ptp_disable_sma_pins(struct ice_pf *pf) +static void ice_ptp_disable_pins(struct ice_pf *pf) { struct ptp_clock_info *info = &pf->ptp.info; - dev_warn(ice_pf_to_dev(pf), "Failed to configure SMA pin control\n"); + dev_warn(ice_pf_to_dev(pf), "Failed to configure PTP pin control\n"); info->enable = NULL; info->verify = NULL; @@ -2444,23 +2444,75 @@ static void ice_ptp_disable_sma_pins(struct ice_pf *pf) } /** - * ice_ptp_setup_pins_e810t - Setup PTP pins in sysfs - * @pf: pointer to the PF instance + * ice_ptp_parse_sdp_entries - update ice_ptp_pin_desc structure from NVM + * @pf: pointer to the PF structure + * @entries: SDP connection section from NVM + * @num_entries: number of valid entries in sdp_entries + * @pins: PTP pins array to update + * + * Return: 0 on success, negative error code otherwise. */ -static void ice_ptp_setup_pins_e810t(struct ice_pf *pf) +static int ice_ptp_parse_sdp_entries(struct ice_pf *pf, __le16 *entries, + uint num_entries, + struct ice_ptp_pin_desc *pins) { - struct ice_ptp *ptp = &pf->ptp; - int err; + uint n_pins = 0; + uint i; - ptp->ice_pin_desc = ice_pin_desc_e810t; - ptp->info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810t); - ptp->info.pin_config = ptp->pin_desc; - ice_ptp_setup_pin_cfg(pf); + /* Setup ice_pin_desc array */ + for (i = 0; i < ICE_N_PINS_MAX; i++) { + pins[i].name_idx = -1; + pins[i].gpio[0] = -1; + pins[i].gpio[1] = -1; + } + + for (i = 0; i < num_entries; i++) { + u16 entry = le16_to_cpu(entries[i]); + DECLARE_BITMAP(bitmap, GPIO_NA); + uint bitmap_idx; + bool dir; + u16 gpio; + + *bitmap = FIELD_GET(ICE_AQC_NVM_SDP_AC_PIN_M, entry); + dir = !!FIELD_GET(ICE_AQC_NVM_SDP_AC_DIR_M, entry); + gpio = FIELD_GET(ICE_AQC_NVM_SDP_AC_SDP_NUM_M, entry); + for_each_set_bit(bitmap_idx, bitmap, GPIO_NA + 1) { + uint idx; + + /* Check if entry's pin bit is valid */ + if (bitmap_idx >= NUM_PTP_PINS_NVM && + bitmap_idx != GPIO_NA) + continue; - /* Clear SMA status */ - err = ice_ptp_set_sma_cfg(pf); - if (err) - ice_ptp_disable_sma_pins(pf); + /* Check if pin already exists */ + for (idx = 0; idx < ICE_N_PINS_MAX; idx++) + if (pins[idx].name_idx == bitmap_idx) + break; + + if (idx == ICE_N_PINS_MAX) { + /* Pin not found, setup its entry and name */ + idx = n_pins++; + pins[idx].name_idx = bitmap_idx; + if (bitmap_idx == GPIO_NA) + strscpy(pf->ptp.pin_desc[idx].name, + ice_pin_names[gpio], + sizeof(pf->ptp.pin_desc[idx] + .name)); + } + + /* Setup in/out GPIO number */ + pins[idx].gpio[dir] = gpio; + } + } + + for (i = 0; i < n_pins; i++) { + dev_dbg(ice_pf_to_dev(pf), + "NVM pin entry[%d] : name_idx %d gpio_out %d gpio_in %d\n", + i, pins[i].name_idx, pins[i].gpio[1], pins[i].gpio[0]); + } + + pf->ptp.info.n_pins = n_pins; + return 0; } /** @@ -2501,15 +2553,49 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) */ static void ice_ptp_set_funcs_e810(struct ice_pf *pf) { - if (ice_is_e810t(&pf->hw) && - ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { - ice_ptp_setup_pins_e810t(pf); - return; + __le16 entries[ICE_AQC_NVM_SDP_AC_MAX_SIZE]; + struct ice_ptp_pin_desc *desc = NULL; + struct ice_ptp *ptp = &pf->ptp; + uint num_entries; + int err; + + err = ice_ptp_read_sdp_ac(&pf->hw, entries, &num_entries); + if (err) { + /* SDP section does not exist in NVM or is corrupted */ + if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { + ptp->ice_pin_desc = ice_pin_desc_e810_sma; + ptp->info.n_pins = + ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810_sma); + } else { + pf->ptp.ice_pin_desc = ice_pin_desc_e810; + pf->ptp.info.n_pins = + ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810); + err = 0; + } + } else { + desc = devm_kcalloc(ice_pf_to_dev(pf), ICE_N_PINS_MAX, + sizeof(struct ice_ptp_pin_desc), + GFP_KERNEL); + if (!desc) + goto err; + + err = ice_ptp_parse_sdp_entries(pf, entries, num_entries, desc); + if (err) + goto err; + + ptp->ice_pin_desc = (const struct ice_ptp_pin_desc *)desc; } - pf->ptp.ice_pin_desc = ice_pin_desc_e810; - pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810); + ptp->info.pin_config = ptp->pin_desc; ice_ptp_setup_pin_cfg(pf); + + if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) + err = ice_ptp_set_sma_cfg(pf); +err: + if (err) { + devm_kfree(ice_pf_to_dev(pf), desc); + ice_ptp_disable_pins(pf); + } } /** diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 27b32da999df..77b637427d67 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -199,12 +199,14 @@ enum ice_ptp_pin { ONE_PPS }; -enum ice_ptp_pin_e810t { +enum ice_ptp_pin_nvm { GNSS = 0, SMA1, UFL1, SMA2, - UFL2 + UFL2, + NUM_PTP_PINS_NVM, + GPIO_NA = 9 }; /* Per-channel register definitions */ diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index 3c314f3d8107..07ecf2a86742 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -5313,6 +5313,66 @@ int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data) return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL); } +/** + * ice_ptp_read_sdp_ac - read SDP available connections section from NVM + * @hw: pointer to the HW struct + * @entries: returns the SDP available connections section from NVM + * @num_entries: returns the number of valid entries + * + * Return: 0 on success, negative error code if NVM read failed or section does + * not exist or is corrupted + */ +int ice_ptp_read_sdp_ac(struct ice_hw *hw, __le16 *entries, uint *num_entries) +{ + __le16 data; + u32 offset; + int err; + + err = ice_acquire_nvm(hw, ICE_RES_READ); + if (err) + goto exit; + + /* Read the offset of SDP_AC */ + offset = ICE_AQC_NVM_SDP_AC_PTR_OFFSET; + err = ice_aq_read_nvm(hw, 0, offset, sizeof(data), &data, false, true, + NULL); + if (err) + goto exit; + + /* Check if section exist */ + offset = FIELD_GET(ICE_AQC_NVM_SDP_AC_PTR_M, le16_to_cpu(data)); + if (offset == ICE_AQC_NVM_SDP_AC_PTR_INVAL) { + err = -EINVAL; + goto exit; + } + + if (offset & ICE_AQC_NVM_SDP_AC_PTR_TYPE_M) { + offset &= ICE_AQC_NVM_SDP_AC_PTR_M; + offset *= ICE_AQC_NVM_SECTOR_UNIT; + } else { + offset *= sizeof(data); + } + + /* Skip reading section length and read the number of valid entries */ + offset += sizeof(data); + err = ice_aq_read_nvm(hw, 0, offset, sizeof(data), &data, false, true, + NULL); + if (err) + goto exit; + *num_entries = le16_to_cpu(data); + + /* Read SDP configuration section */ + offset += sizeof(data); + err = ice_aq_read_nvm(hw, 0, offset, *num_entries * sizeof(data), + entries, false, true, NULL); + +exit: + if (err) + dev_dbg(ice_hw_to_dev(hw), "Failed to configure SDP connection section\n"); + ice_release_nvm(hw); + return err; +} + /** * ice_ptp_init_phy_e810 - initialize PHY parameters * @ptp: pointer to the PTP HW struct diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index c42831449787..ff98f76969e3 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -405,6 +405,7 @@ int ice_read_sma_ctrl(struct ice_hw *hw, u8 *data); int ice_write_sma_ctrl(struct ice_hw *hw, u8 data); int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data); bool ice_is_pca9575_present(struct ice_hw *hw); +int ice_ptp_read_sdp_ac(struct ice_hw *hw, __le16 *entries, uint *num_entries); enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input); struct dpll_pin_frequency * ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num); From patchwork Tue Jul 2 13:41:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karol Kolacinski X-Patchwork-Id: 13719673 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A46519F49D for ; Tue, 2 Jul 2024 13:45:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927914; cv=none; b=TtEwMtKlxeydiSXau05e66q+lYoiZh0xv1G73FLkA+XdV73FMGtlci7QqWqKP00LcU7m7Z8Sk7BOLBWWMLgUUT3FAw7+EhhZhNBBHBYo00AqvyQxlwaDP6jcFtu/7r1NuoOn/1Z7adKauQnXlI79acbxlUdDn0u73ldum/HKFP0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719927914; c=relaxed/simple; bh=7SFDDXFpHqGUQddHeHjcsdcr2pOj5KTCvACLolxvAm0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ssfjf7RpDVlsQtnUi3ylgf2riCODlxecJrs7IIbBnkhxED8eJxJRKnBd92ft3FsJlGHd9AOfyXVBBDiDQY1Ht+o87gxauLxV7FCfurAlvtXf3ixmVDnmnLDhC0AQpB302+OMWjXt2FjbWngdvOAyBCk3dx86JoGQ0wUFEvnorbs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=bdWA3dCr; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="bdWA3dCr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719927913; x=1751463913; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7SFDDXFpHqGUQddHeHjcsdcr2pOj5KTCvACLolxvAm0=; b=bdWA3dCrDb1n5U3KyXAtWQ7jtf2I5FqADlvfTvWGIBxyDABWvnc2PzZI QsdkNcquwbqVWk/6SwEYhFRsh9E11RiCYk9sVMvD2J3FA8iuT5bCqe0GU Xk/lSl8KYcPFJEBM6++VrdMHuMI2zdv4s4hA7IH9kM7q+KL3npBtmtvtR hJy4Eorr+ynqSbIj5rRsLOI3ZhN9Q/o8hxW7D+CmxdBO0z41QdhnMJm3L Yi58bawd8QNdZ2rEVNYhgaG/q5rdaFgquAZEBBvQfbAKb6zB/duYuf7Mw H/pWj/a5fPzQLN4L+/0VCdK4YTyc880Zy9Hj6pubuvFS1WXKz9wVYugtK w==; X-CSE-ConnectionGUID: jMwi5nr1TziHVzilwRPD5Q== X-CSE-MsgGUID: DntyPZ41QEy2Xaiuunho8w== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="16826455" X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="16826455" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 06:45:13 -0700 X-CSE-ConnectionGUID: OOUin8nsR7C+CGKVloLV0A== X-CSE-MsgGUID: qW/DPDclTjW8iI3vIYrU2g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,178,1716274800"; d="scan'208";a="83460586" Received: from kkolacin-desk1.igk.intel.com ([10.102.102.132]) by orviesa001.jf.intel.com with ESMTP; 02 Jul 2024 06:45:10 -0700 From: Karol Kolacinski To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org, anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com, Sergey Temerkhanov , Arkadiusz Kubalewski , Karol Kolacinski Subject: [PATCH v2 iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Date: Tue, 2 Jul 2024 15:41:36 +0200 Message-ID: <20240702134448.132374-16-karol.kolacinski@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240702134448.132374-9-karol.kolacinski@intel.com> References: <20240702134448.132374-9-karol.kolacinski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Sergey Temerkhanov Implement configuring 1PPS signal output from CGU. Use maximal amplitude because Linux PTP pin API does not have any way for user to set signal level. This change is necessary for E825C products to properly output any signal from 1PPS pin. Reviewed-by: Arkadiusz Kubalewski Signed-off-by: Sergey Temerkhanov Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Reviewed-by: Simon Horman --- V1 -> V2: Added return value description, renamed the function and enable parameter. Reworded commit message. drivers/net/ethernet/intel/ice/ice_ptp.c | 10 +++++++++ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 23 +++++++++++++++++++++ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index e324d96c34c6..11fbf2bbcae7 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -4,6 +4,7 @@ #include "ice.h" #include "ice_lib.h" #include "ice_trace.h" +#include "ice_cgu_regs.h" static const char ice_pin_names[][64] = { "SDP0", @@ -1709,6 +1710,15 @@ static int ice_ptp_write_perout(struct ice_hw *hw, unsigned int chan, /* 0. Reset mode & out_en in AUX_OUT */ wr32(hw, GLTSYN_AUX_OUT(chan, tmr_idx), 0); + if (ice_is_e825c(hw)) { + int err; + + /* Enable/disable CGU 1PPS output for E825C */ + err = ice_cgu_cfg_pps_out(hw, !!period); + if (err) + return err; + } + /* 1. Write perout with half of required period value. * HW toggles output when source clock hits the TGT and then adds * GLTSYN_CLKO value to the target, so it ends up with 50% duty cycle. diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index 07ecf2a86742..6dff422b7f4e 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -661,6 +661,29 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw, return 0; } +#define ICE_ONE_PPS_OUT_AMP_MAX 3 + +/** + * ice_cgu_cfg_pps_out - Configure 1PPS output from CGU + * @hw: pointer to the HW struct + * @enable: true to enable 1PPS output, false to disable it + * + * Return: 0 on success, other negative error code when CGU read/write failed + */ +int ice_cgu_cfg_pps_out(struct ice_hw *hw, bool enable) +{ + union nac_cgu_dword9 dw9; + int err; + + err = ice_read_cgu_reg_e82x(hw, NAC_CGU_DWORD9, &dw9.val); + if (err) + return err; + + dw9.one_pps_out_en = enable; + dw9.one_pps_out_amp = enable * ICE_ONE_PPS_OUT_AMP_MAX; + return ice_write_cgu_reg_e82x(hw, NAC_CGU_DWORD9, dw9.val); +} + /** * ice_cfg_cgu_pll_dis_sticky_bits_e82x - disable TS PLL sticky bits * @hw: pointer to the HW struct diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index ff98f76969e3..fc946fcd28b9 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -331,6 +331,7 @@ extern const struct ice_vernier_info_e82x e822_vernier[NUM_ICE_PTP_LNK_SPD]; /* Device agnostic functions */ u8 ice_get_ptp_src_clock_index(struct ice_hw *hw); +int ice_cgu_cfg_pps_out(struct ice_hw *hw, bool enable); bool ice_ptp_lock(struct ice_hw *hw); void ice_ptp_unlock(struct ice_hw *hw); void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd);