The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [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