linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: christopher.s.hall@intel.com
To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	tglx@linutronix.de, hpa@zytor.com, mingo@redhat.com,
	x86@kernel.org, jacob.e.keller@intel.com,
	richardcochran@gmail.com, davem@davemloft.net,
	sean.v.kelley@intel.com
Cc: Christopher Hall <christopher.s.hall@intel.com>
Subject: [Intel PMC TGPIO Driver 2/5] drivers/ptp: Add PEROUT2 ioctl frequency adjustment interface
Date: Wed, 11 Dec 2019 13:48:49 -0800	[thread overview]
Message-ID: <20191211214852.26317-3-christopher.s.hall@intel.com> (raw)
In-Reply-To: <20191211214852.26317-1-christopher.s.hall@intel.com>

From: Christopher Hall <christopher.s.hall@intel.com>

The Intel PMC TGPIO controller logic is driven by ART which is not adjust-
able. Rather than adjusting the clock frequency, an output frequency
adjustment method is added that doesn't require restarting or resetting
output.

Output frequency adjustment is achieved by adding a flag to be passed in
the PEROUT2 ioctl argument. In this case, the driver should disregard the
'start' time field and adjust the hardware output frequency if periodic
output is already "running".

For devices with an adjustable clock, the OFFSET_PRECISE* ioctl is used to
compute the device clock offset with respect to the system clock. For
non-adjustable clocks, the EVENT_COUNT_TSTAMP2 ioctl adds an analogous
relation between output edges and elapsed time device time. This tuple is
captured simultaneously in hardware and is used to precisely compute the
*actual* average cumulative output frequency relative to the device clock.
The actual average is used to adjust the output period to achieve the
*desired* cumulative output frequency.

Signed-off-by: Christopher Hall <christopher.s.hall@intel.com>
---
 drivers/ptp/ptp_chardev.c        | 26 ++++++++++++++++++++++++++
 include/linux/ptp_clock_kernel.h |  2 ++
 include/uapi/linux/ptp_clock.h   | 25 +++++++++++++++++++++++--
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index f9ad6df57fa5..04c51878723d 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -134,6 +134,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
 	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
 	struct ptp_sys_offset_extended *extoff = NULL;
 	struct ptp_sys_offset_precise precise_offset;
+	struct ptp_event_count_tstamp counttstamp;
 	struct system_device_crosststamp xtstamp;
 	struct ptp_clock_info *ops = ptp->info;
 	struct ptp_sys_offset *sysoff = NULL;
@@ -218,6 +219,13 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
 			req.perout.flags &= PTP_PEROUT_V1_VALID_FLAGS;
 			zero_rsv_field(req.perout.rsv);
 		}
+		/* These flags don't make sense together */
+		if (cmd == PTP_PEROUT_REQUEST2 &&
+		    req.perout.flags & PTP_PEROUT_FREQ_ADJ &&
+		    req.perout.flags & PTP_PEROUT_ONE_SHOT) {
+			err = -EINVAL;
+			break;
+		}
 		if (req.perout.index >= ops->n_per_out) {
 			err = -EINVAL;
 			break;
@@ -227,6 +235,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
 		err = ops->enable(ops, &req, enable);
 		break;
 
+	case PTP_EVENT_COUNT_TSTAMP2:
+		if (!ops->counttstamp)
+			return -ENOTSUPP;
+		if (copy_from_user(&counttstamp, (void __user *)arg,
+				   sizeof(counttstamp))) {
+			err = -EFAULT;
+			break;
+		}
+		if (check_rsv_field(counttstamp.rsv)) {
+			err = -EINVAL;
+			break;
+		}
+		err = ops->counttstamp(ops, &counttstamp);
+		if (!err && copy_to_user((void __user *)arg, &counttstamp,
+						sizeof(counttstamp)))
+			err = -EFAULT;
+		break;
+
 	case PTP_ENABLE_PPS:
 	case PTP_ENABLE_PPS2:
 		memset(&req, 0, sizeof(req));
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index 93cc4f1d444a..8223f6f656dd 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -134,6 +134,8 @@ struct ptp_clock_info {
 			  struct ptp_system_timestamp *sts);
 	int (*getcrosststamp)(struct ptp_clock_info *ptp,
 			      struct system_device_crosststamp *cts);
+	int (*counttstamp)(struct ptp_clock_info *ptp,
+			   struct ptp_event_count_tstamp *count);
 	int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts);
 	int (*enable)(struct ptp_clock_info *ptp,
 		      struct ptp_clock_request *request, int on);
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index 9dc9d0079e98..ecb4c4e49205 100644
--- a/include/uapi/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
@@ -34,6 +34,11 @@
 #define PTP_STRICT_FLAGS   (1<<3)
 #define PTP_EXTTS_EDGES    (PTP_RISING_EDGE | PTP_FALLING_EDGE)
 
+/*
+ * Bits of the ptp_pin_desc.flags field:
+ */
+#define PTP_PINDESC_EVTCNTVALID	(1<<0)
+
 /*
  * flag fields valid for the new PTP_EXTTS_REQUEST2 ioctl.
  */
@@ -54,11 +59,13 @@
  * Bits of the ptp_perout_request.flags field:
  */
 #define PTP_PEROUT_ONE_SHOT (1<<0)
+#define PTP_PEROUT_FREQ_ADJ (1<<1)
 
 /*
  * flag fields valid for the new PTP_PEROUT_REQUEST2 ioctl.
  */
-#define PTP_PEROUT_VALID_FLAGS	(PTP_PEROUT_ONE_SHOT)
+#define PTP_PEROUT_VALID_FLAGS	(PTP_PEROUT_ONE_SHOT |	\
+				 PTP_PEROUT_FREQ_ADJ)
 
 /*
  * No flags are valid for the original PTP_PEROUT_REQUEST ioctl
@@ -106,6 +113,14 @@ struct ptp_perout_request {
 	unsigned int rsv[4];          /* Reserved for future use. */
 };
 
+struct ptp_event_count_tstamp {
+	struct ptp_clock_time device_time;
+	unsigned long long event_count;
+	unsigned int index;
+	unsigned int flags;
+	unsigned int rsv[4];          /* Reserved for future use. */
+};
+
 #define PTP_MAX_SAMPLES 25 /* Maximum allowed offset measurement samples. */
 
 struct ptp_sys_offset {
@@ -164,10 +179,14 @@ struct ptp_pin_desc {
 	 * PTP_EXTTS_REQUEST and PTP_PEROUT_REQUEST ioctls.
 	 */
 	unsigned int chan;
+	/*
+	 * Per pin capability flag
+	 */
+	unsigned int flags;
 	/*
 	 * Reserved for future use.
 	 */
-	unsigned int rsv[5];
+	unsigned int rsv[4];
 };
 
 #define PTP_CLK_MAGIC '='
@@ -195,6 +214,8 @@ struct ptp_pin_desc {
 	_IOWR(PTP_CLK_MAGIC, 17, struct ptp_sys_offset_precise)
 #define PTP_SYS_OFFSET_EXTENDED2 \
 	_IOWR(PTP_CLK_MAGIC, 18, struct ptp_sys_offset_extended)
+#define PTP_EVENT_COUNT_TSTAMP2 \
+	_IOWR(PTP_CLK_MAGIC, 19, struct ptp_event_count_tstamp)
 
 struct ptp_extts_event {
 	struct ptp_clock_time t; /* Time event occured. */
-- 
2.21.0


  parent reply	other threads:[~2020-01-31  6:40 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-11 21:48 [Intel PMC TGPIO Driver 0/5] Add support for Intel PMC Time GPIO Driver with PHC interface changes to support additional H/W Features christopher.s.hall
2019-12-11 21:48 ` [Intel PMC TGPIO Driver 1/5] drivers/ptp: Add Enhanced handling of reserve fields christopher.s.hall
2020-01-31 16:54   ` Jacob Keller
2020-02-03  1:45     ` Richard Cochran
2020-02-24 23:29       ` Christopher S. Hall
2020-01-31 17:02   ` Jacob Keller
2020-02-03  1:27   ` Richard Cochran
2020-02-24 23:23     ` Christopher S. Hall
2019-12-11 21:48 ` christopher.s.hall [this message]
2020-02-03  2:14   ` [Intel PMC TGPIO Driver 2/5] drivers/ptp: Add PEROUT2 ioctl frequency adjustment interface Richard Cochran
2020-02-26  0:20     ` Christopher S. Hall
2019-12-11 21:48 ` [Intel PMC TGPIO Driver 3/5] drivers/ptp: Add user-space input polling interface christopher.s.hall
2020-02-03  2:28   ` Richard Cochran
2019-12-11 21:48 ` [Intel PMC TGPIO Driver 4/5] x86/tsc: Add TSC support functions to support ART driven Time-Aware GPIO christopher.s.hall
2019-12-11 21:48 ` [Intel PMC TGPIO Driver 5/5] drivers/ptp: Add PMC Time-Aware GPIO Driver christopher.s.hall
2020-02-03  2:31   ` Richard Cochran
2020-02-07 17:10   ` Linus Walleij
2020-02-07 17:28     ` Andrew Lunn
2020-02-07 19:49       ` Andy Shevchenko
2020-02-07 19:52         ` Andy Shevchenko
2020-02-24 23:17     ` Christopher S. Hall
2020-01-31 15:08 ` [Intel PMC TGPIO Driver 0/5] Add support for Intel PMC Time GPIO Driver with PHC interface changes to support additional H/W Features Jakub Kicinski
2020-01-31 18:14 ` Thomas Gleixner
2020-02-24 22:40   ` Christopher S. Hall
2020-02-26 23:06     ` Thomas Gleixner
2020-03-03  1:56       ` Christopher S. Hall
2020-03-03 13:00       ` Linus Walleij
2020-03-03 15:23         ` Richard Cochran
2020-03-03 15:24         ` Thomas Gleixner
2020-03-08 19:14           ` Jonathan Cameron
2020-02-03  4:08 ` Richard Cochran
2020-02-03 18:27   ` Jacob Keller
2020-02-25 23:37   ` Christopher S. Hall
2020-02-26  2:47     ` Richard Cochran
2020-03-03  2:01       ` Christopher S. Hall
2020-02-07 17:17 ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191211214852.26317-3-christopher.s.hall@intel.com \
    --to=christopher.s.hall@intel.com \
    --cc=davem@davemloft.net \
    --cc=hpa@zytor.com \
    --cc=jacob.e.keller@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=sean.v.kelley@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).