Commit f2dc22af authored by Federico Vaga's avatar Federico Vaga

kernel: use the new FMC registration with FPGA flash

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 92b2ad31
......@@ -656,7 +656,7 @@ static void svec_prepare_description(struct svec_dev *svec)
* via module parameters) or when the configuration is assigned through
* sysfs. Reconfiguration implies re-loading the FMCs.
*/
int svec_reconfigure(struct svec_dev *svec)
int svec_reconfigure(struct svec_dev *svec, struct fmc_gateware *gw)
{
int error;
......@@ -691,7 +691,7 @@ int svec_reconfigure(struct svec_dev *svec)
/* FMC initialization enabled? Start up the FMC drivers. */
if (svec->cfg_cur.use_fmc) {
error = svec_fmc_create(svec);
error = svec_fmc_create(svec, gw);
if (error) {
dev_err(svec->dev, "error creating fmc devices\n");
goto failed_unmap;
......@@ -801,7 +801,7 @@ static int svec_probe(struct device *pdev, unsigned int ndev)
}
/* Map user address space & give control to the FMCs */
svec_reconfigure(svec);
svec_reconfigure(svec, NULL);
return 0;
......
......@@ -33,6 +33,41 @@ static void svec_writel(struct fmc_device *fmc, uint32_t val, int offset)
iowrite32be(val, fmc->fpga_base + offset);
}
static int svec_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *drv,
void *gw, unsigned long len)
{
struct svec_dev *svec = fmc->carrier_data;
struct device *dev = fmc->hwdev;
int ret;
if (!gw || !len) {
dev_err(dev, "Invalid firmware buffer - buf: %p len: %ld\n",
gw, len);
return -EINVAL;
}
if (!drv)
dev_info(dev, "Carrier FPGA re-program\n");
fmc_free_sdb_tree(fmc);
fmc->flags &= ~FMC_DEVICE_HAS_GOLDEN;
/* load the firmware */
ret = svec_load_fpga(svec, gw, len);
if (ret < 0) {
dev_err(dev, "error %i programming firmware\n", ret);
return ret;
}
/* Configure & activate CSR functions depending on chosen AM */
svec_setup_csr(svec);
fmc->flags |= FMC_DEVICE_HAS_CUSTOM;
return 0;
}
static int svec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
char *gw)
{
......@@ -67,23 +102,10 @@ static int svec_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
dev_warn(dev, "request firmware \"%s\": error %i\n", gw, ret);
return ret;
}
fmc_free_sdb_tree(fmc);
fmc->flags &= ~FMC_DEVICE_HAS_GOLDEN;
/* load the firmware */
ret = svec_load_fpga(svec, fw->data, fw->size);
if (ret < 0) {
dev_err(dev, "error %i programming firmware \"%s\"\n", ret, gw);
goto out;
}
/* Configure & activate CSR functions depending on chosen AM */
svec_setup_csr(svec);
fmc->flags |= FMC_DEVICE_HAS_CUSTOM;
/* Re-Program FPGA */
ret = svec_reprogram_raw(fmc, drv, (void *)fw->data, fw->size);
out:
release_firmware(fw);
if (ret < 0)
dev_err(dev, "svec reprogram failed while loading %s\n", gw);
......@@ -120,6 +142,7 @@ static int svec_write_ee(struct fmc_device *fmc, int pos,
static struct fmc_operations svec_fmc_operations = {
.read32 = svec_readl,
.write32 = svec_writel,
.reprogram_raw = svec_reprogram_raw,
.reprogram = svec_reprogram,
.irq_request = svec_irq_request,
.irq_ack = svec_irq_ack,
......@@ -231,7 +254,7 @@ int svec_fmc_prepare(struct svec_dev *svec, unsigned int fmc_slot)
return ret;
}
int svec_fmc_create(struct svec_dev *svec)
int svec_fmc_create(struct svec_dev *svec, struct fmc_gateware *gw)
{
int i;
int error = 0;
......@@ -244,7 +267,7 @@ int svec_fmc_create(struct svec_dev *svec)
}
/* fmc device creation */
error = fmc_device_register_n(svec->fmcs, svec->fmcs_n);
error = fmc_device_register_n_gw(svec->fmcs, svec->fmcs_n, gw);
if (error) {
dev_err(svec->dev, "Error registering fmc devices\n");
goto failed;
......
......@@ -57,22 +57,23 @@ static int svec_fw_cmd_reset(struct svec_dev *card)
static int svec_fw_cmd_program(struct svec_dev *card)
{
int err;
struct fmc_gateware gw = {card->fw_buffer, card->fw_length};
int err = 0;
if (!card->fw_buffer || !card->fw_length)
return -EINVAL;
err = svec_load_fpga(card, card->fw_buffer, card->fw_length);
vfree(card->fw_buffer);
if (err)
goto out;
card->fw_buffer = NULL;
card->fw_length = 0;
if (err < 0)
return err;
svec_reconfigure(card);
return 0;
svec_reconfigure(card, &gw);
out:
vfree(card->fw_buffer);
return err;
}
......@@ -401,7 +402,7 @@ ATTR_STORE_CALLBACK(configured)
card->cfg_new.configured = 1;
card->cfg_cur = card->cfg_new;
error = svec_reconfigure(card);
error = svec_reconfigure(card, NULL);
if (error)
return error;
......
......@@ -104,7 +104,7 @@ extern int svec_map_window(struct svec_dev *svec, enum svec_map_win map_type);
extern char *svec_fw_name;
/* Functions in svec-fmc.c, used by svec-vme.c */
extern int svec_fmc_create(struct svec_dev *svec);
extern int svec_fmc_create(struct svec_dev *svec, struct fmc_gateware *gw);
extern void svec_fmc_destroy(struct svec_dev *svec);
/* Functions in svec-i2c.c, used by svec-fmc.c */
......@@ -138,7 +138,7 @@ int svec_dma_read(struct svec_dev *svec, uint32_t addr, int am, size_t size,
void *buf, int is_fifo);
int svec_reconfigure(struct svec_dev *svec);
int svec_reconfigure(struct svec_dev *svec, struct fmc_gateware *gw);
int svec_setup_csr(struct svec_dev *svec);
int svec_validate_configuration(struct device *pdev, struct svec_config *cfg);
......
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