mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
e156e4d2e4
Advertise the maximum offset the .adjphase callback is capable of supporting in nanoseconds for IDT devices. Refactor the negation of the offset stored in the register to be after the boundary check of the offset value rather than before. Boundary check based on the intended value rather than its device-specific representation. Depend on ptp_clock_adjtime for handling out-of-range offsets. ptp_clock_adjtime returns -ERANGE instead of clamping out-of-range offsets. Cc: Richard Cochran <richardcochran@gmail.com> Cc: Min Li <min.li.xe@renesas.com> Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
115 lines
2.9 KiB
C
115 lines
2.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* PTP hardware clock driver for the IDT 82P33XXX family of clocks.
|
|
*
|
|
* Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.
|
|
*/
|
|
#ifndef PTP_IDT82P33_H
|
|
#define PTP_IDT82P33_H
|
|
|
|
#include <linux/ktime.h>
|
|
#include <linux/mfd/idt82p33_reg.h>
|
|
#include <linux/regmap.h>
|
|
|
|
#define FW_FILENAME "idt82p33xxx.bin"
|
|
#define MAX_PHC_PLL (2)
|
|
#define MAX_TRIG_CLK (3)
|
|
#define MAX_PER_OUT (11)
|
|
#define TOD_BYTE_COUNT (10)
|
|
#define DCO_MAX_PPB (92000)
|
|
#define MAX_MEASURMENT_COUNT (5)
|
|
#define SNAP_THRESHOLD_NS (10000)
|
|
#define IMMEDIATE_SNAP_THRESHOLD_NS (50000)
|
|
#define DDCO_THRESHOLD_NS (5)
|
|
#define IDT82P33_MAX_WRITE_COUNT (512)
|
|
|
|
#define PLLMASK_ADDR_HI 0xFF
|
|
#define PLLMASK_ADDR_LO 0xA5
|
|
|
|
#define PLL0_OUTMASK_ADDR_HI 0xFF
|
|
#define PLL0_OUTMASK_ADDR_LO 0xB0
|
|
|
|
#define PLL1_OUTMASK_ADDR_HI 0xFF
|
|
#define PLL1_OUTMASK_ADDR_LO 0xB2
|
|
|
|
#define PLL2_OUTMASK_ADDR_HI 0xFF
|
|
#define PLL2_OUTMASK_ADDR_LO 0xB4
|
|
|
|
#define PLL3_OUTMASK_ADDR_HI 0xFF
|
|
#define PLL3_OUTMASK_ADDR_LO 0xB6
|
|
|
|
#define DEFAULT_PLL_MASK (0x01)
|
|
#define DEFAULT_OUTPUT_MASK_PLL0 (0xc0)
|
|
#define DEFAULT_OUTPUT_MASK_PLL1 DEFAULT_OUTPUT_MASK_PLL0
|
|
|
|
/**
|
|
* @brief Maximum absolute value for write phase offset in nanoseconds
|
|
*/
|
|
#define WRITE_PHASE_OFFSET_LIMIT (20000l)
|
|
|
|
/** @brief Phase offset resolution
|
|
*
|
|
* DPLL phase offset = 10^15 fs / ( System Clock * 2^13)
|
|
* = 10^15 fs / ( 1638400000 * 2^23)
|
|
* = 74.5058059692382 fs
|
|
*/
|
|
#define IDT_T0DPLL_PHASE_RESOL 74506
|
|
|
|
/* PTP Hardware Clock interface */
|
|
struct idt82p33_channel {
|
|
struct ptp_clock_info caps;
|
|
struct ptp_clock *ptp_clock;
|
|
struct idt82p33 *idt82p33;
|
|
enum pll_mode pll_mode;
|
|
/* Workaround for TOD-to-output alignment issue */
|
|
struct delayed_work adjtime_work;
|
|
s32 current_freq;
|
|
/* double dco mode */
|
|
bool ddco;
|
|
u8 output_mask;
|
|
/* last input trigger for extts */
|
|
u8 tod_trigger;
|
|
bool discard_next_extts;
|
|
u8 plln;
|
|
/* remember last tod_sts for extts */
|
|
u8 extts_tod_sts[TOD_BYTE_COUNT];
|
|
u16 dpll_tod_cnfg;
|
|
u16 dpll_tod_trigger;
|
|
u16 dpll_tod_sts;
|
|
u16 dpll_mode_cnfg;
|
|
u16 dpll_freq_cnfg;
|
|
u16 dpll_phase_cnfg;
|
|
u16 dpll_sync_cnfg;
|
|
u16 dpll_input_mode_cnfg;
|
|
};
|
|
|
|
struct idt82p33 {
|
|
struct idt82p33_channel channel[MAX_PHC_PLL];
|
|
struct device *dev;
|
|
u8 pll_mask;
|
|
/* 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 idt82p33_channel *event_channel[MAX_PHC_PLL];
|
|
/* Mutex to protect operations from being interrupted */
|
|
struct mutex *lock;
|
|
struct regmap *regmap;
|
|
struct device *mfd;
|
|
/* Overhead calculation for adjtime */
|
|
ktime_t start_time;
|
|
int calculate_overhead_flag;
|
|
s64 tod_write_overhead_ns;
|
|
};
|
|
|
|
/* firmware interface */
|
|
struct idt82p33_fwrc {
|
|
u8 hiaddr;
|
|
u8 loaddr;
|
|
u8 value;
|
|
u8 reserved;
|
|
} __packed;
|
|
|
|
#endif /* PTP_IDT82P33_H */
|