summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
diff options
context:
space:
mode:
authorNaveen Mamindlapalli <naveenm@marvell.com>2022-09-10 13:24:15 +0530
committerDavid S. Miller <davem@davemloft.net>2022-09-17 20:13:41 +0100
commit2ef4e45d99b19fb16834616f47d21a9b76b0e5f4 (patch)
tree66fd6c82bb2345020e7b3cb989f91e5fb53f3dc2 /drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
parent2958d17a898416c6193431676f6130b68a2cb9fc (diff)
octeontx2-af: Add PTP PPS Errata workaround on CN10K silicon
Errata: The ptp_clock_hi rollsover to zero one clock cycle before it reaches one second boundary. As a result, the pps threshold comparison fails after one second and the pps output signal won't toggle further. This patch workarounds the issue by programming the pps_lo_incr register to 500msec minus one clock cycle period, ensuring that the pps threshold comparison succeeds at one second rollover boundary and pps edge toggles. After that point, the driver will have enough time (~500msec) to reset the pps threshold value. After each one second boundary, hrtimer is invoked which resets the pps threshold value. Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com> Signed-off-by: Rakesh Babu Saladi <rsaladi2@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c')
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
index 743c8a6d5dad..896b2f9bac34 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
@@ -73,6 +73,23 @@ static int ptp_set_thresh(struct otx2_ptp *ptp, u64 thresh)
return otx2_sync_mbox_msg(&ptp->nic->mbox);
}
+static int ptp_extts_on(struct otx2_ptp *ptp, int on)
+{
+ struct ptp_req *req;
+
+ if (!ptp->nic)
+ return -ENODEV;
+
+ req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox);
+ if (!req)
+ return -ENOMEM;
+
+ req->op = PTP_OP_EXTTS_ON;
+ req->extts_on = on;
+
+ return otx2_sync_mbox_msg(&ptp->nic->mbox);
+}
+
static u64 ptp_cc_read(const struct cyclecounter *cc)
{
struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter);
@@ -189,8 +206,6 @@ static void otx2_ptp_extts_check(struct work_struct *work)
event.index = 0;
event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp);
ptp_clock_event(ptp->ptp_clock, &event);
- ptp->last_extts = tstmp;
-
new_thresh = tstmp % 500000000;
if (ptp->thresh != new_thresh) {
mutex_lock(&ptp->nic->mbox.lock);
@@ -198,6 +213,7 @@ static void otx2_ptp_extts_check(struct work_struct *work)
mutex_unlock(&ptp->nic->mbox.lock);
ptp->thresh = new_thresh;
}
+ ptp->last_extts = tstmp;
}
schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200));
}
@@ -235,10 +251,13 @@ static int otx2_ptp_enable(struct ptp_clock_info *ptp_info,
rq->extts.index);
if (pin < 0)
return -EBUSY;
- if (on)
+ if (on) {
+ ptp_extts_on(ptp, on);
schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200));
- else
+ } else {
+ ptp_extts_on(ptp, on);
cancel_delayed_work_sync(&ptp->extts_work);
+ }
return 0;
default:
break;