diff mbox series

media: s5p-mfc: Support for handling RET_ENC_BUFFER_FULL interrupt

Message ID 20250228065952.14375-1-aakarsh.jain@samsung.com
State New
Headers show
Series media: s5p-mfc: Support for handling RET_ENC_BUFFER_FULL interrupt | expand

Commit Message

Aakarsh Jain/Aakarsh Jain Feb. 28, 2025, 6:59 a.m. UTC
When output encoded buffer size provided by userspace
is insufficient with current encoding parameters, it
leads to RET_ENC_BUFFER_FULL interrupt which was not
handled in IRQ handler.

On handling of RET_ENC_BUFFER_FULL interrupt leads to
NAL_ABORT command from host to risc which in turn leads
to RET_NAL_ABORT interrupt. On receiving RET_NAL_ABORT
driver clears workbit and VB2 queues for cleaner closing
of MFC instance.

When user encounters "Call on DQBUF after unrecoverable
error", userspace should close fd and restart with larger
output encoder buffer size.

Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../media/platform/samsung/s5p-mfc/regs-mfc-v6.h   |  1 +
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c   | 14 ++++++++++++++
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h      |  1 +
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c      |  5 +++++
 4 files changed, 21 insertions(+)

Comments

kernel test robot March 2, 2025, 9:41 p.m. UTC | #1
Hi Aakarsh,

