[PATCH] fpga: altera-cvp: Retry teardown and reset CVP state on failure
[email protected] Thu, 18 Jun 2026 04:24:10 -0700
| Newsgroups | org.kernel.vger.linux-fpga,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260618112410.303-1-muhammad.nazim.amirul.nazle.asmade@altera.com> |
From: Nazim Amirul <[email protected]> If an incorrect bitstream is sent, the teardown may fail due to a CFG_RDY timeout. When this happens, reset CVP_MODE and HIP_CLK_SEL bits to clean up the hardware state and return -EAGAIN, allowing the caller to retry. Introduce altera_cvp_recovery() to wrap this retry logic with a maximum of CVP_TEARDOWN_MAX_RETRY attempts. Signed-off-by: Nazim Amirul <[email protected]> --- drivers/fpga/altera-cvp.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 44badfd11e1b..29faf6f5bde1 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c @@ -63,6 +63,8 @@ #define ALTERA_CVP_V1_SIZE 4 #define ALTERA_CVP_V2_SIZE 4096 +/* Tear-down retry */ +#define CVP_TEARDOWN_MAX_RETRY 10 /* Optional CvP config error status check for debugging */ static bool altera_cvp_chkcfg; @@ -305,12 +307,40 @@ static int altera_cvp_teardown(struct fpga_manager *mgr, /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */ ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0, conf->priv->poll_time_us); - if (ret) + if (ret) { dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n"); + goto error_path; + } return ret; + +error_path: + /* 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); + + return -EAGAIN; + } +static int altera_cvp_recovery(struct fpga_manager *mgr, + struct fpga_image_info *info) +{ + int ret = 0, retry = 0; + + for (retry = 0; retry < CVP_TEARDOWN_MAX_RETRY; retry++) { + ret = altera_cvp_teardown(mgr, info); + if (!ret) + break; + dev_warn(&mgr->dev, + "%s: [%d] Tear-down failed. Retrying\n", + __func__, + retry); + } + return ret; +} static int altera_cvp_write_init(struct fpga_manager *mgr, struct fpga_image_info *info, const char *buf, size_t count) @@ -343,7 +373,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; } @@ -484,7 +514,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; -- 2.43.7