net: ethernet: ti: cpts: switch to use new .gettimex64() interface
authorGrygorii Strashko <grygorii.strashko@ti.com>
Thu, 23 Apr 2020 14:20:16 +0000 (17:20 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 Apr 2020 19:50:20 +0000 (12:50 -0700)
The CPTS HW latches and saves CPTS counter value in CPTS fifo immediately
after writing to CPSW_CPTS_PUSH.TS_PUSH (bit 0), so the total time that the
driver needs to read the CPTS timestamp is the time required CPSW_CPTS_PUSH
write to actually reach HW.

Hence switch CPTS driver to implement new .gettimex64() callback for more
precise measurement of the offset between a PHC and the system clock which
is measured as time between
  write(CPSW_CPTS_PUSH)
  read(CPSW_CPTS_PUSH)

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/cpts.c

index a2974b5..1f738bb 100644 (file)
@@ -203,9 +203,13 @@ static u64 cpts_systim_read(const struct cyclecounter *cc)
        return READ_ONCE(cpts->cur_timestamp);
 }
 
-static void cpts_update_cur_time(struct cpts *cpts, int match)
+static void cpts_update_cur_time(struct cpts *cpts, int match,
+                                struct ptp_system_timestamp *sts)
 {
+       ptp_read_system_prets(sts);
        cpts_write32(cpts, TS_PUSH, ts_push);
+       cpts_read32(cpts, ts_push);
+       ptp_read_system_postts(sts);
 
        if (cpts_fifo_read(cpts, match) && match != -1)
                dev_err(cpts->dev, "cpts: unable to obtain a time stamp\n");
@@ -234,7 +238,7 @@ static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
 
        cpts->mult_new = neg_adj ? mult - diff : mult + diff;
 
-       cpts_update_cur_time(cpts, CPTS_EV_PUSH);
+       cpts_update_cur_time(cpts, CPTS_EV_PUSH, NULL);
 
        spin_unlock_irqrestore(&cpts->lock, flags);
 
@@ -253,15 +257,17 @@ static int cpts_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
        return 0;
 }
 
-static int cpts_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
+static int cpts_ptp_gettimeex(struct ptp_clock_info *ptp,
+                             struct timespec64 *ts,
+                             struct ptp_system_timestamp *sts)
 {
-       u64 ns;
-       unsigned long flags;
        struct cpts *cpts = container_of(ptp, struct cpts, info);
+       unsigned long flags;
+       u64 ns;
 
        spin_lock_irqsave(&cpts->lock, flags);
 
-       cpts_update_cur_time(cpts, CPTS_EV_PUSH);
+       cpts_update_cur_time(cpts, CPTS_EV_PUSH, sts);
 
        ns = timecounter_read(&cpts->tc);
        spin_unlock_irqrestore(&cpts->lock, flags);
@@ -302,7 +308,7 @@ static long cpts_overflow_check(struct ptp_clock_info *ptp)
 
        spin_lock_irqsave(&cpts->lock, flags);
 
-       cpts_update_cur_time(cpts, -1);
+       cpts_update_cur_time(cpts, -1, NULL);
 
        ns = timecounter_read(&cpts->tc);
 
@@ -326,7 +332,7 @@ static const struct ptp_clock_info cpts_info = {
        .pps            = 0,
        .adjfreq        = cpts_ptp_adjfreq,
        .adjtime        = cpts_ptp_adjtime,
-       .gettime64      = cpts_ptp_gettime,
+       .gettimex64     = cpts_ptp_gettimeex,
        .settime64      = cpts_ptp_settime,
        .enable         = cpts_ptp_enable,
        .do_aux_work    = cpts_overflow_check,