Commit 41f1a01b authored by David S. Miller's avatar David S. Miller

Merge branch 'ptp-ptp_clockmatrix-Fix-output-1-PPS-alignment'

Vincent Cheng says:

====================
ptp: ptp_clockmatrix: Fix output 1 PPS alignment.

This series fixes a race condition that may result in the output clock
not aligned to internal 1 PPS clock.

Part of device initialization is to align the rising edge of output
clocks to the internal rising edge of the 1 PPS clock.  If the system
APLL and DPLL are not locked when this alignment occurs, the alignment
fails and a fixed offset between the internal 1 PPS clock and the
output clock occurs.

If a clock is dynamically enabled after power-up, the output clock
also needs to be aligned to the internal 1 PPS clock.

v3:
Suggested by: Jakub Kicinski <kuba@kernel.org>
- Remove unnecessary 'err' variable
- Increase msleep()/loop accuracy by using jiffies in while()
- No empty lines between variables
- No empty lines between call and the if
- parenthesis around a == b are unnecessary
- Inconsistent \n usage in dev_()
- Remove unnecessary empty line
- Leave string format in place so static code checkers can
  validate arguments

v2:
Suggested by: Richard Cochran <richardcochran@gmail.com>
- Added const to "char * fmt"
- Break unrelated header change into separate patch
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 85749080 77fdb168
...@@ -122,6 +122,8 @@ ...@@ -122,6 +122,8 @@
#define OTP_SCSR_CONFIG_SELECT 0x0022 #define OTP_SCSR_CONFIG_SELECT 0x0022
#define STATUS 0xc03c #define STATUS 0xc03c
#define DPLL_SYS_STATUS 0x0020
#define DPLL_SYS_APLL_STATUS 0x0021
#define USER_GPIO0_TO_7_STATUS 0x008a #define USER_GPIO0_TO_7_STATUS 0x008a
#define USER_GPIO8_TO_15_STATUS 0x008b #define USER_GPIO8_TO_15_STATUS 0x008b
...@@ -707,4 +709,12 @@ ...@@ -707,4 +709,12 @@
/* Bit definitions for the DPLL_CTRL_COMBO_MASTER_CFG register */ /* Bit definitions for the DPLL_CTRL_COMBO_MASTER_CFG register */
#define COMBO_MASTER_HOLD BIT(0) #define COMBO_MASTER_HOLD BIT(0)
/* Bit definitions for DPLL_SYS_STATUS register */
#define DPLL_SYS_STATE_MASK (0xf)
/* Bit definitions for SYS_APLL_STATUS register */
#define SYS_APLL_LOSS_LOCK_LIVE_MASK BIT(0)
#define SYS_APLL_LOSS_LOCK_LIVE_LOCKED 0
#define SYS_APLL_LOSS_LOCK_LIVE_UNLOCKED 1
#endif #endif
...@@ -160,7 +160,6 @@ static int idtcm_xfer_read(struct idtcm *idtcm, ...@@ -160,7 +160,6 @@ static int idtcm_xfer_read(struct idtcm *idtcm,
struct i2c_client *client = idtcm->client; struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2]; struct i2c_msg msg[2];
int cnt; int cnt;
char *fmt = "i2c_transfer failed at %d in %s, at addr: %04X!\n";
msg[0].addr = client->addr; msg[0].addr = client->addr;
msg[0].flags = 0; msg[0].flags = 0;
...@@ -176,14 +175,12 @@ static int idtcm_xfer_read(struct idtcm *idtcm, ...@@ -176,14 +175,12 @@ static int idtcm_xfer_read(struct idtcm *idtcm,
if (cnt < 0) { if (cnt < 0) {
dev_err(&client->dev, dev_err(&client->dev,
fmt, "i2c_transfer failed at %d in %s, at addr: %04x!",
__LINE__, __LINE__, __func__, regaddr);
__func__,
regaddr);
return cnt; return cnt;
} else if (cnt != 2) { } else if (cnt != 2) {
dev_err(&client->dev, dev_err(&client->dev,
"i2c_transfer sent only %d of %d messages\n", cnt, 2); "i2c_transfer sent only %d of %d messages", cnt, 2);
return -EIO; return -EIO;
} }
...@@ -199,7 +196,6 @@ static int idtcm_xfer_write(struct idtcm *idtcm, ...@@ -199,7 +196,6 @@ static int idtcm_xfer_write(struct idtcm *idtcm,
/* we add 1 byte for device register */ /* we add 1 byte for device register */
u8 msg[IDTCM_MAX_WRITE_COUNT + 1]; u8 msg[IDTCM_MAX_WRITE_COUNT + 1];
int cnt; int cnt;
char *fmt = "i2c_master_send failed at %d in %s, at addr: %04X!\n";
if (count > IDTCM_MAX_WRITE_COUNT) if (count > IDTCM_MAX_WRITE_COUNT)
return -EINVAL; return -EINVAL;
...@@ -211,10 +207,8 @@ static int idtcm_xfer_write(struct idtcm *idtcm, ...@@ -211,10 +207,8 @@ static int idtcm_xfer_write(struct idtcm *idtcm,
if (cnt < 0) { if (cnt < 0) {
dev_err(&client->dev, dev_err(&client->dev,
fmt, "i2c_master_send failed at %d in %s, at addr: %04x!",
__LINE__, __LINE__, __func__, regaddr);
__func__,
regaddr);
return cnt; return cnt;
} }
...@@ -235,10 +229,9 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val) ...@@ -235,10 +229,9 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
buf[3] = 0x20; buf[3] = 0x20;
err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf)); err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf));
if (err) { if (err) {
idtcm->page_offset = 0xff; idtcm->page_offset = 0xff;
dev_err(&idtcm->client->dev, "failed to set page offset\n"); dev_err(&idtcm->client->dev, "failed to set page offset");
} else { } else {
idtcm->page_offset = val; idtcm->page_offset = val;
} }
...@@ -260,7 +253,6 @@ static int _idtcm_rdwr(struct idtcm *idtcm, ...@@ -260,7 +253,6 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
lo = regaddr & 0xff; lo = regaddr & 0xff;
err = idtcm_page_offset(idtcm, hi); err = idtcm_page_offset(idtcm, hi);
if (err) if (err)
return err; return err;
...@@ -290,12 +282,9 @@ static int idtcm_write(struct idtcm *idtcm, ...@@ -290,12 +282,9 @@ static int idtcm_write(struct idtcm *idtcm,
static int clear_boot_status(struct idtcm *idtcm) static int clear_boot_status(struct idtcm *idtcm)
{ {
int err;
u8 buf[4] = {0}; u8 buf[4] = {0};
err = idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf)); return idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));
return err;
} }
static int read_boot_status(struct idtcm *idtcm, u32 *status) static int read_boot_status(struct idtcm *idtcm, u32 *status)
...@@ -318,7 +307,6 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm) ...@@ -318,7 +307,6 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm)
do { do {
err = read_boot_status(idtcm, &status); err = read_boot_status(idtcm, &status);
if (err) if (err)
return err; return err;
...@@ -330,11 +318,72 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm) ...@@ -330,11 +318,72 @@ static int wait_for_boot_status_ready(struct idtcm *idtcm)
} while (i); } while (i);
dev_warn(&idtcm->client->dev, "%s timed out\n", __func__); dev_warn(&idtcm->client->dev, "%s timed out", __func__);
return -EBUSY; return -EBUSY;
} }
static int read_sys_apll_status(struct idtcm *idtcm, u8 *status)
{
return idtcm_read(idtcm, STATUS, DPLL_SYS_APLL_STATUS, status,
sizeof(u8));
}
static int read_sys_dpll_status(struct idtcm *idtcm, u8 *status)
{
return idtcm_read(idtcm, STATUS, DPLL_SYS_STATUS, status, sizeof(u8));
}
static int wait_for_sys_apll_dpll_lock(struct idtcm *idtcm)
{
unsigned long timeout = jiffies + msecs_to_jiffies(LOCK_TIMEOUT_MS);
u8 apll = 0;
u8 dpll = 0;
int err;
do {
err = read_sys_apll_status(idtcm, &apll);
if (err)
return err;
err = read_sys_dpll_status(idtcm, &dpll);
if (err)
return err;
apll &= SYS_APLL_LOSS_LOCK_LIVE_MASK;
dpll &= DPLL_SYS_STATE_MASK;
if (apll == SYS_APLL_LOSS_LOCK_LIVE_LOCKED &&
dpll == DPLL_STATE_LOCKED) {
return 0;
} else if (dpll == DPLL_STATE_FREERUN ||
dpll == DPLL_STATE_HOLDOVER ||
dpll == DPLL_STATE_OPEN_LOOP) {
dev_warn(&idtcm->client->dev,
"No wait state: DPLL_SYS_STATE %d", dpll);
return -EPERM;
}
msleep(LOCK_POLL_INTERVAL_MS);
} while (time_is_after_jiffies(timeout));
dev_warn(&idtcm->client->dev,
"%d ms lock timeout: SYS APLL Loss Lock %d SYS DPLL state %d",
LOCK_TIMEOUT_MS, apll, dpll);
return -ETIME;
}
static void wait_for_chip_ready(struct idtcm *idtcm)
{
if (wait_for_boot_status_ready(idtcm))
dev_warn(&idtcm->client->dev, "BOOT_STATUS != 0xA0");
if (wait_for_sys_apll_dpll_lock(idtcm))
dev_warn(&idtcm->client->dev,
"Continuing while SYS APLL/DPLL is not locked");
}
static int _idtcm_gettime(struct idtcm_channel *channel, static int _idtcm_gettime(struct idtcm_channel *channel,
struct timespec64 *ts) struct timespec64 *ts)
{ {
...@@ -360,14 +409,12 @@ static int _idtcm_gettime(struct idtcm_channel *channel, ...@@ -360,14 +409,12 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
/* wait trigger to be 0 */ /* wait trigger to be 0 */
while (trigger & TOD_READ_TRIGGER_MASK) { while (trigger & TOD_READ_TRIGGER_MASK) {
if (idtcm->calculate_overhead_flag) if (idtcm->calculate_overhead_flag)
idtcm->start_time = ktime_get_raw(); idtcm->start_time = ktime_get_raw();
err = idtcm_read(idtcm, channel->tod_read_primary, err = idtcm_read(idtcm, channel->tod_read_primary,
TOD_READ_PRIMARY_CMD, &trigger, TOD_READ_PRIMARY_CMD, &trigger,
sizeof(trigger)); sizeof(trigger));
if (err) if (err)
return err; return err;
...@@ -377,7 +424,6 @@ static int _idtcm_gettime(struct idtcm_channel *channel, ...@@ -377,7 +424,6 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
err = idtcm_read(idtcm, channel->tod_read_primary, err = idtcm_read(idtcm, channel->tod_read_primary,
TOD_READ_PRIMARY, buf, sizeof(buf)); TOD_READ_PRIMARY, buf, sizeof(buf));
if (err) if (err)
return err; return err;
...@@ -398,7 +444,7 @@ static int _sync_pll_output(struct idtcm *idtcm, ...@@ -398,7 +444,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
u16 sync_ctrl1; u16 sync_ctrl1;
u8 temp; u8 temp;
if ((qn == 0) && (qn_plus_1 == 0)) if (qn == 0 && qn_plus_1 == 0)
return 0; return 0;
switch (pll) { switch (pll) {
...@@ -463,7 +509,7 @@ static int _sync_pll_output(struct idtcm *idtcm, ...@@ -463,7 +509,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
return err; return err;
/* PLL5 can have OUT8 as second additional output. */ /* PLL5 can have OUT8 as second additional output. */
if ((pll == 5) && (qn_plus_1 != 0)) { if (pll == 5 && qn_plus_1 != 0) {
err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE, err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
&temp, sizeof(temp)); &temp, sizeof(temp));
if (err) if (err)
...@@ -485,7 +531,7 @@ static int _sync_pll_output(struct idtcm *idtcm, ...@@ -485,7 +531,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
} }
/* PLL6 can have OUT11 as second additional output. */ /* PLL6 can have OUT11 as second additional output. */
if ((pll == 6) && (qn_plus_1 != 0)) { if (pll == 6 && qn_plus_1 != 0) {
err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE, err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
&temp, sizeof(temp)); &temp, sizeof(temp));
if (err) if (err)
...@@ -540,7 +586,6 @@ static int sync_source_dpll_tod_pps(u16 tod_addr, u8 *sync_src) ...@@ -540,7 +586,6 @@ static int sync_source_dpll_tod_pps(u16 tod_addr, u8 *sync_src)
static int idtcm_sync_pps_output(struct idtcm_channel *channel) static int idtcm_sync_pps_output(struct idtcm_channel *channel)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 pll; u8 pll;
u8 sync_src; u8 sync_src;
u8 qn; u8 qn;
...@@ -549,7 +594,6 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel) ...@@ -549,7 +594,6 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel)
u8 out8_mux = 0; u8 out8_mux = 0;
u8 out11_mux = 0; u8 out11_mux = 0;
u8 temp; u8 temp;
u16 output_mask = channel->output_mask; u16 output_mask = channel->output_mask;
err = sync_source_dpll_tod_pps(channel->tod_n, &sync_src); err = sync_source_dpll_tod_pps(channel->tod_n, &sync_src);
...@@ -610,7 +654,7 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel) ...@@ -610,7 +654,7 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel)
} }
} }
if ((qn != 0) || (qn_plus_1 != 0)) if (qn != 0 || qn_plus_1 != 0)
err = _sync_pll_output(idtcm, pll, sync_src, qn, err = _sync_pll_output(idtcm, pll, sync_src, qn,
qn_plus_1); qn_plus_1);
...@@ -626,7 +670,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -626,7 +670,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
enum hw_tod_write_trig_sel wr_trig) enum hw_tod_write_trig_sel wr_trig)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 buf[TOD_BYTE_COUNT]; u8 buf[TOD_BYTE_COUNT];
u8 cmd; u8 cmd;
int err; int err;
...@@ -636,7 +679,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -636,7 +679,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
/* Configure HW TOD write trigger. */ /* Configure HW TOD write trigger. */
err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1, err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
&cmd, sizeof(cmd)); &cmd, sizeof(cmd));
if (err) if (err)
return err; return err;
...@@ -645,20 +687,16 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -645,20 +687,16 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1, err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
&cmd, sizeof(cmd)); &cmd, sizeof(cmd));
if (err) if (err)
return err; return err;
if (wr_trig != HW_TOD_WR_TRIG_SEL_MSB) { if (wr_trig != HW_TOD_WR_TRIG_SEL_MSB) {
err = timespec_to_char_array(&local_ts, buf, sizeof(buf)); err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
if (err) if (err)
return err; return err;
err = idtcm_write(idtcm, channel->hw_dpll_n, err = idtcm_write(idtcm, channel->hw_dpll_n,
HW_DPLL_TOD_OVR__0, buf, sizeof(buf)); HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
if (err) if (err)
return err; return err;
} }
...@@ -670,7 +708,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -670,7 +708,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
&cmd, sizeof(cmd)); &cmd, sizeof(cmd));
if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) { if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) {
if (idtcm->calculate_overhead_flag) { if (idtcm->calculate_overhead_flag) {
/* Assumption: I2C @ 400KHz */ /* Assumption: I2C @ 400KHz */
ktime_t diff = ktime_sub(ktime_get_raw(), ktime_t diff = ktime_sub(ktime_get_raw(),
...@@ -685,7 +722,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -685,7 +722,6 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
} }
err = timespec_to_char_array(&local_ts, buf, sizeof(buf)); err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
if (err) if (err)
return err; return err;
...@@ -709,7 +745,6 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel, ...@@ -709,7 +745,6 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
timespec64_add_ns(&local_ts, SETTIME_CORRECTION); timespec64_add_ns(&local_ts, SETTIME_CORRECTION);
err = timespec_to_char_array(&local_ts, buf, sizeof(buf)); err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
if (err) if (err)
return err; return err;
...@@ -750,7 +785,7 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel, ...@@ -750,7 +785,7 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
if (++count > 20) { if (++count > 20) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Timed out waiting for the write counter\n"); "Timed out waiting for the write counter");
return -EIO; return -EIO;
} }
} }
...@@ -813,10 +848,9 @@ static int _idtcm_settime_deprecated(struct idtcm_channel *channel, ...@@ -813,10 +848,9 @@ static int _idtcm_settime_deprecated(struct idtcm_channel *channel,
int err; int err;
err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB); err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"%s: Set HW ToD failed\n", __func__); "%s: Set HW ToD failed", __func__);
return err; return err;
} }
...@@ -838,7 +872,6 @@ static int idtcm_set_phase_pull_in_offset(struct idtcm_channel *channel, ...@@ -838,7 +872,6 @@ static int idtcm_set_phase_pull_in_offset(struct idtcm_channel *channel,
int err; int err;
int i; int i;
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 buf[4]; u8 buf[4];
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -858,7 +891,6 @@ static int idtcm_set_phase_pull_in_slope_limit(struct idtcm_channel *channel, ...@@ -858,7 +891,6 @@ static int idtcm_set_phase_pull_in_slope_limit(struct idtcm_channel *channel,
int err; int err;
u8 i; u8 i;
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 buf[3]; u8 buf[3];
if (max_ffo_ppb & 0xff000000) if (max_ffo_ppb & 0xff000000)
...@@ -879,12 +911,10 @@ static int idtcm_start_phase_pull_in(struct idtcm_channel *channel) ...@@ -879,12 +911,10 @@ static int idtcm_start_phase_pull_in(struct idtcm_channel *channel)
{ {
int err; int err;
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 buf; u8 buf;
err = idtcm_read(idtcm, channel->dpll_phase_pull_in, PULL_IN_CTRL, err = idtcm_read(idtcm, channel->dpll_phase_pull_in, PULL_IN_CTRL,
&buf, sizeof(buf)); &buf, sizeof(buf));
if (err) if (err)
return err; return err;
...@@ -906,12 +936,10 @@ static int idtcm_do_phase_pull_in(struct idtcm_channel *channel, ...@@ -906,12 +936,10 @@ static int idtcm_do_phase_pull_in(struct idtcm_channel *channel,
int err; int err;
err = idtcm_set_phase_pull_in_offset(channel, -offset_ns); err = idtcm_set_phase_pull_in_offset(channel, -offset_ns);
if (err) if (err)
return err; return err;
err = idtcm_set_phase_pull_in_slope_limit(channel, max_ffo_ppb); err = idtcm_set_phase_pull_in_slope_limit(channel, max_ffo_ppb);
if (err) if (err)
return err; return err;
...@@ -927,7 +955,6 @@ static int set_tod_write_overhead(struct idtcm_channel *channel) ...@@ -927,7 +955,6 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
s64 lowest_ns = 0; s64 lowest_ns = 0;
int err; int err;
u8 i; u8 i;
ktime_t start; ktime_t start;
ktime_t stop; ktime_t stop;
ktime_t diff; ktime_t diff;
...@@ -939,12 +966,10 @@ static int set_tod_write_overhead(struct idtcm_channel *channel) ...@@ -939,12 +966,10 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
buf, sizeof(buf)); buf, sizeof(buf));
for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) { for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) {
start = ktime_get_raw(); start = ktime_get_raw();
err = idtcm_write(idtcm, channel->hw_dpll_n, err = idtcm_write(idtcm, channel->hw_dpll_n,
HW_DPLL_TOD_OVR__0, buf, sizeof(buf)); HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
if (err) if (err)
return err; return err;
...@@ -980,12 +1005,10 @@ static int _idtcm_adjtime_deprecated(struct idtcm_channel *channel, s64 delta) ...@@ -980,12 +1005,10 @@ static int _idtcm_adjtime_deprecated(struct idtcm_channel *channel, s64 delta)
idtcm->calculate_overhead_flag = 1; idtcm->calculate_overhead_flag = 1;
err = set_tod_write_overhead(channel); err = set_tod_write_overhead(channel);
if (err) if (err)
return err; return err;
err = _idtcm_gettime(channel, &ts); err = _idtcm_gettime(channel, &ts);
if (err) if (err)
return err; return err;
...@@ -1018,14 +1041,14 @@ static int idtcm_state_machine_reset(struct idtcm *idtcm) ...@@ -1018,14 +1041,14 @@ static int idtcm_state_machine_reset(struct idtcm *idtcm)
if (status == 0xA0) { if (status == 0xA0) {
dev_dbg(&idtcm->client->dev, dev_dbg(&idtcm->client->dev,
"SM_RESET completed in %d ms\n", "SM_RESET completed in %d ms", i * 100);
i * 100);
break; break;
} }
} }
if (!status) if (!status)
dev_err(&idtcm->client->dev, "Timed out waiting for CM_RESET to complete\n"); dev_err(&idtcm->client->dev,
"Timed out waiting for CM_RESET to complete");
} }
return err; return err;
...@@ -1121,12 +1144,12 @@ static int set_pll_output_mask(struct idtcm *idtcm, u16 addr, u8 val) ...@@ -1121,12 +1144,12 @@ static int set_pll_output_mask(struct idtcm *idtcm, u16 addr, u8 val)
static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll) static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll)
{ {
if (index >= MAX_TOD) { if (index >= MAX_TOD) {
dev_err(&idtcm->client->dev, "ToD%d not supported\n", index); dev_err(&idtcm->client->dev, "ToD%d not supported", index);
return -EINVAL; return -EINVAL;
} }
if (pll >= MAX_PLL) { if (pll >= MAX_PLL) {
dev_err(&idtcm->client->dev, "Pll%d not supported\n", pll); dev_err(&idtcm->client->dev, "Pll%d not supported", pll);
return -EINVAL; return -EINVAL;
} }
...@@ -1144,8 +1167,7 @@ static int check_and_set_masks(struct idtcm *idtcm, ...@@ -1144,8 +1167,7 @@ static int check_and_set_masks(struct idtcm *idtcm,
switch (regaddr) { switch (regaddr) {
case TOD_MASK_ADDR: case TOD_MASK_ADDR:
if ((val & 0xf0) || !(val & 0x0f)) { if ((val & 0xf0) || !(val & 0x0f)) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev, "Invalid TOD mask 0x%02x", val);
"Invalid TOD mask 0x%hhx\n", val);
err = -EINVAL; err = -EINVAL;
} else { } else {
idtcm->tod_mask = val; idtcm->tod_mask = val;
...@@ -1176,14 +1198,14 @@ static void display_pll_and_masks(struct idtcm *idtcm) ...@@ -1176,14 +1198,14 @@ static void display_pll_and_masks(struct idtcm *idtcm)
u8 i; u8 i;
u8 mask; u8 mask;
dev_dbg(&idtcm->client->dev, "tod_mask = 0x%02x\n", idtcm->tod_mask); dev_dbg(&idtcm->client->dev, "tod_mask = 0x%02x", idtcm->tod_mask);
for (i = 0; i < MAX_TOD; i++) { for (i = 0; i < MAX_TOD; i++) {
mask = 1 << i; mask = 1 << i;
if (mask & idtcm->tod_mask) if (mask & idtcm->tod_mask)
dev_dbg(&idtcm->client->dev, dev_dbg(&idtcm->client->dev,
"TOD%d pll = %d output_mask = 0x%04x\n", "TOD%d pll = %d output_mask = 0x%04x",
i, idtcm->channel[i].pll, i, idtcm->channel[i].pll,
idtcm->channel[i].output_mask); idtcm->channel[i].output_mask);
} }
...@@ -1204,19 +1226,16 @@ static int idtcm_load_firmware(struct idtcm *idtcm, ...@@ -1204,19 +1226,16 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
if (firmware) /* module parameter */ if (firmware) /* module parameter */
snprintf(fname, sizeof(fname), "%s", firmware); snprintf(fname, sizeof(fname), "%s", firmware);
dev_dbg(&idtcm->client->dev, "requesting firmware '%s'\n", fname); dev_dbg(&idtcm->client->dev, "requesting firmware '%s'", fname);
err = request_firmware(&fw, fname, dev); err = request_firmware(&fw, fname, dev);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
return err; return err;
} }
dev_dbg(&idtcm->client->dev, "firmware size %zu bytes\n", fw->size); dev_dbg(&idtcm->client->dev, "firmware size %zu bytes", fw->size);
rec = (struct idtcm_fwrc *) fw->data; rec = (struct idtcm_fwrc *) fw->data;
...@@ -1224,10 +1243,9 @@ static int idtcm_load_firmware(struct idtcm *idtcm, ...@@ -1224,10 +1243,9 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
idtcm_state_machine_reset(idtcm); idtcm_state_machine_reset(idtcm);
for (len = fw->size; len > 0; len -= sizeof(*rec)) { for (len = fw->size; len > 0; len -= sizeof(*rec)) {
if (rec->reserved) { if (rec->reserved) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"bad firmware, reserved field non-zero\n"); "bad firmware, reserved field non-zero");
err = -EINVAL; err = -EINVAL;
} else { } else {
regaddr = rec->hiaddr << 8; regaddr = rec->hiaddr << 8;
...@@ -1245,13 +1263,11 @@ static int idtcm_load_firmware(struct idtcm *idtcm, ...@@ -1245,13 +1263,11 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
err = 0; err = 0;
/* Top (status registers) and bottom are read-only */ /* Top (status registers) and bottom are read-only */
if ((regaddr < GPIO_USER_CONTROL) if (regaddr < GPIO_USER_CONTROL || regaddr >= SCRATCH)
|| (regaddr >= SCRATCH))
continue; continue;
/* Page size 128, last 4 bytes of page skipped */ /* Page size 128, last 4 bytes of page skipped */
if (((loaddr > 0x7b) && (loaddr <= 0x7f)) if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)
|| loaddr > 0xfb)
continue; continue;
err = idtcm_write(idtcm, regaddr, 0, &val, sizeof(val)); err = idtcm_write(idtcm, regaddr, 0, &val, sizeof(val));
...@@ -1285,7 +1301,6 @@ static int idtcm_output_enable(struct idtcm_channel *channel, ...@@ -1285,7 +1301,6 @@ static int idtcm_output_enable(struct idtcm_channel *channel,
} }
err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val)); err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
...@@ -1308,11 +1323,8 @@ static int idtcm_output_mask_enable(struct idtcm_channel *channel, ...@@ -1308,11 +1323,8 @@ static int idtcm_output_mask_enable(struct idtcm_channel *channel,
outn = 0; outn = 0;
while (mask) { while (mask) {
if (mask & 0x1) { if (mask & 0x1) {
err = idtcm_output_enable(channel, enable, outn); err = idtcm_output_enable(channel, enable, outn);
if (err) if (err)
return err; return err;
} }
...@@ -1328,13 +1340,23 @@ static int idtcm_perout_enable(struct idtcm_channel *channel, ...@@ -1328,13 +1340,23 @@ static int idtcm_perout_enable(struct idtcm_channel *channel,
bool enable, bool enable,
struct ptp_perout_request *perout) struct ptp_perout_request *perout)
{ {
struct idtcm *idtcm = channel->idtcm;
unsigned int flags = perout->flags; unsigned int flags = perout->flags;
struct timespec64 ts = {0, 0};
int err;
if (flags == PEROUT_ENABLE_OUTPUT_MASK) if (flags == PEROUT_ENABLE_OUTPUT_MASK)
return idtcm_output_mask_enable(channel, enable); err = idtcm_output_mask_enable(channel, enable);
else
err = idtcm_output_enable(channel, enable, perout->index);
/* Enable/disable individual output instead */ if (err) {
return idtcm_output_enable(channel, enable, perout->index); dev_err(&idtcm->client->dev, "Unable to set output enable");
return err;
}
/* Align output to internal 1 PPS */
return _idtcm_settime(channel, &ts, SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS);
} }
static int idtcm_get_pll_mode(struct idtcm_channel *channel, static int idtcm_get_pll_mode(struct idtcm_channel *channel,
...@@ -1392,7 +1414,6 @@ static int idtcm_set_pll_mode(struct idtcm_channel *channel, ...@@ -1392,7 +1414,6 @@ static int idtcm_set_pll_mode(struct idtcm_channel *channel,
static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns) static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
u8 i; u8 i;
u8 buf[4] = {0}; u8 buf[4] = {0};
...@@ -1400,9 +1421,7 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns) ...@@ -1400,9 +1421,7 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
s64 offset_ps; s64 offset_ps;
if (channel->pll_mode != PLL_MODE_WRITE_PHASE) { if (channel->pll_mode != PLL_MODE_WRITE_PHASE) {
err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_PHASE); err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_PHASE);
if (err) if (err)
return err; return err;
} }
...@@ -1478,20 +1497,16 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm) ...@@ -1478,20 +1497,16 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_gettime(channel, ts); err = _idtcm_gettime(channel, ts);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev, "Failed at line %d in %s!",
"Failed at line %d in func %s!\n", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1501,20 +1516,16 @@ static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) ...@@ -1501,20 +1516,16 @@ static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
static int idtcm_settime_deprecated(struct ptp_clock_info *ptp, static int idtcm_settime_deprecated(struct ptp_clock_info *ptp,
const struct timespec64 *ts) const struct timespec64 *ts)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_settime_deprecated(channel, ts); err = _idtcm_settime_deprecated(channel, ts);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1524,20 +1535,16 @@ static int idtcm_settime_deprecated(struct ptp_clock_info *ptp, ...@@ -1524,20 +1535,16 @@ static int idtcm_settime_deprecated(struct ptp_clock_info *ptp,
static int idtcm_settime(struct ptp_clock_info *ptp, static int idtcm_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts) const struct timespec64 *ts)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_settime(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE); err = _idtcm_settime(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1546,20 +1553,16 @@ static int idtcm_settime(struct ptp_clock_info *ptp, ...@@ -1546,20 +1553,16 @@ static int idtcm_settime(struct ptp_clock_info *ptp,
static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta) static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_adjtime_deprecated(channel, delta); err = _idtcm_adjtime_deprecated(channel, delta);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1568,8 +1571,7 @@ static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta) ...@@ -1568,8 +1571,7 @@ static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta)
static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta) static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
struct timespec64 ts; struct timespec64 ts;
enum scsr_tod_write_type_sel type; enum scsr_tod_write_type_sel type;
...@@ -1579,9 +1581,7 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta) ...@@ -1579,9 +1581,7 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
err = idtcm_do_phase_pull_in(channel, delta, 0); err = idtcm_do_phase_pull_in(channel, delta, 0);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
return err; return err;
} }
...@@ -1596,12 +1596,9 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta) ...@@ -1596,12 +1596,9 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_settime(channel, &ts, type); err = _idtcm_settime(channel, &ts, type);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1610,22 +1607,16 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta) ...@@ -1610,22 +1607,16 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta) static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_adjphase(channel, delta); err = _idtcm_adjphase(channel, delta);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1634,22 +1625,16 @@ static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta) ...@@ -1634,22 +1625,16 @@ static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)
static int idtcm_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) static int idtcm_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{ {
struct idtcm_channel *channel = struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int err; int err;
mutex_lock(&idtcm->reg_lock); mutex_lock(&idtcm->reg_lock);
err = _idtcm_adjfine(channel, scaled_ppm); err = _idtcm_adjfine(channel, scaled_ppm);
if (err) if (err)
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
mutex_unlock(&idtcm->reg_lock); mutex_unlock(&idtcm->reg_lock);
...@@ -1660,9 +1645,7 @@ static int idtcm_enable(struct ptp_clock_info *ptp, ...@@ -1660,9 +1645,7 @@ static int idtcm_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on) struct ptp_clock_request *rq, int on)
{ {
int err; int err;
struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
struct idtcm_channel *channel =
container_of(ptp, struct idtcm_channel, caps);
switch (rq->type) { switch (rq->type) {
case PTP_CLK_REQ_PEROUT: case PTP_CLK_REQ_PEROUT:
...@@ -1670,9 +1653,8 @@ static int idtcm_enable(struct ptp_clock_info *ptp, ...@@ -1670,9 +1653,8 @@ static int idtcm_enable(struct ptp_clock_info *ptp,
err = idtcm_perout_enable(channel, false, &rq->perout); err = idtcm_perout_enable(channel, false, &rq->perout);
if (err) if (err)
dev_err(&channel->idtcm->client->dev, dev_err(&channel->idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!",
__LINE__, __LINE__, __func__);
__func__);
return err; return err;
} }
...@@ -1684,9 +1666,7 @@ static int idtcm_enable(struct ptp_clock_info *ptp, ...@@ -1684,9 +1666,7 @@ static int idtcm_enable(struct ptp_clock_info *ptp,
err = idtcm_perout_enable(channel, true, &rq->perout); err = idtcm_perout_enable(channel, true, &rq->perout);
if (err) if (err)
dev_err(&channel->idtcm->client->dev, dev_err(&channel->idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
return err; return err;
default: default:
break; break;
...@@ -1706,7 +1686,7 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm, ...@@ -1706,7 +1686,7 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm,
u16 dpll; u16 dpll;
u16 out0 = 0, out1 = 0; u16 out0 = 0, out1 = 0;
if ((qn == 0) && (qn_plus_1 == 0)) if (qn == 0 && qn_plus_1 == 0)
return 0; return 0;
switch (pll) { switch (pll) {
...@@ -1771,28 +1751,24 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm, ...@@ -1771,28 +1751,24 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm,
*/ */
if (out0) { if (out0) {
err = idtcm_read(idtcm, out0, OUT_CTRL_1, &val, sizeof(val)); err = idtcm_read(idtcm, out0, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
val &= ~OUT_SYNC_DISABLE; val &= ~OUT_SYNC_DISABLE;
err = idtcm_write(idtcm, out0, OUT_CTRL_1, &val, sizeof(val)); err = idtcm_write(idtcm, out0, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
} }
if (out1) { if (out1) {
err = idtcm_read(idtcm, out1, OUT_CTRL_1, &val, sizeof(val)); err = idtcm_read(idtcm, out1, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
val &= ~OUT_SYNC_DISABLE; val &= ~OUT_SYNC_DISABLE;
err = idtcm_write(idtcm, out1, OUT_CTRL_1, &val, sizeof(val)); err = idtcm_write(idtcm, out1, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
} }
...@@ -1812,7 +1788,6 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm, ...@@ -1812,7 +1788,6 @@ static int _enable_pll_tod_sync(struct idtcm *idtcm,
static int idtcm_enable_tod_sync(struct idtcm_channel *channel) static int idtcm_enable_tod_sync(struct idtcm_channel *channel)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 pll; u8 pll;
u8 sync_src; u8 sync_src;
u8 qn; u8 qn;
...@@ -1854,8 +1829,7 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel) ...@@ -1854,8 +1829,7 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel)
return -EINVAL; return -EINVAL;
} }
err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE, err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE, &temp, sizeof(temp));
&temp, sizeof(temp));
if (err) if (err)
return err; return err;
...@@ -1863,8 +1837,7 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel) ...@@ -1863,8 +1837,7 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel)
Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
out8_mux = 1; out8_mux = 1;
err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE, err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE, &temp, sizeof(temp));
&temp, sizeof(temp));
if (err) if (err)
return err; return err;
...@@ -1908,10 +1881,9 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel) ...@@ -1908,10 +1881,9 @@ static int idtcm_enable_tod_sync(struct idtcm_channel *channel)
} }
} }
if ((qn != 0) || (qn_plus_1 != 0)) if (qn != 0 || qn_plus_1 != 0)
err = _enable_pll_tod_sync(idtcm, pll, sync_src, qn, err = _enable_pll_tod_sync(idtcm, pll, sync_src, qn,
qn_plus_1); qn_plus_1);
if (err) if (err)
return err; return err;
} }
...@@ -1954,7 +1926,6 @@ static void idtcm_set_version_info(struct idtcm *idtcm) ...@@ -1954,7 +1926,6 @@ static void idtcm_set_version_info(struct idtcm *idtcm)
u16 product_id; u16 product_id;
u8 hw_rev_id; u8 hw_rev_id;
u8 config_select; u8 config_select;
char *fmt = "%d.%d.%d, Id: 0x%04x HW Rev: %d OTP Config Select: %d\n";
idtcm_read_major_release(idtcm, &major); idtcm_read_major_release(idtcm, &major);
idtcm_read_minor_release(idtcm, &minor); idtcm_read_minor_release(idtcm, &minor);
...@@ -1973,7 +1944,9 @@ static void idtcm_set_version_info(struct idtcm *idtcm) ...@@ -1973,7 +1944,9 @@ static void idtcm_set_version_info(struct idtcm *idtcm)
else else
idtcm->deprecated = 1; idtcm->deprecated = 1;
dev_info(&idtcm->client->dev, fmt, major, minor, hotfix, dev_info(&idtcm->client->dev,
"%d.%d.%d, Id: 0x%04x HW Rev: %d OTP Config Select: %d",
major, minor, hotfix,
product_id, hw_rev_id, config_select); product_id, hw_rev_id, config_select);
} }
...@@ -2132,9 +2105,7 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index) ...@@ -2132,9 +2105,7 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
err = idtcm_enable_tod_sync(channel); err = idtcm_enable_tod_sync(channel);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
return err; return err;
} }
} }
...@@ -2143,16 +2114,14 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index) ...@@ -2143,16 +2114,14 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
err = idtcm_get_pll_mode(channel, &channel->pll_mode); err = idtcm_get_pll_mode(channel, &channel->pll_mode);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Error: %s - Unable to read pll mode\n", __func__); "Error: %s - Unable to read pll mode", __func__);
return err; return err;
} }
err = idtcm_enable_tod(channel); err = idtcm_enable_tod(channel);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Failed at line %d in %s!", __LINE__, __func__);
__LINE__,
__func__);
return err; return err;
} }
...@@ -2167,7 +2136,7 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index) ...@@ -2167,7 +2136,7 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
if (!channel->ptp_clock) if (!channel->ptp_clock)
return -ENOTSUPP; return -ENOTSUPP;
dev_info(&idtcm->client->dev, "PLL%d registered as ptp%d\n", dev_info(&idtcm->client->dev, "PLL%d registered as ptp%d",
index, channel->ptp_clock->index); index, channel->ptp_clock->index);
return 0; return 0;
...@@ -2179,7 +2148,6 @@ static void ptp_clock_unregister_all(struct idtcm *idtcm) ...@@ -2179,7 +2148,6 @@ static void ptp_clock_unregister_all(struct idtcm *idtcm)
struct idtcm_channel *channel; struct idtcm_channel *channel;
for (i = 0; i < MAX_TOD; i++) { for (i = 0; i < MAX_TOD; i++) {
channel = &idtcm->channel[i]; channel = &idtcm->channel[i];
if (channel->ptp_clock) if (channel->ptp_clock)
...@@ -2208,7 +2176,6 @@ static int idtcm_probe(struct i2c_client *client, ...@@ -2208,7 +2176,6 @@ static int idtcm_probe(struct i2c_client *client,
struct idtcm *idtcm; struct idtcm *idtcm;
int err; int err;
u8 i; u8 i;
char *fmt = "Failed at %d in line %s with channel output %d!\n";
/* Unused for now */ /* Unused for now */
(void)id; (void)id;
...@@ -2230,13 +2197,10 @@ static int idtcm_probe(struct i2c_client *client, ...@@ -2230,13 +2197,10 @@ static int idtcm_probe(struct i2c_client *client,
idtcm_set_version_info(idtcm); idtcm_set_version_info(idtcm);
err = idtcm_load_firmware(idtcm, &client->dev); err = idtcm_load_firmware(idtcm, &client->dev);
if (err) if (err)
dev_warn(&idtcm->client->dev, dev_warn(&idtcm->client->dev, "loading firmware failed with %d", err);
"loading firmware failed with %d\n", err);
if (wait_for_boot_status_ready(idtcm)) wait_for_chip_ready(idtcm);
dev_warn(&idtcm->client->dev, "BOOT_STATUS != 0xA0\n");
if (idtcm->tod_mask) { if (idtcm->tod_mask) {
for (i = 0; i < MAX_TOD; i++) { for (i = 0; i < MAX_TOD; i++) {
...@@ -2244,17 +2208,14 @@ static int idtcm_probe(struct i2c_client *client, ...@@ -2244,17 +2208,14 @@ static int idtcm_probe(struct i2c_client *client,
err = idtcm_enable_channel(idtcm, i); err = idtcm_enable_channel(idtcm, i);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
fmt, "idtcm_enable_channel %d failed!", i);
__LINE__,
__func__,
i);
break; break;
} }
} }
} }
} else { } else {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"no PLLs flagged as PHCs, nothing to do\n"); "no PLLs flagged as PHCs, nothing to do");
err = -ENODEV; err = -ENODEV;
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#define FW_FILENAME "idtcm.bin" #define FW_FILENAME "idtcm.bin"
#define MAX_TOD (4) #define MAX_TOD (4)
#define MAX_PLL (8) #define MAX_PLL (8)
#define MAX_OUTPUT (12)
#define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL) #define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
...@@ -51,6 +50,9 @@ ...@@ -51,6 +50,9 @@
#define TOD_WRITE_OVERHEAD_COUNT_MAX (2) #define TOD_WRITE_OVERHEAD_COUNT_MAX (2)
#define TOD_BYTE_COUNT (11) #define TOD_BYTE_COUNT (11)
#define LOCK_TIMEOUT_MS (2000)
#define LOCK_POLL_INTERVAL_MS (10)
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef) #define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
#define IDTCM_MAX_WRITE_COUNT (512) #define IDTCM_MAX_WRITE_COUNT (512)
...@@ -105,6 +107,18 @@ enum scsr_tod_write_type_sel { ...@@ -105,6 +107,18 @@ enum scsr_tod_write_type_sel {
SCSR_TOD_WR_TYPE_SEL_MAX = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS, SCSR_TOD_WR_TYPE_SEL_MAX = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS,
}; };
/* Values STATUS.DPLL_SYS_STATUS.DPLL_SYS_STATE */
enum dpll_state {
DPLL_STATE_MIN = 0,
DPLL_STATE_FREERUN = DPLL_STATE_MIN,
DPLL_STATE_LOCKACQ = 1,
DPLL_STATE_LOCKREC = 2,
DPLL_STATE_LOCKED = 3,
DPLL_STATE_HOLDOVER = 4,
DPLL_STATE_OPEN_LOOP = 5,
DPLL_STATE_MAX = DPLL_STATE_OPEN_LOOP,
};
struct idtcm; struct idtcm;
struct idtcm_channel { struct idtcm_channel {
...@@ -123,7 +137,6 @@ struct idtcm_channel { ...@@ -123,7 +137,6 @@ struct idtcm_channel {
enum pll_mode pll_mode; enum pll_mode pll_mode;
u8 pll; u8 pll;
u16 output_mask; u16 output_mask;
u8 output_phase_adj[MAX_OUTPUT][4];
}; };
struct idtcm { struct idtcm {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment