Commit 214da634 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'ptp-add-pulse-signal-loopback-support-for-debugging'

Wei Fang says:

====================
ptp: add pulse signal loopback support for debugging

Some PTP devices support looping back the periodic pulse signal for
debugging. For example, the PTP device of QorIQ platform and the NETC v4
Timer has the ability to loop back the pulse signal and record the extts
events for the loopback signal. So we can make sure that the pulse
intervals and their phase alignment are correct from the perspective of
the emitting PHC's time base. In addition, we can use this loopback
feature as a built-in extts event generator when we have no external
equipment which does that. Therefore, add the generic debugfs interfaces
to the ptp_clock driver. The first two patch are separated from the
previous patch set [1]. The third patch is new added.

[1]: https://lore.kernel.org/imx/20250827063332.1217664-1-wei.fang@nxp.com/ #patch 3 and 9
====================

Link: https://patch.msgid.link/20250905030711.1509648-1-wei.fang@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents cf71bdf6 f3164840
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -9817,7 +9817,6 @@ F: drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp*
F:	drivers/net/ethernet/freescale/dpaa2/dprtc*
F:	drivers/net/ethernet/freescale/enetc/enetc_ptp.c
F:	drivers/ptp/ptp_qoriq.c
F:	drivers/ptp/ptp_qoriq_debugfs.c
F:	include/linux/fsl/ptp_qoriq.h
FREESCALE QUAD SPI DRIVER
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ config PTP_1588_CLOCK_QORIQ
	  packets using the SO_TIMESTAMPING API.

	  To compile this driver as a module, choose M here: the module
	  will be called ptp-qoriq.
	  will be called ptp_qoriq.

comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks."
	depends on PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n
+1 −3
Original line number Diff line number Diff line
@@ -12,9 +12,7 @@ obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o
obj-$(CONFIG_PTP_1588_CLOCK_PCH)	+= ptp_pch.o
obj-$(CONFIG_PTP_1588_CLOCK_KVM)	+= ptp_kvm.o
obj-$(CONFIG_PTP_1588_CLOCK_VMCLOCK)	+= ptp_vmclock.o
obj-$(CONFIG_PTP_1588_CLOCK_QORIQ)	+= ptp-qoriq.o
ptp-qoriq-y				+= ptp_qoriq.o
ptp-qoriq-$(CONFIG_DEBUG_FS)		+= ptp_qoriq_debugfs.o
obj-$(CONFIG_PTP_1588_CLOCK_QORIQ)	+= ptp_qoriq.o
obj-$(CONFIG_PTP_1588_CLOCK_IDTCM)	+= ptp_clockmatrix.o
obj-$(CONFIG_PTP_1588_CLOCK_FC3W)	+= ptp_fc3.o
obj-$(CONFIG_PTP_1588_CLOCK_IDT82P33)	+= ptp_idt82p33.o
+69 −0
Original line number Diff line number Diff line
@@ -248,6 +248,69 @@ static void ptp_aux_kworker(struct kthread_work *work)
		kthread_queue_delayed_work(ptp->kworker, &ptp->aux_work, delay);
}

static ssize_t ptp_n_perout_loopback_read(struct file *filep,
					  char __user *buffer,
					  size_t count, loff_t *pos)
{
	struct ptp_clock *ptp = filep->private_data;
	char buf[12] = {};

	snprintf(buf, sizeof(buf), "%d\n", ptp->info->n_per_lp);

	return simple_read_from_buffer(buffer, count, pos, buf, strlen(buf));
}

static const struct file_operations ptp_n_perout_loopback_fops = {
	.owner	= THIS_MODULE,
	.open	= simple_open,
	.read	= ptp_n_perout_loopback_read,
};

static ssize_t ptp_perout_loopback_write(struct file *filep,
					 const char __user *buffer,
					 size_t count, loff_t *ppos)
{
	struct ptp_clock *ptp = filep->private_data;
	struct ptp_clock_info *ops = ptp->info;
	unsigned int index, enable;
	int len, cnt, err;
	char buf[32] = {};

	if (*ppos || !count)
		return -EINVAL;

	if (count >= sizeof(buf))
		return -ENOSPC;

	len = simple_write_to_buffer(buf, sizeof(buf) - 1,
				     ppos, buffer, count);
	if (len < 0)
		return len;

	buf[len] = '\0';
	cnt = sscanf(buf, "%u %u", &index, &enable);
	if (cnt != 2)
		return -EINVAL;

	if (index >= ops->n_per_lp)
		return -EINVAL;

	if (enable != 0 && enable != 1)
		return -EINVAL;

	err = ops->perout_loopback(ops, index, enable);
	if (err)
		return err;

	return count;
}

static const struct file_operations ptp_perout_loopback_ops = {
	.owner   = THIS_MODULE,
	.open    = simple_open,
	.write	 = ptp_perout_loopback_write,
};

/* public interface */

struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
@@ -389,6 +452,12 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
	/* Debugfs initialization */
	snprintf(debugfsname, sizeof(debugfsname), "ptp%d", ptp->index);
	ptp->debugfs_root = debugfs_create_dir(debugfsname, NULL);
	if (info->n_per_lp > 0 && info->perout_loopback) {
		debugfs_create_file("n_perout_loopback", 0400, ptp->debugfs_root,
				    ptp, &ptp_n_perout_loopback_fops);
		debugfs_create_file("perout_loopback", 0200, ptp->debugfs_root,
				    ptp, &ptp_perout_loopback_ops);
	}

	return ptp;

+25 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#define  TMR_ETEP(i)			BIT(8 + (i))
#define  TMR_COMP_MODE			BIT(15)
#define  TMR_CTRL_TCLK_PERIOD		GENMASK(25, 16)
#define  TMR_CTRL_PPL(i)		BIT(27 - (i))
#define  TMR_CTRL_FS			BIT(28)

#define NETC_TMR_TEVENT			0x0084
@@ -609,6 +610,28 @@ static int netc_timer_enable(struct ptp_clock_info *ptp,
	}
}

static int netc_timer_perout_loopback(struct ptp_clock_info *ptp,
				      unsigned int index, int on)
{
	struct netc_timer *priv = ptp_to_netc_timer(ptp);
	unsigned long flags;
	u32 tmr_ctrl;

	spin_lock_irqsave(&priv->lock, flags);

	tmr_ctrl = netc_timer_rd(priv, NETC_TMR_CTRL);
	if (on)
		tmr_ctrl |= TMR_CTRL_PPL(index);
	else
		tmr_ctrl &= ~TMR_CTRL_PPL(index);

	netc_timer_wr(priv, NETC_TMR_CTRL, tmr_ctrl);

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}

static void netc_timer_adjust_period(struct netc_timer *priv, u64 period)
{
	u32 fractional_period = lower_32_bits(period);
@@ -717,6 +740,7 @@ static const struct ptp_clock_info netc_timer_ptp_caps = {
	.pps		= 1,
	.n_per_out	= 3,
	.n_ext_ts	= 2,
	.n_per_lp	= 2,
	.supported_extts_flags = PTP_RISING_EDGE | PTP_FALLING_EDGE |
				 PTP_STRICT_FLAGS,
	.adjfine	= netc_timer_adjfine,
@@ -724,6 +748,7 @@ static const struct ptp_clock_info netc_timer_ptp_caps = {
	.gettimex64	= netc_timer_gettimex64,
	.settime64	= netc_timer_settime64,
	.enable		= netc_timer_enable,
	.perout_loopback = netc_timer_perout_loopback,
};

static void netc_timer_init(struct netc_timer *priv)
Loading