Commit 5e1dc8e1 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v1.4.10'

parents 5c64edc9 410df44d
......@@ -2,6 +2,26 @@
Change Log
==========
[1.4.10] 2020-05-12
==================
Added
-----
- [hdl] metadata source-id automatic assignment
- [hdl] add option to consider AM in VME slave decoder
Fixed
-----
- [hdl] fix typos when ddr is not configured. This froze the board when
reading a ddr data register.
Changed
-------
- [sw] Linux device hierarchy seen in sysfs. It is incompatible but
tools, today do not rely in this. So we take the freedom to change
it without a major release.
- [sw] on device removal the IRQ vector number in the CR/CSR space is set
to 0x0
[1.4.9] 2020-03-10
==================
Fixed
......@@ -31,7 +51,7 @@ Fixed
[1.4.6] 2019-12-16
==================
Changed
-----
-------
- [sw] better integration in coht, rename environment variable to FPGA_MGR
[1.4.5] 2019-12-16
......@@ -55,7 +75,7 @@ Added
[1.4.2] 2019-10-17
==================
Changed
-----
-------
- [sw] show application metadata in debugfs
[1.4.1] 2019-10-15
......
Subproject commit 75d51c0b92015b48b176374f9a387b2d25fa8198
Subproject commit 6f2c1dbd5021debe6233c9495cb1b9d10f4a79de
files = [
"svec_base_regs.vhd",
"svec_base_wr.vhd",
"sourceid_svec_base_pkg.vhd",
]
try:
# Assume this module is in fact a git submodule of a main project that
# is in the same directory as general-cores...
exec(open("../../../" + "/general-cores/tools/gen_sourceid.py").read(),
None, {'project': 'svec_base'})
except Exception as e:
print("Error: cannot generate source id file")
raise
......@@ -145,6 +145,7 @@ memory-map:
name: wrc_regs
address: 0x1000
description: white-rabbit core registers
comment: In particular, the vuart is at 0x1500
size: 0x1000
interface: wb-32-be
x-hdl:
......
......@@ -36,12 +36,15 @@ use work.wr_svec_pkg.all;
use work.buildinfo_pkg.all;
use work.wr_fabric_pkg.all;
use work.streamers_pkg.all;
use work.sourceid_svec_base_pkg;
library unisim;
use unisim.vcomponents.all;
entity svec_base_wr is
generic (
-- For the VME64x interface: if true, also consider AM in the decoder.
g_DECODE_AM : boolean := TRUE;
-- If true, instantiate a VIC/ONEWIRE/SPI/WR/DDRAM+DMA.
g_WITH_VIC : boolean := True;
g_WITH_ONEWIRE : boolean := True;
......@@ -481,7 +484,7 @@ begin -- architecture top
cmp_vme_core : entity work.xvme64x_core
generic map (
g_CLOCK_PERIOD => 16,
g_DECODE_AM => TRUE,
g_DECODE_AM => g_DECODE_AM,
g_USER_CSR_EXT => FALSE,
g_WB_GRANULARITY => BYTE,
g_WB_MODE => PIPELINED,
......@@ -649,13 +652,22 @@ begin -- architecture top
metadata_data <= x"53564543";
when x"2" =>
-- Version
metadata_data <= x"01040000";
metadata_data <= x"0104000a";
when x"3" =>
-- BOM
metadata_data <= x"fffe0000";
when x"4" | x"5" | x"6" | x"7" =>
when x"4" =>
-- source id
metadata_data <= x"00000000";
metadata_data <= sourceid_svec_base_pkg.sourceid(127 downto 96);
when x"5" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(95 downto 64);
when x"6" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(63 downto 32);
when x"7" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(31 downto 0);
when x"8" =>
-- capability mask
metadata_data <= x"00000000";
......@@ -1241,7 +1253,7 @@ begin -- architecture top
ddr4_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0',
dat => (others => 'X'));
csr_ddr4_data_in <= x"0000_0000";
csr_ddr4_data_rack <= csr_ddr4_data_wr;
csr_ddr4_data_rack <= csr_ddr4_data_rd;
csr_ddr4_data_wack <= csr_ddr4_data_wr;
end generate gen_without_ddr4;
......@@ -1414,7 +1426,7 @@ begin -- architecture top
ddr5_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0',
dat => (others => 'X'));
csr_ddr5_data_in <= x"0000_0000";
csr_ddr5_data_rack <= csr_ddr5_data_wr;
csr_ddr5_data_rack <= csr_ddr5_data_rd;
csr_ddr5_data_wack <= csr_ddr5_data_wr;
end generate gen_without_ddr5;
......
......@@ -28,6 +28,8 @@ clean-spec-core-fpga.h:
install: modules_install
clean: clean-spec-core-fpga.h
$(MAKE) -C $(LINUX) M=$(shell pwd) $@
modules help coccicheck modules_install: svec-core-fpga.h
$(MAKE) -C $(LINUX) M=$(shell pwd) \
VERSION=$(VERSION) \
......
......@@ -93,9 +93,9 @@ int compat_svec_fw_load(struct svec_dev *svec_dev, const char *name)
struct fpga_manager *mgr;
int err;
mgr = fpga_mgr_get(&svec_dev->vdev->dev);
if (IS_ERR(mgr))
return -ENODEV;
mgr = fpga_mgr_get(&svec_dev->dev);
if (IS_ERR_OR_NULL(mgr))
return IS_ERR(mgr) ? PTR_ERR(mgr) : -ENODEV;
err = fpga_mgr_lock(mgr);
if (err)
......
......@@ -74,7 +74,7 @@ static const struct debugfs_reg32 svec_fpga_debugfs_reg32[] = {
static int svec_fpga_dbg_bld_info(struct seq_file *s, void *offset)
{
struct svec_fpga *svec_fpga = s->private;
struct svec_dev *svec_dev = dev_get_drvdata(svec_fpga->dev.parent);
struct svec_dev *svec_dev = to_svec_dev(svec_fpga->dev.parent);
int off;
if (!(svec_dev->meta.cap & SVEC_META_CAP_BLD)) {
......@@ -118,7 +118,7 @@ static const struct file_operations svec_fpga_dbg_bld_info_ops = {
static int svec_fpga_dbg_init(struct svec_fpga *svec_fpga)
{
struct svec_dev *svec_dev = dev_get_drvdata(svec_fpga->dev.parent);
struct svec_dev *svec_dev = to_svec_dev(svec_fpga->dev.parent);
int err;
svec_fpga->dbg_dir = debugfs_create_dir(dev_name(&svec_fpga->dev),
......@@ -196,9 +196,9 @@ static struct resource svec_fpga_vic_res[] = {
static int svec_fpga_vic_init(struct svec_fpga *svec_fpga)
{
struct svec_dev *svec_dev = dev_get_drvdata(svec_fpga->dev.parent);
unsigned long vme_start = vme_resource_start(svec_dev->vdev,
svec_fpga->function_nr);
struct svec_dev *svec_dev = to_svec_dev(svec_fpga->dev.parent);
struct vme_dev *vdev = to_vme_dev(svec_dev->dev.parent);
unsigned long vme_start = vme_resource_start(vdev, svec_fpga->function_nr);
const unsigned int res_n = ARRAY_SIZE(svec_fpga_vic_res);
struct resource res[ARRAY_SIZE(svec_fpga_vic_res)];
struct platform_device *pdev;
......@@ -209,7 +209,7 @@ static int svec_fpga_vic_init(struct svec_fpga *svec_fpga)
memcpy(&res, svec_fpga_vic_res, sizeof(svec_fpga_vic_res));
res[0].start += vme_start;
res[0].end += vme_start;
res[1].start = svec_dev->vdev->irq;
res[1].start = vdev->irq;
res[1].end = res[1].start;
pdev = platform_device_register_resndata(&svec_fpga->dev,
"htvic-svec",
......@@ -327,7 +327,7 @@ static inline size_t __fpga_mfd_devs_size(void)
static int svec_fpga_devices_init(struct svec_fpga *svec_fpga)
{
struct vme_dev *vdev = to_vme_dev(svec_fpga->dev.parent);
struct vme_dev *vdev = to_vme_dev(svec_fpga->dev.parent->parent);
struct mfd_cell *fpga_mfd_devs;
struct irq_domain *vic_domain;
unsigned int n_mfd = 0;
......@@ -376,7 +376,7 @@ static ssize_t temperature_show(struct device *dev,
char *buf)
{
struct svec_fpga *svec_fpga = to_svec_fpga(dev);
struct svec_dev *svec_dev = dev_get_drvdata(svec_fpga->dev.parent);
struct svec_dev *svec_dev = to_svec_dev(svec_fpga->dev.parent);
if (svec_dev->meta.cap & SVEC_META_CAP_THERM) {
uint32_t temp = ioread32be(svec_fpga->fpga
......@@ -396,7 +396,7 @@ static ssize_t serial_number_show(struct device *dev,
char *buf)
{
struct svec_fpga *svec_fpga = to_svec_fpga(dev);
struct svec_dev *svec_dev = dev_get_drvdata(svec_fpga->dev.parent);
struct svec_dev *svec_dev = to_svec_dev(svec_fpga->dev.parent);
if (svec_dev->meta.cap & SVEC_META_CAP_THERM) {
uint32_t msb = ioread32be(svec_fpga->fpga
......@@ -727,14 +727,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
struct svec_meta_id *meta)
{
if ((meta->bom & SVEC_META_BOM_END_MASK) != SVEC_META_BOM_BE) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Expected Big Endian devices BOM: 0x%x\n",
meta->bom);
return false;
}
if ((meta->bom & SVEC_META_BOM_VER_MASK) != 0) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Unknow Metadata svecification version BOM: 0x%x\n",
meta->bom);
return false;
......@@ -742,14 +742,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
if (meta->vendor != SVEC_META_VENDOR_ID ||
meta->device != SVEC_META_DEVICE_ID) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Unknow vendor/device ID: %08x:%08x\n",
meta->vendor, meta->device);
return false;
}
if ((meta->version & SVEC_META_VERSION_MASK) != SVEC_META_VERSION_1_4) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Unknow version: %08x\n", meta->version);
return false;
}
......@@ -757,33 +757,34 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
return true;
}
static void svec_release(struct device *dev)
static void svec_fpga_release(struct device *dev)
{
}
static int svec_uevent(struct device *dev, struct kobj_uevent_env *env)
static int svec_fpga_uevent(struct device *dev, struct kobj_uevent_env *env)
{
return 0;
}
static const struct attribute_group *svec_groups[] = {
static const struct attribute_group *svec_fpga_groups[] = {
&svec_fpga_therm_group,
&svec_fpga_csr_group,
NULL
};
static const struct device_type svec_fpga_type = {
.name = "svec",
.release = svec_release,
.uevent = svec_uevent,
.groups = svec_groups,
.name = "svec-fpga",
.release = svec_fpga_release,
.uevent = svec_fpga_uevent,
.groups = svec_fpga_groups,
};
int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
{
struct svec_fpga *svec_fpga;
struct resource *r = &svec_dev->vdev->resource[function_nr];
struct vme_dev *vdev = to_vme_dev(svec_dev->dev.parent);
struct resource *r = &vdev->resource[function_nr];
int err;
svec_fpga = kzalloc(sizeof(*svec_fpga), GFP_KERNEL);
......@@ -804,18 +805,18 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
goto err_valid;
}
svec_fpga->dev.parent = &svec_dev->vdev->dev;
svec_fpga->dev.driver = svec_dev->vdev->dev.driver;
svec_fpga->dev.parent = &svec_dev->dev;
svec_fpga->dev.driver = svec_dev->dev.driver;
svec_fpga->dev.type = &svec_fpga_type;
err = dev_set_name(&svec_fpga->dev, "svec-%s",
dev_name(&svec_dev->vdev->dev));
err = dev_set_name(&svec_fpga->dev, "%s-fpga",
dev_name(&svec_dev->dev));
if (err)
goto err_name;
err = device_register(&svec_fpga->dev);
if (err) {
dev_err(&svec_dev->vdev->dev, "Failed to register '%s'\n",
dev_name(&svec_dev->vdev->dev));
dev_err(&svec_dev->dev, "Failed to register '%s'\n",
dev_name(&svec_fpga->dev));
goto err_dev;
}
......@@ -823,25 +824,25 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
err = svec_fpga_vic_init(svec_fpga);
if (err) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Failed to initialize VIC %d\n", err);
goto err_vic;
}
err = svec_fpga_devices_init(svec_fpga);
if (err) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Failed to initialize Devices %d\n", err);
goto err_devs;
}
err = svec_fmc_init(svec_fpga);
if (err) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Failed to initialize FMC %d\n", err);
goto err_fmc;
}
err = svec_fpga_app_init(svec_fpga);
if (err) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Failed to initialize APP %d\n", err);
goto err_app;
}
......
......@@ -53,10 +53,10 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name)
{
int err;
dev_dbg(&svec_dev->vdev->dev, "Writing firmware '%s'\n", name);
dev_dbg(&svec_dev->dev, "Writing firmware '%s'\n", name);
err = svec_fpga_exit(svec_dev);
if (err) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance\n");
return err;
}
......@@ -84,7 +84,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
int err, ret;
if (VBRIDGE_DBG_FW_BUF_LEN < count) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Firmware name too long max %u\n",
VBRIDGE_DBG_FW_BUF_LEN);
......@@ -101,7 +101,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
err = svec_fw_load(svec_dev, buf_l);
if (err)
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"FPGA Configuration failure %d\n", err);
/*
......@@ -109,11 +109,11 @@ static ssize_t svec_dbg_fw_write(struct file *file,
* the SVEC device that we used to re-flash the FPGA disappeard and so
* this driver instance must disapear as well.
*/
dev_warn(&svec_dev->vdev->dev, "VME Slave removed\n");
dev_warn(&svec_dev->vdev->dev, "Remove this device driver instance\n");
ret = device_schedule_callback(&svec_dev->vdev->dev, remove_callback);
dev_warn(&svec_dev->dev, "VME Slave removed\n");
dev_warn(&svec_dev->dev, "Remove this device driver instance\n");
ret = device_schedule_callback(svec_dev->dev.parent, remove_callback);
if (ret) {
dev_err(&svec_dev->vdev->dev,
dev_err(&svec_dev->dev,
"Can't remove device driver instance %d\n", ret);
return ret;
}
......@@ -181,7 +181,7 @@ static const struct file_operations svec_dbg_meta_ops = {
static int svec_dbg_init(struct svec_dev *svec_dev)
{
struct device *dev = &svec_dev->vdev->dev;
struct device *dev = &svec_dev->dev;
svec_dev->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
if (IS_ERR_OR_NULL(svec_dev->dbg_dir)) {
......@@ -229,7 +229,8 @@ static void svec_dbg_exit(struct svec_dev *svec_dev)
static int svec_fpga_reset(struct fpga_manager *mgr)
{
struct svec_dev *svec = mgr->priv;
void *loader_addr = svec->vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
void *loader_addr = vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
int i;
for (i = 0; i < 8; i++) {
......@@ -252,7 +253,8 @@ static int svec_fpga_reset(struct fpga_manager *mgr)
static int svec_fpga_loader_is_active(struct fpga_manager *mgr)
{
struct svec_dev *svec = mgr->priv;
void *loader_addr = svec->vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
void *loader_addr = vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
char buf[5];
uint32_t idc;
......@@ -282,7 +284,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
unsigned int is_last)
{
struct svec_dev *svec = mgr->priv;
void *loader_addr = svec->vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
void *loader_addr = vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
uint32_t xldr_fifo_r0; /* Bitstream data input control register */
uint32_t xldr_fifo_r1; /* Bitstream data input register */
int rv, try = 10000;
......@@ -315,7 +318,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
static int svec_fpga_write_start(struct fpga_manager *mgr)
{
struct svec_dev *svec = mgr->priv;
void *loader_addr = svec->vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
void *loader_addr = vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
int err, succ;
/* reset the FPGA */
......@@ -355,7 +359,8 @@ static int svec_fpga_write_stop(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
struct svec_dev *svec = mgr->priv;
void *loader_addr = svec->vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
void *loader_addr = vdev->map_cr.kernel_va + SVEC_BASE_LOADER;
u64 timeout;
int rval = 0, err;
......@@ -500,7 +505,7 @@ static const struct fpga_manager_ops svec_fpga_ops = {
static int svec_vme_init(struct svec_dev *svec)
{
struct vme_dev *vdev = svec->vdev;
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
int err;
err = vme_disable_device(vdev);
......@@ -515,6 +520,35 @@ static int svec_vme_init(struct svec_dev *svec)
return vme_enable_device(vdev);
}
static int svec_vme_exit(struct svec_dev *svec)
{
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
int err;
err = vme_disable_device(vdev);
if (err)
return err;
svec_csr_write(0x0, vdev->map_cr.kernel_va,
SVEC_USER_CSR_INT_VECTOR);
return vme_enable_device(vdev);
}
static void svec_dev_release(struct device *dev)
{
}
static int svec_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
return 0;
}
static const struct device_type svec_type = {
.name = "svec",
.release = svec_dev_release,
.uevent = svec_dev_uevent,
};
/**
* It initialize a new SVEC instance
* @pdev correspondend Linux device instance
......@@ -534,15 +568,27 @@ static int svec_probe(struct device *dev, unsigned int ndev)
goto err;
}
dev_set_drvdata(dev, svec);
spin_lock_init(&svec->lock);
mutex_init(&svec->mtx);
svec->vdev = vdev;
dev_set_drvdata(dev, svec);
svec->dev.parent = &vdev->dev;
svec->dev.type = &svec_type;
svec->dev.driver = vdev->dev.driver;
err = dev_set_name(&svec->dev, "svec-%s",
dev_name(svec->dev.parent));
if (err)
goto err_name;
err = device_register(&svec->dev);
if (err) {
dev_err(dev, "Failed to register '%s'\n",
dev_name(&svec->dev));
goto err_dev;
}
svec_vme_init(svec);
svec->fpga_status = FPGA_MGR_STATE_UNKNOWN;
svec->mgr = fpga_mgr_create(dev, dev_name(dev),
svec->mgr = fpga_mgr_create(&svec->dev, dev_name(&svec->dev),
&svec_fpga_ops, svec);
if (!svec->mgr) {
err = -EPERM;
......@@ -565,6 +611,9 @@ static int svec_probe(struct device *dev, unsigned int ndev)
err_fpga_reg:
fpga_mgr_free(svec->mgr);
err_fpga_new:
device_unregister(&svec->dev);
err_dev:
err_name:
dev_set_drvdata(dev, NULL);
kfree(svec);
err:
......@@ -585,17 +634,20 @@ static int svec_remove(struct device *dev, unsigned int ndev)
svec_dbg_exit(svec);
fpga_mgr_unregister(svec->mgr);
fpga_mgr_free(svec->mgr);
dev_set_drvdata(dev, NULL);
svec_vme_exit(svec);
if ((svec->flags & SVEC_DEV_FLAGS_REPROGRAMMED) == 0) {
/*
* If FPGA is REPROGRAMMED then there is
* no device to disable
*/
vme_disable_device(svec->vdev);
vme_disable_device(to_vme_dev(svec->dev.parent));
}
device_unregister(&svec->dev);
kfree(svec);
dev_set_drvdata(dev, NULL);
return 0;
}
......
......@@ -126,7 +126,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev)
* @mem: ioremapped memory
*/
struct svec_dev {
struct vme_dev *vdev;
struct device dev;
char name[8];
unsigned long flags;
struct svec_meta_id meta;
......@@ -150,6 +150,11 @@ struct svec_dev {
struct svec_fpga *svec_fpga;
};
static inline struct svec_dev *to_svec_dev(struct device *_dev)
{
return container_of(_dev, struct svec_dev, dev);
}
extern int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr);
extern int svec_fpga_exit(struct svec_dev *svec_dev);
#endif /* __SVEC_H__ */
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