Commit 7260d1c8 authored by Min Li's avatar Min Li Committed by Jakub Kicinski

ptp: clockmatrix: Fix non-zero phase_adj is lost after snap

Fix non-zero phase_adj is lost after snap. Use ktime_sub
to do ktime_t subtraction.
Signed-off-by: default avatarMin Li <min.li.xe@renesas.com>
Link: https://lore.kernel.org/r/1607442117-13661-3-git-send-email-min.li.xe@renesas.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fa439059
...@@ -673,8 +673,9 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel, ...@@ -673,8 +673,9 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
if (idtcm->calculate_overhead_flag) { if (idtcm->calculate_overhead_flag) {
/* Assumption: I2C @ 400KHz */ /* Assumption: I2C @ 400KHz */
total_overhead_ns = ktime_to_ns(ktime_get_raw() ktime_t diff = ktime_sub(ktime_get_raw(),
- idtcm->start_time) idtcm->start_time);
total_overhead_ns = ktime_to_ns(diff)
+ idtcm->tod_write_overhead_ns + idtcm->tod_write_overhead_ns
+ SETTIME_CORRECTION; + SETTIME_CORRECTION;
...@@ -757,6 +758,54 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel, ...@@ -757,6 +758,54 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
return 0; return 0;
} }
static int get_output_base_addr(u8 outn)
{
int base;
switch (outn) {
case 0:
base = OUTPUT_0;
break;
case 1:
base = OUTPUT_1;
break;
case 2:
base = OUTPUT_2;
break;
case 3:
base = OUTPUT_3;
break;
case 4:
base = OUTPUT_4;
break;
case 5:
base = OUTPUT_5;
break;
case 6:
base = OUTPUT_6;
break;
case 7:
base = OUTPUT_7;
break;
case 8:
base = OUTPUT_8;
break;
case 9:
base = OUTPUT_9;
break;
case 10:
base = OUTPUT_10;
break;
case 11:
base = OUTPUT_11;
break;
default:
base = -EINVAL;
}
return base;
}
static int _idtcm_settime(struct idtcm_channel *channel, static int _idtcm_settime(struct idtcm_channel *channel,
struct timespec64 const *ts) struct timespec64 const *ts)
{ {
...@@ -881,6 +930,7 @@ static int set_tod_write_overhead(struct idtcm_channel *channel) ...@@ -881,6 +930,7 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
ktime_t start; ktime_t start;
ktime_t stop; ktime_t stop;
ktime_t diff;
char buf[TOD_BYTE_COUNT] = {0}; char buf[TOD_BYTE_COUNT] = {0};
...@@ -900,7 +950,9 @@ static int set_tod_write_overhead(struct idtcm_channel *channel) ...@@ -900,7 +950,9 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
stop = ktime_get_raw(); stop = ktime_get_raw();
current_ns = ktime_to_ns(stop - start); diff = ktime_sub(stop, start);
current_ns = ktime_to_ns(diff);
if (i == 0) { if (i == 0) {
lowest_ns = current_ns; lowest_ns = current_ns;
...@@ -1220,11 +1272,19 @@ static int idtcm_output_enable(struct idtcm_channel *channel, ...@@ -1220,11 +1272,19 @@ static int idtcm_output_enable(struct idtcm_channel *channel,
bool enable, unsigned int outn) bool enable, unsigned int outn)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
int base;
int err; int err;
u8 val; u8 val;
err = idtcm_read(idtcm, OUTPUT_MODULE_FROM_INDEX(outn), base = get_output_base_addr(outn);
OUT_CTRL_1, &val, sizeof(val));
if (!(base > 0)) {
dev_err(&idtcm->client->dev,
"%s - Unsupported out%d", __func__, outn);
return base;
}
err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
if (err) if (err)
return err; return err;
...@@ -1234,8 +1294,7 @@ static int idtcm_output_enable(struct idtcm_channel *channel, ...@@ -1234,8 +1294,7 @@ static int idtcm_output_enable(struct idtcm_channel *channel,
else else
val &= ~SQUELCH_DISABLE; val &= ~SQUELCH_DISABLE;
return idtcm_write(idtcm, OUTPUT_MODULE_FROM_INDEX(outn), return idtcm_write(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
OUT_CTRL_1, &val, sizeof(val));
} }
static int idtcm_output_mask_enable(struct idtcm_channel *channel, static int idtcm_output_mask_enable(struct idtcm_channel *channel,
...@@ -1278,6 +1337,23 @@ static int idtcm_perout_enable(struct idtcm_channel *channel, ...@@ -1278,6 +1337,23 @@ static int idtcm_perout_enable(struct idtcm_channel *channel,
return idtcm_output_enable(channel, enable, perout->index); return idtcm_output_enable(channel, enable, perout->index);
} }
static int idtcm_get_pll_mode(struct idtcm_channel *channel,
enum pll_mode *pll_mode)
{
struct idtcm *idtcm = channel->idtcm;
int err;
u8 dpll_mode;
err = idtcm_read(idtcm, channel->dpll_n, DPLL_MODE,
&dpll_mode, sizeof(dpll_mode));
if (err)
return err;
*pll_mode = (dpll_mode >> PLL_MODE_SHIFT) & PLL_MODE_MASK;
return 0;
}
static int idtcm_set_pll_mode(struct idtcm_channel *channel, static int idtcm_set_pll_mode(struct idtcm_channel *channel,
enum pll_mode pll_mode) enum pll_mode pll_mode)
{ {
...@@ -1343,7 +1419,7 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns) ...@@ -1343,7 +1419,7 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS) else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS)
offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS; offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS;
phase_50ps = DIV_ROUND_CLOSEST(div64_s64(offset_ps, 50), 1); phase_50ps = div_s64(offset_ps, 50);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
buf[i] = phase_50ps & 0xff; buf[i] = phase_50ps & 0xff;
...@@ -1360,7 +1436,6 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm) ...@@ -1360,7 +1436,6 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
{ {
struct idtcm *idtcm = channel->idtcm; struct idtcm *idtcm = channel->idtcm;
u8 i; u8 i;
bool neg_adj = 0;
int err; int err;
u8 buf[6] = {0}; u8 buf[6] = {0};
s64 fcw; s64 fcw;
...@@ -1384,18 +1459,11 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm) ...@@ -1384,18 +1459,11 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
* FCW = ------------- * FCW = -------------
* 111 * 2^4 * 111 * 2^4
*/ */
if (scaled_ppm < 0) {
neg_adj = 1;
scaled_ppm = -scaled_ppm;
}
/* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */ /* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */
fcw = scaled_ppm * 244140625ULL; fcw = scaled_ppm * 244140625ULL;
fcw = div_u64(fcw, 1776); fcw = div_s64(fcw, 1776);
if (neg_adj)
fcw = -fcw;
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
buf[i] = fcw & 0xff; buf[i] = fcw & 0xff;
...@@ -2062,12 +2130,11 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index) ...@@ -2062,12 +2130,11 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
} }
} }
err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_FREQUENCY); /* Sync pll mode with hardware */
err = idtcm_get_pll_mode(channel, &channel->pll_mode);
if (err) { if (err) {
dev_err(&idtcm->client->dev, dev_err(&idtcm->client->dev,
"Failed at line %d in func %s!\n", "Error: %s - Unable to read pll mode\n", __func__);
__LINE__,
__func__);
return err; return err;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#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)
...@@ -49,9 +50,6 @@ ...@@ -49,9 +50,6 @@
#define PHASE_PULL_IN_THRESHOLD_NS_V487 (15000) #define PHASE_PULL_IN_THRESHOLD_NS_V487 (15000)
#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 WR_PHASE_SETUP_MS (5000)
#define OUTPUT_MODULE_FROM_INDEX(index) (OUTPUT_0 + (index) * 0x10)
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef) #define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
...@@ -125,6 +123,7 @@ struct idtcm_channel { ...@@ -125,6 +123,7 @@ 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