Commit 2dba3f53 authored by Jorge Machado's avatar Jorge Machado

Add sw support for leap second

parent 16e6a7bc
......@@ -55,6 +55,10 @@
#define FMC_DIO_BUFFER_LEN 512
struct dio_channel {
struct timespec tsbuf[FMC_DIO_BUFFER_LEN];
uint16_t leap_second[FMC_DIO_BUFFER_LEN];
uint8_t leap_second_valid[FMC_DIO_BUFFER_LEN];
uint8_t flag59[FMC_DIO_BUFFER_LEN];
uint8_t flag61[FMC_DIO_BUFFER_LEN];
int bhead, btail;
wait_queue_head_t q;
......@@ -246,6 +250,10 @@ static int fmc_dio_int_cmd_stamp(struct fmc_dio *dev,
struct dio_device *d = dev->priv;
struct dio_channel *c = 0;
struct timespec *ts = cmd->t;
uint16_t * leap_second = cmd->leap_second;
uint8_t * leap_second_valid = cmd->leap_second_valid;
uint8_t * flag59 = cmd->flag59;
uint8_t * flag61 = cmd->flag61;
struct regmap *map;
int mask, ch, last;
int nstamp = 0;
......@@ -282,9 +290,17 @@ again:
if (c->bhead == c->btail)
break;
*ts = c->tsbuf[c->btail];
*leap_second = c->leap_second[c->btail];
*leap_second_valid = c->leap_second_valid[c->btail];
*flag59 = c->flag59[c->btail];
*flag61 = c->flag61[c->btail];
c->btail = (c->btail + 1) % FMC_DIO_BUFFER_LEN;
nstamp++;
ts++;
leap_second++;
leap_second_valid++;
flag59++;
flag61++;
}
if (nstamp) {
cmd->channel = ch;
......@@ -661,6 +677,11 @@ irqreturn_t fmc_dio_int_interrupt(struct fmc_dio *dev)
ts->tv_sec |= readl(base + map->fifo_tai_l);
ts->tv_nsec = 8 * readl(base + map->fifo_cycle);
uint32_t leap_second_reg = readl(base + map->fifo_leap_second);
c->leap_second[h] = leap_second_reg & DIO_TSF_R3_LEAP_SECOND_VALUE_MASK;
c->leap_second_valid[h] = (leap_second_reg >> DIO_TSF_R3_LEAP_SECOND_VALID_SHIFT) & 1;
c->flag59[h] = (leap_second_reg >> DIO_TSF_R3_LEAP_SECOND_FLAG_59_SHIFT) & 1;
c->flag61[h] = (leap_second_reg >> DIO_TSF_R3_LEAP_SECOND_FLAG_61_SHIFT) & 1;
/* subtract 4 cycles lost in input sync circuits */
fmc_dio_int_ts_sub(ts, 32);
}
......
......@@ -154,6 +154,10 @@ struct wr_dio_cmd {
uint32_t flags;
uint32_t nstamp; /* from kernel, if IN_STAMP */
struct timespec t[WR_DIO_N_STAMP]; /* may be from user */
uint16_t leap_second[WR_DIO_N_STAMP];
uint8_t leap_second_valid[WR_DIO_N_STAMP];
uint8_t flag59[WR_DIO_N_STAMP];
uint8_t flag61[WR_DIO_N_STAMP];
};
#define WR_DIO_F_NOW 0x01 /* Output is now, t[0] ignored */
......
......@@ -23,6 +23,7 @@ struct regmap {
int fifo_tai_l;
int fifo_tai_h;
int fifo_cycle;
int fifo_leap_second;
int fifo_status;
};
......@@ -64,6 +65,21 @@ extern struct regmap_common regmap_common_v2;
/* definitions for field: dio fifo not-empty 5 in reg: Interrupt status register */
#define DIO_EIC_ISR_NEMPTY_5 WBGEN2_GEN_MASK(5, 1)
/* definitions for field: LeapSecond value in reg: FIFO 'Timestamp FIFO 2' data output register 3 */
#define DIO_TSF_R3_LEAP_SECOND_VALUE_MASK WBGEN2_GEN_MASK(0, 16)
/* definitions for field: LeapSecond valid in reg: FIFO 'Timestamp FIFO 2' data output register 3 */
#define DIO_TSF_R3_LEAP_SECOND_VALID WBGEN2_GEN_MASK(18, 1)
#define DIO_TSF_R3_LEAP_SECOND_VALID_SHIFT 18
/* definitions for field: LeapSecond flag 59 in reg: FIFO 'Timestamp FIFO 2' data output register 3 */
#define DIO_TSF_R3_LEAP_SECOND_FLAG_59 WBGEN2_GEN_MASK(16, 1)
#define DIO_TSF_R3_LEAP_SECOND_FLAG_59_SHIFT 16
/* definitions for field: LeapSecond flag 61 in reg: FIFO 'Timestamp FIFO 2' data output register 3 */
#define DIO_TSF_R3_LEAP_SECOND_FLAG_61 WBGEN2_GEN_MASK(17, 1)
#define DIO_TSF_R3_LEAP_SECOND_FLAG_61_SHIFT 17
struct regmap_common get_regmap_common(unsigned int ver);
struct regmap *get_regmap(unsigned int ver);
......
......@@ -12,6 +12,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = R(TSF0_R0),
.fifo_tai_h = R(TSF0_R1),
.fifo_cycle = R(TSF0_R2),
.fifo_leap_second = 0,
.fifo_status = R(TSF0_CSR),
}, {
.trig_l = R(TRIG1),
......@@ -22,6 +23,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = R(TSF1_R0),
.fifo_tai_h = R(TSF1_R1),
.fifo_cycle = R(TSF1_R2),
.fifo_leap_second = 0,
.fifo_status = R(TSF1_CSR),
}, {
.trig_l = R(TRIG2),
......@@ -32,6 +34,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = R(TSF2_R0),
.fifo_tai_h = R(TSF2_R1),
.fifo_cycle = R(TSF2_R2),
.fifo_leap_second = 0,
.fifo_status = R(TSF2_CSR),
}, {
.trig_l = R(TRIG3),
......@@ -42,6 +45,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = R(TSF3_R0),
.fifo_tai_h = R(TSF3_R1),
.fifo_cycle = R(TSF3_R2),
.fifo_leap_second = 0,
.fifo_status = R(TSF3_CSR),
}, {
.trig_l = R(TRIG4),
......@@ -52,6 +56,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = R(TSF4_R0),
.fifo_tai_h = R(TSF4_R1),
.fifo_cycle = R(TSF4_R2),
.fifo_leap_second = 0,
.fifo_status = R(TSF4_CSR),
}, {
.trig_l = 0,
......@@ -62,6 +67,7 @@ struct regmap regmap_v1[] = {
.fifo_tai_l = 0,
.fifo_tai_h = 0,
.fifo_cycle = 0,
.fifo_leap_second = 0,
.fifo_status = 0,
}
};
......
......@@ -12,6 +12,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF0_R0),
.fifo_tai_h = R(TSF0_R1),
.fifo_cycle = R(TSF0_R2),
.fifo_leap_second = R(TSF0_R3),
.fifo_status = R(TSF0_CSR),
}, {
.trig_l = R(TRIG1),
......@@ -22,6 +23,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF1_R0),
.fifo_tai_h = R(TSF1_R1),
.fifo_cycle = R(TSF1_R2),
.fifo_leap_second = R(TSF1_R3),
.fifo_status = R(TSF1_CSR),
}, {
.trig_l = R(TRIG2),
......@@ -32,6 +34,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF2_R0),
.fifo_tai_h = R(TSF2_R1),
.fifo_cycle = R(TSF2_R2),
.fifo_leap_second = R(TSF2_R3),
.fifo_status = R(TSF2_CSR),
}, {
.trig_l = R(TRIG3),
......@@ -42,6 +45,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF3_R0),
.fifo_tai_h = R(TSF3_R1),
.fifo_cycle = R(TSF3_R2),
.fifo_leap_second = R(TSF3_R3),
.fifo_status = R(TSF3_CSR),
}, {
.trig_l = R(TRIG4),
......@@ -52,6 +56,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF4_R0),
.fifo_tai_h = R(TSF4_R1),
.fifo_cycle = R(TSF4_R2),
.fifo_leap_second = R(TSF4_R3),
.fifo_status = R(TSF4_CSR),
}, {
.trig_l = R(TRIG5),
......@@ -62,6 +67,7 @@ struct regmap regmap_v2[] = {
.fifo_tai_l = R(TSF5_R0),
.fifo_tai_h = R(TSF5_R1),
.fifo_cycle = R(TSF5_R2),
.fifo_leap_second = R(TSF5_R3),
.fifo_status = R(TSF5_CSR),
}
};
......
......@@ -247,8 +247,8 @@ static int scan_stamp(int argc, char **argv, int ismask)
return -1;
}
for (i = 0; i < cmd->nstamp; i++)
printf("ch %i, %9li.%09li\n", cmd->channel,
(long)cmd->t[i].tv_sec, cmd->t[i].tv_nsec);
printf("ch %i, %9li.%09li, leap second 0x%04X, leap second valid %02x, flag59 %01x, flag61 %01x \n", cmd->channel,
(long)cmd->t[i].tv_sec, cmd->t[i].tv_nsec, cmd->leap_second[i], cmd->leap_second_valid[i], cmd->flag59[i], cmd->flag61[i]);
}
return 0;
}
......
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