From nobody Sat Jun 27 19:01:24 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6A5CC433FE for ; Mon, 21 Feb 2022 07:19:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345951AbiBUHUG (ORCPT ); Mon, 21 Feb 2022 02:20:06 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:56030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236498AbiBUHUE (ORCPT ); Mon, 21 Feb 2022 02:20:04 -0500 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4670E197; Sun, 20 Feb 2022 23:19:41 -0800 (PST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 21KNQuXG015100; Sun, 20 Feb 2022 23:19:30 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=CvSSijCj2vCdApXotvACpYUsAWweKn+jI5eXiIXwmFc=; b=Fh/PcWL3Klca0DKT5+QpChsQhNZ63EINDtauYrRNzZrLXf9m/pL52ULW0PwrnAfuTxoV 8pcSiGuL84JRB07hNSNsM5dYjiZ6bIIYzC7k8MFTqScR4fkt3nFZXaTZTfudrBe7sQ/R ahaOPAd/1cMdPkMWKSiNrTJb2FC8QJO+N+wuPZRCpnNzD6DPw4p8fbvP8p/Ma/MA4EMA toVpqFyGp+JKRcrUmz8+mZrJ/9eTibOcv3KtsAXCmK7wSwnpFkJChzJ1oZ7y5dSnAoey R4cPrrzeKC9uaQbqBysFnh3ncsBGw8HDIXnNbD0orHtMv3gdHZ9y/N1j5wdKC2Vu7xTb Ug== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3ebpvntctk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sun, 20 Feb 2022 23:19:30 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 20 Feb 2022 23:19:28 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Sun, 20 Feb 2022 23:19:49 -0800 Received: from hyd1soter3.marvell.com (unknown [10.29.37.12]) by maili.marvell.com (Postfix) with ESMTP id D0CAD65E8C5; Sun, 20 Feb 2022 22:45:15 -0800 (PST) From: Rakesh Babu Saladi To: , , , , , , , , CC: , Naveen Mamindlapalli Subject: [net-next PATCH v2 1/2] octeontx2-pf: cn10k: add support for new ptp timestamp format Date: Mon, 21 Feb 2022 12:15:07 +0530 Message-ID: <20220221064508.19148-2-rsaladi2@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220221064508.19148-1-rsaladi2@marvell.com> References: <20220221064508.19148-1-rsaladi2@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: w--jUk3Dvn0WSR5W_BU-F87elNhXKdQk X-Proofpoint-GUID: w--jUk3Dvn0WSR5W_BU-F87elNhXKdQk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-02-21_02,2022-02-18_01,2021-12-02_01 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Naveen Mamindlapalli The cn10k hardware ptp timestamp format has been modified primarily to support 1-step ptp clock. The 64-bit timestamp used by hardware is split into two 32-bit fields, the upper one holds seconds, the lower one nanoseconds. A new register (PTP_CLOCK_SEC) has been added that returns the current seconds value. The nanoseconds register PTP_CLOCK_HI resets after every second. The cn10k RPM block provides Rx/Tx timestamps to the NIX block using the new timestamp format. The software can read the current timestamp in nanoseconds by reading both PTP_CLOCK_SEC & PTP_CLOCK_HI registers. This patch provides support for new timestamp format. Signed-off-by: Naveen Mamindlapalli Signed-off-by: Sunil Kovvuri Goutham Signed-off-by: Rakesh Babu Saladi --- .../net/ethernet/marvell/octeontx2/af/ptp.c | 44 ++++++++++++++++++- .../net/ethernet/marvell/octeontx2/af/ptp.h | 2 + .../marvell/octeontx2/nic/otx2_common.h | 3 ++ .../ethernet/marvell/octeontx2/nic/otx2_ptp.c | 8 ++++ .../ethernet/marvell/octeontx2/nic/otx2_ptp.h | 15 +++++++ .../marvell/octeontx2/nic/otx2_txrx.c | 6 ++- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c b/drivers/net/= ethernet/marvell/octeontx2/af/ptp.c index e682b7bfde64..5b8906fd45c3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c @@ -25,6 +25,9 @@ #define PCI_SUBSYS_DEVID_OCTX2_95XXO_PTP 0xB600 #define PCI_DEVID_OCTEONTX2_RST 0xA085 #define PCI_DEVID_CN10K_PTP 0xA09E +#define PCI_SUBSYS_DEVID_CN10K_A_PTP 0xB900 +#define PCI_SUBSYS_DEVID_CNF10K_A_PTP 0xBA00 +#define PCI_SUBSYS_DEVID_CNF10K_B_PTP 0xBC00 =20 #define PCI_PTP_BAR_NO 0 =20 @@ -46,10 +49,43 @@ #define PTP_CLOCK_HI 0xF10ULL #define PTP_CLOCK_COMP 0xF18ULL #define PTP_TIMESTAMP 0xF20ULL +#define PTP_CLOCK_SEC 0xFD0ULL =20 static struct ptp *first_ptp_block; static const struct pci_device_id ptp_id_table[]; =20 +static bool is_ptp_tsfmt_sec_nsec(struct ptp *ptp) +{ + if (ptp->pdev->subsystem_device =3D=3D PCI_SUBSYS_DEVID_CN10K_A_PTP || + ptp->pdev->subsystem_device =3D=3D PCI_SUBSYS_DEVID_CNF10K_A_PTP) + return true; + return false; +} + +static u64 read_ptp_tstmp_sec_nsec(struct ptp *ptp) +{ + u64 sec, sec1, nsec; + unsigned long flags; + + spin_lock_irqsave(&ptp->ptp_lock, flags); + sec =3D readq(ptp->reg_base + PTP_CLOCK_SEC) & 0xFFFFFFFFUL; + nsec =3D readq(ptp->reg_base + PTP_CLOCK_HI); + sec1 =3D readq(ptp->reg_base + PTP_CLOCK_SEC) & 0xFFFFFFFFUL; + /* check nsec rollover */ + if (sec1 > sec) { + nsec =3D readq(ptp->reg_base + PTP_CLOCK_HI); + sec =3D sec1; + } + spin_unlock_irqrestore(&ptp->ptp_lock, flags); + + return sec * NSEC_PER_SEC + nsec; +} + +static u64 read_ptp_tstmp_nsec(struct ptp *ptp) +{ + return readq(ptp->reg_base + PTP_CLOCK_HI); +} + struct ptp *ptp_get(void) { struct ptp *ptp =3D first_ptp_block; @@ -117,7 +153,7 @@ static int ptp_adjfine(struct ptp *ptp, long scaled_ppm) static int ptp_get_clock(struct ptp *ptp, u64 *clk) { /* Return the current PTP clock */ - *clk =3D readq(ptp->reg_base + PTP_CLOCK_HI); + *clk =3D ptp->read_ptp_tstmp(ptp); =20 return 0; } @@ -214,6 +250,12 @@ static int ptp_probe(struct pci_dev *pdev, if (!first_ptp_block) first_ptp_block =3D ptp; =20 + spin_lock_init(&ptp->ptp_lock); + if (is_ptp_tsfmt_sec_nsec(ptp)) + ptp->read_ptp_tstmp =3D &read_ptp_tstmp_sec_nsec; + else + ptp->read_ptp_tstmp =3D &read_ptp_tstmp_nsec; + return 0; =20 error_free: diff --git a/drivers/net/ethernet/marvell/octeontx2/af/ptp.h b/drivers/net/= ethernet/marvell/octeontx2/af/ptp.h index 1b81a0493cd3..95a955159f40 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/ptp.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/ptp.h @@ -15,6 +15,8 @@ struct ptp { struct pci_dev *pdev; void __iomem *reg_base; + u64 (*read_ptp_tstmp)(struct ptp *ptp); + spinlock_t ptp_lock; /* lock */ u32 clock_rate; }; =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/dri= vers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index 7724f17ec31f..65e31a2210d9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -17,6 +17,7 @@ #include #include #include +#include =20 #include #include @@ -275,6 +276,8 @@ struct otx2_ptp { u64 thresh; =20 struct ptp_pin_desc extts_config; + u64 (*convert_rx_ptp_tstmp)(u64 timestamp); + u64 (*convert_tx_ptp_tstmp)(u64 timestamp); }; =20 #define OTX2_HW_TIMESTAMP_LEN 8 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c b/driver= s/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c index 61c20907315f..fdc2c9315b91 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c @@ -294,6 +294,14 @@ int otx2_ptp_init(struct otx2_nic *pfvf) goto error; } =20 + if (is_dev_otx2(pfvf->pdev)) { + ptp_ptr->convert_rx_ptp_tstmp =3D &otx2_ptp_convert_rx_timestamp; + ptp_ptr->convert_tx_ptp_tstmp =3D &otx2_ptp_convert_tx_timestamp; + } else { + ptp_ptr->convert_rx_ptp_tstmp =3D &cn10k_ptp_convert_timestamp; + ptp_ptr->convert_tx_ptp_tstmp =3D &cn10k_ptp_convert_timestamp; + } + pfvf->ptp =3D ptp_ptr; =20 error: diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.h b/driver= s/net/ethernet/marvell/octeontx2/nic/otx2_ptp.h index 6ff284211d7b..7ff41927ceaf 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.h @@ -8,6 +8,21 @@ #ifndef OTX2_PTP_H #define OTX2_PTP_H =20 +static inline u64 otx2_ptp_convert_rx_timestamp(u64 timestamp) +{ + return be64_to_cpu(*(__be64 *)×tamp); +} + +static inline u64 otx2_ptp_convert_tx_timestamp(u64 timestamp) +{ + return timestamp; +} + +static inline u64 cn10k_ptp_convert_timestamp(u64 timestamp) +{ + return ((timestamp >> 32) * NSEC_PER_SEC) + (timestamp & 0xFFFFFFFFUL); +} + int otx2_ptp_init(struct otx2_nic *pfvf); void otx2_ptp_destroy(struct otx2_nic *pfvf); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drive= rs/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c index 7c4068c5d1ac..c26de15b2ac3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -148,6 +148,7 @@ static void otx2_snd_pkt_handler(struct otx2_nic *pfvf, if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) { timestamp =3D ((u64 *)sq->timestamps->base)[snd_comp->sqe_id]; if (timestamp !=3D 1) { + timestamp =3D pfvf->ptp->convert_tx_ptp_tstmp(timestamp); err =3D otx2_ptp_tstamp2time(pfvf, timestamp, &tsns); if (!err) { memset(&ts, 0, sizeof(ts)); @@ -167,14 +168,15 @@ static void otx2_snd_pkt_handler(struct otx2_nic *pfv= f, static void otx2_set_rxtstamp(struct otx2_nic *pfvf, struct sk_buff *skb, void *data) { - u64 tsns; + u64 timestamp, tsns; int err; =20 if (!(pfvf->flags & OTX2_FLAG_RX_TSTAMP_ENABLED)) return; =20 + timestamp =3D pfvf->ptp->convert_rx_ptp_tstmp(*(u64 *)data); /* The first 8 bytes is the timestamp */ - err =3D otx2_ptp_tstamp2time(pfvf, be64_to_cpu(*(__be64 *)data), &tsns); + err =3D otx2_ptp_tstamp2time(pfvf, timestamp, &tsns); if (err) return; =20 --=20 2.17.1 From nobody Sat Jun 27 19:01:24 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 592B3C433EF for ; Mon, 21 Feb 2022 07:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345975AbiBUHVW (ORCPT ); Mon, 21 Feb 2022 02:21:22 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:56524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345973AbiBUHVS (ORCPT ); Mon, 21 Feb 2022 02:21:18 -0500 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C47B1DA9; Sun, 20 Feb 2022 23:20:55 -0800 (PST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 21KMnbFP030539; Sun, 20 Feb 2022 23:20:52 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=8kOwvDTl45DgZnzS4zO0qxmfSeJRd8nohhKRQkC6CgU=; b=PXsB/xybIE8ciW/TcLiDMFE66WQrDoazznpnBfwuKRSLhPGx6cMGWRtYDisEFIajTSDm /Aqn5JH8xOXWLX+DJgsSaPkhMx6EIeBzNZEbciqs8gL1jTJVD7Ak6gEaPqCrEIiVMBr/ LyWzC40U6CSY8Csnxnt6Zc5s4XnYAWmjZwpdA2uwfPFOaj5RwWIEJhgR1S3Ex6Gy8NE9 VrLpr25F7ysIoudrKL+AHPJgzfMinmEFVT9yVO5N4rPtpFvY0eu9USyay8uMXta3C0BV H/m1TKl1OoW0HTUg7l0XMEDc9hItraDz3Iq4LzS6GAGjuxE15QnzQDlBWkr2EOX3Upqy bA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3ebpvntcwx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sun, 20 Feb 2022 23:20:52 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 20 Feb 2022 23:20:50 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Sun, 20 Feb 2022 23:21:12 -0800 Received: from hyd1soter3.marvell.com (unknown [10.29.37.12]) by maili.marvell.com (Postfix) with ESMTP id 6E4D765E8FA; Sun, 20 Feb 2022 22:45:19 -0800 (PST) From: Rakesh Babu Saladi To: , , , , , , , , CC: , Naveen Mamindlapalli Subject: [net-next PATCH v2 2/2] octeontx2-af: cn10k: add workaround for ptp errata Date: Mon, 21 Feb 2022 12:15:08 +0530 Message-ID: <20220221064508.19148-3-rsaladi2@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220221064508.19148-1-rsaladi2@marvell.com> References: <20220221064508.19148-1-rsaladi2@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: YfbHU52-3iaLSbp4Ih57xkLpcT-WeoGJ X-Proofpoint-GUID: YfbHU52-3iaLSbp4Ih57xkLpcT-WeoGJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-02-21_02,2022-02-18_01,2021-12-02_01 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Naveen Mamindlapalli This patch adds workaround for PTP errata given below. 1. At the time of 1 sec rollover of nano-second counter, the nano-second counter is set to 0. However, it should be set to (existing counter_value - 10^9). This leads to an accumulating error in the timestamp value with each sec rollover. 2. Additionally, the nano-second counter currently is rolling over at 'h3B9A_C9FF. It should roll over at 'h3B9A_CA00. The workaround for issue #1 is to speed up the ptp clock by adjusting PTP_CLOCK_COMP register to the desired value to compensate for the nanoseconds lost per each second. The workaround for issue #2 is to slow down the ptp clock such that the rollover occurs at ~1sec. Signed-off-by: Naveen Mamindlapalli Signed-off-by: Sunil Kovvuri Goutham Signed-off-by: Rakesh Babu Saladi --- .../net/ethernet/marvell/octeontx2/af/ptp.c | 87 +++++++++++++++++-- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c b/drivers/net/= ethernet/marvell/octeontx2/af/ptp.c index 5b8906fd45c3..67a6821d2dff 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c @@ -51,9 +51,19 @@ #define PTP_TIMESTAMP 0xF20ULL #define PTP_CLOCK_SEC 0xFD0ULL =20 +#define CYCLE_MULT 1000 + static struct ptp *first_ptp_block; static const struct pci_device_id ptp_id_table[]; =20 +static bool cn10k_ptp_errata(struct ptp *ptp) +{ + if (ptp->pdev->subsystem_device =3D=3D PCI_SUBSYS_DEVID_CN10K_A_PTP || + ptp->pdev->subsystem_device =3D=3D PCI_SUBSYS_DEVID_CNF10K_A_PTP) + return true; + return false; +} + static bool is_ptp_tsfmt_sec_nsec(struct ptp *ptp) { if (ptp->pdev->subsystem_device =3D=3D PCI_SUBSYS_DEVID_CN10K_A_PTP || @@ -86,6 +96,58 @@ static u64 read_ptp_tstmp_nsec(struct ptp *ptp) return readq(ptp->reg_base + PTP_CLOCK_HI); } =20 +static u64 ptp_calc_adjusted_comp(u64 ptp_clock_freq) +{ + u64 comp, adj =3D 0, cycles_per_sec, ns_drift =3D 0; + u32 ptp_clock_nsec, cycle_time; + int cycle; + + /* Errata: + * Issue #1: At the time of 1 sec rollover of the nano-second counter, + * the nano-second counter is set to 0. However, it should be set to + * (existing counter_value - 10^9). + * + * Issue #2: The nano-second counter rolls over at 0x3B9A_C9FF. + * It should roll over at 0x3B9A_CA00. + */ + + /* calculate ptp_clock_comp value */ + comp =3D ((u64)1000000000ULL << 32) / ptp_clock_freq; + /* use CYCLE_MULT to avoid accuracy loss due to integer arithmetic */ + cycle_time =3D NSEC_PER_SEC * CYCLE_MULT / ptp_clock_freq; + /* cycles per sec */ + cycles_per_sec =3D ptp_clock_freq; + + /* check whether ptp nanosecond counter rolls over early */ + cycle =3D cycles_per_sec - 1; + ptp_clock_nsec =3D (cycle * comp) >> 32; + while (ptp_clock_nsec < NSEC_PER_SEC) { + if (ptp_clock_nsec =3D=3D 0x3B9AC9FF) + goto calc_adj_comp; + cycle++; + ptp_clock_nsec =3D (cycle * comp) >> 32; + } + /* compute nanoseconds lost per second when nsec counter rolls over */ + ns_drift =3D ptp_clock_nsec - NSEC_PER_SEC; + /* calculate ptp_clock_comp adjustment */ + if (ns_drift > 0) { + adj =3D comp * ns_drift; + adj =3D adj / 1000000000ULL; + } + /* speed up the ptp clock to account for nanoseconds lost */ + comp +=3D adj; + return comp; + +calc_adj_comp: + /* slow down the ptp clock to not rollover early */ + adj =3D comp * cycle_time; + adj =3D adj / 1000000000ULL; + adj =3D adj / CYCLE_MULT; + comp -=3D adj; + + return comp; +} + struct ptp *ptp_get(void) { struct ptp *ptp =3D first_ptp_block; @@ -113,8 +175,8 @@ void ptp_put(struct ptp *ptp) static int ptp_adjfine(struct ptp *ptp, long scaled_ppm) { bool neg_adj =3D false; - u64 comp; - u64 adj; + u32 freq, freq_adj; + u64 comp, adj; s64 ppb; =20 if (scaled_ppm < 0) { @@ -136,15 +198,22 @@ static int ptp_adjfine(struct ptp *ptp, long scaled_p= pm) * where tbase is the basic compensation value calculated * initialy in the probe function. */ - comp =3D ((u64)1000000000ull << 32) / ptp->clock_rate; /* convert scaled_ppm to ppb */ ppb =3D 1 + scaled_ppm; ppb *=3D 125; ppb >>=3D 13; - adj =3D comp * ppb; - adj =3D div_u64(adj, 1000000000ull); - comp =3D neg_adj ? comp - adj : comp + adj; =20 + if (cn10k_ptp_errata(ptp)) { + /* calculate the new frequency based on ppb */ + freq_adj =3D (ptp->clock_rate * ppb) / 1000000000ULL; + freq =3D neg_adj ? ptp->clock_rate + freq_adj : ptp->clock_rate - freq_a= dj; + comp =3D ptp_calc_adjusted_comp(freq); + } else { + comp =3D ((u64)1000000000ull << 32) / ptp->clock_rate; + adj =3D comp * ppb; + adj =3D div_u64(adj, 1000000000ull); + comp =3D neg_adj ? comp - adj : comp + adj; + } writeq(comp, ptp->reg_base + PTP_CLOCK_COMP); =20 return 0; @@ -202,7 +271,11 @@ void ptp_start(struct ptp *ptp, u64 sclk, u32 ext_clk_= freq, u32 extts) writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_HI_INCR); writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_LO_INCR); =20 - clock_comp =3D ((u64)1000000000ull << 32) / ptp->clock_rate; + if (cn10k_ptp_errata(ptp)) + clock_comp =3D ptp_calc_adjusted_comp(ptp->clock_rate); + else + clock_comp =3D ((u64)1000000000ull << 32) / ptp->clock_rate; + /* Initial compensation value to start the nanosecs counter */ writeq(clock_comp, ptp->reg_base + PTP_CLOCK_COMP); } --=20 2.17.1