Commit 954a5ad6 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'devfede-tst' into proposed_master

Mixed improvements
parents 2d45c267 c21b972a
......@@ -35,6 +35,11 @@ module_param_named(dma_buf_ddr_burst_size, dma_buf_ddr_burst_size_default,
MODULE_PARM_DESC(dma_buf_ddr_burst_size,
"DDR size coalesing timeout (default: 16 timestamps).");
static int test_data_period = 0;
module_param_named(test_data_period, test_data_period, int, 0444);
MODULE_PARM_DESC(test_data_period,
"It sets how many fake timestamps to generate every seconds on the first channel, 0 to disable (default: 0)");
static int ft_verbose;
module_param_named(verbose, ft_verbose, int, 0444);
MODULE_PARM_DESC(verbose, "Print a lot of debugging messages.");
......@@ -108,6 +113,19 @@ int ft_enable_termination(struct fmctdc_dev *ft, int channel, int enable)
return 0;
}
static void ft_buffer_burst_size_set(struct fmctdc_dev *ft,
unsigned int chan,
uint32_t size)
{
const uint32_t base = ft->ft_dma_base + (0x40 * chan);
uint32_t tmp;
tmp = ft_ioread(ft, base + TDC_BUF_REG_CSR);
tmp &= ~TDC_BUF_CSR_BURST_SIZE_MASK;
tmp |= TDC_BUF_CSR_BURST_SIZE_W(size);
ft_iowrite(ft, tmp, base + TDC_BUF_REG_CSR);
}
static void ft_buffer_burst_enable(struct fmctdc_dev *ft,
unsigned int chan)
{
......@@ -168,6 +186,7 @@ static void ft_buffer_init(struct fmctdc_dev *ft, int channel)
val |= TDC_BUF_NEXT_SIZE_VALID;
ft_iowrite(ft, val, base + TDC_BUF_REG_NEXT_SIZE);
ft_buffer_burst_size_set(ft, channel, dma_buf_ddr_burst_size_default);
ft_buffer_burst_enable(ft, channel);
dev_info(&ft->fmc->dev,
......@@ -370,6 +389,42 @@ out_buf1:
}
#endif
/**
* It configures the test data
* @chan channel number [0, 4]
* @period period in 125Mhz ticks (125000000 -1 = 1Hz)
* @enable enable or disable
*/
void ft_test_data(struct fmctdc_dev *ft,
unsigned int chan,
unsigned int period,
bool enable)
{
uint32_t tmp = 0;
if (chan >= ft->zdev->n_cset) {
dev_err(&ft->fmc->dev, "%s Invalid channel %d\n",
__func__, chan);
return;
}
if (period == 0) {
dev_err(&ft->fmc->dev, "%s Invalid period %d\n",
__func__, period);
return;
}
tmp |= (enable ? TDC_FAKE_TS_EN : 0);
tmp |= ((chan << TDC_FAKE_TS_CHAN_SHIFT) & TDC_FAKE_TS_CHAN_MASK);
tmp |= ((period << TDC_FAKE_TS_PERIOD_SHIFT) & TDC_FAKE_TS_PERIOD_MASK);
ft_writel(ft, tmp, TDC_REG_FAKE_TS_CSR);
if (enable)
dev_warn(&ft->fmc->dev,
"Channel 0 is running in test mode 0x%x\n",
tmp);
}
/* probe and remove are called by the FMC bus core */
int ft_probe(struct fmc_device *fmc)
{
......@@ -505,6 +560,8 @@ int ft_probe(struct fmc_device *fmc)
goto err;
}
ft_test_data(ft, 0, test_data_period, !!test_data_period);
ret = ft_irq_init(ft);
if (ret < 0)
goto err;
......
......@@ -267,7 +267,7 @@ static void ft_readout_dma_start(struct fmctdc_dev *ft, int channel)
count = 0;
while (total > 0) {
cset->ti->nsamples = min((unsigned long)total,
KMALLOC_MAX_SIZE);
PAGE_SIZE / cset->ssize);
zio_cset_busy_set(cset, 1);
zio_arm_trigger(cset->ti); /* actually a fire */
ft_readout_dma_run(cset, base_cur, count, cset->ti->nsamples);
......@@ -474,7 +474,6 @@ static void ft_dma_irq_coalescing_timeout_set(struct fmctdc_dev *ft,
for (i = (chan == -1 ? 0 : chan);
i < (chan == -1 ? ft->zdev->n_cset : chan + 1);
++i) {
pr_info("%s:%d %d %d\n", __func__, __LINE__, i, timeout);
base = ft->ft_dma_base + (0x40 * i);
tmp = ft_ioread(ft, base + TDC_BUF_REG_CSR);
tmp &= ~TDC_BUF_CSR_IRQ_TIMEOUT_MASK;
......@@ -549,7 +548,7 @@ uint32_t ft_irq_coalescing_timeout_get(struct fmctdc_dev *ft,
timeout = ft_readl(ft, TDC_REG_IRQ_THRESHOLD);
break;
case FT_ACQ_TYPE_DMA:
/* There is none */
timeout = ft_dma_irq_coalescing_timeout_get(ft, chan);
break;
default:
......
......@@ -49,7 +49,7 @@ static struct zio_attribute ft_zattr_input[] = {
ZIO_ATTR_EXT("diff-reference", ZIO_RW_PERM, FT_ATTR_TDC_DELAY_REF, 0),
ZIO_ATTR_EXT("transfer-mode", ZIO_RO_PERM, FT_ATTR_TDC_TRANSFER_MODE, 0),
ZIO_ATTR_EXT("irq_coalescing_time", ZIO_RW_PERM,
FT_ATTR_TDC_COALESCING_TIME, 0),
FT_ATTR_TDC_COALESCING_TIME, 10),
};
/* This identifies if our "struct device" is device, input, output */
......@@ -483,10 +483,24 @@ static int ft_trig_data_done(struct zio_cset *cset)
goto out;
ts = cset->chan->active_block->data;
dev_dbg(&cset->head.dev, "%s TS 0/%d %d.%d.%d %d\n",
__func__, cset->ti->nsamples,
ts[0].seconds,ts[0].coarse, ts[0].frac,
FT_HW_TS_META_SEQ(ts[0].metadata));
dev_dbg(&cset->head.dev, "%s TS %d/%d %d.%d.%d %d\n",
__func__, cset->ti->nsamples - 1, cset->ti->nsamples,
ts[cset->ti->nsamples - 1].seconds,
ts[cset->ti->nsamples - 1].coarse,
ts[cset->ti->nsamples - 1].frac,
FT_HW_TS_META_SEQ(ts[cset->ti->nsamples - 1].metadata));
for(i = 0; i < cset->ti->nsamples; ++i) {
dev_dbg(&cset->head.dev, "TS%d %d.%d.%d 0x%x\n", i,
dev_vdbg(&cset->head.dev, "%s TS %d/%d %d.%d.%d %d\n",
__func__, i, cset->ti->nsamples,
ts[i].seconds,ts[i].coarse,
ts[i].frac, ts[i].metadata);
ts[i].frac, FT_HW_TS_META_SEQ(ts[i].metadata));
ft_timestamp_apply_offsets(ft, &ts[i]);
}
ft_zio_update_ctrl(cset, &ts[0]);
......
......@@ -32,6 +32,14 @@
#define TDC_REG_CTRL 0x00fc
#define TDC_REG_WR_CTRL 0x00b4
#define TDC_REG_WR_STAT 0x00b0
#define TDC_REG_FAKE_TS_CSR 0x00b8
/* TDC_REG_FAKE_TS_CSR bits */
#define TDC_FAKE_TS_EN BIT(31)
#define TDC_FAKE_TS_CHAN_MASK 0xE0000000
#define TDC_FAKE_TS_CHAN_SHIFT 28
#define TDC_FAKE_TS_PERIOD_MASK 0x0FFFFFFF
#define TDC_FAKE_TS_PERIOD_SHIFT 0
/* TDC_REG_STAT bits */
#define TDC_STAT_DMA BIT(0)
......
......@@ -1028,6 +1028,7 @@ int fmctdc_get_offset_user(struct fmctdc_board *userb,
}
/**
* It gets the current buffer mode
* @param[in] userb TDC board instance token
* @param[in] channel target channel [0, 4]
* @param[out] mode transfer mode
......
......@@ -29,22 +29,58 @@ char git_version[] = "git_version: " GIT_VERSION;
struct fmctdc_time ts_prev[FMCTDC_NUM_CHANNELS];
static unsigned int stop = 0, fmt_wr = 0;
enum tstamp_print_format {
TSTAMP_FMT_PS = 0,
TSTAMP_FMT_WR,
};
/**
* It prints the given timestamp using the White-Rabit format
* @param[in] ts timestamp
*
* seconds:coarse:frac
*/
static inline void print_ts_wr(struct fmctdc_time ts)
{
fprintf(stdout, "%10"PRIu64":%09u:%04u",
ts.seconds, ts.coarse, ts.frac);
}
void dump_timestamp(struct fmctdc_time ts)
/**
* It prints the given timestamp using the picosecond format
* @param[in] ts timestamp
*
* seconds.picoseconds
*/
static inline void print_ts_ps(struct fmctdc_time ts)
{
uint64_t picoseconds;
if (fmt_wr) {
/* White rabbit format */
fprintf(stdout, "%10"PRIu64":%09u:%04u",
ts.seconds, ts.coarse, ts.frac);
return;
} else {
picoseconds = (uint64_t) ts.coarse * 8000ULL +
(uint64_t) ts.frac * 8000ULL / 4096ULL;
fprintf(stdout,
"%010"PRIu64"s %012"PRIu64"ps",
ts.seconds, picoseconds);
picoseconds = ((uint64_t)ts.coarse) * 8000ULL;
picoseconds += ((uint64_t)ts.frac) * 8000ULL / 4096ULL;
fprintf(stdout,
"%010"PRIu64"s %012"PRIu64"ps",
ts.seconds, picoseconds);
}
/**
* It prints the given timestamp
* @param[in] ts timestamp
* @param[in] fmt timestamp print format
*/
static void print_ts(struct fmctdc_time ts, enum tstamp_print_format fmt)
{
switch (fmt) {
case TSTAMP_FMT_WR:
print_ts_wr(ts);
break;
case TSTAMP_FMT_PS:
print_ts_ps(ts);
break;
default:
fprintf(stdout, "--- invalid format ---\n");
break;
}
}
......@@ -57,7 +93,7 @@ void dump(unsigned int ch, struct fmctdc_time *ts, int diff_mode)
fprintf(stdout,
"channel %d | channel seq %-12u\n ts ",
ch, ts->seq_id);
dump_timestamp(*ts);
print_ts(*ts, fmt_wr);
fprintf(stdout, "\n");
ts_tmp = *ts;
......@@ -71,7 +107,7 @@ void dump(unsigned int ch, struct fmctdc_time *ts, int diff_mode)
/* We are in normal mode, calculate the difference */
fprintf(stdout, " diff ");
dump_timestamp(ts_tmp);
print_ts(ts_tmp, fmt_wr);
ns = (uint64_t) ts_tmp.coarse * 8ULL;
ns += (uint64_t) (ts_tmp.frac * 8000ULL / 4096ULL) / 1000ULL;
......@@ -116,6 +152,7 @@ static void help(char *name)
fprintf(stderr, " -V: print version info\n\n");
fprintf(stderr, " -t <mode>: It does some test of the incoming timestampts\n\n");
fprintf(stderr, " -o <ms>: IRQ coalescing milleseconds timeout\n\n");
fprintf(stderr, " -e: stop on error\n\n");
fprintf(stderr, " channels enumerations go from %d to %d \n\n",
FMCTDC_CH_1, FMCTDC_CH_LAST);
......@@ -145,11 +182,11 @@ static int tstamp_testing_mode_1(struct fmctdc_time *ts, unsigned int n)
for (i = 0; i < n; ts_prev = ts[i], ++i) {
if (ts_prev.seq_id == -1)
continue;
if (ts_prev.seq_id + 1 != ts[i].seq_id) {
if (ts_prev.seq_id + 1 != ts[i].seq_id && ts[i].seq_id != 0) {
fprintf(stderr,
"*** Invalid sequence number. Previous %d, current %d, expected +1\n",
ts_prev.seq_id, ts[i].seq_id);
return -EINVAL;
goto err;
}
ns_p = fmctdc_ts_approx_ns(&ts_prev);
ns_c = fmctdc_ts_approx_ns(&ts[i]);
......@@ -157,11 +194,13 @@ static int tstamp_testing_mode_1(struct fmctdc_time *ts, unsigned int n)
fprintf(stderr,
"*** Invalid timestamp. Previous %d %"PRIu64"ns, current %d %"PRIu64"ns current one should be greater\n",
ts_prev.seq_id, ns_p, ts[i].seq_id, ns_c);
return -EINVAL;
goto err;
}
}
return 0;
err:
ts_prev = ts[n - 1];
return -EINVAL;
}
static int tstamp_testing_mode(struct fmctdc_time *ts, unsigned int n,
......@@ -199,6 +238,7 @@ int main(int argc, char **argv)
struct pollfd p[FMCTDC_NUM_CHANNELS];
enum tstamp_testing_modes mode = 0;
int timeout_ms = -1;
int stop_on_err = 0;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
......@@ -222,7 +262,7 @@ int main(int argc, char **argv)
ref[i] = -1;
/* Parse Options */
while ((opt = getopt(argc, argv, "D:hwns:d:frm:l:Lc:VS:t:o:")) != -1) {
while ((opt = getopt(argc, argv, "D:hwns:d:frm:l:Lc:VS:t:o:e")) != -1) {
switch (opt) {
case 'D':
ret = sscanf(optarg, "0x%04x", &dev_id);
......@@ -267,6 +307,9 @@ int main(int argc, char **argv)
case 'w':
fmt_wr = 1;
break;
case 'e':
stop_on_err = 1;
break;
case 'd':
sscanf(optarg, "%i,%i", &a, &b);
if (a < 0 || a > FMCTDC_CH_LAST) {
......@@ -369,11 +412,13 @@ int main(int argc, char **argv)
ref[ch] = -1;
}
ret = fmctdc_coalescing_timeout_set(brd, ch, timeout_ms);
if (ret) {
fprintf(stderr,
"%s: chan %d: cannot set IRQ coalescing timeout: %s. Use default\n",
argv[0], ch, fmctdc_strerror(errno));
if (timeout_ms > 0) {
ret = fmctdc_coalescing_timeout_set(brd, ch, timeout_ms);
if (ret) {
fprintf(stderr,
"%s: chan %d: cannot set IRQ coalescing timeout: %s. Use default\n",
argv[0], ch, fmctdc_strerror(errno));
}
}
/* set buffer mode */
......@@ -437,7 +482,7 @@ int main(int argc, char **argv)
continue;
ret = tstamp_testing_mode(ts, n_ts, mode);
if (ret)
if (ret && stop_on_err)
stop = 1;
if (n % n_show == 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