Commit e9e37200 authored by Xiaoliang Yang's avatar Xiaoliang Yang Committed by David S. Miller

net: stmmac: ptp: update tas basetime after ptp adjust

After adjusting the ptp time, the Qbv base time may be the past time
of the new current time. dwmac5 hardware limited the base time cannot
be set as past time. This patch add a btr_reserve to store the base
time get from qopt, then calculate the base time and reset the Qbv
configuration after ptp time adjust.
Signed-off-by: default avatarXiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b2aae654
...@@ -62,7 +62,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) ...@@ -62,7 +62,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
u32 sec, nsec; u32 sec, nsec;
u32 quotient, reminder; u32 quotient, reminder;
int neg_adj = 0; int neg_adj = 0;
bool xmac; bool xmac, est_rst = false;
int ret;
xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
...@@ -75,10 +76,48 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) ...@@ -75,10 +76,48 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
sec = quotient; sec = quotient;
nsec = reminder; nsec = reminder;
/* If EST is enabled, disabled it before adjust ptp time. */
if (priv->plat->est && priv->plat->est->enable) {
est_rst = true;
mutex_lock(&priv->plat->est->lock);
priv->plat->est->enable = false;
stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
mutex_unlock(&priv->plat->est->lock);
}
spin_lock_irqsave(&priv->ptp_lock, flags); spin_lock_irqsave(&priv->ptp_lock, flags);
stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac); stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
spin_unlock_irqrestore(&priv->ptp_lock, flags); spin_unlock_irqrestore(&priv->ptp_lock, flags);
/* Caculate new basetime and re-configured EST after PTP time adjust. */
if (est_rst) {
struct timespec64 current_time, time;
ktime_t current_time_ns, basetime;
u64 cycle_time;
mutex_lock(&priv->plat->est->lock);
priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
current_time_ns = timespec64_to_ktime(current_time);
time.tv_nsec = priv->plat->est->btr_reserve[0];
time.tv_sec = priv->plat->est->btr_reserve[1];
basetime = timespec64_to_ktime(time);
cycle_time = priv->plat->est->ctr[1] * NSEC_PER_SEC +
priv->plat->est->ctr[0];
time = stmmac_calc_tas_basetime(basetime,
current_time_ns,
cycle_time);
priv->plat->est->btr[0] = (u32)time.tv_nsec;
priv->plat->est->btr[1] = (u32)time.tv_sec;
priv->plat->est->enable = true;
ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
mutex_unlock(&priv->plat->est->lock);
if (ret)
netdev_err(priv->dev, "failed to configure EST\n");
}
return 0; return 0;
} }
......
...@@ -739,7 +739,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv, ...@@ -739,7 +739,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
{ {
u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep; u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
struct plat_stmmacenet_data *plat = priv->plat; struct plat_stmmacenet_data *plat = priv->plat;
struct timespec64 time, current_time; struct timespec64 time, current_time, qopt_time;
ktime_t current_time_ns; ktime_t current_time_ns;
bool fpe = false; bool fpe = false;
int i, ret = 0; int i, ret = 0;
...@@ -848,6 +848,10 @@ static int tc_setup_taprio(struct stmmac_priv *priv, ...@@ -848,6 +848,10 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
priv->plat->est->btr[0] = (u32)time.tv_nsec; priv->plat->est->btr[0] = (u32)time.tv_nsec;
priv->plat->est->btr[1] = (u32)time.tv_sec; priv->plat->est->btr[1] = (u32)time.tv_sec;
qopt_time = ktime_to_timespec64(qopt->base_time);
priv->plat->est->btr_reserve[0] = (u32)qopt_time.tv_nsec;
priv->plat->est->btr_reserve[1] = (u32)qopt_time.tv_sec;
ctr = qopt->cycle_time; ctr = qopt->cycle_time;
priv->plat->est->ctr[0] = do_div(ctr, NSEC_PER_SEC); priv->plat->est->ctr[0] = do_div(ctr, NSEC_PER_SEC);
priv->plat->est->ctr[1] = (u32)ctr; priv->plat->est->ctr[1] = (u32)ctr;
......
...@@ -117,6 +117,7 @@ struct stmmac_axi { ...@@ -117,6 +117,7 @@ struct stmmac_axi {
struct stmmac_est { struct stmmac_est {
struct mutex lock; struct mutex lock;
int enable; int enable;
u32 btr_reserve[2];
u32 btr_offset[2]; u32 btr_offset[2];
u32 btr[2]; u32 btr[2];
u32 ctr[2]; u32 ctr[2];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment