FPGA Manager changes for 7.4-rc1

- Uwe drops unnecessary header file for fpga-dfl driver
 - Heiko corrects GPIO controls for xilinx driver
 - Hemanth fixes a comment typo in altera driver
 - Karl fixes a code comment in fpga manager core
 - Nazim introduces a graceful error handling for altera driver
 
 All patches have been reviewed on the mailing list, and have been in the
 last linux-next releases (as part of our for-next branch).
 
 Signed-off-by: Xu Yilun <yilun.xu@intel.com>
 -----BEGIN PGP SIGNATURE-----
 
 iIkEABYIADEWIQSgSJpClIeaArXyudb8twOBpKCM2gUCasdVSxMceWlsdW4ueHVA
 aW50ZWwuY29tAAoJEPy3A4GkoIzaYiEBAJJsmiGv8B7M0tM4IVsTx/HrkU5FTMeu
 q19OB/wzl66RAQDAoCUUZ3zNJBDuGsKK72kMl+gjiXZcvL38U2lKG/zDBA==
 =aY/S
 -----END PGP SIGNATURE-----

Merge tag 'fpga-for-7.4-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga into char-misc-next

Xu writes:

FPGA Manager changes for 7.4-rc1

- Uwe drops unnecessary header file for fpga-dfl driver
- Heiko corrects GPIO controls for xilinx driver
- Hemanth fixes a comment typo in altera driver
- Karl fixes a code comment in fpga manager core
- Nazim introduces a graceful error handling for altera driver

All patches have been reviewed on the mailing list, and have been in the
last linux-next releases (as part of our for-next branch).

Signed-off-by: Xu Yilun <yilun.xu@intel.com>

* tag 'fpga-for-7.4-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga:
  fpga: altera-cvp: Retry teardown and reset CVP state on failure
  fpga: altera-cvp: Add helper to disable CvP mode
  fpga: Fix of_fpga_mgr_get() reference in fpga_mgr_lock() docs
  fpga: fix typo in s10_ops_write() comment
  fpga: xilinx-selectmap: control CSI_B and RDWR_B during configuration
  fpga: dfl: Drop #include for <linux/mod_devicetable.h>
This commit is contained in:
Greg Kroah-Hartman 2026-10-09 16:24:13 +02:00
commit 4bfc44cd14
5 changed files with 68 additions and 19 deletions

View File

@ -280,6 +280,16 @@ static int altera_cvp_send_block(struct altera_cvp_conf *conf,
return 0;
}
static void altera_cvp_disable_cvp_mode(struct altera_cvp_conf *conf)
{
u32 val;
altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
}
static int altera_cvp_teardown(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
@ -308,7 +318,29 @@ static int altera_cvp_teardown(struct fpga_manager *mgr,
ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0,
conf->priv->poll_time_us);
if (ret)
dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n");
dev_warn(&mgr->dev, "CFG_RDY == 0 timeout\n");
return ret;
}
static int altera_cvp_recovery(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
struct altera_cvp_conf *conf = mgr->priv;
int ret;
ret = altera_cvp_teardown(mgr, info);
if (ret) {
/*
* CVP_STATUS may get stuck if the device left user mode
* before the poll. Exit CvP mode to switch back the clock
* feeding CVP_STATUS, then try the teardown again.
*/
altera_cvp_disable_cvp_mode(conf);
ret = altera_cvp_teardown(mgr, info);
if (ret)
dev_err(&mgr->dev, "Tear-down failed\n");
}
return ret;
}
@ -345,7 +377,7 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
if (val & VSE_CVP_STATUS_CFG_RDY) {
dev_warn(&mgr->dev, "CvP already started, tear down first\n");
ret = altera_cvp_teardown(mgr, info);
ret = altera_cvp_recovery(mgr, info);
if (ret)
return ret;
}
@ -486,7 +518,7 @@ static int altera_cvp_write_complete(struct fpga_manager *mgr,
u32 mask, val;
int ret;
ret = altera_cvp_teardown(mgr, info);
ret = altera_cvp_recovery(mgr, info);
if (ret)
return ret;
@ -498,10 +530,7 @@ static int altera_cvp_write_complete(struct fpga_manager *mgr,
}
/* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */
altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
altera_cvp_disable_cvp_mode(conf);
/* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */
mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE;

View File

@ -23,7 +23,6 @@
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/uuid.h>

View File

@ -744,7 +744,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
* @mgr: fpga manager
*
* Given a pointer to FPGA Manager (from fpga_mgr_get() or
* of_fpga_mgr_put()) attempt to get the mutex. The user should call
* of_fpga_mgr_get()) attempt to get the mutex. The user should call
* fpga_mgr_lock() and verify that it returns 0 before attempting to
* program the FPGA. Likewise, the user should call fpga_mgr_unlock
* when done programming the FPGA.

View File

@ -286,7 +286,7 @@ static int s10_ops_write(struct fpga_manager *mgr, const char *buf,
/*
* Loop waiting for buffers to be returned. When a buffer is returned,
* reuse it to send more data or free if if all data has been sent.
* reuse it to send more data or free it if all data has been sent.
*/
while (count > 0 || s10_free_buffer_count(mgr) != NUM_SVC_BUFS) {
reinit_completion(&priv->status_return_completion);

View File

@ -19,6 +19,8 @@
struct xilinx_selectmap_conf {
struct xilinx_fpga_core core;
void __iomem *base;
struct gpio_desc *csi_b;
struct gpio_desc *rdwr_b;
};
#define to_xilinx_selectmap_conf(obj) \
@ -30,16 +32,28 @@ static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
size_t i;
/*
* Select this device and put its SelectMAP port into write mode.
*
* RDWR_B is set before CSI_B. UG470 describes in chapter
* "SelectMAP ABORT" that changing RDWR_B while the device is
* selected aborts the configuration on the next CCLK.
*/
gpiod_set_value(conf->rdwr_b, 1);
gpiod_set_value(conf->csi_b, 1);
for (i = 0; i < count; ++i)
writeb(buf[i], conf->base);
gpiod_set_value(conf->csi_b, 0);
gpiod_set_value(conf->rdwr_b, 0);
return 0;
}
static int xilinx_selectmap_probe(struct platform_device *pdev)
{
struct xilinx_selectmap_conf *conf;
struct gpio_desc *gpio;
void __iomem *base;
conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
@ -55,16 +69,23 @@ static int xilinx_selectmap_probe(struct platform_device *pdev)
"ioremap error\n");
conf->base = base;
/* CSI_B is active low */
gpio = devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
if (IS_ERR(gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(gpio),
/*
* Request both signals deasserted, so a device sharing the SelectMAP
* bus with others stays off that bus until its bitstream is written.
*
* The value in the gpiod flags is logical, gpiolib drives the line
* high for GPIOD_OUT_LOW when the firmware describes it active low.
*/
conf->csi_b = devm_gpiod_get_optional(&pdev->dev, "csi",
GPIOD_OUT_LOW);
if (IS_ERR(conf->csi_b))
return dev_err_probe(&pdev->dev, PTR_ERR(conf->csi_b),
"Failed to get CSI_B gpio\n");
/* RDWR_B is active low */
gpio = devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
if (IS_ERR(gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(gpio),
conf->rdwr_b = devm_gpiod_get_optional(&pdev->dev, "rdwr",
GPIOD_OUT_LOW);
if (IS_ERR(conf->rdwr_b))
return dev_err_probe(&pdev->dev, PTR_ERR(conf->rdwr_b),
"Failed to get RDWR_B gpio\n");
return xilinx_core_probe(&conf->core);