/* SPDX-License-Identifier: GPL-2.0+ */ /* * PTP hardware clock driver for the IDT ClockMatrix(TM) family of timing and * synchronization devices. * * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company. */ #ifndef PTP_IDTCLOCKMATRIX_H #define PTP_IDTCLOCKMATRIX_H #include #include #include #include #define FW_FILENAME "idtcm.bin" #define MAX_TOD (4) #define MAX_PLL (8) #define MAX_REF_CLK (16) #define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL) #define TOD_MASK_ADDR (0xFFA5) #define DEFAULT_TOD_MASK (0x04) #define SET_U16_LSB(orig, val8) (orig = (0xff00 & (orig)) | (val8)) #define SET_U16_MSB(orig, val8) (orig = (0x00ff & (orig)) | (val8 << 8)) #define TOD0_PTP_PLL_ADDR (0xFFA8) #define TOD1_PTP_PLL_ADDR (0xFFA9) #define TOD2_PTP_PLL_ADDR (0xFFAA) #define TOD3_PTP_PLL_ADDR (0xFFAB) #define TOD0_OUT_ALIGN_MASK_ADDR (0xFFB0) #define TOD1_OUT_ALIGN_MASK_ADDR (0xFFB2) #define TOD2_OUT_ALIGN_MASK_ADDR (0xFFB4) #define TOD3_OUT_ALIGN_MASK_ADDR (0xFFB6) #define DEFAULT_OUTPUT_MASK_PLL0 (0x003) #define DEFAULT_OUTPUT_MASK_PLL1 (0x00c) #define DEFAULT_OUTPUT_MASK_PLL2 (0x030) #define DEFAULT_OUTPUT_MASK_PLL3 (0x0c0) #define DEFAULT_TOD0_PTP_PLL (0) #define DEFAULT_TOD1_PTP_PLL (1) #define DEFAULT_TOD2_PTP_PLL (2) #define DEFAULT_TOD3_PTP_PLL (3) #define PHASE_PULL_IN_THRESHOLD_NS_DEPRECATED (150000) #define PHASE_PULL_IN_THRESHOLD_NS (15000) #define TOD_WRITE_OVERHEAD_COUNT_MAX (2) #define TOD_BYTE_COUNT (11) #define LOCK_TIMEOUT_MS (2000) #define LOCK_POLL_INTERVAL_MS (10) #define IDTCM_MAX_WRITE_COUNT (512) #define PHASE_PULL_IN_MAX_PPB (144000) #define PHASE_PULL_IN_MIN_THRESHOLD_NS (2) /* * Return register address based on passed in firmware version */ #define IDTCM_FW_REG(FW, VER, REG) (((FW) < (VER)) ? (REG) : (REG##_##VER)) enum fw_version { V_DEFAULT = 0, V487 = 1, V520 = 2, }; /* PTP PLL Mode */ enum ptp_pll_mode { PTP_PLL_MODE_MIN = 0, PTP_PLL_MODE_WRITE_FREQUENCY = PTP_PLL_MODE_MIN, PTP_PLL_MODE_WRITE_PHASE, PTP_PLL_MODE_UNSUPPORTED, PTP_PLL_MODE_MAX = PTP_PLL_MODE_UNSUPPORTED, }; struct idtcm; struct idtcm_channel { struct ptp_clock_info caps; struct ptp_clock *ptp_clock; struct idtcm *idtcm; u16 dpll_phase; u16 dpll_freq; u16 dpll_n; u16 dpll_ctrl_n; u16 dpll_phase_pull_in; u16 tod_read_primary; u16 tod_read_secondary; u16 tod_write; u16 tod_n; u16 hw_dpll_n; u8 sync_src; enum ptp_pll_mode mode; int (*configure_write_frequency)(struct idtcm_channel *channel); int (*configure_write_phase)(struct idtcm_channel *channel); int (*do_phase_pull_in)(struct idtcm_channel *channel, s32 offset_ns, u32 max_ffo_ppb); s32 current_freq_scaled_ppm; bool phase_pull_in; u32 dco_delay; /* last input trigger for extts */ u8 refn; u8 pll; u8 tod; u16 output_mask; }; struct idtcm { struct idtcm_channel channel[MAX_TOD]; struct device *dev; u8 tod_mask; char version[16]; enum fw_version fw_ver; /* Polls for external time stamps */ u8 extts_mask; bool extts_single_shot; struct delayed_work extts_work; /* Remember the ptp channel to report extts */ struct idtcm_channel *event_channel[MAX_TOD]; /* Mutex to protect operations from being interrupted */ struct mutex *lock; struct device *mfd; struct regmap *regmap; /* Overhead calculation for adjtime */ u8 calculate_overhead_flag; s64 tod_write_overhead_ns; ktime_t start_time; }; struct idtcm_fwrc { u8 hiaddr; u8 loaddr; u8 value; u8 reserved; } __packed; #endif /* PTP_IDTCLOCKMATRIX_H */