Commit 26017cff authored by Karol Kolacinski's avatar Karol Kolacinski Committed by Tony Nguyen
Browse files

ice: Implement ice_ptp_pin_desc



Add a new internal structure describing PTP pins.
Use the new structure for all non-E810T products.

Reviewed-by: default avatarArkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: default avatarKarol Kolacinski <karol.kolacinski@intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 44badc90
Loading
Loading
Loading
Loading
+170 −86
Original line number Diff line number Diff line
@@ -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, {  4, -1 }},
	{  ONE_PPS,   { -1,  5 }},
};

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, { -1, 5 }},
};

#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
@@ -1900,13 +1947,13 @@ 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,
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);
@@ -1930,22 +1977,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);
@@ -1960,13 +2003,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;
@@ -1981,34 +2022,89 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
}

/**
 * ice_ptp_gpio_enable_e823 - Enable/disable ancillary features of PHC
 * ice_verify_pin - verify if pin supports requested pin function
 * @info: the driver's PTP info structure
 * @pin: Pin index
 * @func: Assigned function
 * @chan: Assigned channel
 *
 * Return: 0 on success, -EOPNOTSUPP when function is not supported.
 */
static int ice_verify_pin(struct ptp_clock_info *info, unsigned int pin,
			  enum ptp_pin_function func, unsigned int chan)
{
	struct ice_pf *pf = ptp_info_to_pf(info);
	const struct ice_ptp_pin_desc *pin_desc;

	pin_desc = &pf->ptp.ice_pin_desc[pin];

	/* Is assigned function allowed? */
	switch (func) {
	case PTP_PF_EXTTS:
		if (pin_desc->gpio[0] < 0)
			return -EOPNOTSUPP;
		break;
	case PTP_PF_PEROUT:
		if (pin_desc->gpio[1] < 0)
			return -EOPNOTSUPP;
		break;
	case PTP_PF_NONE:
		break;
	case PTP_PF_PHYSYNC:
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

/**
 * ice_ptp_gpio_enable - Enable/disable ancillary features of PHC
 * @info: The driver's PTP info structure
 * @rq: The requested feature to change
 * @on: Enable/disable flag
 *
 * Return: 0 on success, -EOPNOTSUPP when request type is not supported
 */
static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info,
static int ice_ptp_gpio_enable(struct ptp_clock_info *info,
			       struct ptp_clock_request *rq, int on)
{
	struct ice_pf *pf = ptp_info_to_pf(info);

	switch (rq->type) {
	case PTP_CLK_REQ_PPS:
	case PTP_CLK_REQ_PEROUT:
	{
		struct ice_perout_channel clk_cfg = {};
		struct ice_perout_channel clk_cfg;
		int pin_desc_idx;

		pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT,
						    rq->perout.index);
		if (pin_desc_idx < 0)
			return -EIO;


		clk_cfg.flags = rq->perout.flags;
		clk_cfg.gpio_pin = PPS_PIN_INDEX;
		clk_cfg.period = NSEC_PER_SEC;
		clk_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[1];
		clk_cfg.period = rq->perout.period.sec * NSEC_PER_SEC +
				 rq->perout.period.nsec;
		clk_cfg.start_time = rq->perout.start.sec * NSEC_PER_SEC +
				     rq->perout.start.nsec;
		clk_cfg.ena = !!on;

		return ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
		return ice_ptp_cfg_clkout(pf, rq->perout.index, &clk_cfg, true);
	}
	case PTP_CLK_REQ_EXTTS:
	{
		struct ice_extts_channel extts_cfg = {};
		int pin_desc_idx;

		pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS,
						    rq->extts.index);
		if (pin_desc_idx < 0)
			return -EIO;

		extts_cfg.flags = rq->extts.flags;
		extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX;
		extts_cfg.gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[0];
		extts_cfg.ena = !!on;

		return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
@@ -2404,6 +2500,26 @@ 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)
{
	for (unsigned int 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;
	}

	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
@@ -2457,61 +2573,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)
static void ice_ptp_setup_pins_e810t(struct ice_pf *pf)
{
	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;
	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, 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)
{
	info->pps = 1;
	info->n_per_out = 0;
	info->n_ext_ts = 1;
	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);
}

/**
@@ -2527,27 +2623,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);
	if (ice_is_e810t(&pf->hw) &&
	    ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) {
		ice_ptp_setup_pins_e810t(pf);
		return;
	}

/**
 * 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);

	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);
}

/**
@@ -2567,13 +2651,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);
}

/**
+44 −21
Original line number Diff line number Diff line
@@ -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;
@@ -289,27 +333,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);