RK3506 GAMC PPS调试日志
更新: 10/23/2026 字数: 0 字 时长: 0 分钟
寄存器
c
#define GMAC_BASE 0xff4C8B00
#define GMAC_MAP_SIZE 0x100
#define GMAC_TS_CTRL 0x00
#define GMAC_ST_SEC 0x08
#define GMAC_ST_NSEC 0x0C
#define GMAC_TIMESTAMP_STATUS 0x20
#define GMAC_PPS_CTRL 0x70
#define GMAC_PPS0_TAT_SEC 0x80
#define GMAC_PPS0_TAT_NSEC 0x84
#define GMAC_PPS0_INTVL 0x88
#define GMAC_PPS0_WIDTH 0x8C
#define TRGTBUSY (0x1 << 31)
#define TSCTRLSSR (0x1 << 9)配置流程
参考源码kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
配置 PPS 模式
ctemp_reg = (0x2 << 5) | // TRGMODSEL: 设置为可触发中断并输出PPS信号 (0x1 << 4); // PPSEN: 灵活PPS模式 writel(temp_reg, base + GMAC_PPS_CTRL);设置 PPS 周期
cperiod = tv_sec * 1000000000; period += tv_nsec; do_div(period, sub_second_inc); if (period <= 1) return -EINVAL; writel(period - 1, base + GMAC_PPS0_INTVL); // 设置上升沿的时间间隔 period >>= 1; if (period <= 1) return -EINVAL; writel(period - 1, base + GMAC_PPS0_WIDTH); // 设置信号宽度是间隔的一半获取当前时间并设置目标时间
cvoid ptp_get_sys_time(uint32_t *pSec, uint32_t *pNs) { *pSec = readl(base + GMAC_ST_SEC); *pNs = readl(base + GMAC_ST_NSEC); if ((*pSec + 1u) == readl(base + GMAC_ST_SEC)) { *pSec = readl(base + GMAC_ST_SEC); *pNs = readl(base + GMAC_ST_NSEC); } if (!(readl(base + GMAC_TS_CTRL) & TSCTRLSSR)) { *pNs &= 0x7FFFFFFF; } } int pps_set_tgt_time(uint32_t tgt_sec, uint32_t tgt_ns) { int res = 0; uint32_t timeout = 0u; if (init_done == 0u) { return(1); } while ((readl(base + GMAC_PPS0_TAT_NSEC) & TRGTBUSY) == TRGTBUSY) { if (timeout++ > ETH_MAXIMUM_POLL) { res = 1; break; } } if (res == 0) { if (!(readl(base + GMAC_TS_CTRL) & TSCTRLSSR)) { tgt_ns = (tgt_ns * 1000) / 465; } // 设置的时间间隔小于 1s 需要先写纳秒寄存器 writel(tgt_ns, base + GMAC_PPS0_TAT_NSEC); writel(tgt_sec, base + GMAC_PPS0_TAT_SEC); } return res; }启动
writel(0x52, base + GMAC_PPS_CTRL);