* [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling
@ 2024-06-27 15:09 Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc Karol Kolacinski
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski
This series cleans up current PTP GPIO pin handling, fixes minor bugs,
refactors implementation for all products, introduces SDP (Software
Definable Pins) for E825C and implements reading SDP section from NVM
for E810 products.
Karol Kolacinski (5):
ice: Implement ice_ptp_pin_desc
ice: Add SDPs support for E825C
ice: Align E810T GPIO to other products
ice: Cache perout/extts requests and check flags
ice: Disable shared pin on E810 on setfunc
Sergey Temerkhanov (1):
ice: Enable 1PPS out from CGU for E825C products
Yochai Hagvi (1):
ice: Read SDP section from NVM for pin definitions
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 9 +
drivers/net/ethernet/intel/ice/ice_gnss.c | 4 +-
drivers/net/ethernet/intel/ice/ice_ptp.c | 1129 +++++++++--------
drivers/net/ethernet/intel/ice/ice_ptp.h | 119 +-
.../net/ethernet/intel/ice/ice_ptp_consts.h | 2 +-
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 101 +-
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 72 +-
7 files changed, 800 insertions(+), 636 deletions(-)
base-commit: 6a788e1f6ddc6750a553314403136b1be9301cf5
--
2.45.2
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-07-01 13:23 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 2/7] ice: Add SDPs support for E825C Karol Kolacinski
` (5 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski,
Arkadiusz Kubalewski
Add a new internal structure describing PTP pins.
Use the new structure for all non-E810T products.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 271 ++++++++++++++++-------
drivers/net/ethernet/intel/ice/ice_ptp.h | 65 ++++--
2 files changed, 229 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..28b82c634194 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,90 @@ 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);
+ int err;
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 +2506,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 +2593,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
+ * 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_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
- * @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 +2643,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 +2671,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);
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 2/7] ice: Add SDPs support for E825C
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-07-01 13:25 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products Karol Kolacinski
` (4 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski,
Arkadiusz Kubalewski
Add support of PTP SDPs (Software Definable Pins) for E825C products.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 28b82c634194..e38563905ca7 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 }},
@@ -2623,9 +2633,13 @@ 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;
- pf->ptp.ice_pin_desc = 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);
+ }
pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x);
ice_ptp_setup_pin_cfg(pf);
}
@@ -2673,6 +2687,8 @@ 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);
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 2/7] ice: Add SDPs support for E825C Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-07-01 13:25 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags Karol Kolacinski
` (3 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski,
Arkadiusz Kubalewski
Instead of having separate PTP GPIO implementation for E810T, use
existing one from all other products.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
drivers/net/ethernet/intel/ice/ice_gnss.c | 4 +-
drivers/net/ethernet/intel/ice/ice_ptp.c | 460 +++++---------------
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, 153 insertions(+), 403 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 e38563905ca7..53885ba71ca8 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 }},
};
/**
@@ -72,242 +78,99 @@ static int ice_ptp_find_pin_idx(struct ice_pf *pf, enum ptp_pin_function func,
return -1;
}
-
/**
- * 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;
-
- /* 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;
- }
+ const char *state1, *state2;
- /* 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 +1825,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
@@ -2531,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) {
@@ -2551,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;
@@ -2573,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;
- /* Complete setup of the SMA pins */
- ice_ptp_setup_sma_pins_e810t(pf, &pf->ptp.info);
+ 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);
+
+ /* Clear SMA status */
+ err = ice_ptp_set_sma_cfg(pf);
+ if (err)
+ ice_ptp_disable_sma_pins(pf);
}
/**
@@ -2647,15 +2413,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)) {
@@ -2691,7 +2455,7 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
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 <linux/kthread.h>
#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 */
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
` (2 preceding siblings ...)
2024-06-27 15:09 ` [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-07-01 13:26 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc Karol Kolacinski
` (2 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski,
Arkadiusz Kubalewski
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 <arkadiusz.kubalewski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 353 +++++++++---------
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, 215 insertions(+), 194 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 53885ba71ca8..82b30ea0c8bf 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -1576,33 +1576,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;
@@ -1611,33 +1619,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;
}
@@ -1648,16 +1662,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);
}
@@ -1670,159 +1680,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);
}
/**
@@ -1868,7 +1894,7 @@ 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)
@@ -1879,40 +1905,29 @@ static int ice_ptp_gpio_enable(struct ptp_clock_info *info,
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 +1987,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 +1996,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 +2058,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);
@@ -2659,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);
@@ -2736,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;
@@ -3316,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..d5bc93036200 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
@@ -8,19 +8,6 @@
#include <linux/kthread.h>
#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,18 @@ 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
+<<<<<<< HEAD
* @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
+>>>>>>> de618462ed43 (ice: Cache perout/extts requests and check flags)
* @info: structure defining PTP hardware capabilities
* @clock: pointer to registered PTP clock device
* @tstamp_config: hardware timestamping configuration
@@ -285,13 +277,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
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
` (3 preceding siblings ...)
2024-06-27 15:09 ` [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-07-01 13:27 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 6/7] ice: Read SDP section from NVM for pin definitions Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Karol Kolacinski
6 siblings, 1 reply; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Karol Kolacinski,
Arkadiusz Kubalewski
When setting a new supported function for a pin on E810, disable other
enabled pin that shares the same GPIO.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
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 82b30ea0c8bf..467675dd2693 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -1851,6 +1851,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
@@ -1885,6 +1942,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_e810t(pf);
+ }
+
return 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 6/7] ice: Read SDP section from NVM for pin definitions
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
` (4 preceding siblings ...)
2024-06-27 15:09 ` [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Karol Kolacinski
6 siblings, 0 replies; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Yochai Hagvi,
Arkadiusz Kubalewski, Karol Kolacinski
From: Yochai Hagvi <yochai.hagvi@intel.com>
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 <arkadiusz.kubalewski@intel.com>
Signed-off-by: Yochai Hagvi <yochai.hagvi@intel.com>
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 9 ++
drivers/net/ethernet/intel/ice/ice_ptp.c | 140 ++++++++++++++----
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, 187 insertions(+), 29 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 467675dd2693..d9ff94a4b293 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 }},
@@ -1947,7 +1947,7 @@ static int ice_verify_pin(struct ptp_clock_info *info, unsigned int pin,
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_e810t(pf);
+ return ice_ptp_set_sma_cfg(pf);
}
return 0;
@@ -2401,8 +2401,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));
@@ -2423,17 +2423,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;
@@ -2443,23 +2443,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 d5bc93036200..b6694dc25122 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);
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
` (5 preceding siblings ...)
2024-06-27 15:09 ` [PATCH iwl-next 6/7] ice: Read SDP section from NVM for pin definitions Karol Kolacinski
@ 2024-06-27 15:09 ` Karol Kolacinski
2024-06-27 15:37 ` [Intel-wired-lan] " Paul Menzel
2024-07-01 13:27 ` Simon Horman
6 siblings, 2 replies; 18+ messages in thread
From: Karol Kolacinski @ 2024-06-27 15:09 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, Sergey Temerkhanov,
Arkadiusz Kubalewski, Karol Kolacinski
From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Implement 1PPS signal enabling/disabling in CGU. The amplitude is
always the maximum in this implementation
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 10 ++++++++++
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 21 +++++++++++++++++++++
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
3 files changed, 32 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index d9ff94a4b293..b97ea2b61e5c 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",
@@ -1708,6 +1709,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_ena_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..fa7cf8453b88 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -661,6 +661,27 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw,
return 0;
}
+#define ICE_ONE_PPS_OUT_AMP_MAX 3
+
+/**
+ * ice_cgu_ena_pps_out - Enable/disable 1PPS output
+ * @hw: pointer to the HW struct
+ * @ena: Enable/disable 1PPS output
+ */
+int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
+{
+ 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 = ena;
+ dw9.one_pps_out_amp = ena * 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..382e84568256 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_ena_pps_out(struct ice_hw *hw, bool ena);
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);
--
2.45.2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Intel-wired-lan] [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-06-27 15:09 ` [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Karol Kolacinski
@ 2024-06-27 15:37 ` Paul Menzel
2024-07-01 13:49 ` Kolacinski, Karol
2024-07-01 13:27 ` Simon Horman
1 sibling, 1 reply; 18+ messages in thread
From: Paul Menzel @ 2024-06-27 15:37 UTC (permalink / raw)
To: Karol Kolacinski, Sergey Temerkhanov
Cc: intel-wired-lan, netdev, Arkadiusz Kubalewski, anthony.l.nguyen,
przemyslaw.kitszel
Dear Karol, dear Sergey,
Thank you for the patch.
Am 27.06.24 um 17:09 schrieb Karol Kolacinski:
> From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
>
> Implement 1PPS signal enabling/disabling in CGU. The amplitude is
> always the maximum in this implementation
(Please add a dot/period at the end of sentences.)
Could you please elaborate why using the maximum is alright, that means
what are the downsides, and what is the alternative approahc.
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
> Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
> ---
> drivers/net/ethernet/intel/ice/ice_ptp.c | 10 ++++++++++
> drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 21 +++++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
> 3 files changed, 32 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
> index d9ff94a4b293..b97ea2b61e5c 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",
> @@ -1708,6 +1709,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_ena_pps_out(hw, !!period);
> + if (err)
> + return err;
> + }
Does only E825C products support this feature?
> +
> /* 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..fa7cf8453b88 100644
> --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> @@ -661,6 +661,27 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw,
> return 0;
> }
>
> +#define ICE_ONE_PPS_OUT_AMP_MAX 3
> +
> +/**
> + * ice_cgu_ena_pps_out - Enable/disable 1PPS output
> + * @hw: pointer to the HW struct
> + * @ena: Enable/disable 1PPS output
> + */
> +int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
Is `ena` short for 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 = ena;
> + dw9.one_pps_out_amp = ena * 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..382e84568256 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_ena_pps_out(struct ice_hw *hw, bool ena);
If *ena* means “enable”, I do not like this pattern very much, and I’d
prefer an enable and a disable function.
> 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);
Kind regards,
Paul
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc
2024-06-27 15:09 ` [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc Karol Kolacinski
@ 2024-07-01 13:23 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:23 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:25PM +0200, Karol Kolacinski wrote:
> Add a new internal structure describing PTP pins.
> Use the new structure for all non-E810T products.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
> ---
> drivers/net/ethernet/intel/ice/ice_ptp.c | 271 ++++++++++++++++-------
> drivers/net/ethernet/intel/ice/ice_ptp.h | 65 ++++--
> 2 files changed, 229 insertions(+), 107 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
...
> +/**
> + * 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);
> + int err;
nit: This appears to be resolved by a subsequent patch in this series,
but err is unused in this function.
Flagged by W=1 allmodconfig builds on x86_64 with gcc-13 and clang-18.
>
> 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);
...
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 2/7] ice: Add SDPs support for E825C
2024-06-27 15:09 ` [PATCH iwl-next 2/7] ice: Add SDPs support for E825C Karol Kolacinski
@ 2024-07-01 13:25 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:25 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:26PM +0200, Karol Kolacinski wrote:
> Add support of PTP SDPs (Software Definable Pins) for E825C products.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
...
> @@ -2623,9 +2633,13 @@ 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;
> - pf->ptp.ice_pin_desc = 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);
> + }
> pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x);
Hi Karol,
Maybe I'm reading it wrong, but should the line immediately
above be remove to avoid overwriting the value for pf->ptp.info.n_pins
set in the new if/else condition above?
> ice_ptp_setup_pin_cfg(pf);
> }
> @@ -2673,6 +2687,8 @@ 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);
Moving these assignments seems unnecessary, but ok.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products
2024-06-27 15:09 ` [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products Karol Kolacinski
@ 2024-07-01 13:25 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:25 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:27PM +0200, Karol Kolacinski wrote:
> Instead of having separate PTP GPIO implementation for E810T, use
> existing one from all other products.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
...
> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
...
> @@ -72,242 +78,99 @@ static int ice_ptp_find_pin_idx(struct ice_pf *pf, enum ptp_pin_function func,
>
> return -1;
> }
> -
nit: I think this blank line should stay
> /**
> - * 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)
...
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags
2024-06-27 15:09 ` [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags Karol Kolacinski
@ 2024-07-01 13:26 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:26 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:28PM +0200, Karol Kolacinski wrote:
> 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 <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
...
> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
...
> @@ -259,13 +246,18 @@ 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
> +<<<<<<< HEAD
> * @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
> +>>>>>>> de618462ed43 (ice: Cache perout/extts requests and check flags)
> * @info: structure defining PTP hardware capabilities
> * @clock: pointer to registered PTP clock device
> * @tstamp_config: hardware timestamping configuration
I think something went wrong when resolving a merge at some point :)
...
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc
2024-06-27 15:09 ` [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc Karol Kolacinski
@ 2024-07-01 13:27 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:27 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:29PM +0200, Karol Kolacinski wrote:
> When setting a new supported function for a pin on E810, disable other
> enabled pin that shares the same GPIO.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
> ---
> 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
...
> @@ -1885,6 +1942,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_e810t(pf);
This appears to be resolved in the following patch by calling
ice_ptp_set_sma_cfg_() instead, but this fails to build because
ice_ptp_set_sma_cfg_e810t() does not exits.
> + }
> +
> return 0;
> }
>
> --
> 2.45.2
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-06-27 15:09 ` [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Karol Kolacinski
2024-06-27 15:37 ` [Intel-wired-lan] " Paul Menzel
@ 2024-07-01 13:27 ` Simon Horman
2024-07-01 15:08 ` Przemek Kitszel
1 sibling, 1 reply; 18+ messages in thread
From: Simon Horman @ 2024-07-01 13:27 UTC (permalink / raw)
To: Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, przemyslaw.kitszel,
Sergey Temerkhanov, Arkadiusz Kubalewski
On Thu, Jun 27, 2024 at 05:09:31PM +0200, Karol Kolacinski wrote:
> From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
>
> Implement 1PPS signal enabling/disabling in CGU. The amplitude is
> always the maximum in this implementation
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
> Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
...
> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> index 07ecf2a86742..fa7cf8453b88 100644
> --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> @@ -661,6 +661,27 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw,
> return 0;
> }
>
> +#define ICE_ONE_PPS_OUT_AMP_MAX 3
> +
> +/**
> + * ice_cgu_ena_pps_out - Enable/disable 1PPS output
> + * @hw: pointer to the HW struct
> + * @ena: Enable/disable 1PPS output
Please include a "Returns: " or "Return: " section in the kernel doc
for functions that have a return value.
NIPA has recently got more picky about this.
Flagged by kernel-doc -none --Warn
> + */
> +int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
> +{
> + 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 = ena;
> + dw9.one_pps_out_amp = ena * 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
...
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Intel-wired-lan] [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-06-27 15:37 ` [Intel-wired-lan] " Paul Menzel
@ 2024-07-01 13:49 ` Kolacinski, Karol
0 siblings, 0 replies; 18+ messages in thread
From: Kolacinski, Karol @ 2024-07-01 13:49 UTC (permalink / raw)
To: Paul Menzel, Temerkhanov, Sergey
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
Kubalewski, Arkadiusz, Nguyen, Anthony L, Kitszel, Przemyslaw
Hi Paul,
Thank you for your feedback!
On 6/27/2024 5:37 PM, Paul Menzel wrote:
> > @@ -1708,6 +1709,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_ena_pps_out(hw, !!period);
> > + if (err)
> > + return err;
> > + }
>
> Does only E825C products support this feature?
Yes, it's only necessary for E825C, other products don't need or support
it.
> > +/**
> > + * ice_cgu_ena_pps_out - Enable/disable 1PPS output
> > + * @hw: pointer to the HW struct
> > + * @ena: Enable/disable 1PPS output
> > + */
> > +int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
>
> Is `ena` short for enable?
Yes. I guess for the function argument 'enable' would be better.
> > diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
> > index ff98f76969e3..382e84568256 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_ena_pps_out(struct ice_hw *hw, bool ena);
>
> If *ena* means “enable”, I do not like this pattern very much, and I’d
> prefer an enable and a disable function.
Good point regarding the name, I guess I should use 'cfg' instead of
'ena' in this case to be clear that this function doesn't only enable
PPS output.
That said, I don't see a point to use two separate functions for
a simple enable/disable functionality. From my point of view, ~20 lines
for 2 lines of actual code difference would be unnecessarily redundant.
Kind regards,
Karol
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-07-01 13:27 ` Simon Horman
@ 2024-07-01 15:08 ` Przemek Kitszel
2024-07-02 10:56 ` Simon Horman
0 siblings, 1 reply; 18+ messages in thread
From: Przemek Kitszel @ 2024-07-01 15:08 UTC (permalink / raw)
To: Simon Horman, Karol Kolacinski
Cc: intel-wired-lan, netdev, anthony.l.nguyen, Sergey Temerkhanov,
Arkadiusz Kubalewski
On 7/1/24 15:27, Simon Horman wrote:
> On Thu, Jun 27, 2024 at 05:09:31PM +0200, Karol Kolacinski wrote:
>> From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
>>
>> Implement 1PPS signal enabling/disabling in CGU. The amplitude is
>> always the maximum in this implementation
>>
>> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>> Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
>> Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
>> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
>
> ...
>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
>> index 07ecf2a86742..fa7cf8453b88 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
>> @@ -661,6 +661,27 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw,
>> return 0;
>> }
>>
>> +#define ICE_ONE_PPS_OUT_AMP_MAX 3
>> +
>> +/**
>> + * ice_cgu_ena_pps_out - Enable/disable 1PPS output
>> + * @hw: pointer to the HW struct
>> + * @ena: Enable/disable 1PPS output
>
> Please include a "Returns: " or "Return: " section in the kernel doc
> for functions that have a return value.
last time I have checked only the singular "Return:" was supported (aka
non-complained) by kdoc checker on W=2 builds
>
> NIPA has recently got more picky about this.
> Flagged by kernel-doc -none --Warn
>
>> + */
>> +int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
>> +{
>> + 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 = ena;
>> + dw9.one_pps_out_amp = ena * 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
>
> ...
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products
2024-07-01 15:08 ` Przemek Kitszel
@ 2024-07-02 10:56 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2024-07-02 10:56 UTC (permalink / raw)
To: Przemek Kitszel
Cc: Karol Kolacinski, intel-wired-lan, netdev, anthony.l.nguyen,
Sergey Temerkhanov, Arkadiusz Kubalewski
On Mon, Jul 01, 2024 at 05:08:09PM +0200, Przemek Kitszel wrote:
> On 7/1/24 15:27, Simon Horman wrote:
> > On Thu, Jun 27, 2024 at 05:09:31PM +0200, Karol Kolacinski wrote:
> > > From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
> > >
> > > Implement 1PPS signal enabling/disabling in CGU. The amplitude is
> > > always the maximum in this implementation
> > >
> > > Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> > > Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
> > > Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
> > > Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
> >
> > ...
> >
> > > diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> > > index 07ecf2a86742..fa7cf8453b88 100644
> > > --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> > > +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
> > > @@ -661,6 +661,27 @@ static int ice_cfg_cgu_pll_e825c(struct ice_hw *hw,
> > > return 0;
> > > }
> > > +#define ICE_ONE_PPS_OUT_AMP_MAX 3
> > > +
> > > +/**
> > > + * ice_cgu_ena_pps_out - Enable/disable 1PPS output
> > > + * @hw: pointer to the HW struct
> > > + * @ena: Enable/disable 1PPS output
> >
> > Please include a "Returns: " or "Return: " section in the kernel doc
> > for functions that have a return value.
>
> last time I have checked only the singular "Return:" was supported (aka
> non-complained) by kdoc checker on W=2 builds
Yes, agreed.
My point was that the kernel document should have a (correct :)
section to document the return value.
>
> >
> > NIPA has recently got more picky about this.
> > Flagged by kernel-doc -none --Warn
> >
> > > + */
> > > +int ice_cgu_ena_pps_out(struct ice_hw *hw, bool ena)
> > > +{
> > > + 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 = ena;
> > > + dw9.one_pps_out_amp = ena * 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
> >
> > ...
> >
>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2024-07-02 10:56 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-27 15:09 [PATCH iwl-next 0/7] ice: Cleanup and refactor PTP pin handling Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 1/7] ice: Implement ice_ptp_pin_desc Karol Kolacinski
2024-07-01 13:23 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 2/7] ice: Add SDPs support for E825C Karol Kolacinski
2024-07-01 13:25 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 3/7] ice: Align E810T GPIO to other products Karol Kolacinski
2024-07-01 13:25 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 4/7] ice: Cache perout/extts requests and check flags Karol Kolacinski
2024-07-01 13:26 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 5/7] ice: Disable shared pin on E810 on setfunc Karol Kolacinski
2024-07-01 13:27 ` Simon Horman
2024-06-27 15:09 ` [PATCH iwl-next 6/7] ice: Read SDP section from NVM for pin definitions Karol Kolacinski
2024-06-27 15:09 ` [PATCH iwl-next 7/7] ice: Enable 1PPS out from CGU for E825C products Karol Kolacinski
2024-06-27 15:37 ` [Intel-wired-lan] " Paul Menzel
2024-07-01 13:49 ` Kolacinski, Karol
2024-07-01 13:27 ` Simon Horman
2024-07-01 15:08 ` Przemek Kitszel
2024-07-02 10:56 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).