in ptp_clockmatrix.c [685:750]
static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
struct timespec64 const *ts,
enum hw_tod_write_trig_sel wr_trig)
{
struct idtcm *idtcm = channel->idtcm;
u8 buf[TOD_BYTE_COUNT];
u8 cmd;
int err;
struct timespec64 local_ts = *ts;
s64 total_overhead_ns;
/* Configure HW TOD write trigger. */
err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
&cmd, sizeof(cmd));
if (err)
return err;
cmd &= ~(0x0f);
cmd |= wr_trig | 0x08;
err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
&cmd, sizeof(cmd));
if (err)
return err;
if (wr_trig != HW_TOD_WR_TRIG_SEL_MSB) {
err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
if (err)
return err;
err = idtcm_write(idtcm, channel->hw_dpll_n,
HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
if (err)
return err;
}
/* ARM HW TOD write trigger. */
cmd &= ~(0x08);
err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
&cmd, sizeof(cmd));
if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) {
if (idtcm->calculate_overhead_flag) {
/* Assumption: I2C @ 400KHz */
ktime_t diff = ktime_sub(ktime_get_raw(),
idtcm->start_time);
total_overhead_ns = ktime_to_ns(diff)
+ idtcm->tod_write_overhead_ns
+ SETTIME_CORRECTION;
timespec64_add_ns(&local_ts, total_overhead_ns);
idtcm->calculate_overhead_flag = 0;
}
err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
if (err)
return err;
err = idtcm_write(idtcm, channel->hw_dpll_n,
HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
}
return err;
}