/* For GMAC3.x, 4.x versions, in "fine adjustement mode" set sub-second * increment to twice the number of nanoseconds of a clock cycle. * The calculation of the default_addend value by the caller will set it * to mid-range = 2^31 when the remainder of this division is zero, * which will make the accumulator overflow once every 2 ptp_clock * cycles, adding twice the number of nanoseconds of a clock cycle : * 2000000000ULL / ptp_clock.
*/ if (value & PTP_TCR_TSCFUPDT)
data = (2000000000ULL / ptp_clock); else
data = (1000000000ULL / ptp_clock);
/* 0.465ns accuracy */ if (!(value & PTP_TCR_TSCTRLSSR))
data = (data * 1000) / 465;
if (data > PTP_SSIR_SSINC_MAX)
data = PTP_SSIR_SSINC_MAX;
reg_value = data; if (gmac4)
reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT;
/* See section 11.7.2.5.3.1 "Ingress Correction" on page 4001 of * i.MX8MP Applications Processor Reference Manual Rev. 1, 06/2021
*/
val = readl(ioaddr + PTP_TCR); if (val & PTP_TCR_TSCTRLSSR) /* nanoseconds field is in decimal format with granularity of 1ns/bit */
scaled_ns = ((u64)NSEC_PER_SEC << 16) - scaled_ns; else /* nanoseconds field is in binary format with granularity of ~0.466ns/bit */
scaled_ns = ((1ULL << 31) << 16) -
DIV_U64_ROUND_CLOSEST(scaled_ns * PSEC_PER_NSEC, 466U);
writel(sec, ioaddr + PTP_STSUR);
writel(nsec, ioaddr + PTP_STNSUR); /* issue command to initialize the system time value */
value = readl(ioaddr + PTP_TCR);
value |= PTP_TCR_TSINIT;
writel(value, ioaddr + PTP_TCR);
/* wait for present system time initialize to complete */ return readl_poll_timeout_atomic(ioaddr + PTP_TCR, value,
!(value & PTP_TCR_TSINIT),
10, 100000);
}
writel(addend, ioaddr + PTP_TAR); /* issue command to update the addend value */
value = readl(ioaddr + PTP_TCR);
value |= PTP_TCR_TSADDREG;
writel(value, ioaddr + PTP_TCR);
/* wait for present addend update to complete */
limit = 10; while (limit--) { if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSADDREG)) break;
mdelay(10);
} if (limit < 0) return -EBUSY;
return 0;
}
staticint adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, int add_sub, int gmac4)
{
u32 value; int limit;
if (add_sub) { /* If the new sec value needs to be subtracted with * the system time, then MAC_STSUR reg should be * programmed with (2^32 – <new_sec_value>)
*/ if (gmac4)
sec = -sec;
/* issue command to initialize the system time value */
value = readl(ioaddr + PTP_TCR);
value |= PTP_TCR_TSUPDT;
writel(value, ioaddr + PTP_TCR);
/* wait for present system time adjust/update to complete */
limit = 10; while (limit--) { if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSUPDT)) break;
mdelay(10);
} if (limit < 0) return -EBUSY;
/* Get the TSS value */
sec1 = readl_relaxed(ioaddr + PTP_STSR); do {
sec0 = sec1; /* Get the TSSS value */
ns = readl_relaxed(ioaddr + PTP_STNSR); /* Get the TSS value */
sec1 = readl_relaxed(ioaddr + PTP_STSR);
} while (sec0 != sec1);
if (systime)
*systime = ns + (sec1 * 1000000000ULL);
}
/* Read timestamp status to clear interrupt from either external * timestamp or start/end of PPS.
*/
ts_status = readl(priv->ioaddr + GMAC_TIMESTAMP_STATUS);
if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN)) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.