diff options
author | Fugang Duan <B38611@freescale.com> | 2014-04-17 03:30:07 -0400 |
---|---|---|
committer | Fugang Duan <B38611@freescale.com> | 2014-04-18 04:48:39 -0400 |
commit | 85e59f19de756eeb537139e71b177ca852957778 (patch) | |
tree | 1984a897468e88a3e2c45eca8c0a84a8183fa801 /drivers/net | |
parent | ee589681988b0550f0f6d8e8dd2c5c8f6a7bb180 (diff) |
ENGR00309055 net: fec_ptp: optimize 1588 convergent performance
1588 convergence process (setup time about 15s) is not ideal:
Applied a time jump on the reference master which causes both slaves
to apply a time jump as well and then synchronize back to the nanoseconds.
Optimize the 1588 adjust algorithm to get better convergent action.
Signed-off-by: Fugang Duan <B38611@freescale.com>
(cherry picked from commit 46a727f7ef469ae7c77c3458efd8a0de2396c360)
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_ptp.c | 51 |
1 files changed, 18 insertions, 33 deletions
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 03e10de40e94..93e55bc441a6 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c | |||
@@ -473,8 +473,7 @@ static void fec_handle_ptpdrift(struct fec_enet_private *priv, | |||
473 | struct ptp_set_comp *comp, struct ptp_time_correct *ptc) | 473 | struct ptp_set_comp *comp, struct ptp_time_correct *ptc) |
474 | { | 474 | { |
475 | u32 ndrift; | 475 | u32 ndrift; |
476 | u32 i, adj_inc, adj_period; | 476 | u32 i; |
477 | u32 tmp_current, tmp_winner; | ||
478 | u32 ptp_ts_clk, ptp_inc; | 477 | u32 ptp_ts_clk, ptp_inc; |
479 | 478 | ||
480 | ptp_ts_clk = clk_get_rate(priv->clk_ptp); | 479 | ptp_ts_clk = clk_get_rate(priv->clk_ptp); |
@@ -486,40 +485,26 @@ static void fec_handle_ptpdrift(struct fec_enet_private *priv, | |||
486 | ptc->corr_inc = 0; | 485 | ptc->corr_inc = 0; |
487 | ptc->corr_period = 0; | 486 | ptc->corr_period = 0; |
488 | return; | 487 | return; |
489 | } else if (ndrift >= ptp_ts_clk) { | 488 | } |
490 | ptc->corr_inc = (u32)(ndrift / ptp_ts_clk); | ||
491 | ptc->corr_period = 1; | ||
492 | return; | ||
493 | } else { | ||
494 | tmp_winner = 0xFFFFFFFF; | ||
495 | adj_inc = 1; | ||
496 | |||
497 | if (ndrift > (ptp_ts_clk / ptp_inc)) { | ||
498 | adj_inc = ptp_inc / FEC_PTP_SPINNER_2; | ||
499 | } else if (ndrift > (ptp_ts_clk / | ||
500 | (ptp_inc * FEC_PTP_SPINNER_4))) { | ||
501 | adj_inc = ptp_inc / FEC_PTP_SPINNER_4; | ||
502 | adj_period = FEC_PTP_SPINNER_2; | ||
503 | } else { | ||
504 | adj_inc = FEC_PTP_SPINNER_4; | ||
505 | adj_period = FEC_PTP_SPINNER_4; | ||
506 | } | ||
507 | 489 | ||
508 | for (i = 1; i < adj_inc; i++) { | 490 | for (i = 1; i <= ptp_inc; i++) { |
509 | tmp_current = (ptp_ts_clk * i) % ndrift; | 491 | if (((i * FEC_T_PERIOD_ONE_SEC) / ndrift) > ptp_inc) { |
510 | if (tmp_current == 0) { | 492 | ptc->corr_inc = i; |
511 | ptc->corr_inc = i; | 493 | ptc->corr_period = ((i * FEC_T_PERIOD_ONE_SEC) / |
512 | ptc->corr_period = (u32)((ptp_ts_clk * | 494 | (ptp_inc * ndrift)); |
513 | adj_period * i) / ndrift); | 495 | break; |
514 | break; | ||
515 | } else if (tmp_current < tmp_winner) { | ||
516 | ptc->corr_inc = i; | ||
517 | ptc->corr_period = (u32)((ptp_ts_clk * | ||
518 | adj_period * i) / ndrift); | ||
519 | tmp_winner = tmp_current; | ||
520 | } | ||
521 | } | 496 | } |
522 | } | 497 | } |
498 | |||
499 | /* not found ? */ | ||
500 | if (i > ptp_inc) { | ||
501 | /* | ||
502 | * set it to high value - double speed | ||
503 | * correct in every clock step. | ||
504 | */ | ||
505 | ptc->corr_inc = ptp_inc; | ||
506 | ptc->corr_period = 1; | ||
507 | } | ||
523 | } | 508 | } |
524 | 509 | ||
525 | static void fec_set_drift(struct fec_enet_private *priv, | 510 | static void fec_set_drift(struct fec_enet_private *priv, |