diff options
| author | Dikshita Agarwal <quic_dikshita@quicinc.com> | 2025-08-25 12:30:28 +0530 |
|---|---|---|
| committer | Hans Verkuil <hverkuil+cisco@kernel.org> | 2025-09-10 09:02:31 +0200 |
| commit | 4b67ef9b333ed645879b4b1a11e35e019ff4cfea (patch) | |
| tree | 8b719575bb7762fa1d7c8096dafd8e17e51ccda5 | |
| parent | 02a24f13b3a1d9da9f3de56aa5fdb7cc1fe167a2 (diff) | |
media: iris: Fix port streaming handling
The previous check to block capture port streaming before output port
was incorrect and caused some valid usecase to fail. While removing that
check allows capture port to enter streaming independently, it also
introduced firmware errors due to premature queuing of DPB buffers
before the firmware session was fully started which happens only when
streamon is called on output port.
Fix this by deferring DPB buffer queuing to the firmware until both
capture and output are streaming and state is 'STREAMING'.
Fixes: 11712ce70f8e ("media: iris: implement vb2 streaming ops")
Cc: stable@vger.kernel.org
Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # X1E80100
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e80100-crd
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
| -rw-r--r-- | drivers/media/platform/qcom/iris/iris_buffer.c | 27 | ||||
| -rw-r--r-- | drivers/media/platform/qcom/iris/iris_buffer.h | 1 | ||||
| -rw-r--r-- | drivers/media/platform/qcom/iris/iris_vb2.c | 8 |
3 files changed, 32 insertions, 4 deletions
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index 9f664c241149..23cac5d13129 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -334,6 +334,29 @@ int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) return 0; } +int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + struct iris_buffer *buffer, *next; + struct iris_buffers *buffers; + int ret = 0; + + buffers = &inst->buffers[buffer_type]; + list_for_each_entry_safe(buffer, next, &buffers->list, list) { + if (buffer->attr & BUF_ATTR_PENDING_RELEASE) + continue; + if (buffer->attr & BUF_ATTR_QUEUED) + continue; + + if (buffer->attr & BUF_ATTR_DEFERRED) { + ret = iris_queue_buffer(inst, buffer); + if (ret) + return ret; + } + } + + return ret; +} + int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) { const struct iris_platform_data *platform_data = inst->core->iris_platform_data; @@ -358,6 +381,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) continue; if (buffer->attr & BUF_ATTR_QUEUED) continue; + if (buffer->type == BUF_DPB && inst->state != IRIS_INST_STREAMING) { + buffer->attr |= BUF_ATTR_DEFERRED; + continue; + } ret = iris_queue_buffer(inst, buffer); if (ret) return ret; diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h index 00825ad2dc3a..b9b011faa13a 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_buffer.h @@ -105,6 +105,7 @@ int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_ty void iris_get_internal_buffers(struct iris_inst *inst, u32 plane); int iris_create_internal_buffers(struct iris_inst *inst, u32 plane); int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane); +int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type); int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer); int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane); int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane); diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c index 8b17c7c39487..e62ed7a57df2 100644 --- a/drivers/media/platform/qcom/iris/iris_vb2.c +++ b/drivers/media/platform/qcom/iris/iris_vb2.c @@ -173,9 +173,6 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) inst = vb2_get_drv_priv(q); - if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state == IRIS_INST_INIT) - return 0; - mutex_lock(&inst->lock); if (inst->state == IRIS_INST_ERROR) { ret = -EBUSY; @@ -203,7 +200,10 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) buf_type = iris_v4l2_type_to_driver(q->type); - ret = iris_queue_deferred_buffers(inst, buf_type); + if (inst->state == IRIS_INST_STREAMING) + ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB); + if (!ret) + ret = iris_queue_deferred_buffers(inst, buf_type); if (ret) goto error; |