* [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software
@ 2026-05-11 5:38 muhammad.nazim.amirul.nazle.asmade
2026-05-12 18:48 ` kernel test robot
2026-05-12 19:09 ` kernel test robot
0 siblings, 2 replies; 3+ messages in thread
From: muhammad.nazim.amirul.nazle.asmade @ 2026-05-11 5:38 UTC (permalink / raw)
To: Moritz Fischer, Xu Yilun; +Cc: Tom Rix, linux-fpga, linux-kernel
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Mask the hardware credit value using compound assignment and replace the
simple masked comparison with a software-extended counter that handles
wrap-around.
The HW credit register is limited to n bits and wraps naturally. The
previous logic compared the masked value directly against sent_packets,
which breaks once the counter wraps. Extend the counter in software by
tracking forward wraps and accumulating an overflow counter. A wrap is
detected when the masked value decreases by more than half of the modulo,
avoiding false detection from small backward glitches.
Compute a monotonic real_credit from the overflow counter and the masked
value, then compare it directly with sent_packets. This ensures correct
FIFO space detection across wraps. Also add error reporting when the
credit appears to move behind the sent count.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
drivers/fpga/altera-cvp.c | 58 ++++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 44badfd11e1b..6e7a8ced2d68 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -76,6 +76,9 @@ struct altera_cvp_conf {
char mgr_name[64];
u8 numclks;
u32 sent_packets;
+ u32 overflow_counter;
+ u32 last_credit_hw;
+ bool credit_ext_inited;
u32 vsec_offset;
const struct cvp_priv *priv;
};
@@ -228,19 +231,64 @@ static int altera_cvp_v2_wait_for_credit(struct fpga_manager *mgr,
u32 timeout = V2_CREDIT_TIMEOUT_US / V2_CHECK_CREDIT_US;
struct altera_cvp_conf *conf = mgr->priv;
int ret;
- u8 val;
+ u32 val;
+ u32 credit_mask;
+ u32 vse_cvp_tx_credits_offset = VSE_CVP_TX_CREDITS;
+ u32 mod;
+ u32 real_credit;
do {
- ret = altera_read_config_byte(conf, VSE_CVP_TX_CREDITS, &val);
+ /* READ DWORD is required for Agilex5 but READ BYTE is required for non-Agilex5 */
+ if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
+ vse_cvp_tx_credits_offset = VSE_CVP_AG5_TX_CREDITS;
+ credit_mask = 0xFFF;
+ ret = altera_read_config_dword(conf, vse_cvp_tx_credits_offset, &val);
+ } else {
+ /*
+ * For the byte config read path, val is zeroed before pci_read_config_byte
+ * so only the low byte is defined before masking.
+ */
+ val = 0;
+ credit_mask = 0xFF;
+ ret = altera_read_config_byte(conf, vse_cvp_tx_credits_offset,
+ (u8 *)&val);
+ }
+
+
if (ret) {
dev_err(&conf->pci_dev->dev,
"Error reading CVP Credit Register\n");
return ret;
}
- /* Return if there is space in FIFO */
- if (val - (u8)conf->sent_packets)
+ val &= credit_mask;
+ mod = credit_mask + 1;
+
+ /*
+ * HW credit is n bits and wraps; extend it in software so we can
+ * compare to sent_packets directly. On a forward wrap the masked
+ * value jumps from high to low; require (last - val) > mod/2 so a
+ * small backward glitch is not counted as a wrap. More than one
+ * wrap between polls is not detected if the low bits repeat.
+ */
+ if (conf->credit_ext_inited &&
+ val < conf->last_credit_hw &&
+ (conf->last_credit_hw - val) > (mod / 2))
+ conf->overflow_counter++;
+
+ conf->last_credit_hw = val;
+ conf->credit_ext_inited = true;
+
+ real_credit = conf->overflow_counter * mod + val;
+
+ if (real_credit > conf->sent_packets)
return 0;
+ if (real_credit < conf->sent_packets) {
+ dev_err(&conf->pci_dev->dev,
+ "CVP credit behind sent count (real %u reg 0x%x sent %u)\n",
+ real_credit, val, conf->sent_packets);
+ return -EPROTO;
+ }
ret = altera_cvp_chk_error(mgr, blocks * ALTERA_CVP_V2_SIZE);
if (ret) {
@@ -378,6 +426,8 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
}
conf->sent_packets = 0;
+ conf->overflow_counter = 0;
+ conf->credit_ext_inited = false;
/* STEP 4 - set CVP_CONFIG bit */
altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
--
2.43.7
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software
2026-05-11 5:38 [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software muhammad.nazim.amirul.nazle.asmade
@ 2026-05-12 18:48 ` kernel test robot
2026-05-12 19:09 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-12 18:48 UTC (permalink / raw)
To: muhammad.nazim.amirul.nazle.asmade, Moritz Fischer, Xu Yilun
Cc: llvm, oe-kbuild-all, Tom Rix, linux-fpga, linux-kernel
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on linus/master]
[also build test ERROR on v7.1-rc3 next-20260508]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/muhammad-nazim-amirul-nazle-asmade-altera-com/fpga-altera-cvp-Extend-wrapped-HW-credit-counter-in-software/20260512-200019
base: linus/master
patch link: https://lore.kernel.org/r/20260511053858.30921-1-muhammad.nazim.amirul.nazle.asmade%40altera.com
patch subject: [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software
config: i386-buildonly-randconfig-006-20260512 (https://download.01.org/0day-ci/archive/20260513/202605130220.ZrvfCQQU-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260513/202605130220.ZrvfCQQU-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605130220.ZrvfCQQU-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/fpga/altera-cvp.c:242:13: error: no member named 'device_family_type' in 'struct altera_cvp_conf'
242 | if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
| ~~~~ ^
>> drivers/fpga/altera-cvp.c:242:35: error: use of undeclared identifier 'SOCFPGA_CVP_V2_AGILEX5'
242 | if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
| ^
>> drivers/fpga/altera-cvp.c:243:32: error: use of undeclared identifier 'VSE_CVP_AG5_TX_CREDITS'
243 | vse_cvp_tx_credits_offset = VSE_CVP_AG5_TX_CREDITS;
| ^
3 errors generated.
vim +242 drivers/fpga/altera-cvp.c
227
228 static int altera_cvp_v2_wait_for_credit(struct fpga_manager *mgr,
229 u32 blocks)
230 {
231 u32 timeout = V2_CREDIT_TIMEOUT_US / V2_CHECK_CREDIT_US;
232 struct altera_cvp_conf *conf = mgr->priv;
233 int ret;
234 u32 val;
235 u32 credit_mask;
236 u32 vse_cvp_tx_credits_offset = VSE_CVP_TX_CREDITS;
237 u32 mod;
238 u32 real_credit;
239
240 do {
241 /* READ DWORD is required for Agilex5 but READ BYTE is required for non-Agilex5 */
> 242 if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
> 243 vse_cvp_tx_credits_offset = VSE_CVP_AG5_TX_CREDITS;
244 credit_mask = 0xFFF;
245 ret = altera_read_config_dword(conf, vse_cvp_tx_credits_offset, &val);
246 } else {
247 /*
248 * For the byte config read path, val is zeroed before pci_read_config_byte
249 * so only the low byte is defined before masking.
250 */
251 val = 0;
252 credit_mask = 0xFF;
253 ret = altera_read_config_byte(conf, vse_cvp_tx_credits_offset,
254 (u8 *)&val);
255 }
256
257
258 if (ret) {
259 dev_err(&conf->pci_dev->dev,
260 "Error reading CVP Credit Register\n");
261 return ret;
262 }
263
264 val &= credit_mask;
265 mod = credit_mask + 1;
266
267 /*
268 * HW credit is n bits and wraps; extend it in software so we can
269 * compare to sent_packets directly. On a forward wrap the masked
270 * value jumps from high to low; require (last - val) > mod/2 so a
271 * small backward glitch is not counted as a wrap. More than one
272 * wrap between polls is not detected if the low bits repeat.
273 */
274 if (conf->credit_ext_inited &&
275 val < conf->last_credit_hw &&
276 (conf->last_credit_hw - val) > (mod / 2))
277 conf->overflow_counter++;
278
279 conf->last_credit_hw = val;
280 conf->credit_ext_inited = true;
281
282 real_credit = conf->overflow_counter * mod + val;
283
284 if (real_credit > conf->sent_packets)
285 return 0;
286 if (real_credit < conf->sent_packets) {
287 dev_err(&conf->pci_dev->dev,
288 "CVP credit behind sent count (real %u reg 0x%x sent %u)\n",
289 real_credit, val, conf->sent_packets);
290 return -EPROTO;
291 }
292
293 ret = altera_cvp_chk_error(mgr, blocks * ALTERA_CVP_V2_SIZE);
294 if (ret) {
295 dev_err(&conf->pci_dev->dev,
296 "CE Bit error credit reg[0x%x]:sent[0x%x]\n",
297 val, conf->sent_packets);
298 return -EAGAIN;
299 }
300
301 /* Limit the check credit byte traffic */
302 usleep_range(V2_CHECK_CREDIT_US, V2_CHECK_CREDIT_US + 1);
303 } while (timeout--);
304
305 dev_err(&conf->pci_dev->dev, "Timeout waiting for credit\n");
306 return -ETIMEDOUT;
307 }
308
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software
2026-05-11 5:38 [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software muhammad.nazim.amirul.nazle.asmade
2026-05-12 18:48 ` kernel test robot
@ 2026-05-12 19:09 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-12 19:09 UTC (permalink / raw)
To: muhammad.nazim.amirul.nazle.asmade, Moritz Fischer, Xu Yilun
Cc: oe-kbuild-all, Tom Rix, linux-fpga, linux-kernel
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on linus/master]
[also build test ERROR on v7.1-rc3 next-20260508]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/muhammad-nazim-amirul-nazle-asmade-altera-com/fpga-altera-cvp-Extend-wrapped-HW-credit-counter-in-software/20260512-200019
base: linus/master
patch link: https://lore.kernel.org/r/20260511053858.30921-1-muhammad.nazim.amirul.nazle.asmade%40altera.com
patch subject: [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software
config: x86_64-randconfig-r072-20260512 (https://download.01.org/0day-ci/archive/20260513/202605130328.AdvlQMiJ-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
smatch: v0.5.0-9065-ge9cc34fd
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260513/202605130328.AdvlQMiJ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605130328.AdvlQMiJ-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/fpga/altera-cvp.c: In function 'altera_cvp_v2_wait_for_credit':
>> drivers/fpga/altera-cvp.c:242:25: error: 'struct altera_cvp_conf' has no member named 'device_family_type'
242 | if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
| ^~
>> drivers/fpga/altera-cvp.c:242:49: error: 'SOCFPGA_CVP_V2_AGILEX5' undeclared (first use in this function)
242 | if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/fpga/altera-cvp.c:242:49: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/fpga/altera-cvp.c:243:53: error: 'VSE_CVP_AG5_TX_CREDITS' undeclared (first use in this function); did you mean 'VSE_CVP_TX_CREDITS'?
243 | vse_cvp_tx_credits_offset = VSE_CVP_AG5_TX_CREDITS;
| ^~~~~~~~~~~~~~~~~~~~~~
| VSE_CVP_TX_CREDITS
vim +242 drivers/fpga/altera-cvp.c
227
228 static int altera_cvp_v2_wait_for_credit(struct fpga_manager *mgr,
229 u32 blocks)
230 {
231 u32 timeout = V2_CREDIT_TIMEOUT_US / V2_CHECK_CREDIT_US;
232 struct altera_cvp_conf *conf = mgr->priv;
233 int ret;
234 u32 val;
235 u32 credit_mask;
236 u32 vse_cvp_tx_credits_offset = VSE_CVP_TX_CREDITS;
237 u32 mod;
238 u32 real_credit;
239
240 do {
241 /* READ DWORD is required for Agilex5 but READ BYTE is required for non-Agilex5 */
> 242 if (conf->device_family_type == SOCFPGA_CVP_V2_AGILEX5) {
> 243 vse_cvp_tx_credits_offset = VSE_CVP_AG5_TX_CREDITS;
244 credit_mask = 0xFFF;
245 ret = altera_read_config_dword(conf, vse_cvp_tx_credits_offset, &val);
246 } else {
247 /*
248 * For the byte config read path, val is zeroed before pci_read_config_byte
249 * so only the low byte is defined before masking.
250 */
251 val = 0;
252 credit_mask = 0xFF;
253 ret = altera_read_config_byte(conf, vse_cvp_tx_credits_offset,
254 (u8 *)&val);
255 }
256
257
258 if (ret) {
259 dev_err(&conf->pci_dev->dev,
260 "Error reading CVP Credit Register\n");
261 return ret;
262 }
263
264 val &= credit_mask;
265 mod = credit_mask + 1;
266
267 /*
268 * HW credit is n bits and wraps; extend it in software so we can
269 * compare to sent_packets directly. On a forward wrap the masked
270 * value jumps from high to low; require (last - val) > mod/2 so a
271 * small backward glitch is not counted as a wrap. More than one
272 * wrap between polls is not detected if the low bits repeat.
273 */
274 if (conf->credit_ext_inited &&
275 val < conf->last_credit_hw &&
276 (conf->last_credit_hw - val) > (mod / 2))
277 conf->overflow_counter++;
278
279 conf->last_credit_hw = val;
280 conf->credit_ext_inited = true;
281
282 real_credit = conf->overflow_counter * mod + val;
283
284 if (real_credit > conf->sent_packets)
285 return 0;
286 if (real_credit < conf->sent_packets) {
287 dev_err(&conf->pci_dev->dev,
288 "CVP credit behind sent count (real %u reg 0x%x sent %u)\n",
289 real_credit, val, conf->sent_packets);
290 return -EPROTO;
291 }
292
293 ret = altera_cvp_chk_error(mgr, blocks * ALTERA_CVP_V2_SIZE);
294 if (ret) {
295 dev_err(&conf->pci_dev->dev,
296 "CE Bit error credit reg[0x%x]:sent[0x%x]\n",
297 val, conf->sent_packets);
298 return -EAGAIN;
299 }
300
301 /* Limit the check credit byte traffic */
302 usleep_range(V2_CHECK_CREDIT_US, V2_CHECK_CREDIT_US + 1);
303 } while (timeout--);
304
305 dev_err(&conf->pci_dev->dev, "Timeout waiting for credit\n");
306 return -ETIMEDOUT;
307 }
308
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-12 19:10 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11 5:38 [PATCH] fpga: altera-cvp: Extend wrapped HW credit counter in software muhammad.nazim.amirul.nazle.asmade
2026-05-12 18:48 ` kernel test robot
2026-05-12 19:09 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox