Commit d8d26354 authored by Richard Cochran's avatar Richard Cochran Committed by David S. Miller

ptp: Introduce a high resolution frequency adjustment method.

The internal PTP Hardware Clock (PHC) interface limits the resolution for
frequency adjustments to one part per billion.  However, some hardware
devices allow finer adjustment, and making use of the increased resolution
improves synchronization measurably on such devices.

This patch adds an alternative method that allows finer frequency tuning
by passing the scaled ppm value to PHC drivers.  This value comes from
user space, and it has a resolution of about 0.015 ppb.  We also deprecate
the older method, anticipating its removal once existing drivers have been
converted over.
Signed-off-by: default avatarRichard Cochran <richardcochran@gmail.com>
Suggested-by: default avatarUlrik De Bie <ulrik.debie-os@e2big.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 149d6ad8
...@@ -153,7 +153,10 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) ...@@ -153,7 +153,10 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
s32 ppb = scaled_ppm_to_ppb(tx->freq); s32 ppb = scaled_ppm_to_ppb(tx->freq);
if (ppb > ops->max_adj || ppb < -ops->max_adj) if (ppb > ops->max_adj || ppb < -ops->max_adj)
return -ERANGE; return -ERANGE;
err = ops->adjfreq(ops, ppb); if (ops->adjfine)
err = ops->adjfine(ops, tx->freq);
else
err = ops->adjfreq(ops, ppb);
ptp->dialed_frequency = tx->freq; ptp->dialed_frequency = tx->freq;
} else if (tx->modes == 0) { } else if (tx->modes == 0) {
tx->freq = ptp->dialed_frequency; tx->freq = ptp->dialed_frequency;
......
...@@ -58,7 +58,14 @@ struct system_device_crosststamp; ...@@ -58,7 +58,14 @@ struct system_device_crosststamp;
* *
* clock operations * clock operations
* *
* @adjfine: Adjusts the frequency of the hardware clock.
* parameter scaled_ppm: Desired frequency offset from
* nominal frequency in parts per million, but with a
* 16 bit binary fractional field.
*
* @adjfreq: Adjusts the frequency of the hardware clock. * @adjfreq: Adjusts the frequency of the hardware clock.
* This method is deprecated. New drivers should implement
* the @adjfine method instead.
* parameter delta: Desired frequency offset from nominal frequency * parameter delta: Desired frequency offset from nominal frequency
* in parts per billion * in parts per billion
* *
...@@ -108,6 +115,7 @@ struct ptp_clock_info { ...@@ -108,6 +115,7 @@ struct ptp_clock_info {
int n_pins; int n_pins;
int pps; int pps;
struct ptp_pin_desc *pin_config; 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 (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts); int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment