diff mbox series

[v2,net-next,1/3] ptp: Add adjphase function to support phase offset control.

Message ID 1588390538-24589-2-git-send-email-vincent.cheng.xh@renesas.com
State New
Headers show
Series [v2,net-next,1/3] ptp: Add adjphase function to support phase offset control. | expand

Commit Message

Vincent Cheng May 2, 2020, 3:35 a.m. UTC
From: Vincent Cheng <vincent.cheng.xh@renesas.com>

Adds adjust phase function to take advantage of a PHC
clock's hardware filtering capability that uses phase offset
control word instead of frequency offset control word.

Signed-off-by: Vincent Cheng <vincent.cheng.xh@renesas.com>
---
 drivers/ptp/ptp_clock.c          | 3 +++
 include/linux/ptp_clock_kernel.h | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

Comments

Vincent Cheng Aug. 4, 2022, 1:29 p.m. UTC | #1
Hi Aya,

>>+ * @adjphase:  Adjusts the phase offset of the hardware clock.
>>+ *             parameter delta: Desired change in nanoseconds.
>>+ *
>>   * @adjtime:  Shifts the time of the hardware clock.
>>   *            parameter delta: Desired change in nanoseconds.
>>   *
>>@@ -128,6 +131,7 @@ struct ptp_clock_info {
>>  	struct ptp_pin_desc *pin_config;
>>  	int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm);
>>  	int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
>>+	int (*adjphase)(struct ptp_clock_info *ptp, s32 phase);
>Hi,
>
>Please explain the difference in the output between adjphase and adjtime. I'd
>expect both to add delta to current time. Am I missing something?

Yes, both add delta to the current time and the 1 PPS should arrive at the same location.

adjtime modifies HW counter with a value to move the 1 PPS abruptly to new location.
adjphase modifies the frequency to quickly nudge the 1 PPS to new location and also includes a HW filter to smooth out the adjustments and fine tune frequency.

Continuous small offset adjustments using adjtime, likley see sudden shifts of the 1 PPS.  The 1 PPS probably disappears and re-appears.
Continuous small offset adjustments using adjphase, should see continuous 1 PPS.

adjtime is good for large offset corrections
adjphase is good for small offset corrections to allow HW filter to control the frequency instead of relying on SW filter.

On interruption of timestamps, adjphase HW can hold the frequency steady better since it has history of corrections.

ptp4l will switch to adjphase only if servo_offset_threshold and servo_num_offset_values conditions are met, ie. when offsets are stabalized below servo_offset_threshold.

adjphase is most useful for scnearios with minimal PDV.

Hope that helps.

Thanks,
Vincent

>
>Thanks, Aya
>>  	int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
>>  	int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
>>  	int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts,
diff mbox series

Patch

diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index acabbe7..fc984a8 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -146,6 +146,9 @@  static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
 		else
 			err = ops->adjfreq(ops, ppb);
 		ptp->dialed_frequency = tx->freq;
+	} else if (tx->modes & ADJ_OFFSET) {
+		if (ops->adjphase)
+			err = ops->adjphase(ops, tx->offset);
 	} else if (tx->modes == 0) {
 		tx->freq = ptp->dialed_frequency;
 		err = 0;
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index 121a7ed..31144d9 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -36,7 +36,7 @@  struct ptp_system_timestamp {
 };
 
 /**
- * struct ptp_clock_info - decribes a PTP hardware clock
+ * struct ptp_clock_info - describes a PTP hardware clock
  *
  * @owner:     The clock driver should set to THIS_MODULE.
  * @name:      A short "friendly name" to identify the clock and to
@@ -65,6 +65,9 @@  struct ptp_system_timestamp {
  *            parameter delta: Desired frequency offset from nominal frequency
  *            in parts per billion
  *
+ * @adjphase:  Adjusts the phase offset of the hardware clock.
+ *             parameter delta: Desired change in nanoseconds.
+ *
  * @adjtime:  Shifts the time of the hardware clock.
  *            parameter delta: Desired change in nanoseconds.
  *
@@ -128,6 +131,7 @@  struct ptp_clock_info {
 	struct ptp_pin_desc *pin_config;
 	int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm);
 	int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
+	int (*adjphase)(struct ptp_clock_info *ptp, s32 phase);
 	int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
 	int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
 	int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts,