Skip to content

Commit

Permalink
ptp: ptp_clockmatrix: Add .getmaxphase ptp_clock_info callback
Browse files Browse the repository at this point in the history
Advertise the maximum offset the .adjphase callback is capable of
supporting in nanoseconds for IDT ClockMatrix devices. 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: Vincent Cheng <vincent.cheng.xh@renesas.com>
Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Rahul Rameshbabu authored and David S. Miller committed Jun 20, 2023
1 parent 67ac72a commit c066e74
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 20 deletions.
36 changes: 17 additions & 19 deletions drivers/ptp/ptp_clockmatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1692,14 +1692,23 @@ static int initialize_dco_operating_mode(struct idtcm_channel *channel)
/* PTP Hardware Clock interface */

/*
* Maximum absolute value for write phase offset in picoseconds
*
* @channel: channel
* @delta_ns: delta in nanoseconds
* Maximum absolute value for write phase offset in nanoseconds
*
* Destination signed register is 32-bit register in resolution of 50ps
*
* 0x7fffffff * 50 = 2147483647 * 50 = 107374182350
* 0x7fffffff * 50 = 2147483647 * 50 = 107374182350 ps
* Represent 107374182350 ps as 107374182 ns
*/
static s32 idtcm_getmaxphase(struct ptp_clock_info *ptp __always_unused)
{
return MAX_ABS_WRITE_PHASE_NANOSECONDS;
}

/*
* Internal function for implementing support for write phase offset
*
* @channel: channel
* @delta_ns: delta in nanoseconds
*/
static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
{
Expand All @@ -1708,27 +1717,14 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
u8 i;
u8 buf[4] = {0};
s32 phase_50ps;
s64 offset_ps;

if (channel->mode != PTP_PLL_MODE_WRITE_PHASE) {
err = channel->configure_write_phase(channel);
if (err)
return err;
}

offset_ps = (s64)delta_ns * 1000;

/*
* Check for 32-bit signed max * 50:
*
* 0x7fffffff * 50 = 2147483647 * 50 = 107374182350
*/
if (offset_ps > MAX_ABS_WRITE_PHASE_PICOSECONDS)
offset_ps = MAX_ABS_WRITE_PHASE_PICOSECONDS;
else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS)
offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS;

phase_50ps = div_s64(offset_ps, 50);
phase_50ps = div_s64((s64)delta_ns * 1000, 50);

for (i = 0; i < 4; i++) {
buf[i] = phase_50ps & 0xff;
Expand Down Expand Up @@ -2048,6 +2044,7 @@ static const struct ptp_clock_info idtcm_caps = {
.n_ext_ts = MAX_TOD,
.n_pins = MAX_REF_CLK,
.adjphase = &idtcm_adjphase,
.getmaxphase = &idtcm_getmaxphase,
.adjfine = &idtcm_adjfine,
.adjtime = &idtcm_adjtime,
.gettime64 = &idtcm_gettime,
Expand All @@ -2064,6 +2061,7 @@ static const struct ptp_clock_info idtcm_caps_deprecated = {
.n_ext_ts = MAX_TOD,
.n_pins = MAX_REF_CLK,
.adjphase = &idtcm_adjphase,
.getmaxphase = &idtcm_getmaxphase,
.adjfine = &idtcm_adjfine,
.adjtime = &idtcm_adjtime_deprecated,
.gettime64 = &idtcm_gettime,
Expand Down
2 changes: 1 addition & 1 deletion drivers/ptp/ptp_clockmatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define MAX_PLL (8)
#define MAX_REF_CLK (16)

#define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
#define MAX_ABS_WRITE_PHASE_NANOSECONDS (107374182L)

#define TOD_MASK_ADDR (0xFFA5)
#define DEFAULT_TOD_MASK (0x04)
Expand Down

0 comments on commit c066e74

Please sign in to comment.