Commit 9ea3fede authored by Alessandro Rubini's avatar Alessandro Rubini

general: upgraded to new fmc-bus version

This includes a new version of the submodule and fixes the code
to match the new set of fields in the fmc structure. The biggest change
is in the i2c address, that is now hosted in the fmc structure (this
changes the spec-i2c file).

Also, use new fmc_reprogram().  The function allows to centralize
dumping the eeprom and the sdb tree, so the bus framework dumps or
not, and can be changed at run time.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 4f90018d
fmc-bus @ b2ca26a5
Subproject commit 29f077e42c420f596d05b51fdc356505cc42edb1
Subproject commit b2ca26a566e978dc8426a0cebe8dba40cadac2ac
......@@ -7,6 +7,7 @@
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/fmc.h>
#include <linux/interrupt.h>
......@@ -256,7 +257,7 @@ static int spec_read_ee(struct fmc_device *fmc, int pos, void *data, int len)
{
if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
return -ENOTSUPP;
return spec_eeprom_read(fmc, SPEC_I2C_EEPROM_ADDR, pos, data, len);
return spec_eeprom_read(fmc, pos, data, len);
}
static int spec_write_ee(struct fmc_device *fmc, int pos,
......@@ -264,7 +265,7 @@ static int spec_write_ee(struct fmc_device *fmc, int pos,
{
if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
return -ENOTSUPP;
return spec_eeprom_write(fmc, SPEC_I2C_EEPROM_ADDR, pos, data, len);
return spec_eeprom_write(fmc, pos, data, len);
}
static struct fmc_operations spec_fmc_operations = {
......@@ -391,6 +392,7 @@ static int check_golden(struct fmc_device *fmc)
int spec_fmc_create(struct spec_dev *spec)
{
struct fmc_device *fmc;
struct pci_dev *pdev;
int ret;
fmc = kzalloc(sizeof(*fmc), GFP_KERNEL);
......@@ -398,14 +400,27 @@ int spec_fmc_create(struct spec_dev *spec)
return -ENOMEM;
fmc->version = FMC_VERSION;
fmc->owner = THIS_MODULE;
fmc->carrier_name = "SPEC";
fmc->carrier_data = spec;
fmc->base = spec->remap[0]; /* 1M window at offset 0 */
/* 1M window at offset 0 */
fmc->fpga_base = spec->remap[0];
fmc->memlen = 1 << 20;
fmc->irq = spec->pdev->irq;
fmc->op = &spec_fmc_operations;
fmc->hwdev = &spec->pdev->dev; /* for messages */
spec->fmc = fmc;
/* We have one slot only, and the i2c address is mandated */
fmc->slot_id = 0;
fmc->eeprom_addr = SPEC_I2C_EEPROM_ADDR;
/* The device id is needed to build mezzanine unique names */
pdev = spec->pdev;
fmc->device_id = (pdev->bus->number << 8) | pdev->devfn;
/* Check that the golden binary is actually correct */
ret = check_golden(fmc);
if (ret)
......
......@@ -139,7 +139,7 @@ int mi2c_scan(struct fmc_device *fmc)
}
/* FIXME: this is very inefficient: read several bytes in a row instead */
int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
int spec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
void *buf, size_t size)
{
int i;
......@@ -148,7 +148,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
for(i = 0; i < size; i++) {
mi2c_start(fmc);
if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) {
if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
mi2c_stop(fmc);
return -EIO;
}
......@@ -158,7 +158,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
offset++;
mi2c_stop(fmc);
mi2c_start(fmc);
mi2c_put_byte(fmc, (i2c_addr << 1) | 1);
mi2c_put_byte(fmc, (fmc->eeprom_addr << 1) | 1);
mi2c_get_byte(fmc, &c, 0);
*buf8++ = c;
mi2c_stop(fmc);
......@@ -166,7 +166,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
return size;
}
int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
const void *buf, size_t size)
{
int i, busy;
......@@ -175,7 +175,7 @@ int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
for(i = 0; i < size; i++) {
mi2c_start((fmc));
if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) {
if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
mi2c_stop(fmc);
return -1;
}
......@@ -187,7 +187,7 @@ int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
do { /* wait until the chip becomes ready */
mi2c_start(fmc);
busy = mi2c_put_byte(fmc, i2c_addr << 1);
busy = mi2c_put_byte(fmc, fmc->eeprom_addr << 1);
mi2c_stop(fmc);
} while(busy);
}
......@@ -210,12 +210,12 @@ int spec_i2c_init(struct fmc_device *fmc)
if (!buf)
return -ENOMEM;
i = spec_eeprom_read(fmc, SPEC_I2C_EEPROM_ADDR, 0, buf,
SPEC_I2C_EEPROM_SIZE);
i = spec_eeprom_read(fmc, 0, buf, SPEC_I2C_EEPROM_SIZE);
if (i != SPEC_I2C_EEPROM_SIZE) {
dev_err(&spec->pdev->dev, "EEPROM read error: retval is %i\n",
i);
dev_err(&spec->pdev->dev, "EEPROM read error %i\n", i);
kfree(buf);
fmc->eeprom = NULL;
fmc->eeprom_len = 0;
return -EIO;
}
fmc->eeprom = buf;
......
......@@ -125,10 +125,10 @@ extern void spec_fmc_destroy(struct spec_dev *spec);
/* Functions in spec-i2c.c, used by spec-fmc.c */
extern int spec_i2c_init(struct fmc_device *fmc);
extern void spec_i2c_exit(struct fmc_device *fmc);
extern int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr,
uint32_t offset, void *buf, size_t size);
extern int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr,
uint32_t offset, const void *buf, size_t size);
extern int spec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
void *buf, size_t size);
extern int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
const void *buf, size_t size);
/* The eeprom is at address 0x50 */
#define SPEC_I2C_EEPROM_ADDR 0x50
......
......@@ -88,9 +88,9 @@ int wrn_fmc_probe(struct fmc_device *fmc)
* global name
*/
if (wrn_drv.gw_n)
ret = fmc->op->reprogram(fmc, &wrn_drv, "");
ret = fmc_reprogram(fmc, &wrn_drv, "", 0x630000 /* SDB */);
else
ret = fmc->op->reprogram(fmc, &wrn_drv, wrn_filename);
ret = fmc_reprogram(fmc, &wrn_drv, wrn_filename, 0x63000);
if (ret <0) {
if (ret == -ESRCH) {
dev_info(fmc->hwdev, "%s: no gateware at index %i\n",
......@@ -102,19 +102,9 @@ int wrn_fmc_probe(struct fmc_device *fmc)
wrn_filename, ret);
return ret;
}
/* Verify that we have SDB at offset WRN_SDB_ADDR (0x63000) */
if (fmc_readl(fmc, WRN_SDB_ADDR) != 0x5344422d) {
dev_err(dev, "Can't find SDB magic\n");
ret = -ENODEV;
goto out;
}
dev_info(dev, "Gateware successfully loaded\n");
if ( (ret = fmc_scan_sdb_tree(fmc, WRN_SDB_ADDR)) < 0) {
dev_err(dev, "scan fmc failed %i\n", ret);
goto out;
}
/* FIXME: remove this parameter, fmc.ko shows it already */
if (wrn_show_sdb)
fmc_show_sdb_tree(fmc);
......
......@@ -223,7 +223,8 @@ int wrn_eth_init(struct fmc_device *fmc)
continue;
}
/* use c->offset to copy and already-remapped value */
*((void **)((u8 *)drvdata + c->offset)) = fmc->base + start;
*((void **)((u8 *)drvdata + c->offset)) =
fmc->fpga_base + start;
}
pdev->resource = resarr;
pdev->num_resources = ARRAY_SIZE(wrn_cores);
......
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