Skip to content

Commit e096438

Browse files
larsclausenclaudiubeznea
authored andcommitted
net: macb: ptp: Switch to gettimex64() interface
The macb PTP support currently implements the `gettime64` callback to allow to retrieve the hardware clock time. Update the implementation to provide the `gettimex64` callback instead. The difference between the two is that with `gettime64` a snapshot of the system clock is taken before and after invoking the callback. Whereas `gettimex64` expects the callback itself to take the snapshots. To get the time from the macb Ethernet core multiple register accesses have to be done. Only one of which will happen at the time reported by the function. This leads to a non-symmetric delay and adds a slight offset between the hardware and system clock time when using the `gettime64` method. This offset can be a few 100 nanoseconds. Switching to the `gettimex64` method allows for a more precise correlation of the hardware and system clocks and results in a lower offset between the two. On a Xilinx ZynqMP system `phc2sys` reports a delay of 1120 ns before and 300 ns after the patch. With the latter being mostly symmetric. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent fcae4de commit e096438

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

drivers/net/ethernet/cadence/macb_ptp.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,18 @@ static struct macb_dma_desc_ptp *macb_ptp_desc(struct macb *bp,
3838
return NULL;
3939
}
4040

41-
static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
41+
static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts,
42+
struct ptp_system_timestamp *sts)
4243
{
4344
struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
4445
unsigned long flags;
4546
long first, second;
4647
u32 secl, sech;
4748

4849
spin_lock_irqsave(&bp->tsu_clk_lock, flags);
50+
ptp_read_system_prets(sts);
4951
first = gem_readl(bp, TN);
52+
ptp_read_system_postts(sts);
5053
secl = gem_readl(bp, TSL);
5154
sech = gem_readl(bp, TSH);
5255
second = gem_readl(bp, TN);
@@ -56,7 +59,9 @@ static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
5659
/* if so, use later read & re-read seconds
5760
* (assume all done within 1s)
5861
*/
62+
ptp_read_system_prets(sts);
5963
ts->tv_nsec = gem_readl(bp, TN);
64+
ptp_read_system_postts(sts);
6065
secl = gem_readl(bp, TSL);
6166
sech = gem_readl(bp, TSH);
6267
} else {
@@ -161,7 +166,7 @@ static int gem_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
161166
}
162167

163168
if (delta > TSU_NSEC_MAX_VAL) {
164-
gem_tsu_get_time(&bp->ptp_clock_info, &now);
169+
gem_tsu_get_time(&bp->ptp_clock_info, &now, NULL);
165170
now = timespec64_add(now, then);
166171

167172
gem_tsu_set_time(&bp->ptp_clock_info,
@@ -192,7 +197,7 @@ static const struct ptp_clock_info gem_ptp_caps_template = {
192197
.pps = 1,
193198
.adjfine = gem_ptp_adjfine,
194199
.adjtime = gem_ptp_adjtime,
195-
.gettime64 = gem_tsu_get_time,
200+
.gettimex64 = gem_tsu_get_time,
196201
.settime64 = gem_tsu_set_time,
197202
.enable = gem_ptp_enable,
198203
};
@@ -251,7 +256,7 @@ static int gem_hw_timestamp(struct macb *bp, u32 dma_desc_ts_1,
251256
* The timestamp only contains lower few bits of seconds,
252257
* so add value from 1588 timer
253258
*/
254-
gem_tsu_get_time(&bp->ptp_clock_info, &tsu);
259+
gem_tsu_get_time(&bp->ptp_clock_info, &tsu, NULL);
255260

256261
/* If the top bit is set in the timestamp,
257262
* but not in 1588 timer, it has rolled over,

0 commit comments

Comments
 (0)