FPGA Manager Changes for 5.15-rc1
FPGA Manager - Navin's change removes a duplicate word in a comment - Tom's change fixes a spelling mistake - Mauro's change fixes up documentation - Tom's second set adds wrappers to allow drivers not having to implement empty functions by moving checks into fpga-mgr core code - My changes address a bunch of warnings DFL - Martin's change adds a new PCI ID for Silicom N501x PAC cards All patches have been reviewed on the mailing list, and have been in the last linux-next releases (as part of my for-next branch). I did get a complaint about one of the commit messages w/ a Fixes: tags which has been addressed. Signed-offy-by: Moritz Fischer <mdf@kernel.org> -----BEGIN PGP SIGNATURE----- iIUEABYIAC0WIQSdhnt2PwibB65UG0C3mJX/Vsn7uQUCYPyT4g8cbWRmQGtlcm5l bC5vcmcACgkQt5iV/1bJ+7mV9AD9EczMsxBVFXM0VH1T7nvMNLuWo2+ygbVyin4J 8JBJbJgBAL2koRK8VJNVRS8QsMSxNF2rsdRNGSoeAuHgHfqgtLEH =zcmE -----END PGP SIGNATURE----- Merge tag 'fpga-for-5.15-early' of git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga into char-misc-next Moritz writes: FPGA Manager Changes for 5.15-rc1 FPGA Manager - Navin's change removes a duplicate word in a comment - Tom's change fixes a spelling mistake - Mauro's change fixes up documentation - Tom's second set adds wrappers to allow drivers not having to implement empty functions by moving checks into fpga-mgr core code - My changes address a bunch of warnings DFL - Martin's change adds a new PCI ID for Silicom N501x PAC cards All patches have been reviewed on the mailing list, and have been in the last linux-next releases (as part of my for-next branch). I did get a complaint about one of the commit messages w/ a Fixes: tags which has been addressed. Signed-offy-by: Moritz Fischer <mdf@kernel.org> * tag 'fpga-for-5.15-early' of git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga: fpga: fpga-mgr: wrap the write_sg() op fpga: fpga-mgr: wrap the fpga_remove() op fpga: fpga-mgr: wrap the state() op fpga: fpga-mgr: wrap the status() op fpga: fpga-mgr: wrap the write() op fpga: fpga-mgr: make write_complete() op optional fpga: fpga-mgr: wrap the write_init() op fpga: zynqmp-fpga: Address warning about unused variable fpga: xilinx-pr-decoupler: Address warning about unused variable fpga: xiilnx-spi: Address warning about unused variable fpga: altera-freeze-bridge: Address warning about unused variable fpga: dfl: pci: add device IDs for Silicom N501x PAC cards fpga: fpga-bridge: removed repeated word fpga: fix spelling mistakes docs: driver-api: fpga: avoid using UTF-8 chars
This commit is contained in:
commit
c3328c5e64
|
@ -4,11 +4,11 @@ FPGA Bridge
|
||||||
API to implement a new FPGA bridge
|
API to implement a new FPGA bridge
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* struct fpga_bridge — The FPGA Bridge structure
|
* struct fpga_bridge - The FPGA Bridge structure
|
||||||
* struct fpga_bridge_ops — Low level Bridge driver ops
|
* struct fpga_bridge_ops - Low level Bridge driver ops
|
||||||
* devm_fpga_bridge_create() — Allocate and init a bridge struct
|
* devm_fpga_bridge_create() - Allocate and init a bridge struct
|
||||||
* fpga_bridge_register() — Register a bridge
|
* fpga_bridge_register() - Register a bridge
|
||||||
* fpga_bridge_unregister() — Unregister a bridge
|
* fpga_bridge_unregister() - Unregister a bridge
|
||||||
|
|
||||||
.. kernel-doc:: include/linux/fpga/fpga-bridge.h
|
.. kernel-doc:: include/linux/fpga/fpga-bridge.h
|
||||||
:functions: fpga_bridge
|
:functions: fpga_bridge
|
||||||
|
|
|
@ -101,12 +101,12 @@ in state.
|
||||||
API for implementing a new FPGA Manager driver
|
API for implementing a new FPGA Manager driver
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
* ``fpga_mgr_states`` — Values for :c:expr:`fpga_manager->state`.
|
* ``fpga_mgr_states`` - Values for :c:expr:`fpga_manager->state`.
|
||||||
* struct fpga_manager — the FPGA manager struct
|
* struct fpga_manager - the FPGA manager struct
|
||||||
* struct fpga_manager_ops — Low level FPGA manager driver ops
|
* struct fpga_manager_ops - Low level FPGA manager driver ops
|
||||||
* devm_fpga_mgr_create() — Allocate and init a manager struct
|
* devm_fpga_mgr_create() - Allocate and init a manager struct
|
||||||
* fpga_mgr_register() — Register an FPGA manager
|
* fpga_mgr_register() - Register an FPGA manager
|
||||||
* fpga_mgr_unregister() — Unregister an FPGA manager
|
* fpga_mgr_unregister() - Unregister an FPGA manager
|
||||||
|
|
||||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||||
:functions: fpga_mgr_states
|
:functions: fpga_mgr_states
|
||||||
|
|
|
@ -84,10 +84,10 @@ will generate that list. Here's some sample code of what to do next::
|
||||||
API for programming an FPGA
|
API for programming an FPGA
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
* fpga_region_program_fpga() — Program an FPGA
|
* fpga_region_program_fpga() - Program an FPGA
|
||||||
* fpga_image_info() — Specifies what FPGA image to program
|
* fpga_image_info() - Specifies what FPGA image to program
|
||||||
* fpga_image_info_alloc() — Allocate an FPGA image info struct
|
* fpga_image_info_alloc() - Allocate an FPGA image info struct
|
||||||
* fpga_image_info_free() — Free an FPGA image info struct
|
* fpga_image_info_free() - Free an FPGA image info struct
|
||||||
|
|
||||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||||
:functions: fpga_region_program_fpga
|
:functions: fpga_region_program_fpga
|
||||||
|
|
|
@ -45,19 +45,19 @@ An example of usage can be seen in the probe function of [#f2]_.
|
||||||
API to add a new FPGA region
|
API to add a new FPGA region
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
* struct fpga_region — The FPGA region struct
|
* struct fpga_region - The FPGA region struct
|
||||||
* devm_fpga_region_create() — Allocate and init a region struct
|
* devm_fpga_region_create() - Allocate and init a region struct
|
||||||
* fpga_region_register() — Register an FPGA region
|
* fpga_region_register() - Register an FPGA region
|
||||||
* fpga_region_unregister() — Unregister an FPGA region
|
* fpga_region_unregister() - Unregister an FPGA region
|
||||||
|
|
||||||
The FPGA region's probe function will need to get a reference to the FPGA
|
The FPGA region's probe function will need to get a reference to the FPGA
|
||||||
Manager it will be using to do the programming. This usually would happen
|
Manager it will be using to do the programming. This usually would happen
|
||||||
during the region's probe function.
|
during the region's probe function.
|
||||||
|
|
||||||
* fpga_mgr_get() — Get a reference to an FPGA manager, raise ref count
|
* fpga_mgr_get() - Get a reference to an FPGA manager, raise ref count
|
||||||
* of_fpga_mgr_get() — Get a reference to an FPGA manager, raise ref count,
|
* of_fpga_mgr_get() - Get a reference to an FPGA manager, raise ref count,
|
||||||
given a device node.
|
given a device node.
|
||||||
* fpga_mgr_put() — Put an FPGA manager
|
* fpga_mgr_put() - Put an FPGA manager
|
||||||
|
|
||||||
The FPGA region will need to specify which bridges to control while programming
|
The FPGA region will need to specify which bridges to control while programming
|
||||||
the FPGA. The region driver can build a list of bridges during probe time
|
the FPGA. The region driver can build a list of bridges during probe time
|
||||||
|
@ -66,11 +66,11 @@ the list of bridges to program just before programming
|
||||||
(:c:expr:`fpga_region->get_bridges`). The FPGA bridge framework supplies the
|
(:c:expr:`fpga_region->get_bridges`). The FPGA bridge framework supplies the
|
||||||
following APIs to handle building or tearing down that list.
|
following APIs to handle building or tearing down that list.
|
||||||
|
|
||||||
* fpga_bridge_get_to_list() — Get a ref of an FPGA bridge, add it to a
|
* fpga_bridge_get_to_list() - Get a ref of an FPGA bridge, add it to a
|
||||||
list
|
list
|
||||||
* of_fpga_bridge_get_to_list() — Get a ref of an FPGA bridge, add it to a
|
* of_fpga_bridge_get_to_list() - Get a ref of an FPGA bridge, add it to a
|
||||||
list, given a device node
|
list, given a device node
|
||||||
* fpga_bridges_put() — Given a list of bridges, put them
|
* fpga_bridges_put() - Given a list of bridges, put them
|
||||||
|
|
||||||
.. kernel-doc:: include/linux/fpga/fpga-region.h
|
.. kernel-doc:: include/linux/fpga/fpga-region.h
|
||||||
:functions: fpga_region
|
:functions: fpga_region
|
||||||
|
|
|
@ -10,7 +10,7 @@ Authors:
|
||||||
- Xu Yilun <yilun.xu@intel.com>
|
- Xu Yilun <yilun.xu@intel.com>
|
||||||
|
|
||||||
The Device Feature List (DFL) FPGA framework (and drivers according to
|
The Device Feature List (DFL) FPGA framework (and drivers according to
|
||||||
this framework) hides the very details of low layer hardwares and provides
|
this framework) hides the very details of low layer hardware and provides
|
||||||
unified interfaces to userspace. Applications could use these interfaces to
|
unified interfaces to userspace. Applications could use these interfaces to
|
||||||
configure, enumerate, open and access FPGA accelerators on platforms which
|
configure, enumerate, open and access FPGA accelerators on platforms which
|
||||||
implement the DFL in the device memory. Besides this, the DFL framework
|
implement the DFL in the device memory. Besides this, the DFL framework
|
||||||
|
@ -205,7 +205,7 @@ given Device Feature Lists and create platform devices for feature devices
|
||||||
also abstracts operations for the private features and exposes common ops to
|
also abstracts operations for the private features and exposes common ops to
|
||||||
feature device drivers.
|
feature device drivers.
|
||||||
|
|
||||||
The FPGA DFL Device could be different hardwares, e.g. PCIe device, platform
|
The FPGA DFL Device could be different hardware, e.g. PCIe device, platform
|
||||||
device and etc. Its driver module is always loaded first once the device is
|
device and etc. Its driver module is always loaded first once the device is
|
||||||
created by the system. This driver plays an infrastructural role in the
|
created by the system. This driver plays an infrastructural role in the
|
||||||
driver architecture. It locates the DFLs in the device memory, handles them
|
driver architecture. It locates the DFLs in the device memory, handles them
|
||||||
|
|
|
@ -346,7 +346,7 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val & VSE_CVP_STATUS_CFG_RDY) {
|
if (val & VSE_CVP_STATUS_CFG_RDY) {
|
||||||
dev_warn(&mgr->dev, "CvP already started, teardown first\n");
|
dev_warn(&mgr->dev, "CvP already started, tear down first\n");
|
||||||
ret = altera_cvp_teardown(mgr, info);
|
ret = altera_cvp_teardown(mgr, info);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -198,11 +198,13 @@ static const struct fpga_bridge_ops altera_freeze_br_br_ops = {
|
||||||
.enable_show = altera_freeze_br_enable_show,
|
.enable_show = altera_freeze_br_enable_show,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
static const struct of_device_id altera_freeze_br_of_match[] = {
|
static const struct of_device_id altera_freeze_br_of_match[] = {
|
||||||
{ .compatible = "altr,freeze-bridge-controller", },
|
{ .compatible = "altr,freeze-bridge-controller", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, altera_freeze_br_of_match);
|
MODULE_DEVICE_TABLE(of, altera_freeze_br_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static int altera_freeze_br_probe(struct platform_device *pdev)
|
static int altera_freeze_br_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -252,11 +252,6 @@ static int fme_mgr_write_complete(struct fpga_manager *mgr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fpga_mgr_states fme_mgr_state(struct fpga_manager *mgr)
|
|
||||||
{
|
|
||||||
return FPGA_MGR_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 fme_mgr_status(struct fpga_manager *mgr)
|
static u64 fme_mgr_status(struct fpga_manager *mgr)
|
||||||
{
|
{
|
||||||
struct fme_mgr_priv *priv = mgr->priv;
|
struct fme_mgr_priv *priv = mgr->priv;
|
||||||
|
@ -268,7 +263,6 @@ static const struct fpga_manager_ops fme_mgr_ops = {
|
||||||
.write_init = fme_mgr_write_init,
|
.write_init = fme_mgr_write_init,
|
||||||
.write = fme_mgr_write,
|
.write = fme_mgr_write,
|
||||||
.write_complete = fme_mgr_write_complete,
|
.write_complete = fme_mgr_write_complete,
|
||||||
.state = fme_mgr_state,
|
|
||||||
.status = fme_mgr_status,
|
.status = fme_mgr_status,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ static int fme_pr(struct platform_device *pdev, unsigned long arg)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* it allows userspace to reset the PR region's logic by disabling and
|
* it allows userspace to reset the PR region's logic by disabling and
|
||||||
* reenabling the bridge to clear things out between accleration runs.
|
* reenabling the bridge to clear things out between acceleration runs.
|
||||||
* so no need to hold the bridges after partial reconfiguration.
|
* so no need to hold the bridges after partial reconfiguration.
|
||||||
*/
|
*/
|
||||||
if (region->get_bridges)
|
if (region->get_bridges)
|
||||||
|
|
|
@ -461,7 +461,7 @@ static int n3000_nios_poll_stat_timeout(void __iomem *base, u64 *v)
|
||||||
* We don't use the time based timeout here for performance.
|
* We don't use the time based timeout here for performance.
|
||||||
*
|
*
|
||||||
* The regbus read/write is on the critical path of Intel PAC N3000
|
* The regbus read/write is on the critical path of Intel PAC N3000
|
||||||
* image programing. The time based timeout checking will add too much
|
* image programming. The time based timeout checking will add too much
|
||||||
* overhead on it. Usually the state changes in 1 or 2 loops on the
|
* overhead on it. Usually the state changes in 1 or 2 loops on the
|
||||||
* test server, and we set 10000 times loop here for safety.
|
* test server, and we set 10000 times loop here for safety.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -74,6 +74,9 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
|
||||||
#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
|
#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
|
||||||
#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
|
#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
|
||||||
#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
|
#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
|
||||||
|
#define PCIE_DEVICE_ID_SILICOM_PAC_N5010 0x1000
|
||||||
|
#define PCIE_DEVICE_ID_SILICOM_PAC_N5011 0x1001
|
||||||
|
|
||||||
/* VF Device */
|
/* VF Device */
|
||||||
#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
|
#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
|
||||||
#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
|
#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
|
||||||
|
@ -90,6 +93,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
|
||||||
{0,}
|
{0,}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
|
MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
|
||||||
|
|
|
@ -232,7 +232,7 @@ struct dfl_feature_irq_ctx {
|
||||||
* @id: sub feature id.
|
* @id: sub feature id.
|
||||||
* @resource_index: each sub feature has one mmio resource for its registers.
|
* @resource_index: each sub feature has one mmio resource for its registers.
|
||||||
* this index is used to find its mmio resource from the
|
* this index is used to find its mmio resource from the
|
||||||
* feature dev (platform device)'s reources.
|
* feature dev (platform device)'s resources.
|
||||||
* @ioaddr: mapped mmio resource address.
|
* @ioaddr: mapped mmio resource address.
|
||||||
* @irq_ctx: interrupt context list.
|
* @irq_ctx: interrupt context list.
|
||||||
* @nr_irqs: number of interrupt contexts.
|
* @nr_irqs: number of interrupt contexts.
|
||||||
|
|
|
@ -228,9 +228,9 @@ EXPORT_SYMBOL_GPL(fpga_bridges_put);
|
||||||
* @info: fpga image specific information
|
* @info: fpga image specific information
|
||||||
* @bridge_list: list of FPGA bridges
|
* @bridge_list: list of FPGA bridges
|
||||||
*
|
*
|
||||||
* Get an exclusive reference to the bridge and and it to the list.
|
* Get an exclusive reference to the bridge and it to the list.
|
||||||
*
|
*
|
||||||
* Return 0 for success, error code from of_fpga_bridge_get() othewise.
|
* Return 0 for success, error code from of_fpga_bridge_get() otherwise.
|
||||||
*/
|
*/
|
||||||
int of_fpga_bridge_get_to_list(struct device_node *np,
|
int of_fpga_bridge_get_to_list(struct device_node *np,
|
||||||
struct fpga_image_info *info,
|
struct fpga_image_info *info,
|
||||||
|
@ -258,9 +258,9 @@ EXPORT_SYMBOL_GPL(of_fpga_bridge_get_to_list);
|
||||||
* @info: fpga image specific information
|
* @info: fpga image specific information
|
||||||
* @bridge_list: list of FPGA bridges
|
* @bridge_list: list of FPGA bridges
|
||||||
*
|
*
|
||||||
* Get an exclusive reference to the bridge and and it to the list.
|
* Get an exclusive reference to the bridge and it to the list.
|
||||||
*
|
*
|
||||||
* Return 0 for success, error code from fpga_bridge_get() othewise.
|
* Return 0 for success, error code from fpga_bridge_get() otherwise.
|
||||||
*/
|
*/
|
||||||
int fpga_bridge_get_to_list(struct device *dev,
|
int fpga_bridge_get_to_list(struct device *dev,
|
||||||
struct fpga_image_info *info,
|
struct fpga_image_info *info,
|
||||||
|
|
|
@ -25,6 +25,72 @@ struct fpga_mgr_devres {
|
||||||
struct fpga_manager *mgr;
|
struct fpga_manager *mgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void fpga_mgr_fpga_remove(struct fpga_manager *mgr)
|
||||||
|
{
|
||||||
|
if (mgr->mops->fpga_remove)
|
||||||
|
mgr->mops->fpga_remove(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum fpga_mgr_states fpga_mgr_state(struct fpga_manager *mgr)
|
||||||
|
{
|
||||||
|
if (mgr->mops->state)
|
||||||
|
return mgr->mops->state(mgr);
|
||||||
|
return FPGA_MGR_STATE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 fpga_mgr_status(struct fpga_manager *mgr)
|
||||||
|
{
|
||||||
|
if (mgr->mops->status)
|
||||||
|
return mgr->mops->status(mgr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int fpga_mgr_write(struct fpga_manager *mgr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
if (mgr->mops->write)
|
||||||
|
return mgr->mops->write(mgr, buf, count);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After all the FPGA image has been written, do the device specific steps to
|
||||||
|
* finish and set the FPGA into operating mode.
|
||||||
|
*/
|
||||||
|
static inline int fpga_mgr_write_complete(struct fpga_manager *mgr,
|
||||||
|
struct fpga_image_info *info)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
|
||||||
|
if (mgr->mops->write_complete)
|
||||||
|
ret = mgr->mops->write_complete(mgr, info);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&mgr->dev, "Error after writing image data to FPGA\n");
|
||||||
|
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mgr->state = FPGA_MGR_STATE_OPERATING;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int fpga_mgr_write_init(struct fpga_manager *mgr,
|
||||||
|
struct fpga_image_info *info,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
if (mgr->mops->write_init)
|
||||||
|
return mgr->mops->write_init(mgr, info, buf, count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int fpga_mgr_write_sg(struct fpga_manager *mgr,
|
||||||
|
struct sg_table *sgt)
|
||||||
|
{
|
||||||
|
if (mgr->mops->write_sg)
|
||||||
|
return mgr->mops->write_sg(mgr, sgt);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpga_image_info_alloc - Allocate an FPGA image info struct
|
* fpga_image_info_alloc - Allocate an FPGA image info struct
|
||||||
* @dev: owning device
|
* @dev: owning device
|
||||||
|
@ -83,9 +149,9 @@ static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
|
||||||
|
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE_INIT;
|
mgr->state = FPGA_MGR_STATE_WRITE_INIT;
|
||||||
if (!mgr->mops->initial_header_size)
|
if (!mgr->mops->initial_header_size)
|
||||||
ret = mgr->mops->write_init(mgr, info, NULL, 0);
|
ret = fpga_mgr_write_init(mgr, info, NULL, 0);
|
||||||
else
|
else
|
||||||
ret = mgr->mops->write_init(
|
ret = fpga_mgr_write_init(
|
||||||
mgr, info, buf, min(mgr->mops->initial_header_size, count));
|
mgr, info, buf, min(mgr->mops->initial_header_size, count));
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -137,27 +203,6 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* After all the FPGA image has been written, do the device specific steps to
|
|
||||||
* finish and set the FPGA into operating mode.
|
|
||||||
*/
|
|
||||||
static int fpga_mgr_write_complete(struct fpga_manager *mgr,
|
|
||||||
struct fpga_image_info *info)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
|
|
||||||
ret = mgr->mops->write_complete(mgr, info);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(&mgr->dev, "Error after writing image data to FPGA\n");
|
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
mgr->state = FPGA_MGR_STATE_OPERATING;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list
|
* fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list
|
||||||
* @mgr: fpga manager
|
* @mgr: fpga manager
|
||||||
|
@ -188,13 +233,13 @@ static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
|
||||||
/* Write the FPGA image to the FPGA. */
|
/* Write the FPGA image to the FPGA. */
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE;
|
mgr->state = FPGA_MGR_STATE_WRITE;
|
||||||
if (mgr->mops->write_sg) {
|
if (mgr->mops->write_sg) {
|
||||||
ret = mgr->mops->write_sg(mgr, sgt);
|
ret = fpga_mgr_write_sg(mgr, sgt);
|
||||||
} else {
|
} else {
|
||||||
struct sg_mapping_iter miter;
|
struct sg_mapping_iter miter;
|
||||||
|
|
||||||
sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
|
sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
|
||||||
while (sg_miter_next(&miter)) {
|
while (sg_miter_next(&miter)) {
|
||||||
ret = mgr->mops->write(mgr, miter.addr, miter.length);
|
ret = fpga_mgr_write(mgr, miter.addr, miter.length);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +269,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
|
||||||
* Write the FPGA image to the FPGA.
|
* Write the FPGA image to the FPGA.
|
||||||
*/
|
*/
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE;
|
mgr->state = FPGA_MGR_STATE_WRITE;
|
||||||
ret = mgr->mops->write(mgr, buf, count);
|
ret = fpga_mgr_write(mgr, buf, count);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
|
dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
|
||||||
mgr->state = FPGA_MGR_STATE_WRITE_ERR;
|
mgr->state = FPGA_MGR_STATE_WRITE_ERR;
|
||||||
|
@ -417,10 +462,7 @@ static ssize_t status_show(struct device *dev,
|
||||||
u64 status;
|
u64 status;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (!mgr->mops->status)
|
status = fpga_mgr_status(mgr);
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
status = mgr->mops->status(mgr);
|
|
||||||
|
|
||||||
if (status & FPGA_MGR_STATUS_OPERATION_ERR)
|
if (status & FPGA_MGR_STATUS_OPERATION_ERR)
|
||||||
len += sprintf(buf + len, "reconfig operation error\n");
|
len += sprintf(buf + len, "reconfig operation error\n");
|
||||||
|
@ -568,9 +610,7 @@ struct fpga_manager *fpga_mgr_create(struct device *parent, const char *name,
|
||||||
struct fpga_manager *mgr;
|
struct fpga_manager *mgr;
|
||||||
int id, ret;
|
int id, ret;
|
||||||
|
|
||||||
if (!mops || !mops->write_complete || !mops->state ||
|
if (!mops) {
|
||||||
!mops->write_init || (!mops->write && !mops->write_sg) ||
|
|
||||||
(mops->write && mops->write_sg)) {
|
|
||||||
dev_err(parent, "Attempt to register without fpga_manager_ops\n");
|
dev_err(parent, "Attempt to register without fpga_manager_ops\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -688,7 +728,7 @@ int fpga_mgr_register(struct fpga_manager *mgr)
|
||||||
* from device. FPGA may be in reset mode or may have been programmed
|
* from device. FPGA may be in reset mode or may have been programmed
|
||||||
* by bootloader or EEPROM.
|
* by bootloader or EEPROM.
|
||||||
*/
|
*/
|
||||||
mgr->state = mgr->mops->state(mgr);
|
mgr->state = fpga_mgr_state(mgr);
|
||||||
|
|
||||||
ret = device_add(&mgr->dev);
|
ret = device_add(&mgr->dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -719,8 +759,7 @@ void fpga_mgr_unregister(struct fpga_manager *mgr)
|
||||||
* If the low level driver provides a method for putting fpga into
|
* If the low level driver provides a method for putting fpga into
|
||||||
* a desired state upon unregister, do it.
|
* a desired state upon unregister, do it.
|
||||||
*/
|
*/
|
||||||
if (mgr->mops->fpga_remove)
|
fpga_mgr_fpga_remove(mgr);
|
||||||
mgr->mops->fpga_remove(mgr);
|
|
||||||
|
|
||||||
device_unregister(&mgr->dev);
|
device_unregister(&mgr->dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,13 +388,7 @@ static int s10_ops_write_complete(struct fpga_manager *mgr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fpga_mgr_states s10_ops_state(struct fpga_manager *mgr)
|
|
||||||
{
|
|
||||||
return FPGA_MGR_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct fpga_manager_ops s10_ops = {
|
static const struct fpga_manager_ops s10_ops = {
|
||||||
.state = s10_ops_state,
|
|
||||||
.write_init = s10_ops_write_init,
|
.write_init = s10_ops_write_init,
|
||||||
.write = s10_ops_write,
|
.write = s10_ops_write,
|
||||||
.write_complete = s10_ops_write_complete,
|
.write_complete = s10_ops_write_complete,
|
||||||
|
|
|
@ -32,11 +32,6 @@ struct ts73xx_fpga_priv {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum fpga_mgr_states ts73xx_fpga_state(struct fpga_manager *mgr)
|
|
||||||
{
|
|
||||||
return FPGA_MGR_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ts73xx_fpga_write_init(struct fpga_manager *mgr,
|
static int ts73xx_fpga_write_init(struct fpga_manager *mgr,
|
||||||
struct fpga_image_info *info,
|
struct fpga_image_info *info,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
|
@ -98,7 +93,6 @@ static int ts73xx_fpga_write_complete(struct fpga_manager *mgr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct fpga_manager_ops ts73xx_fpga_ops = {
|
static const struct fpga_manager_ops ts73xx_fpga_ops = {
|
||||||
.state = ts73xx_fpga_state,
|
|
||||||
.write_init = ts73xx_fpga_write_init,
|
.write_init = ts73xx_fpga_write_init,
|
||||||
.write = ts73xx_fpga_write,
|
.write = ts73xx_fpga_write,
|
||||||
.write_complete = ts73xx_fpga_write_complete,
|
.write_complete = ts73xx_fpga_write_complete,
|
||||||
|
|
|
@ -81,6 +81,7 @@ static const struct fpga_bridge_ops xlnx_pr_decoupler_br_ops = {
|
||||||
.enable_show = xlnx_pr_decoupler_enable_show,
|
.enable_show = xlnx_pr_decoupler_enable_show,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
static const struct xlnx_config_data decoupler_config = {
|
static const struct xlnx_config_data decoupler_config = {
|
||||||
.name = "Xilinx PR Decoupler",
|
.name = "Xilinx PR Decoupler",
|
||||||
};
|
};
|
||||||
|
@ -99,6 +100,7 @@ static const struct of_device_id xlnx_pr_decoupler_of_match[] = {
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
|
MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
|
static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -256,11 +256,13 @@ static int xilinx_spi_probe(struct spi_device *spi)
|
||||||
return devm_fpga_mgr_register(&spi->dev, mgr);
|
return devm_fpga_mgr_register(&spi->dev, mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
static const struct of_device_id xlnx_spi_of_match[] = {
|
static const struct of_device_id xlnx_spi_of_match[] = {
|
||||||
{ .compatible = "xlnx,fpga-slave-serial", },
|
{ .compatible = "xlnx,fpga-slave-serial", },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
|
MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct spi_driver xilinx_slave_spi_driver = {
|
static struct spi_driver xilinx_slave_spi_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -192,7 +192,7 @@ static void zynq_step_dma(struct zynq_fpga_priv *priv)
|
||||||
|
|
||||||
/* Once the first transfer is queued we can turn on the ISR, future
|
/* Once the first transfer is queued we can turn on the ISR, future
|
||||||
* calls to zynq_step_dma will happen from the ISR context. The
|
* calls to zynq_step_dma will happen from the ISR context. The
|
||||||
* dma_lock spinlock guarentees this handover is done coherently, the
|
* dma_lock spinlock guarantees this handover is done coherently, the
|
||||||
* ISR enable is put at the end to avoid another CPU spinning in the
|
* ISR enable is put at the end to avoid another CPU spinning in the
|
||||||
* ISR on this lock.
|
* ISR on this lock.
|
||||||
*/
|
*/
|
||||||
|
@ -267,7 +267,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||||
ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
|
ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
|
||||||
if (!(ctrl & CTRL_SEC_EN_MASK)) {
|
if (!(ctrl & CTRL_SEC_EN_MASK)) {
|
||||||
dev_err(&mgr->dev,
|
dev_err(&mgr->dev,
|
||||||
"System not secure, can't use crypted bitstreams\n");
|
"System not secure, can't use encrypted bitstreams\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||||
|
|
||||||
/* set configuration register with following options:
|
/* set configuration register with following options:
|
||||||
* - enable PCAP interface
|
* - enable PCAP interface
|
||||||
* - set throughput for maximum speed (if bistream not crypted)
|
* - set throughput for maximum speed (if bistream not encrypted)
|
||||||
* - set CPU in user mode
|
* - set CPU in user mode
|
||||||
*/
|
*/
|
||||||
ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
|
ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
|
||||||
|
|
|
@ -66,12 +66,6 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zynqmp_fpga_ops_write_complete(struct fpga_manager *mgr,
|
|
||||||
struct fpga_image_info *info)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
|
static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
|
||||||
{
|
{
|
||||||
u32 status = 0;
|
u32 status = 0;
|
||||||
|
@ -87,7 +81,6 @@ static const struct fpga_manager_ops zynqmp_fpga_ops = {
|
||||||
.state = zynqmp_fpga_ops_state,
|
.state = zynqmp_fpga_ops_state,
|
||||||
.write_init = zynqmp_fpga_ops_write_init,
|
.write_init = zynqmp_fpga_ops_write_init,
|
||||||
.write = zynqmp_fpga_ops_write,
|
.write = zynqmp_fpga_ops_write,
|
||||||
.write_complete = zynqmp_fpga_ops_write_complete,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int zynqmp_fpga_probe(struct platform_device *pdev)
|
static int zynqmp_fpga_probe(struct platform_device *pdev)
|
||||||
|
@ -110,12 +103,13 @@ static int zynqmp_fpga_probe(struct platform_device *pdev)
|
||||||
return devm_fpga_mgr_register(dev, mgr);
|
return devm_fpga_mgr_register(dev, mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
static const struct of_device_id zynqmp_fpga_of_match[] = {
|
static const struct of_device_id zynqmp_fpga_of_match[] = {
|
||||||
{ .compatible = "xlnx,zynqmp-pcap-fpga", },
|
{ .compatible = "xlnx,zynqmp-pcap-fpga", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(of, zynqmp_fpga_of_match);
|
MODULE_DEVICE_TABLE(of, zynqmp_fpga_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver zynqmp_fpga_driver = {
|
static struct platform_driver zynqmp_fpga_driver = {
|
||||||
.probe = zynqmp_fpga_probe,
|
.probe = zynqmp_fpga_probe,
|
||||||
|
|
|
@ -110,7 +110,7 @@ struct fpga_image_info {
|
||||||
* @initial_header_size: Maximum number of bytes that should be passed into write_init
|
* @initial_header_size: Maximum number of bytes that should be passed into write_init
|
||||||
* @state: returns an enum value of the FPGA's state
|
* @state: returns an enum value of the FPGA's state
|
||||||
* @status: returns status of the FPGA, including reconfiguration error code
|
* @status: returns status of the FPGA, including reconfiguration error code
|
||||||
* @write_init: prepare the FPGA to receive confuration data
|
* @write_init: prepare the FPGA to receive configuration data
|
||||||
* @write: write count bytes of configuration data to the FPGA
|
* @write: write count bytes of configuration data to the FPGA
|
||||||
* @write_sg: write the scatter list of configuration data to the FPGA
|
* @write_sg: write the scatter list of configuration data to the FPGA
|
||||||
* @write_complete: set FPGA to operating state after writing is done
|
* @write_complete: set FPGA to operating state after writing is done
|
||||||
|
|
Loading…
Reference in New Issue