linux/drivers/net/ethernet/marvell/mvpp2/mvpp2_tai.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Marvell PP2.2 TAI support
 *
 * Note:
 *   Do NOT use the event capture support.
 *   Do Not even set the MPP muxes to allow PTP_EVENT_REQ to be used.
 *   It will disrupt the operation of this driver, and there is nothing
 *   that this driver can do to prevent that.  Even using PTP_EVENT_REQ
 *   as an output will be seen as a trigger input, which can't be masked.
 *   When ever a trigger input is seen, the action in the TCFCR0_TCF
 *   field will be performed - whether it is a set, increment, decrement
 *   read, or frequency update.
 *
 * Other notes (useful, not specified in the documentation):
 * - PTP_PULSE_OUT (PTP_EVENT_REQ MPP)
 *   It looks like the hardware can't generate a pulse at nsec=0. (The
 *   output doesn't trigger if the nsec field is zero.)
 *   Note: when configured as an output via the register at 0xfX441120,
 *   the input is still very much alive, and will trigger the current TCF
 *   function.
 * - PTP_CLK_OUT (PTP_TRIG_GEN MPP)
 *   This generates a "PPS" signal determined by the CCC registers. It
 *   seems this is not aligned to the TOD counter in any way (it may be
 *   initially, but if you specify a non-round second interval, it won't,
 *   and you can't easily get it back.)
 * - PTP_PCLK_OUT
 *   This generates a 50% duty cycle clock based on the TOD counter, and
 *   seems it can be set to any period of 1ns resolution. It is probably
 *   limited by the TOD step size. Its period is defined by the PCLK_CCC
 *   registers. Again, its alignment to the second is questionable.
 *
 * Consequently, we support none of these.
 */
#include <linux/io.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/slab.h>

#include "mvpp2.h"

#define CR0_SW_NRESET

#define TCFCR0_PHASE_UPDATE_ENABLE
#define TCFCR0_TCF_MASK
#define TCFCR0_TCF_UPDATE
#define TCFCR0_TCF_FREQUPDATE
#define TCFCR0_TCF_INCREMENT
#define TCFCR0_TCF_DECREMENT
#define TCFCR0_TCF_CAPTURE
#define TCFCR0_TCF_NOP
#define TCFCR0_TCF_TRIGGER

#define TCSR_CAPTURE_1_VALID
#define TCSR_CAPTURE_0_VALID

struct mvpp2_tai {};

static void mvpp2_tai_modify(void __iomem *reg, u32 mask, u32 set)
{}

static void mvpp2_tai_write(u32 val, void __iomem *reg)
{}

static u32 mvpp2_tai_read(void __iomem *reg)
{}

static struct mvpp2_tai *ptp_to_tai(struct ptp_clock_info *ptp)
{}

static void mvpp22_tai_read_ts(struct timespec64 *ts, void __iomem *base)
{}

static void mvpp2_tai_write_tlv(const struct timespec64 *ts, u32 frac,
			        void __iomem *base)
{}

static void mvpp2_tai_op(u32 op, void __iomem *base)
{}

/* The adjustment has a range of +0.5ns to -0.5ns in 2^32 steps, so has units
 * of 2^-32 ns.
 *
 * units(s) = 1 / (2^32 * 10^9)
 * fractional = abs_scaled_ppm / (2^16 * 10^6)
 *
 * What we want to achieve:
 *  freq_adjusted = freq_nominal * (1 + fractional)
 *  freq_delta = freq_adjusted - freq_nominal => positive = faster
 *  freq_delta = freq_nominal * (1 + fractional) - freq_nominal
 * So: freq_delta = freq_nominal * fractional
 *
 * However, we are dealing with periods, so:
 *  period_adjusted = period_nominal / (1 + fractional)
 *  period_delta = period_nominal - period_adjusted => positive = faster
 *  period_delta = period_nominal * fractional / (1 + fractional)
 *
 * Hence:
 *  period_delta = period_nominal * abs_scaled_ppm /
 *		   (2^16 * 10^6 + abs_scaled_ppm)
 *
 * To avoid overflow, we reduce both sides of the divide operation by a factor
 * of 16.
 */
static u64 mvpp22_calc_frac_ppm(struct mvpp2_tai *tai, long abs_scaled_ppm)
{}

static s32 mvpp22_calc_max_adj(struct mvpp2_tai *tai)
{}

static int mvpp22_tai_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{}

static int mvpp22_tai_adjtime(struct ptp_clock_info *ptp, s64 delta)
{}

static int mvpp22_tai_gettimex64(struct ptp_clock_info *ptp,
				 struct timespec64 *ts,
				 struct ptp_system_timestamp *sts)
{}

static int mvpp22_tai_settime64(struct ptp_clock_info *ptp,
				const struct timespec64 *ts)
{}

static long mvpp22_tai_aux_work(struct ptp_clock_info *ptp)
{}

static void mvpp22_tai_set_step(struct mvpp2_tai *tai)
{}

static void mvpp22_tai_init(struct mvpp2_tai *tai)
{}

int mvpp22_tai_ptp_clock_index(struct mvpp2_tai *tai)
{}

void mvpp22_tai_tstamp(struct mvpp2_tai *tai, u32 tstamp,
		       struct skb_shared_hwtstamps *hwtstamp)
{}

void mvpp22_tai_start(struct mvpp2_tai *tai)
{}

void mvpp22_tai_stop(struct mvpp2_tai *tai)
{}

static void mvpp22_tai_remove(void *priv)
{}

int mvpp22_tai_probe(struct device *dev, struct mvpp2 *priv)
{}