The FPGA (as a device) and the register map supplied by a FPGA are two different entities. There are U-Boot drivers for the former, but not for the later.
Add a uclass that makes it possible to read from and write to FPGA memory maps. The interface provided emulates the PCI interface, with one function for reading/writing plus a size parameter. Signed-off-by: Mario Six <mario....@gdsys.cc> --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/fpgamap/Kconfig | 9 +++ drivers/fpgamap/Makefile | 8 +++ drivers/fpgamap/fpgamap-uclass.c | 53 ++++++++++++++++ include/dm/uclass-id.h | 1 + include/fpgamap.h | 131 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 205 insertions(+) create mode 100644 drivers/fpgamap/Kconfig create mode 100644 drivers/fpgamap/Makefile create mode 100644 drivers/fpgamap/fpgamap-uclass.c create mode 100644 include/fpgamap.h diff --git a/drivers/Kconfig b/drivers/Kconfig index c2e813f5ad..29dac7b50e 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -32,6 +32,8 @@ source "drivers/firmware/Kconfig" source "drivers/fpga/Kconfig" +source "drivers/fpgamap/Kconfig" + source "drivers/gpio/Kconfig" source "drivers/i2c/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 6846d181aa..32f0527001 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_CPU) += cpu/ obj-y += crypto/ obj-y += firmware/ obj-$(CONFIG_FPGA) += fpga/ +obj-$(CONFIG_FPGAMAP) += fpgamap/ obj-y += misc/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_NVME) += nvme/ diff --git a/drivers/fpgamap/Kconfig b/drivers/fpgamap/Kconfig new file mode 100644 index 0000000000..b57d31e3f7 --- /dev/null +++ b/drivers/fpgamap/Kconfig @@ -0,0 +1,9 @@ +menuconfig FPGAMAP + bool "FPGA register map drivers" + help + Support drivers to operate on memory-mapped register maps of FPGAs. + Drivers are necessarily very device-dependant. + + Generic read/write operations with varying widths (8, 16, and 32 for + now), as well as read/write access to named registers (defined via + device tree entries) are supported diff --git a/drivers/fpgamap/Makefile b/drivers/fpgamap/Makefile new file mode 100644 index 0000000000..c32efba771 --- /dev/null +++ b/drivers/fpgamap/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2017 +# Mario Six, Guntermann & Drunck GmbH, mario....@gdsys.cc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_FPGAMAP) += fpgamap-uclass.o diff --git a/drivers/fpgamap/fpgamap-uclass.c b/drivers/fpgamap/fpgamap-uclass.c new file mode 100644 index 0000000000..8f39e22dad --- /dev/null +++ b/drivers/fpgamap/fpgamap-uclass.c @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario....@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fpgamap.h> + +int fpgamap_set_reg(struct udevice *dev, const char *compat, uint value) +{ + struct fpgamap_ops *ops = fpgamap_get_ops(dev); + + return ops->set_reg(dev, compat, value); +} + +int fpgamap_get_reg(struct udevice *dev, const char *compat, uint *value) +{ + struct fpgamap_ops *ops = fpgamap_get_ops(dev); + + return ops->get_reg(dev, compat, value); +} + +int fpgamap_read(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size) +{ + struct fpgamap_ops *ops = fpgamap_get_ops(dev); + + if (!ops->read) + return -ENOSYS; + + return ops->read(dev, address, data, size); +} + +int fpgamap_write(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size) +{ + struct fpgamap_ops *ops = fpgamap_get_ops(dev); + + if (!ops->write) + return -ENOSYS; + + return ops->write(dev, address, data, size); +} + +UCLASS_DRIVER(fpgamap) = { + .id = UCLASS_FPGAMAP, + .name = "fpgamap", + .post_bind = dm_scan_fdt_dev, + .flags = DM_UC_FLAG_SEQ_ALIAS, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 07fabc3ce6..8c47ae9d00 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -36,6 +36,7 @@ enum uclass_id { UCLASS_DMA, /* Direct Memory Access */ UCLASS_EFI, /* EFI managed devices */ UCLASS_ETH, /* Ethernet device */ + UCLASS_FPGAMAP, /* FPGA register maps */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ UCLASS_FIRMWARE, /* Firmware */ UCLASS_I2C, /* I2C bus */ diff --git a/include/fpgamap.h b/include/fpgamap.h new file mode 100644 index 0000000000..a04ac4d5ae --- /dev/null +++ b/include/fpgamap.h @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario....@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FPGAMAP_H_ +#define _FPGAMAP_H_ + +/* Access sizes for fpgamap reads and writes */ +enum fpgamap_size_t { + FPGAMAP_SIZE_8, + FPGAMAP_SIZE_16, + FPGAMAP_SIZE_32, +}; + +/** + * struct fpgamap_ops - driver operations for FPGA register map uclass. + * + * Drivers should support these operations unless otherwise noted. These + * operations are intended to be used by uclass code, not directly from + * other code. + */ +struct fpgamap_ops { + /** + * get_reg() - Read a single integer from a named register of a FPGA + * register map + * + * @dev: FPGA register map to read from. + * @compat: Compatible string of a named register of the FPGA map. + * @value: Pointer to a variable that takes the data value read + * from the register of the FPGA register map. + * @return 0 if OK, -ve on error. + */ + int (*get_reg)(struct udevice *dev, const char *compat, uint *value); + + /** + * set_reg() - Write a single integer to a named register of a FPGA + * register map + * + * @dev: FPGA register map to write to. + * @compat: Compatible string of a named register of the FPGA map. + * @value: Data value to be written to the register of the FPGA + * register map. + * @return 0 if OK, -ve on error. + */ + int (*set_reg)(struct udevice *dev, const char *compat, uint value); + + /** + * read() - Read a single value from a specified address on a FPGA + * register map + * + * @dev: FPGA register map to read from. + * @address: The address to read from. + * @data: Pointer to a variable that takes the data value read + * from the address on the FPGA register map. + * @return 0 if OK, -ve on error. + */ + int (*read)(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size); + + /** + * write() - Write a single value to a specified address on a FPGA + * register map + * + * @dev: FPGA register map to write to. + * @address: The address to write to. + * @data: Data value to be written to the address on the FPGA + * register map. + * @return 0 if OK, -ve on error. + */ + int (*write)(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size); + +}; + +#define fpgamap_get_ops(dev) ((struct fpgamap_ops *)(dev)->driver->ops) + +/** + * fpgamap_get_reg() - Read a single integer from a named register of a FPGA + * register map + * + * @dev: FPGA register map to read from. + * @compat: Compatible string of a named register of the FPGA map. + * @value: Pointer to a variable that takes the data value read + * from the register of the FPGA register map. + * @return 0 if OK, -ve on error. + */ +int fpgamap_get_reg(struct udevice *dev, const char *compat, uint *value); + +/** + * fpgamap_set_reg() - Write a single integer to a named register of a FPGA + * register map + * + * @dev: FPGA register map to write to. + * @compat: Compatible string of a named register of the FPGA map. + * @value: Data value to be written to the register of the FPGA + * register map. + * @return 0 if OK, -ve on error. + */ +int fpgamap_set_reg(struct udevice *dev, const char *compat, uint value); +/** + * fpgamap_read() - Read a single value from a specified address on a FPGA + * register map + * + * @dev: FPGA register map to read from. + * @address: The address to read from. + * @data: Pointer to a variable that takes the data value read from the + * address on the FPGA register map. + * @size: The size of the data to be read + * @return 0 if OK, -ve on error. + */ +int fpgamap_read(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size); + +/** + * fpgamap_write() - Write a single value to a specified address on a FPGA + * register map + * + * @dev: FPGA register map to write to. + * @address: The address to write to. + * @data: Data value to be written to the address on the FPGA register + * map. + * @size: The size of the data to be written + * @return 0 if OK, -ve on error. + */ +int fpgamap_write(struct udevice *dev, ulong address, void *data, + enum fpgamap_size_t size); + +#endif -- 2.16.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot