Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

octeontx2-pf: Use PTP HW timestamp counter atomic update feature

Some of the newer silicon versions in CN10K series supports a feature
where in the current PTP timestamp in HW can be updated atomically
without losing any cpu cycles unlike read/modify/write register.
This patch uses this feature so that PTP accuracy can be improved
while adjusting the master offset in HW. There is no need for SW
timecounter when using this feature. So removed references to SW
timecounter wherever appropriate.

Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com>
Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sai Krishna and committed by
David S. Miller
bdf79b12 6176b8c4

+307 -55
+12
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
··· 136 136 M(LMTST_TBL_SETUP, 0x00a, lmtst_tbl_setup, lmtst_tbl_setup_req, \ 137 137 msg_rsp) \ 138 138 M(SET_VF_PERM, 0x00b, set_vf_perm, set_vf_perm, msg_rsp) \ 139 + M(PTP_GET_CAP, 0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp) \ 139 140 /* CGX mbox IDs (range 0x200 - 0x3FF) */ \ 140 141 M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \ 141 142 M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \ ··· 1438 1437 u8 mkex_pfl_name[MKEX_NAME_LEN]; 1439 1438 }; 1440 1439 1440 + struct ptp_get_cap_rsp { 1441 + struct mbox_msghdr hdr; 1442 + #define PTP_CAP_HW_ATOMIC_UPDATE BIT_ULL(0) 1443 + u64 cap; 1444 + }; 1445 + 1441 1446 struct flow_msg { 1442 1447 unsigned char dmac[6]; 1443 1448 unsigned char smac[6]; ··· 1575 1568 PTP_OP_GET_TSTMP = 2, 1576 1569 PTP_OP_SET_THRESH = 3, 1577 1570 PTP_OP_EXTTS_ON = 4, 1571 + PTP_OP_ADJTIME = 5, 1572 + PTP_OP_SET_CLOCK = 6, 1578 1573 }; 1579 1574 1580 1575 struct ptp_req { ··· 1585 1576 s64 scaled_ppm; 1586 1577 u64 thresh; 1587 1578 int extts_on; 1579 + s64 delta; 1580 + u64 clk; 1588 1581 }; 1589 1582 1590 1583 struct ptp_rsp { 1591 1584 struct mbox_msghdr hdr; 1592 1585 u64 clk; 1586 + u64 tsc; 1593 1587 }; 1594 1588 1595 1589 struct npc_get_field_status_req {
+135 -20
drivers/net/ethernet/marvell/octeontx2/af/ptp.c
··· 12 12 #include <linux/hrtimer.h> 13 13 #include <linux/ktime.h> 14 14 15 - #include "ptp.h" 16 15 #include "mbox.h" 16 + #include "ptp.h" 17 17 #include "rvu.h" 18 18 19 19 #define DRV_NAME "Marvell PTP Driver" ··· 40 40 #define PTP_CLOCK_CFG_TSTMP_EDGE BIT_ULL(9) 41 41 #define PTP_CLOCK_CFG_TSTMP_EN BIT_ULL(8) 42 42 #define PTP_CLOCK_CFG_TSTMP_IN_MASK GENMASK_ULL(15, 10) 43 + #define PTP_CLOCK_CFG_ATOMIC_OP_MASK GENMASK_ULL(28, 26) 43 44 #define PTP_CLOCK_CFG_PPS_EN BIT_ULL(30) 44 45 #define PTP_CLOCK_CFG_PPS_INV BIT_ULL(31) 45 46 ··· 54 53 #define PTP_TIMESTAMP 0xF20ULL 55 54 #define PTP_CLOCK_SEC 0xFD0ULL 56 55 #define PTP_SEC_ROLLOVER 0xFD8ULL 56 + /* Atomic update related CSRs */ 57 + #define PTP_FRNS_TIMESTAMP 0xFE0ULL 58 + #define PTP_NXT_ROLLOVER_SET 0xFE8ULL 59 + #define PTP_CURR_ROLLOVER_SET 0xFF0ULL 60 + #define PTP_NANO_TIMESTAMP 0xFF8ULL 61 + #define PTP_SEC_TIMESTAMP 0x1000ULL 57 62 58 63 #define CYCLE_MULT 1000 64 + 65 + #define is_rev_A0(ptp) (((ptp)->pdev->revision & 0x0F) == 0x0) 66 + #define is_rev_A1(ptp) (((ptp)->pdev->revision & 0x0F) == 0x1) 67 + 68 + /* PTP atomic update operation type */ 69 + enum atomic_opcode { 70 + ATOMIC_SET = 1, 71 + ATOMIC_INC = 3, 72 + ATOMIC_DEC = 4 73 + }; 59 74 60 75 static struct ptp *first_ptp_block; 61 76 static const struct pci_device_id ptp_id_table[]; 62 77 63 - static bool is_ptp_dev_cnf10kb(struct ptp *ptp) 78 + static bool is_ptp_dev_cnf10ka(struct ptp *ptp) 64 79 { 65 - return ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_B_PTP; 80 + return ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP; 66 81 } 67 82 68 - static bool is_ptp_dev_cn10k(struct ptp *ptp) 83 + static bool is_ptp_dev_cn10ka(struct ptp *ptp) 69 84 { 70 - return ptp->pdev->device == PCI_DEVID_CN10K_PTP; 85 + return ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_PTP; 71 86 } 72 87 73 88 static bool cn10k_ptp_errata(struct ptp *ptp) 74 89 { 75 - if (ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_PTP || 76 - ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP) 90 + if ((is_ptp_dev_cn10ka(ptp) || is_ptp_dev_cnf10ka(ptp)) && 91 + (is_rev_A0(ptp) || is_rev_A1(ptp))) 77 92 return true; 93 + 78 94 return false; 79 95 } 80 96 81 - static bool is_ptp_tsfmt_sec_nsec(struct ptp *ptp) 97 + static bool is_tstmp_atomic_update_supported(struct rvu *rvu) 82 98 { 83 - if (ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_PTP || 84 - ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP) 85 - return true; 86 - return false; 99 + struct ptp *ptp = rvu->ptp; 100 + 101 + if (is_rvu_otx2(rvu)) 102 + return false; 103 + 104 + /* On older silicon variants of CN10K, atomic update feature 105 + * is not available. 106 + */ 107 + if ((is_ptp_dev_cn10ka(ptp) || is_ptp_dev_cnf10ka(ptp)) && 108 + (is_rev_A0(ptp) || is_rev_A1(ptp))) 109 + return false; 110 + 111 + return true; 87 112 } 88 113 89 114 static enum hrtimer_restart ptp_reset_thresh(struct hrtimer *hrtimer) ··· 249 222 pci_dev_put(ptp->pdev); 250 223 } 251 224 225 + static void ptp_atomic_update(struct ptp *ptp, u64 timestamp) 226 + { 227 + u64 regval, curr_rollover_set, nxt_rollover_set; 228 + 229 + /* First setup NSECs and SECs */ 230 + writeq(timestamp, ptp->reg_base + PTP_NANO_TIMESTAMP); 231 + writeq(0, ptp->reg_base + PTP_FRNS_TIMESTAMP); 232 + writeq(timestamp / NSEC_PER_SEC, 233 + ptp->reg_base + PTP_SEC_TIMESTAMP); 234 + 235 + nxt_rollover_set = roundup(timestamp, NSEC_PER_SEC); 236 + curr_rollover_set = nxt_rollover_set - NSEC_PER_SEC; 237 + writeq(nxt_rollover_set, ptp->reg_base + PTP_NXT_ROLLOVER_SET); 238 + writeq(curr_rollover_set, ptp->reg_base + PTP_CURR_ROLLOVER_SET); 239 + 240 + /* Now, initiate atomic update */ 241 + regval = readq(ptp->reg_base + PTP_CLOCK_CFG); 242 + regval &= ~PTP_CLOCK_CFG_ATOMIC_OP_MASK; 243 + regval |= (ATOMIC_SET << 26); 244 + writeq(regval, ptp->reg_base + PTP_CLOCK_CFG); 245 + } 246 + 247 + static void ptp_atomic_adjtime(struct ptp *ptp, s64 delta) 248 + { 249 + bool neg_adj = false, atomic_inc_dec = false; 250 + u64 regval, ptp_clock_hi; 251 + 252 + if (delta < 0) { 253 + delta = -delta; 254 + neg_adj = true; 255 + } 256 + 257 + /* use atomic inc/dec when delta < 1 second */ 258 + if (delta < NSEC_PER_SEC) 259 + atomic_inc_dec = true; 260 + 261 + if (!atomic_inc_dec) { 262 + ptp_clock_hi = readq(ptp->reg_base + PTP_CLOCK_HI); 263 + if (neg_adj) { 264 + if (ptp_clock_hi > delta) 265 + ptp_clock_hi -= delta; 266 + else 267 + ptp_clock_hi = delta - ptp_clock_hi; 268 + } else { 269 + ptp_clock_hi += delta; 270 + } 271 + ptp_atomic_update(ptp, ptp_clock_hi); 272 + } else { 273 + writeq(delta, ptp->reg_base + PTP_NANO_TIMESTAMP); 274 + writeq(0, ptp->reg_base + PTP_FRNS_TIMESTAMP); 275 + 276 + /* initiate atomic inc/dec */ 277 + regval = readq(ptp->reg_base + PTP_CLOCK_CFG); 278 + regval &= ~PTP_CLOCK_CFG_ATOMIC_OP_MASK; 279 + regval |= neg_adj ? (ATOMIC_DEC << 26) : (ATOMIC_INC << 26); 280 + writeq(regval, ptp->reg_base + PTP_CLOCK_CFG); 281 + } 282 + } 283 + 252 284 static int ptp_adjfine(struct ptp *ptp, long scaled_ppm) 253 285 { 254 286 bool neg_adj = false; ··· 363 277 return 0; 364 278 } 365 279 366 - void ptp_start(struct ptp *ptp, u64 sclk, u32 ext_clk_freq, u32 extts) 280 + void ptp_start(struct rvu *rvu, u64 sclk, u32 ext_clk_freq, u32 extts) 367 281 { 282 + struct ptp *ptp = rvu->ptp; 368 283 struct pci_dev *pdev; 369 284 u64 clock_comp; 370 285 u64 clock_cfg; ··· 384 297 ptp->clock_rate = sclk * 1000000; 385 298 386 299 /* Program the seconds rollover value to 1 second */ 387 - if (is_ptp_dev_cnf10kb(ptp)) 300 + if (is_tstmp_atomic_update_supported(rvu)) { 301 + writeq(0, ptp->reg_base + PTP_NANO_TIMESTAMP); 302 + writeq(0, ptp->reg_base + PTP_FRNS_TIMESTAMP); 303 + writeq(0, ptp->reg_base + PTP_SEC_TIMESTAMP); 304 + writeq(0, ptp->reg_base + PTP_CURR_ROLLOVER_SET); 305 + writeq(0x3b9aca00, ptp->reg_base + PTP_NXT_ROLLOVER_SET); 388 306 writeq(0x3b9aca00, ptp->reg_base + PTP_SEC_ROLLOVER); 307 + } 389 308 390 309 /* Enable PTP clock */ 391 310 clock_cfg = readq(ptp->reg_base + PTP_CLOCK_CFG); ··· 412 319 413 320 clock_cfg |= PTP_CLOCK_CFG_PTP_EN; 414 321 clock_cfg |= PTP_CLOCK_CFG_PPS_EN | PTP_CLOCK_CFG_PPS_INV; 322 + writeq(clock_cfg, ptp->reg_base + PTP_CLOCK_CFG); 323 + clock_cfg = readq(ptp->reg_base + PTP_CLOCK_CFG); 324 + clock_cfg &= ~PTP_CLOCK_CFG_ATOMIC_OP_MASK; 325 + clock_cfg |= (ATOMIC_SET << 26); 415 326 writeq(clock_cfg, ptp->reg_base + PTP_CLOCK_CFG); 416 327 417 328 /* Set 50% duty cycle for 1Hz output */ ··· 447 350 { 448 351 u64 timestamp; 449 352 450 - if (is_ptp_dev_cn10k(ptp)) { 353 + if (is_ptp_dev_cn10ka(ptp) || is_ptp_dev_cnf10ka(ptp)) { 451 354 timestamp = readq(ptp->reg_base + PTP_TIMESTAMP); 452 355 *clk = (timestamp >> 32) * NSEC_PER_SEC + (timestamp & 0xFFFFFFFF); 453 356 } else { ··· 511 414 first_ptp_block = ptp; 512 415 513 416 spin_lock_init(&ptp->ptp_lock); 514 - if (is_ptp_tsfmt_sec_nsec(ptp)) 515 - ptp->read_ptp_tstmp = &read_ptp_tstmp_sec_nsec; 516 - else 517 - ptp->read_ptp_tstmp = &read_ptp_tstmp_nsec; 518 - 519 417 if (cn10k_ptp_errata(ptp)) { 418 + ptp->read_ptp_tstmp = &read_ptp_tstmp_sec_nsec; 520 419 hrtimer_init(&ptp->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 521 420 ptp->hrtimer.function = ptp_reset_thresh; 421 + } else { 422 + ptp->read_ptp_tstmp = &read_ptp_tstmp_nsec; 522 423 } 523 424 524 425 return 0; ··· 616 521 case PTP_OP_EXTTS_ON: 617 522 err = ptp_extts_on(rvu->ptp, req->extts_on); 618 523 break; 524 + case PTP_OP_ADJTIME: 525 + ptp_atomic_adjtime(rvu->ptp, req->delta); 526 + break; 527 + case PTP_OP_SET_CLOCK: 528 + ptp_atomic_update(rvu->ptp, (u64)req->clk); 529 + break; 619 530 default: 620 531 err = -EINVAL; 621 532 break; 622 533 } 623 534 624 535 return err; 536 + } 537 + 538 + int rvu_mbox_handler_ptp_get_cap(struct rvu *rvu, struct msg_req *req, 539 + struct ptp_get_cap_rsp *rsp) 540 + { 541 + if (!rvu->ptp) 542 + return -ENODEV; 543 + 544 + if (is_tstmp_atomic_update_supported(rvu)) 545 + rsp->cap |= PTP_CAP_HW_ATOMIC_UPDATE; 546 + else 547 + rsp->cap &= ~BIT_ULL_MASK(0); 548 + 549 + return 0; 625 550 }
+2 -1
drivers/net/ethernet/marvell/octeontx2/af/ptp.h
··· 23 23 u32 clock_period; 24 24 }; 25 25 26 + struct rvu; 26 27 struct ptp *ptp_get(void); 27 28 void ptp_put(struct ptp *ptp); 28 - void ptp_start(struct ptp *ptp, u64 sclk, u32 ext_clk_freq, u32 extts); 29 + void ptp_start(struct rvu *rvu, u64 sclk, u32 ext_clk_freq, u32 extts); 29 30 30 31 extern struct pci_driver ptp_driver; 31 32
+1 -1
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
··· 3322 3322 mutex_init(&rvu->rswitch.switch_lock); 3323 3323 3324 3324 if (rvu->fwdata) 3325 - ptp_start(rvu->ptp, rvu->fwdata->sclk, rvu->fwdata->ptp_ext_clk_rate, 3325 + ptp_start(rvu, rvu->fwdata->sclk, rvu->fwdata->ptp_ext_clk_rate, 3326 3326 rvu->fwdata->ptp_ext_tstamp); 3327 3327 3328 3328 return 0;
+12
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
··· 17 17 #include "mbox.h" 18 18 #include "npc.h" 19 19 #include "rvu_reg.h" 20 + #include "ptp.h" 20 21 21 22 /* PCI device IDs */ 22 23 #define PCI_DEVID_OCTEONTX2_RVU_AF 0xA065 ··· 27 26 #define PCI_SUBSYS_DEVID_98XX 0xB100 28 27 #define PCI_SUBSYS_DEVID_96XX 0xB200 29 28 #define PCI_SUBSYS_DEVID_CN10K_A 0xB900 29 + #define PCI_SUBSYS_DEVID_CNF10K_A 0xBA00 30 30 #define PCI_SUBSYS_DEVID_CNF10K_B 0xBC00 31 31 #define PCI_SUBSYS_DEVID_CN10K_B 0xBD00 32 32 ··· 634 632 return (midr == PCI_REVISION_ID_96XX || midr == PCI_REVISION_ID_95XX || 635 633 midr == PCI_REVISION_ID_95XXN || midr == PCI_REVISION_ID_98XX || 636 634 midr == PCI_REVISION_ID_95XXMM || midr == PCI_REVISION_ID_95XXO); 635 + } 636 + 637 + static inline bool is_cnf10ka_a0(struct rvu *rvu) 638 + { 639 + struct pci_dev *pdev = rvu->pdev; 640 + 641 + if (pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A && 642 + (pdev->revision & 0x0F) == 0x0) 643 + return true; 644 + return false; 637 645 } 638 646 639 647 static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu)
+1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 326 326 struct ptp_pin_desc extts_config; 327 327 u64 (*convert_rx_ptp_tstmp)(u64 timestamp); 328 328 u64 (*convert_tx_ptp_tstmp)(u64 timestamp); 329 + u64 (*ptp_tstamp2nsec)(const struct timecounter *time_counter, u64 timestamp); 329 330 struct delayed_work synctstamp_work; 330 331 u64 tstamp; 331 332 u32 base_ns;
+144 -33
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
··· 10 10 #include "otx2_common.h" 11 11 #include "otx2_ptp.h" 12 12 13 + static bool is_tstmp_atomic_update_supported(struct otx2_ptp *ptp) 14 + { 15 + struct ptp_get_cap_rsp *rsp; 16 + struct msg_req *req; 17 + int err; 18 + 19 + if (!ptp->nic) 20 + return false; 21 + 22 + mutex_lock(&ptp->nic->mbox.lock); 23 + req = otx2_mbox_alloc_msg_ptp_get_cap(&ptp->nic->mbox); 24 + if (!req) { 25 + mutex_unlock(&ptp->nic->mbox.lock); 26 + return false; 27 + } 28 + 29 + err = otx2_sync_mbox_msg(&ptp->nic->mbox); 30 + if (err) { 31 + mutex_unlock(&ptp->nic->mbox.lock); 32 + return false; 33 + } 34 + rsp = (struct ptp_get_cap_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 35 + &req->hdr); 36 + mutex_unlock(&ptp->nic->mbox.lock); 37 + 38 + if (IS_ERR(rsp)) 39 + return false; 40 + 41 + if (rsp->cap & PTP_CAP_HW_ATOMIC_UPDATE) 42 + return true; 43 + 44 + return false; 45 + } 46 + 47 + static int otx2_ptp_hw_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 48 + { 49 + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 50 + ptp_info); 51 + struct otx2_nic *pfvf = ptp->nic; 52 + struct ptp_req *req; 53 + int rc; 54 + 55 + if (!ptp->nic) 56 + return -ENODEV; 57 + 58 + mutex_lock(&pfvf->mbox.lock); 59 + req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 60 + if (!req) { 61 + mutex_unlock(&pfvf->mbox.lock); 62 + return -ENOMEM; 63 + } 64 + req->op = PTP_OP_ADJTIME; 65 + req->delta = delta; 66 + rc = otx2_sync_mbox_msg(&ptp->nic->mbox); 67 + mutex_unlock(&pfvf->mbox.lock); 68 + 69 + return rc; 70 + } 71 + 13 72 static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) 14 73 { 15 74 struct ptp_req *req; ··· 94 35 return 0; 95 36 96 37 return rsp->clk; 38 + } 39 + 40 + static int otx2_ptp_hw_gettime(struct ptp_clock_info *ptp_info, 41 + struct timespec64 *ts) 42 + { 43 + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 44 + ptp_info); 45 + u64 tstamp; 46 + 47 + tstamp = otx2_ptp_get_clock(ptp); 48 + 49 + *ts = ns_to_timespec64(tstamp); 50 + return 0; 51 + } 52 + 53 + static int otx2_ptp_hw_settime(struct ptp_clock_info *ptp_info, 54 + const struct timespec64 *ts) 55 + { 56 + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 57 + ptp_info); 58 + struct otx2_nic *pfvf = ptp->nic; 59 + struct ptp_req *req; 60 + u64 nsec; 61 + int rc; 62 + 63 + if (!ptp->nic) 64 + return -ENODEV; 65 + 66 + nsec = timespec64_to_ns(ts); 67 + 68 + mutex_lock(&pfvf->mbox.lock); 69 + req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 70 + if (!req) { 71 + mutex_unlock(&pfvf->mbox.lock); 72 + return -ENOMEM; 73 + } 74 + 75 + req->op = PTP_OP_SET_CLOCK; 76 + req->clk = nsec; 77 + rc = otx2_sync_mbox_msg(&ptp->nic->mbox); 78 + mutex_unlock(&pfvf->mbox.lock); 79 + 80 + return rc; 97 81 } 98 82 99 83 static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) ··· 226 124 return rsp->clk; 227 125 } 228 126 229 - static void otx2_get_ptpclock(struct otx2_ptp *ptp, u64 *tstamp) 230 - { 231 - struct otx2_nic *pfvf = ptp->nic; 232 - 233 - mutex_lock(&pfvf->mbox.lock); 234 - *tstamp = timecounter_read(&ptp->time_counter); 235 - mutex_unlock(&pfvf->mbox.lock); 236 - } 237 - 238 - static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 127 + static int otx2_ptp_tc_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 239 128 { 240 129 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 241 130 ptp_info); ··· 239 146 return 0; 240 147 } 241 148 242 - static int otx2_ptp_gettime(struct ptp_clock_info *ptp_info, 243 - struct timespec64 *ts) 149 + static int otx2_ptp_tc_gettime(struct ptp_clock_info *ptp_info, 150 + struct timespec64 *ts) 244 151 { 245 152 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 246 153 ptp_info); 247 154 u64 tstamp; 248 155 249 - otx2_get_ptpclock(ptp, &tstamp); 156 + mutex_lock(&ptp->nic->mbox.lock); 157 + tstamp = timecounter_read(&ptp->time_counter); 158 + mutex_unlock(&ptp->nic->mbox.lock); 250 159 *ts = ns_to_timespec64(tstamp); 251 160 252 161 return 0; 253 162 } 254 163 255 - static int otx2_ptp_settime(struct ptp_clock_info *ptp_info, 256 - const struct timespec64 *ts) 164 + static int otx2_ptp_tc_settime(struct ptp_clock_info *ptp_info, 165 + const struct timespec64 *ts) 257 166 { 258 167 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 259 168 ptp_info); 260 - struct otx2_nic *pfvf = ptp->nic; 261 169 u64 nsec; 262 170 263 171 nsec = timespec64_to_ns(ts); 264 172 265 - mutex_lock(&pfvf->mbox.lock); 173 + mutex_lock(&ptp->nic->mbox.lock); 266 174 timecounter_init(&ptp->time_counter, &ptp->cycle_counter, nsec); 267 - mutex_unlock(&pfvf->mbox.lock); 175 + mutex_unlock(&ptp->nic->mbox.lock); 268 176 269 177 return 0; 270 178 } ··· 284 190 return 0; 285 191 } 286 192 193 + static u64 otx2_ptp_hw_tstamp2time(const struct timecounter *time_counter, u64 tstamp) 194 + { 195 + /* On HW which supports atomic updates, timecounter is not initialized */ 196 + return tstamp; 197 + } 198 + 287 199 static void otx2_ptp_extts_check(struct work_struct *work) 288 200 { 289 201 struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, ··· 304 204 if (tstmp != ptp->last_extts) { 305 205 event.type = PTP_CLOCK_EXTTS; 306 206 event.index = 0; 307 - event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp); 207 + event.timestamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstmp); 308 208 ptp_clock_event(ptp->ptp_clock, &event); 309 209 new_thresh = tstmp % 500000000; 310 210 if (ptp->thresh != new_thresh) { ··· 329 229 tstamp = otx2_ptp_get_clock(ptp); 330 230 mutex_unlock(&pfvf->mbox.lock); 331 231 332 - ptp->tstamp = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 232 + ptp->tstamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstamp); 333 233 ptp->base_ns = tstamp % NSEC_PER_SEC; 334 234 335 235 schedule_delayed_work(&ptp->synctstamp_work, msecs_to_jiffies(250)); ··· 402 302 403 303 ptp_ptr->nic = pfvf; 404 304 405 - cc = &ptp_ptr->cycle_counter; 406 - cc->read = ptp_cc_read; 407 - cc->mask = CYCLECOUNTER_MASK(64); 408 - cc->mult = 1; 409 - cc->shift = 0; 410 - 411 - timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, 412 - ktime_to_ns(ktime_get_real())); 413 - 414 305 snprintf(ptp_ptr->extts_config.name, sizeof(ptp_ptr->extts_config.name), "TSTAMP"); 415 306 ptp_ptr->extts_config.index = 0; 416 307 ptp_ptr->extts_config.func = PTP_PF_NONE; ··· 415 324 .pps = 0, 416 325 .pin_config = &ptp_ptr->extts_config, 417 326 .adjfine = otx2_ptp_adjfine, 418 - .adjtime = otx2_ptp_adjtime, 419 - .gettime64 = otx2_ptp_gettime, 420 - .settime64 = otx2_ptp_settime, 421 327 .enable = otx2_ptp_enable, 422 328 .verify = otx2_ptp_verify_pin, 423 329 }; 330 + 331 + /* Check whether hardware supports atomic updates to timestamp */ 332 + if (is_tstmp_atomic_update_supported(ptp_ptr)) { 333 + ptp_ptr->ptp_info.adjtime = otx2_ptp_hw_adjtime; 334 + ptp_ptr->ptp_info.gettime64 = otx2_ptp_hw_gettime; 335 + ptp_ptr->ptp_info.settime64 = otx2_ptp_hw_settime; 336 + 337 + ptp_ptr->ptp_tstamp2nsec = otx2_ptp_hw_tstamp2time; 338 + } else { 339 + ptp_ptr->ptp_info.adjtime = otx2_ptp_tc_adjtime; 340 + ptp_ptr->ptp_info.gettime64 = otx2_ptp_tc_gettime; 341 + ptp_ptr->ptp_info.settime64 = otx2_ptp_tc_settime; 342 + 343 + cc = &ptp_ptr->cycle_counter; 344 + cc->read = ptp_cc_read; 345 + cc->mask = CYCLECOUNTER_MASK(64); 346 + cc->mult = 1; 347 + cc->shift = 0; 348 + ptp_ptr->ptp_tstamp2nsec = timecounter_cyc2time; 349 + 350 + timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, 351 + ktime_to_ns(ktime_get_real())); 352 + } 424 353 425 354 INIT_DELAYED_WORK(&ptp_ptr->extts_work, otx2_ptp_extts_check); 426 355 ··· 498 387 if (!pfvf->ptp) 499 388 return -ENODEV; 500 389 501 - *tsns = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 390 + *tsns = pfvf->ptp->ptp_tstamp2nsec(&pfvf->ptp->time_counter, tstamp); 502 391 503 392 return 0; 504 393 }