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.

net: ethernet: ti: am65-cpts: adjust estf following ptp changes

When the CPTS clock is synced/adjusted by running linuxptp (ptp4l/phc2sys),
it will cause the TSN EST schedule to drift away over time. This is because
the schedule is driven by the EstF periodic counter whose pulse length is
defined in ref_clk cycles and it does not automatically sync to CPTS clock.
_______
_|
^
expected cycle start time boundary
_______________
_|_|___|_|
^
EstF drifted away -> direction

To fix it, the same PPM adjustment has to be applied to EstF as done to the
PHC CPTS clock, in order to correct the TSN EST cycle length and keep them
in sync.

Drifted cycle:
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230373377017
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230373877017
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230374377017
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230374877017
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230375377017
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230375877023
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230376377018
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230376877018
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635968230377377018

Stable cycle:
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863193375473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863193875473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863194375473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863194875473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863195375473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863195875473
AM65_CPTS_EVT: 7 e1:01770001 e2:000000ff t:1635966863196375473

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Reviewed-by: Roger Quadros <rogerq@kernel.org>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Link: https://lore.kernel.org/r/20230321062600.2539544-1-s-vadapalli@ti.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Grygorii Strashko and committed by
Paolo Abeni
7849c42d 59da2d7b

+24 -10
+24 -10
drivers/net/ethernet/ti/am65-cpts.c
··· 175 175 u64 timestamp; 176 176 u32 genf_enable; 177 177 u32 hw_ts_enable; 178 + u32 estf_enable; 178 179 struct sk_buff_head txq; 179 180 bool pps_enabled; 180 181 bool pps_present; ··· 406 405 static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) 407 406 { 408 407 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info); 409 - u32 pps_ctrl_val = 0, pps_ppm_hi = 0, pps_ppm_low = 0; 408 + u32 estf_ctrl_val = 0, estf_ppm_hi = 0, estf_ppm_low = 0; 410 409 s32 ppb = scaled_ppm_to_ppb(scaled_ppm); 411 410 int pps_index = cpts->pps_genf_idx; 412 411 u64 adj_period, pps_adj_period; 413 412 u32 ctrl_val, ppm_hi, ppm_low; 414 413 unsigned long flags; 415 - int neg_adj = 0; 414 + int neg_adj = 0, i; 416 415 417 416 if (ppb < 0) { 418 417 neg_adj = 1; ··· 442 441 ppm_low = lower_32_bits(adj_period); 443 442 444 443 if (cpts->pps_enabled) { 445 - pps_ctrl_val = am65_cpts_read32(cpts, genf[pps_index].control); 444 + estf_ctrl_val = am65_cpts_read32(cpts, genf[pps_index].control); 446 445 if (neg_adj) 447 - pps_ctrl_val &= ~BIT(1); 446 + estf_ctrl_val &= ~BIT(1); 448 447 else 449 - pps_ctrl_val |= BIT(1); 448 + estf_ctrl_val |= BIT(1); 450 449 451 450 /* GenF PPM will do correction using cpts refclk tick which is 452 451 * (cpts->ts_add_val + 1) ns, so GenF length PPM adj period 453 452 * need to be corrected. 454 453 */ 455 454 pps_adj_period = adj_period * (cpts->ts_add_val + 1); 456 - pps_ppm_hi = upper_32_bits(pps_adj_period) & 0x3FF; 457 - pps_ppm_low = lower_32_bits(pps_adj_period); 455 + estf_ppm_hi = upper_32_bits(pps_adj_period) & 0x3FF; 456 + estf_ppm_low = lower_32_bits(pps_adj_period); 458 457 } 459 458 460 459 spin_lock_irqsave(&cpts->lock, flags); ··· 472 471 am65_cpts_write32(cpts, ppm_low, ts_ppm_low); 473 472 474 473 if (cpts->pps_enabled) { 475 - am65_cpts_write32(cpts, pps_ctrl_val, genf[pps_index].control); 476 - am65_cpts_write32(cpts, pps_ppm_hi, genf[pps_index].ppm_hi); 477 - am65_cpts_write32(cpts, pps_ppm_low, genf[pps_index].ppm_low); 474 + am65_cpts_write32(cpts, estf_ctrl_val, genf[pps_index].control); 475 + am65_cpts_write32(cpts, estf_ppm_hi, genf[pps_index].ppm_hi); 476 + am65_cpts_write32(cpts, estf_ppm_low, genf[pps_index].ppm_low); 478 477 } 479 478 479 + for (i = 0; i < AM65_CPTS_ESTF_MAX_NUM; i++) { 480 + if (cpts->estf_enable & BIT(i)) { 481 + am65_cpts_write32(cpts, estf_ctrl_val, estf[i].control); 482 + am65_cpts_write32(cpts, estf_ppm_hi, estf[i].ppm_hi); 483 + am65_cpts_write32(cpts, estf_ppm_low, estf[i].ppm_low); 484 + } 485 + } 480 486 /* All GenF/EstF can be updated here the same way */ 481 487 spin_unlock_irqrestore(&cpts->lock, flags); 482 488 ··· 604 596 am65_cpts_write32(cpts, val, estf[idx].comp_lo); 605 597 val = lower_32_bits(cycles); 606 598 am65_cpts_write32(cpts, val, estf[idx].length); 599 + am65_cpts_write32(cpts, 0, estf[idx].control); 600 + am65_cpts_write32(cpts, 0, estf[idx].ppm_hi); 601 + am65_cpts_write32(cpts, 0, estf[idx].ppm_low); 602 + 603 + cpts->estf_enable |= BIT(idx); 607 604 608 605 dev_dbg(cpts->dev, "%s: ESTF:%u enabled\n", __func__, idx); 609 606 ··· 619 606 void am65_cpts_estf_disable(struct am65_cpts *cpts, int idx) 620 607 { 621 608 am65_cpts_write32(cpts, 0, estf[idx].length); 609 + cpts->estf_enable &= ~BIT(idx); 622 610 623 611 dev_dbg(cpts->dev, "%s: ESTF:%u disabled\n", __func__, idx); 624 612 }