Linux 的 PTP 硬件时钟基础设施

此补丁集引入了 Linux 中对 IEEE 1588 PTP 时钟的支持。 结合 SO_TIMESTAMPING 套接字选项,这提供了一种标准化方法,用于开发 PTP 用户空间程序、将 Linux 与外部时钟同步以及使用 PTP 硬件时钟的辅助功能。

一个新的类驱动程序导出一个内核接口用于特定时钟驱动程序和一个用户空间接口。 该基础设施支持一整套 PTP 硬件时钟功能。

  • 基本时钟操作 - 设置时间 - 获取时间 - 通过给定的偏移量原子地移动时钟 - 调整时钟频率

  • 辅助时钟功能 - 时间戳外部事件 - 可从用户空间配置的周期输出信号 - 来自用户空间的低通滤波器 (LPF) 访问 - 通过 PPS 子系统同步 Linux 系统时间

PTP 硬件时钟内核 API

PTP 时钟驱动程序向类驱动程序注册自身。 类驱动程序处理与用户空间的所有交互。 时钟驱动程序的作者只需实现编程时钟硬件的细节。 时钟驱动程序通过简单的消息传递接口通知类驱动程序异步事件(警报和外部时间戳)。

类驱动程序支持多个 PTP 时钟驱动程序。 在正常使用情况下,只需要一个 PTP 时钟。 但是,为了测试和开发,在单个系统中拥有多个时钟可能很有用,以便进行性能比较。

PTP 硬件时钟用户空间 API

类驱动程序还为每个注册的时钟创建一个字符设备。 用户空间可以使用来自字符设备的打开文件描述符作为 POSIX 时钟 ID,并且可以调用 clock_gettime、clock_settime 和 clock_adjtime。 这些调用实现了基本的时钟操作。

用户空间程序可以使用标准化的 ioctl 控制时钟。 程序可以查询、启用、配置和禁用辅助时钟功能。 用户空间可以通过阻塞 read() 和 poll() 接收带有时间戳的事件。

编写时钟驱动程序

时钟驱动程序包含 include/linux/ptp_clock_kernel.h 并通过向注册方法提供“struct ptp_clock_info”来注册自身。 时钟驱动程序必须实现接口中的所有功能。 如果时钟不提供特定的辅助功能,则驱动程序应仅从这些函数返回 -EOPNOTSUPP。

驱动程序必须确保接口中的所有方法都是可重入的。 由于大多数硬件实现将时间值视为作为两个 32 位寄存器访问的 64 位整数,因此驱动程序应使用 spin_lock_irqsave/spin_unlock_irqrestore 来防止并发访问。 此锁定无法在类驱动程序中完成,因为时钟驱动程序的中断服务例程也可能需要该锁。

PTP 硬件时钟对 '.adjphase' 的要求

“struct ptp_clock_info”接口具有“.adjphase”函数。 此函数对 PHC 有一组要求才能实现。

  • PHC 在内部实现伺服算法,用于校正在 '.adjphase' 调用中传递的偏移量。

  • 当调用其他 PTP 调整函数时,PHC 伺服算法将被禁用。

注意: '.adjphase' 不是一个简单的时间调整功能,它会根据提供的偏移量'跳跃' PHC 时钟时间。 它应该使用内部算法校正提供的偏移量。

支持的硬件

  • Freescale eTSEC gianfar

    • 2 个时间戳外部触发器,可编程极性(可选中断)

    • 2 个警报寄存器(可选中断)

    • 3 个周期信号(可选中断)

  • 国家半导体 DP83640

    • 6 个 GPIO 可编程为输入或输出

    • 6 个具有专用功能(LED/JTAG/时钟)的 GPIO 也可以用作通用输入或输出

    • GPIO 输入可以对外部触发器进行时间戳

    • GPIO 输出可以产生周期信号

    • 1 个中断引脚

  • 英特尔 IXP465

    • 辅助从/主模式快照(可选中断)

    • 目标时间(可选中断)

  • 瑞萨(IDT)ClockMatrix™

    • 最多 4 个独立的 PHC 通道

    • 集成低通滤波器 (LPF),通过 .adjPhase 访问(符合 ITU-T G.8273.2)

    • 可编程输出周期信号

    • 可编程输入可以对外部触发器进行时间戳

    • 通过固件 (idtcm.bin) 进行驱动程序和/或硬件配置
      • LPF 设置(带宽、相位限制、自动保持、物理层辅助(符合 ITU-T G.8273.2))

      • 可编程输出 PTP 时钟,任何高达 1GHz 的频率(到其他 PHY/MAC 时间戳器,到 ASSP/SoC/FPGA 的 refclk)

      • 锁定到 GNSS 输入,GNSS 和用户空间 PHC 控制之间的自动切换(可选)

  • NVIDIA Mellanox

    • GPIO
      • 某些 ConnectX-6 Dx 及更高版本的产品支持一个 GPIO,它可以对外部触发器进行时间戳,以及一个 GPIO 来产生周期信号。

      • 某些 ConnectX-5 及更早版本的产品支持一个 GPIO,配置为对外部触发器进行时间戳或产生周期信号。

    • PHC 实例
      • 所有 ConnectX 设备都有一个自由运行的计数器

      • ConnectX-6 Dx 及更高版本的设备具有 UTC 格式的计数器