kernel test robot noticed the following build errors:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linuxtv-media-pending/master linus/master sailus-media-tree/streams sailus-media-tree/master v6.14-rc4 next-20250228]
[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/Aakarsh-Jain/media-s5p-mfc-Support-for-handling-RET_ENC_BUFFER_FULL-interrupt/20250228-175738
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20250228065952.14375-1-aakarsh.jain%40samsung.com
patch subject: [PATCH] media: s5p-mfc: Support for handling RET_ENC_BUFFER_FULL interrupt
config: loongarch-allyesconfig (https://download.01.org/0day-ci/archive/20250303/202503030529.ccd21udL-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250303/202503030529.ccd21udL-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/202503030529.ccd21udL-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c: In function 's5p_mfc_irq':
>> drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c:742:14: error: 'S5P_MFC_R2H_CMD_ENC_BUFFER_FULL_RET' undeclared (first use in this function); did you mean 'S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET'?
     742 |         case S5P_MFC_R2H_CMD_ENC_BUFFER_FULL_RET:
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |              S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET
   drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c:742:14: note: each undeclared identifier is reported only once for each function it appears in


vim +742 drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c

   645	
   646	/* Interrupt processing */
   647	static irqreturn_t s5p_mfc_irq(int irq, void *priv)
   648	{
   649		struct s5p_mfc_dev *dev = priv;
   650		struct s5p_mfc_ctx *ctx;
   651		unsigned int reason;
   652		unsigned int err;
   653	
   654		mfc_debug_enter();
   655		/* Reset the timeout watchdog */
   656		atomic_set(&dev->watchdog_cnt, 0);
   657		spin_lock(&dev->irqlock);
   658		ctx = dev->ctx[dev->curr_ctx];
   659		/* Get the reason of interrupt and the error code */
   660		reason = s5p_mfc_hw_call(dev->mfc_ops, get_int_reason, dev);
   661		err = s5p_mfc_hw_call(dev->mfc_ops, get_int_err, dev);
   662		mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
   663		switch (reason) {
   664		case S5P_MFC_R2H_CMD_ERR_RET:
   665			/* An error has occurred */
   666			if (ctx->state == MFCINST_RUNNING &&
   667				(s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >=
   668					dev->warn_start ||
   669					err == S5P_FIMV_ERR_NO_VALID_SEQ_HDR ||
   670					err == S5P_FIMV_ERR_INCOMPLETE_FRAME ||
   671					err == S5P_FIMV_ERR_TIMEOUT))
   672				s5p_mfc_handle_frame(ctx, reason, err);
   673			else
   674				s5p_mfc_handle_error(dev, ctx, reason, err);
   675			clear_bit(0, &dev->enter_suspend);
   676			break;
   677	
   678		case S5P_MFC_R2H_CMD_SLICE_DONE_RET:
   679		case S5P_MFC_R2H_CMD_FIELD_DONE_RET:
   680		case S5P_MFC_R2H_CMD_FRAME_DONE_RET:
   681			if (ctx->c_ops->post_frame_start) {
   682				if (ctx->c_ops->post_frame_start(ctx))
   683					mfc_err("post_frame_start() failed\n");
   684	
   685				if (ctx->state == MFCINST_FINISHING &&
   686							list_empty(&ctx->ref_queue)) {
   687					s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   688					s5p_mfc_handle_stream_complete(ctx);
   689					break;
   690				}
   691				s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   692				WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
   693				s5p_mfc_clock_off(dev);
   694				wake_up_ctx(ctx, reason, err);
   695				s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
   696			} else {
   697				s5p_mfc_handle_frame(ctx, reason, err);
   698			}
   699			break;
   700	
   701		case S5P_MFC_R2H_CMD_SEQ_DONE_RET:
   702			s5p_mfc_handle_seq_done(ctx, reason, err);
   703			break;
   704	
   705		case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET:
   706			ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev);
   707			ctx->state = MFCINST_GOT_INST;
   708			goto irq_cleanup_hw;
   709	
   710		case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET:
   711			ctx->inst_no = MFC_NO_INSTANCE_SET;
   712			ctx->state = MFCINST_FREE;
   713			goto irq_cleanup_hw;
   714	
   715		case S5P_MFC_R2H_CMD_SYS_INIT_RET:
   716		case S5P_MFC_R2H_CMD_FW_STATUS_RET:
   717		case S5P_MFC_R2H_CMD_SLEEP_RET:
   718		case S5P_MFC_R2H_CMD_WAKEUP_RET:
   719			if (ctx)
   720				clear_work_bit(ctx);
   721			s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   722			clear_bit(0, &dev->hw_lock);
   723			clear_bit(0, &dev->enter_suspend);
   724			wake_up_dev(dev, reason, err);
   725			break;
   726	
   727		case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET:
   728			s5p_mfc_handle_init_buffers(ctx, reason, err);
   729			break;
   730	
   731		case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET:
   732			s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   733			ctx->int_type = reason;
   734			ctx->int_err = err;
   735			s5p_mfc_handle_stream_complete(ctx);
   736			break;
   737	
   738		case S5P_MFC_R2H_CMD_DPB_FLUSH_RET:
   739			ctx->state = MFCINST_RUNNING;
   740			goto irq_cleanup_hw;
   741	
 > 742		case S5P_MFC_R2H_CMD_ENC_BUFFER_FULL_RET:
   743			ctx->state = MFCINST_NAL_ABORT;
   744			s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   745			set_work_bit(ctx);
   746			WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
   747			s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
   748			break;
   749	
   750		case S5P_MFC_R2H_CMD_NAL_ABORT_RET:
   751			ctx->state = MFCINST_ERROR;
   752			s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
   753			s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
   754			goto irq_cleanup_hw;
   755	
   756		default:
   757			mfc_debug(2, "Unknown int reason\n");
   758			s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   759		}
   760		spin_unlock(&dev->irqlock);
   761		mfc_debug_leave();
   762		return IRQ_HANDLED;
   763	irq_cleanup_hw:
   764		s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
   765		ctx->int_type = reason;
   766		ctx->int_err = err;
   767		ctx->int_cond = 1;
   768		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
   769			mfc_err("Failed to unlock hw\n");
   770	
   771		s5p_mfc_clock_off(dev);
   772		clear_work_bit(ctx);
   773		wake_up(&ctx->queue);
   774	
   775		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
   776		spin_unlock(&dev->irqlock);
   777		mfc_debug(2, "Exit via irq_cleanup_hw\n");
   778		return IRQ_HANDLED;
   779	}
   780
diff mbox series

Patch

diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h
index fa49fe580e1a..075a58b50b8c 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h
@@ -45,6 +45,7 @@ 
 #define S5P_FIMV_H2R_CMD_WAKEUP_V6		8
 #define S5P_FIMV_CH_LAST_FRAME_V6		9
 #define S5P_FIMV_H2R_CMD_FLUSH_V6		10
+#define S5P_FIMV_H2R_CMD_NAL_ABORT_V6		11
 /* RMVME: REALLOC used? */
 #define S5P_FIMV_CH_FRAME_START_REALLOC_V6	5
 
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index 5f80931f056d..fa211c2d68a4 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -739,6 +739,20 @@  static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 		ctx->state = MFCINST_RUNNING;
 		goto irq_cleanup_hw;
 
+	case S5P_MFC_R2H_CMD_ENC_BUFFER_FULL_RET:
+		ctx->state = MFCINST_NAL_ABORT;
+		s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
+		set_work_bit(ctx);
+		WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
+		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+		break;
+
+	case S5P_MFC_R2H_CMD_NAL_ABORT_RET:
+		ctx->state = MFCINST_ERROR;
+		s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
+		s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+		goto irq_cleanup_hw;
+
 	default:
 		mfc_debug(2, "Unknown int reason\n");
 		s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index 3cc2a4f5c40a..86c316c1ff8f 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -141,6 +141,7 @@  enum s5p_mfc_inst_state {
 	MFCINST_RES_CHANGE_INIT,
 	MFCINST_RES_CHANGE_FLUSH,
 	MFCINST_RES_CHANGE_END,
+	MFCINST_NAL_ABORT,
 };
 
 /*
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index 4cf12f33d706..356adfddcfcf 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -2229,6 +2229,11 @@  static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
 		case MFCINST_HEAD_PRODUCED:
 			ret = s5p_mfc_run_init_enc_buffers(ctx);
 			break;
+		case MFCINST_NAL_ABORT:
+			mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+			s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc,
+					dev, S5P_FIMV_H2R_CMD_NAL_ABORT_V6, NULL);
+			break;
 		default:
 			ret = -EAGAIN;
 		}