]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: s5p-mfc: Support for handling RET_ENC_BUFFER_FULL interrupt
authorAakarsh Jain <aakarsh.jain@samsung.com>
Wed, 5 Mar 2025 05:53:08 +0000 (11:23 +0530)
committerHans Verkuil <hverkuil@xs4all.nl>
Fri, 25 Apr 2025 13:14:27 +0000 (15:14 +0200)
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>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h
drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c

index fa49fe580e1ac8a59115082ff57c8bcfde36142c..075a58b50b8caeabe25dd40909bf427a4b5bc51d 100644 (file)
@@ -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
 
index c8e0ee383af3884751d6babaf2ab8a9bfaace3dd..9f89bd2620c70a09922e5b4117978f7b2d9225b3 100644 (file)
@@ -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_FUL_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);
index 3cc2a4f5c40a61b086bd7383a84c7c9976aae85b..86c316c1ff8f69cd0f172fa14477331e325ed8f5 100644 (file)
@@ -141,6 +141,7 @@ enum s5p_mfc_inst_state {
        MFCINST_RES_CHANGE_INIT,
        MFCINST_RES_CHANGE_FLUSH,
        MFCINST_RES_CHANGE_END,
+       MFCINST_NAL_ABORT,
 };
 
 /*
index 0c636090d723de0efaff8fef74da9ead9534cca8..98f8292b317388c740bbca079a0a1f3a9bb09585 100644 (file)
@@ -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;
                }