Commit 85f8d109 authored by Federico Vaga's avatar Federico Vaga

kernel: no need anymore for different reset procedure

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent da1a76f3
......@@ -28,8 +28,8 @@ endif
subdirs-ccflags-y = $(ccflags-y)
obj-m := fmc-tdc.o
fmc-tdc-objs = acam.o calibration.o fmc-util.o ft-spec.o \
ft-svec.o ft-core.o onewire.o ft-time.o ft-irq.o ft-zio.o\
fmc-tdc-objs = acam.o calibration.o fmc-util.o \
ft-core.o onewire.o ft-time.o ft-irq.o ft-zio.o\
fmc-bus-link/sdb-lib/access.o fmc-bus-link/sdb-lib/glue.o
all: modules
......
......@@ -84,11 +84,6 @@ enum ft_channel_flags {
struct fmctdc_dev;
struct ft_carrier_specific {
char *gateware_name;
int (*reset_core) (struct fmctdc_dev *);
};
struct ft_calibration { /* All of these are big endian in the EEPROM */
/* Input-to-WR timebase offset in ps. */
int32_t zero_offset[5];
......@@ -149,8 +144,6 @@ struct fmctdc_dev {
/* IRQ base index (for SVEC) */
struct fmc_device *fmc;
struct zio_device *zdev, *hwzdev;
/* carrier specific functions (init/exit/reset/readout/irq handling) */
struct ft_carrier_specific *carrier_specific;
/* carrier private data */
void *carrier_data;
/* current calibration block */
......@@ -171,9 +164,6 @@ struct fmctdc_dev {
uint64_t sequence; /**< Board time-stamp sequence number */
};
extern struct ft_carrier_specific ft_carrier_spec;
extern struct ft_carrier_specific ft_carrier_svec;
static inline uint32_t ft_readl(struct fmctdc_dev *ft, unsigned long reg)
{
return fmc_readl(ft->fmc, ft->ft_core_base + reg);
......
......@@ -41,6 +41,35 @@ static struct fmc_driver ft_drv; /* forward declaration */
FMC_PARAM_BUSID(ft_drv);
FMC_PARAM_GATEWARE(ft_drv);
static char bitstream_name[32];
static int ft_reset_core(struct fmctdc_dev *ft)
{
uint32_t val, shift = 0, addr;
if (!strcmp(ft->fmc->carrier_name, "SVEC")) {
shift = 1;
addr = TDC_SVEC_CARRIER_BASE;
} else {
addr = TDC_SPEC_CARRIER_BASE;
}
addr += TDC_REG_CARRIER_RST;
dev_dbg(&ft->fmc->dev, "Un-resetting FMCs...\n");
/* Reset - reset bits are shifted by 1 */
fmc_writel(ft->fmc, ~(1 << (ft->fmc->slot_id + shift)), addr);
udelay(5000);
val = fmc_readl(ft->fmc, addr);
val |= (1 << (ft->fmc->slot_id + shift));
/* Un-Reset */
fmc_writel(ft->fmc, val, addr);
return 0;
}
static int ft_init_channel(struct fmctdc_dev *ft, int channel)
{
......@@ -160,13 +189,12 @@ int ft_probe(struct fmc_device *fmc)
ft->verbose = ft_verbose;
/* apply carrier-specific hacks and workarounds */
if (!strcmp(fmc->carrier_name, "SPEC"))
ft->carrier_specific = &ft_carrier_spec;
else if (!strcmp(fmc->carrier_name, "SVEC"))
ft->carrier_specific = &ft_carrier_svec;
else {
dev_err(dev, "unsupported carrier '%s'\n",
fmc->carrier_name);
if (!strcmp(ft->fmc->carrier_name, "SVEC")) {
sprintf(bitstream_name, "svec-fmc-tdc.bin");
} else if (!strcmp(fmc->carrier_name, "SPEC")) {
sprintf(bitstream_name, "svec-fmc-tdc.bin");
} else {
dev_err(dev, "unsupported carrier '%s'\n", fmc->carrier_name);
return -ENODEV;
}
......@@ -179,7 +207,7 @@ int ft_probe(struct fmc_device *fmc)
if (ft_drv.gw_n)
fwname = ""; /* reprogram will pick from module parameter */
else
fwname = ft->carrier_specific->gateware_name;
fwname = bitstream_name;
dev_info(fmc->hwdev, "Gateware (%s)\n", fwname);
ret = fmc_reprogram(fmc, &ft_drv, fwname, -1);
......@@ -200,7 +228,7 @@ int ft_probe(struct fmc_device *fmc)
"Gateware already there. Set the \"gateware\" parameter to overwrite the current gateware\n");
}
ret = ft->carrier_specific->reset_core(ft);
ret = ft_reset_core(ft);
if (ret < 0)
return ret;
......
/*
* SPEC-specific workarounds for the fmc-tdc driver.
*
* Copyright (C) 2012-2013 CERN (http://www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/fmc.h>
#include "fmc-tdc.h"
#include "spec.h"
#include "hw/tdc_regs.h"
static int ft_spec_reset(struct fmctdc_dev *ft)
{
/* it takes a while for the PLL to bootstrap.... or not!
We have no possibility to check, as the PLL status register is driven
by the clock from this PLL :( */
msleep(3000);
return 0;
}
struct ft_carrier_specific ft_carrier_spec = {
FT_GATEWARE_SPEC,
ft_spec_reset
};
/*
* SVEC-specific workarounds for the fmc-tdc driver.
*
* Copyright (C) 2012-2013 CERN (http://www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fmc.h>
#include "fmc-tdc.h"
#include "hw/tdc_regs.h"
static int ft_svec_reset(struct fmctdc_dev *ft)
{
uint32_t val;
dev_dbg(&ft->fmc->dev, "Un-resetting FMCs...\n");
/* Reset - reset bits are shifted by 1 */
fmc_writel(ft->fmc, ~(1 << (ft->fmc->slot_id + 1)),
TDC_SVEC_CARRIER_BASE + TDC_REG_CARRIER_RST);
udelay(5000);
val = fmc_readl(ft->fmc, TDC_SVEC_CARRIER_BASE + TDC_REG_CARRIER_RST);
val |= (1 << (ft->fmc->slot_id + 1));
/* Un-Reset */
fmc_writel(ft->fmc, val, TDC_SVEC_CARRIER_BASE + TDC_REG_CARRIER_RST);
return 0;
}
struct ft_carrier_specific ft_carrier_svec = {
FT_GATEWARE_SVEC,
ft_svec_reset
};
......@@ -122,6 +122,7 @@
#define TDC_DMA_STAT_ERROR 0x3
#define TDC_SVEC_CARRIER_BASE 0x1000
#define TDC_SPEC_CARRIER_BASE 0x20000
/* TDC core submodule offsets (wrs to the TDC control registers block) */
......
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