Commit b19881b9 authored by Federico Vaga's avatar Federico Vaga

drv: add dedicated ZIO trigger

For the time being is used only to change the BURST size using POST-SAMPLEs

This solves also a bug with the ZIO trigger "user" which does arm for us, but
this is not exactly what we want because we need to arm only when we know the
number of samples to acquire
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent ab7367ed
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#define FT_VERSION_MAJ 2 /* version of the driver */ #define FT_VERSION_MAJ 2 /* version of the driver */
#define FT_VERSION_MIN 1 #define FT_VERSION_MIN 1
#define FT_ZIO_TRIG_TYPE_NAME "tdc1n5c-trig"
/* default gatewares */ /* default gatewares */
#define FT_GATEWARE_SVEC "fmc/svec-fmc-tdc.bin" #define FT_GATEWARE_SVEC "fmc/svec-fmc-tdc.bin"
#define FT_GATEWARE_SPEC "fmc/spec-fmc-tdc.bin" #define FT_GATEWARE_SPEC "fmc/spec-fmc-tdc.bin"
...@@ -92,6 +94,8 @@ struct ft_hw_timestamp { ...@@ -92,6 +94,8 @@ struct ft_hw_timestamp {
#include <linux/version.h> #include <linux/version.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/zio-trigger.h>
#include "hw/tdc_regs.h" #include "hw/tdc_regs.h"
#include "hw/tdc_eic.h" #include "hw/tdc_eic.h"
#include "hw/tdc_dma_eic.h" #include "hw/tdc_dma_eic.h"
...@@ -141,6 +145,15 @@ enum ft_transfer_mode { ...@@ -141,6 +145,15 @@ enum ft_transfer_mode {
FT_ACQ_TYPE_DMA, FT_ACQ_TYPE_DMA,
}; };
struct fmctdc_trig {
struct zio_ti ti;
};
static inline struct fmctdc_trig *to_fmctdc_trig(struct zio_ti *ti_ptr)
{
return container_of(ti_ptr, struct fmctdc_trig, ti);
}
/* /*
* Main TDC device context * Main TDC device context
* @lock it protects: irq_imr (irq vs user), offset (user vs user), * @lock it protects: irq_imr (irq vs user), offset (user vs user),
......
...@@ -139,19 +139,6 @@ static void ft_buffer_burst_disable(struct fmctdc_dev *ft, ...@@ -139,19 +139,6 @@ static void ft_buffer_burst_disable(struct fmctdc_dev *ft,
} }
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_timeout_set(struct fmctdc_dev *ft, static void ft_buffer_burst_timeout_set(struct fmctdc_dev *ft,
unsigned int chan, unsigned int chan,
uint32_t timeout) uint32_t timeout)
...@@ -201,7 +188,6 @@ static void ft_buffer_init(struct fmctdc_dev *ft, int channel) ...@@ -201,7 +188,6 @@ static void ft_buffer_init(struct fmctdc_dev *ft, int channel)
val |= TDC_BUF_NEXT_SIZE_VALID; val |= TDC_BUF_NEXT_SIZE_VALID;
ft_iowrite(ft, val, base + TDC_BUF_REG_NEXT_SIZE); 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_timeout_set(ft, channel, ft_buffer_burst_timeout_set(ft, channel,
dma_buf_irq_timeout_ms_default); dma_buf_irq_timeout_ms_default);
ft_buffer_burst_enable(ft, channel); ft_buffer_burst_enable(ft, channel);
......
...@@ -336,7 +336,7 @@ static struct zio_cset ft_cset[] = { ...@@ -336,7 +336,7 @@ static struct zio_cset ft_cset[] = {
static struct zio_device ft_tmpl = { static struct zio_device ft_tmpl = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.preferred_trigger = "user", .preferred_trigger = FT_ZIO_TRIG_TYPE_NAME,
.s_op = &ft_zio_sysfs_ops, .s_op = &ft_zio_sysfs_ops,
.cset = ft_cset, .cset = ft_cset,
.n_cset = ARRAY_SIZE(ft_cset), .n_cset = ARRAY_SIZE(ft_cset),
...@@ -366,6 +366,137 @@ static struct zio_driver ft_zdrv = { ...@@ -366,6 +366,137 @@ static struct zio_driver ft_zdrv = {
a specific patch */ a specific patch */
}; };
#define FT_TRIG_POST_DEFAULT 1
enum ft_trig_options {
FT_TRIG_POST = 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 ZIO_ATTR_DEFINE_STD(ZIO_TRG, ft_trig_std_zattr) = {
/* Number of shots */
ZIO_ATTR(trig, ZIO_ATTR_TRIG_POST_SAMP, ZIO_RW_PERM, FT_TRIG_POST,
FT_TRIG_POST_DEFAULT),
};
static int ft_trig_conf_set(struct device *dev, struct zio_attribute *zattr,
uint32_t usr_val)
{
struct zio_ti *ti = to_zio_ti(dev);
struct fmctdc_dev *ft = ti->cset->zdev->priv_d;
switch (zattr->id) {
case FT_TRIG_POST:
switch (ft->mode) {
case FT_ACQ_TYPE_FIFO:
break;
case FT_ACQ_TYPE_DMA:
ft_buffer_burst_size_set(ft, ti->cset->index, usr_val);
break;
default:
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int ft_trig_info_get(struct device *dev, struct zio_attribute *zattr,
uint32_t *usr_val)
{
switch (zattr->id) {
case FT_TRIG_POST:
break;
default:
return -EINVAL;
}
return 0;
}
static const struct zio_sysfs_operations ft_trig_s_op = {
.conf_set = ft_trig_conf_set,
.info_get = ft_trig_info_get,
};
static struct zio_ti *ft_trig_create(struct zio_trigger_type *trig,
struct zio_cset *cset,
struct zio_control *ctrl, fmode_t flags)
{
struct fmctdc_dev *ft = cset->zdev->priv_d;
struct fmctdc_trig *tti;
tti = kzalloc(sizeof(*tti), GFP_KERNEL);
if (!tti)
return ERR_PTR(-ENOMEM);
tti->ti.flags = ZIO_DISABLED;
tti->ti.cset = cset;
switch (ft->mode) {
case FT_ACQ_TYPE_FIFO:
break;
case FT_ACQ_TYPE_DMA:
ft_buffer_burst_size_set(ft, cset->index, FT_TRIG_POST_DEFAULT);
break;
default:
return ERR_PTR(-EINVAL);
}
return &tti->ti;
}
static void ft_trig_destroy(struct zio_ti *ti)
{
struct fmctdc_trig *tti = to_fmctdc_trig(ti);
kfree(tti);
}
static int ft_trig_push(struct zio_ti *ti, struct zio_channel *chan,
struct zio_block *block)
{
dev_err(&ti->head.dev, "output not supported\n");
return -EIO;
}
static const struct zio_trigger_operations ft_trig_ops = {
.create = ft_trig_create,
.destroy = ft_trig_destroy,
.change_status = NULL,
.data_done = NULL,
.arm = NULL,
.abort = NULL,
.push_block = ft_trig_push,
};
/* Definition of the trigger type -- can't be static */
struct zio_trigger_type ft_trig_type = {
.owner = THIS_MODULE,
.zattr_set = {
.std_zattr = ft_trig_std_zattr,
.ext_zattr = NULL,
.n_ext_attr = 0,
},
.s_op = &ft_trig_s_op,
.t_op = &ft_trig_ops,
};
/* Register and unregister are used to set up the template driver */ /* Register and unregister are used to set up the template driver */
int ft_zio_register(void) int ft_zio_register(void)
{ {
...@@ -390,9 +521,19 @@ int ft_zio_init(struct fmctdc_dev *ft) ...@@ -390,9 +521,19 @@ int ft_zio_init(struct fmctdc_dev *ft)
int err = 0; int err = 0;
int dev_id; int dev_id;
err = zio_register_trig(&ft_trig_type, FT_ZIO_TRIG_TYPE_NAME);
if (err) {
dev_err(&ft->fmc->dev,
"Cannot register ZIO trigger type \"%s\" (error %i)\n",
FT_ZIO_TRIG_TYPE_NAME, err);
return err;
}
ft->hwzdev = zio_allocate_device(); ft->hwzdev = zio_allocate_device();
if (IS_ERR(ft->hwzdev)) if (IS_ERR(ft->hwzdev)) {
return PTR_ERR(ft->hwzdev); err = PTR_ERR(ft->hwzdev);
goto err_dev_alloc;
}
/* Mandatory fields */ /* Mandatory fields */
ft->hwzdev->owner = THIS_MODULE; ft->hwzdev->owner = THIS_MODULE;
...@@ -401,16 +542,21 @@ int ft_zio_init(struct fmctdc_dev *ft) ...@@ -401,16 +542,21 @@ int ft_zio_init(struct fmctdc_dev *ft)
dev_id = ft->fmc->device_id; dev_id = ft->fmc->device_id;
err = zio_register_device(ft->hwzdev, "tdc-1n5c", dev_id); err = zio_register_device(ft->hwzdev, "tdc-1n5c", dev_id);
if (err) { if (err)
zio_free_device(ft->hwzdev); goto err_dev_reg;
return err;
}
return 0; return 0;
err_dev_reg:
zio_free_device(ft->hwzdev);
err_dev_alloc:
zio_unregister_trig(&ft_trig_type);
return err;
} }
void ft_zio_exit(struct fmctdc_dev *ft) void ft_zio_exit(struct fmctdc_dev *ft)
{ {
zio_unregister_device(ft->hwzdev); zio_unregister_device(ft->hwzdev);
zio_free_device(ft->hwzdev); zio_free_device(ft->hwzdev);
zio_unregister_trig(&ft_trig_type);
} }
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