Commit 969ee716 authored by Federico Vaga's avatar Federico Vaga

kernel: always reset FPGA after programming

There should not be any side effect on resetting the FGPA every time
we program it. Confirmed by Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent c1db3e8a
......@@ -161,3 +161,17 @@ void gpiofix_low_level(int fd, void __iomem *bar4)
gpio_out(fd, bar4, GNGPIO_OUTPUT_ENABLE, GPIO_BOOTSEL0, 0);
gpio_out(fd, bar4, GNGPIO_OUTPUT_ENABLE, GPIO_BOOTSEL1, 0);
}
void loader_reset_fpga(int fd, void __iomem *bar4)
{
uint32_t reg;
/* After reprogramming, reset the FPGA using the gennum register */
reg = lll_read(fd, bar4, GNPCI_SYS_CFG_SYSTEM);
/*
* This _fucking_ register must be written with extreme care,
* becase some fields are "protected" and some are not. *hate*
*/
lll_write(fd, bar4, (reg & ~0xffff) | 0x3fff, GNPCI_SYS_CFG_SYSTEM);
lll_write(fd, bar4, (reg & ~0xffff) | 0x7fff, GNPCI_SYS_CFG_SYSTEM);
}
......@@ -11,6 +11,7 @@
extern int loader_low_level(int fd, void __iomem *bar4, const void *, int);
extern void waitdone_low_level(int fd, void __iomem *bar4);
extern void gpiofix_low_level(int fd, void __iomem *bar4);
extern void loader_reset_fpga(int fd, void __iomem *bar4);
/* The following part implements a different access rule for user and kernel */
......
......@@ -45,7 +45,6 @@ static int spec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
const struct firmware *fw;
struct spec_dev *spec = fmc->carrier_data;
struct device *dev = fmc->hwdev;
uint32_t reg;
int ret;
if (!gw)
......@@ -79,15 +78,6 @@ static int spec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
else
fmc->flags |= FMC_DEVICE_HAS_CUSTOM;
/* After reprogramming, reset the FPGA using the gennum register */
reg = gennum_readl(spec, GNPCI_SYS_CFG_SYSTEM);
/*
* This _fucking_ register must be written with extreme care,
* becase some fields are "protected" and some are not. *hate*
*/
gennum_writel(spec, (reg & ~0xffff) | 0x3fff, GNPCI_SYS_CFG_SYSTEM);
gennum_writel(spec, (reg & ~0xffff) | 0x7fff, GNPCI_SYS_CFG_SYSTEM);
out:
release_firmware(fw);
return ret;
......
......@@ -36,6 +36,7 @@ int spec_load_fpga(struct spec_dev *spec, const void *data, int size)
struct device *dev = &spec->pdev->dev;
int i, wrote;
unsigned long j;
uint32_t reg;
/* loader_low_level is designed to run from user space too */
wrote = loader_low_level(0 /* unused fd */,
......@@ -62,6 +63,8 @@ int spec_load_fpga(struct spec_dev *spec, const void *data, int size)
}
}
gpiofix_low_level(0 /* unused fd */, spec->remap[2]);
loader_reset_fpga(0 /* unused fd */, spec->remap[2]);
return 0;
}
......
......@@ -12,7 +12,7 @@ extern int loader_low_level(
void __iomem *bar4, /* This is ignored in user space */
const void *data,
int size8);
extern void loader_reset_fpga(int fd, void __iomem *bar4);
......@@ -40,7 +40,7 @@ enum {
FCL_TIMER2_1 = FCL_BASE + 0x30,
FCL_DBG_STS = FCL_BASE + 0x34,
FCL_FIFO = 0xE00,
PCI_SYS_CFG_SYSTEM = 0x800
GNPCI_SYS_CFG_SYSTEM = 0x800
};
......
......@@ -278,6 +278,7 @@ int spec_load_bitstream_buffer(void *card, void *buf, size_t size)
rv = loader_low_level(0, p->bar4, buf, size);
waitdone_low_level(0, p->bar4);
gpiofix_low_level(0, p->bar4);
loader_reset_fpga(0, p->bar4);
return rv;
}
......
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