* [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware
@ 2026-09-30 17:46 David Carlier
2026-10-07 10:29 ` Dan Scally
2026-11-10 13:22 ` Jacopo Mondi
0 siblings, 2 replies; 4+ messages in thread
From: David Carlier @ 2026-09-30 17:46 UTC (permalink / raw)
To: Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab,
Nayden Kanchev, Hans Verkuil
Cc: linux-media, linux-kernel, David Carlier, stable
The single frame_sequence counter in struct mali_c55_isp is incremented
in mali_c55_set_plane_done(), which runs once per completed buffer per
capture device rather than once per frame. Hardware fitted with the
downscale pipe always hits this: mali_c55_pipeline_ready() refuses to
start the ISP unless both the full-resolution and the downscale queues
are streaming, so the counter advances twice per frame.
Each video node then reports sequence numbers 0, 2, 4, ..., which
userspace reads as a dropped frame between every pair of frames, and the
two pipes never number the same frame alike, contrary to
Documentation/admin-guide/media/mali-c55.rst. The V4L2_EVENT_FRAME_SYNC
event and the statistics and parameters buffers only read the counter,
so their sequence numbers stop identifying a frame too.
Increment the counter once per frame, when the ISP start interrupt is
handled, and stamp each capture buffer when mali_c55_set_next_buffer()
programs it, as it is written out during the following frame. Stamping
at completion would be off by one whenever DONE(n) and START(n+1) are
handled in the same interrupt, since ISP_START is processed first. Hold
the counter at UINT_MAX while the ISP is stopped, as the first buffers
are programmed before it starts, so the first frame gets sequence zero.
Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: David Carlier <devnexen@gmail.com>
---
v2:
- Stamp the buffer sequence in mali_c55_set_next_buffer() instead of
at completion, which broke when START(n+1) and DONE(n) are handled
together (Jacopo)
- Reset the counter when the ISP stops instead of when it starts
v1: https://lore.kernel.org/r/20260801205311.386692-1-devnexen@gmail.com
---
drivers/media/platform/arm/mali-c55/mali-c55-capture.c | 5 +++--
drivers/media/platform/arm/mali-c55/mali-c55-common.h | 4 ++++
drivers/media/platform/arm/mali-c55/mali-c55-core.c | 1 +
drivers/media/platform/arm/mali-c55/mali-c55-isp.c | 3 ++-
4 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c
index ff01553026fb..fa073ce4b2bd 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c
@@ -413,6 +413,9 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev)
return;
}
+ /* The buffer is written out during the frame following this one. */
+ buf->vb.sequence = cap_dev->mali_c55->isp.frame_sequence + 1;
+
pix_mp = &cap_dev->format.format;
mali_c55_cap_dev_update_bits(cap_dev, MALI_C55_REG_Y_WRITER_MODE,
@@ -457,7 +460,6 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev)
void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev,
enum mali_c55_planes plane)
{
- struct mali_c55_isp *isp = &cap_dev->mali_c55->isp;
struct mali_c55_buffer *buf;
scoped_guard(spinlock, &cap_dev->buffers.processing_lock) {
@@ -476,7 +478,6 @@ void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev,
/* If the other plane is also done... */
buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns();
- buf->vb.sequence = isp->frame_sequence++;
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-common.h b/drivers/media/platform/arm/mali-c55/mali-c55-common.h
index 13a3e9dc4243..50f2b7a85f62 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-common.h
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-common.h
@@ -76,6 +76,10 @@ struct mali_c55_isp {
struct media_pad *remote_src;
/* Mutex to guard vb2 start/stop streaming */
struct mutex capture_lock;
+ /*
+ * Sequence of the frame being processed, incremented at SOF. Held at
+ * UINT_MAX while stopped so the first frame gets sequence 0.
+ */
unsigned int frame_sequence;
};
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
index fb81141d1653..be562156b295 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c
@@ -573,6 +573,7 @@ static irqreturn_t mali_c55_isr(int irq, void *context)
for_each_set_bit(i, &interrupt_status, MALI_C55_NUM_IRQ_BITS) {
switch (i) {
case MALI_C55_IRQ_ISP_START:
+ mali_c55->isp.frame_sequence++;
mali_c55_isp_queue_event_sof(mali_c55);
mali_c55_set_next_buffer(&mali_c55->cap_devs[MALI_C55_CAP_DEV_FR]);
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c
index e128adf6ee37..dd3bce287a3d 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c
@@ -342,7 +342,6 @@ static int mali_c55_isp_enable_streams(struct v4l2_subdev *sd,
src_sd = media_entity_to_v4l2_subdev(isp->remote_src->entity);
- isp->frame_sequence = 0;
ret = mali_c55_isp_start(mali_c55, state);
if (ret) {
dev_err(mali_c55->dev, "Failed to start ISP\n");
@@ -380,6 +379,7 @@ static int mali_c55_isp_disable_streams(struct v4l2_subdev *sd,
isp->remote_src = NULL;
mali_c55_isp_stop(mali_c55);
+ isp->frame_sequence = UINT_MAX;
return 0;
}
@@ -584,6 +584,7 @@ int mali_c55_register_isp(struct mali_c55 *mali_c55)
int ret;
isp->mali_c55 = mali_c55;
+ isp->frame_sequence = UINT_MAX;
v4l2_subdev_init(sd, &mali_c55_isp_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
base-commit: 95f76f51937fdfb0fc1e14cae606b1ef574a56f3
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware 2026-09-30 17:46 [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware David Carlier @ 2026-10-07 10:29 ` Dan Scally 2026-11-10 13:22 ` Jacopo Mondi 1 sibling, 0 replies; 4+ messages in thread From: Dan Scally @ 2026-10-07 10:29 UTC (permalink / raw) To: David Carlier, Jacopo Mondi, Mauro Carvalho Chehab, Nayden Kanchev, Hans Verkuil Cc: linux-media, linux-kernel, stable Hi David On 30/09/2026 18:46, David Carlier wrote: > The single frame_sequence counter in struct mali_c55_isp is incremented > in mali_c55_set_plane_done(), which runs once per completed buffer per > capture device rather than once per frame. Hardware fitted with the > downscale pipe always hits this: mali_c55_pipeline_ready() refuses to > start the ISP unless both the full-resolution and the downscale queues > are streaming, so the counter advances twice per frame. > > Each video node then reports sequence numbers 0, 2, 4, ..., which > userspace reads as a dropped frame between every pair of frames, and the > two pipes never number the same frame alike, contrary to > Documentation/admin-guide/media/mali-c55.rst. The V4L2_EVENT_FRAME_SYNC > event and the statistics and parameters buffers only read the counter, > so their sequence numbers stop identifying a frame too. > > Increment the counter once per frame, when the ISP start interrupt is > handled, and stamp each capture buffer when mali_c55_set_next_buffer() > programs it, as it is written out during the following frame. Stamping > at completion would be off by one whenever DONE(n) and START(n+1) are > handled in the same interrupt, since ISP_START is processed first. Hold > the counter at UINT_MAX while the ISP is stopped, as the first buffers > are programmed before it starts, so the first frame gets sequence zero. > > Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver") > Cc: stable@vger.kernel.org > Assisted-by: Claude:claude-opus-5 > Signed-off-by: David Carlier <devnexen@gmail.com> > --- I think this approach is fine. In v1 Jacopo said that he'd rather handle it with per-output counters though; @Jacopo, do you mean there that you'd rather an independent sequence counter for the FR and DS outputs? Thanks Dan > v2: > - Stamp the buffer sequence in mali_c55_set_next_buffer() instead of > at completion, which broke when START(n+1) and DONE(n) are handled > together (Jacopo) > - Reset the counter when the ISP stops instead of when it starts > > v1: https://lore.kernel.org/r/20260801205311.386692-1-devnexen@gmail.com > --- > drivers/media/platform/arm/mali-c55/mali-c55-capture.c | 5 +++-- > drivers/media/platform/arm/mali-c55/mali-c55-common.h | 4 ++++ > drivers/media/platform/arm/mali-c55/mali-c55-core.c | 1 + > drivers/media/platform/arm/mali-c55/mali-c55-isp.c | 3 ++- > 4 files changed, 10 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > index ff01553026fb..fa073ce4b2bd 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > @@ -413,6 +413,9 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev) > return; > } > > + /* The buffer is written out during the frame following this one. */ > + buf->vb.sequence = cap_dev->mali_c55->isp.frame_sequence + 1; > + > pix_mp = &cap_dev->format.format; > > mali_c55_cap_dev_update_bits(cap_dev, MALI_C55_REG_Y_WRITER_MODE, > @@ -457,7 +460,6 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev) > void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, > enum mali_c55_planes plane) > { > - struct mali_c55_isp *isp = &cap_dev->mali_c55->isp; > struct mali_c55_buffer *buf; > > scoped_guard(spinlock, &cap_dev->buffers.processing_lock) { > @@ -476,7 +478,6 @@ void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, > > /* If the other plane is also done... */ > buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns(); > - buf->vb.sequence = isp->frame_sequence++; > vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); > } > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-common.h b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > index 13a3e9dc4243..50f2b7a85f62 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-common.h > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > @@ -76,6 +76,10 @@ struct mali_c55_isp { > struct media_pad *remote_src; > /* Mutex to guard vb2 start/stop streaming */ > struct mutex capture_lock; > + /* > + * Sequence of the frame being processed, incremented at SOF. Held at > + * UINT_MAX while stopped so the first frame gets sequence 0. > + */ > unsigned int frame_sequence; > }; > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > index fb81141d1653..be562156b295 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > @@ -573,6 +573,7 @@ static irqreturn_t mali_c55_isr(int irq, void *context) > for_each_set_bit(i, &interrupt_status, MALI_C55_NUM_IRQ_BITS) { > switch (i) { > case MALI_C55_IRQ_ISP_START: > + mali_c55->isp.frame_sequence++; > mali_c55_isp_queue_event_sof(mali_c55); > > mali_c55_set_next_buffer(&mali_c55->cap_devs[MALI_C55_CAP_DEV_FR]); > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > index e128adf6ee37..dd3bce287a3d 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > @@ -342,7 +342,6 @@ static int mali_c55_isp_enable_streams(struct v4l2_subdev *sd, > > src_sd = media_entity_to_v4l2_subdev(isp->remote_src->entity); > > - isp->frame_sequence = 0; > ret = mali_c55_isp_start(mali_c55, state); > if (ret) { > dev_err(mali_c55->dev, "Failed to start ISP\n"); > @@ -380,6 +379,7 @@ static int mali_c55_isp_disable_streams(struct v4l2_subdev *sd, > isp->remote_src = NULL; > > mali_c55_isp_stop(mali_c55); > + isp->frame_sequence = UINT_MAX; > > return 0; > } > @@ -584,6 +584,7 @@ int mali_c55_register_isp(struct mali_c55 *mali_c55) > int ret; > > isp->mali_c55 = mali_c55; > + isp->frame_sequence = UINT_MAX; > > v4l2_subdev_init(sd, &mali_c55_isp_ops); > sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; > > base-commit: 95f76f51937fdfb0fc1e14cae606b1ef574a56f3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware 2026-09-30 17:46 [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware David Carlier 2026-10-07 10:29 ` Dan Scally @ 2026-11-10 13:22 ` Jacopo Mondi [not found] ` <CA+XhMqz--zg_rR8_TqziuPXLRDDP1Y1xcNV7WS9_004AfaBtuA@mail.gmail.com> 1 sibling, 1 reply; 4+ messages in thread From: Jacopo Mondi @ 2026-11-10 13:22 UTC (permalink / raw) To: David Carlier Cc: Daniel Scally, Jacopo Mondi, Mauro Carvalho Chehab, Nayden Kanchev, Hans Verkuil, linux-media, linux-kernel, stable Hi David On Wed, Sep 30, 2026 at 06:46:21PM +0100, David Carlier wrote: > The single frame_sequence counter in struct mali_c55_isp is incremented > in mali_c55_set_plane_done(), which runs once per completed buffer per > capture device rather than once per frame. Hardware fitted with the > downscale pipe always hits this: mali_c55_pipeline_ready() refuses to > start the ISP unless both the full-resolution and the downscale queues > are streaming, so the counter advances twice per frame. > > Each video node then reports sequence numbers 0, 2, 4, ..., which > userspace reads as a dropped frame between every pair of frames, and the > two pipes never number the same frame alike, contrary to Sorry to ask, this is not meant to be detrimental to the value of this patch, but in these days I feel like I should ask: - is this an error found running the system with an FR/DS pipeline - is this a report from an LLM Mostly I'm curious to know as I can't test on a system with a DS pipe fitted, knowing you actually tested this would make me more confident in accepting the patch > Documentation/admin-guide/media/mali-c55.rst. The V4L2_EVENT_FRAME_SYNC > event and the statistics and parameters buffers only read the counter, > so their sequence numbers stop identifying a frame too. > > Increment the counter once per frame, when the ISP start interrupt is > handled, and stamp each capture buffer when mali_c55_set_next_buffer() > programs it, as it is written out during the following frame. Stamping > at completion would be off by one whenever DONE(n) and START(n+1) are > handled in the same interrupt, since ISP_START is processed first. Hold > the counter at UINT_MAX while the ISP is stopped, as the first buffers > are programmed before it starts, so the first frame gets sequence zero. > > Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver") > Cc: stable@vger.kernel.org > Assisted-by: Claude:claude-opus-5 > Signed-off-by: David Carlier <devnexen@gmail.com> > --- > v2: > - Stamp the buffer sequence in mali_c55_set_next_buffer() instead of > at completion, which broke when START(n+1) and DONE(n) are handled > together (Jacopo) > - Reset the counter when the ISP stops instead of when it starts > > v1: https://lore.kernel.org/r/20260801205311.386692-1-devnexen@gmail.com > --- > drivers/media/platform/arm/mali-c55/mali-c55-capture.c | 5 +++-- > drivers/media/platform/arm/mali-c55/mali-c55-common.h | 4 ++++ > drivers/media/platform/arm/mali-c55/mali-c55-core.c | 1 + > drivers/media/platform/arm/mali-c55/mali-c55-isp.c | 3 ++- > 4 files changed, 10 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > index ff01553026fb..fa073ce4b2bd 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > @@ -413,6 +413,9 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev) > return; > } > > + /* The buffer is written out during the frame following this one. */ > + buf->vb.sequence = cap_dev->mali_c55->isp.frame_sequence + 1; > + > pix_mp = &cap_dev->format.format; > > mali_c55_cap_dev_update_bits(cap_dev, MALI_C55_REG_Y_WRITER_MODE, > @@ -457,7 +460,6 @@ void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev) > void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, > enum mali_c55_planes plane) > { > - struct mali_c55_isp *isp = &cap_dev->mali_c55->isp; > struct mali_c55_buffer *buf; > > scoped_guard(spinlock, &cap_dev->buffers.processing_lock) { > @@ -476,7 +478,6 @@ void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, > > /* If the other plane is also done... */ > buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns(); > - buf->vb.sequence = isp->frame_sequence++; > vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); > } > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-common.h b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > index 13a3e9dc4243..50f2b7a85f62 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-common.h > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > @@ -76,6 +76,10 @@ struct mali_c55_isp { > struct media_pad *remote_src; > /* Mutex to guard vb2 start/stop streaming */ > struct mutex capture_lock; > + /* > + * Sequence of the frame being processed, incremented at SOF. Held at > + * UINT_MAX while stopped so the first frame gets sequence 0. > + */ > unsigned int frame_sequence; > }; > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > index fb81141d1653..be562156b295 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > @@ -573,6 +573,7 @@ static irqreturn_t mali_c55_isr(int irq, void *context) > for_each_set_bit(i, &interrupt_status, MALI_C55_NUM_IRQ_BITS) { > switch (i) { > case MALI_C55_IRQ_ISP_START: > + mali_c55->isp.frame_sequence++; > mali_c55_isp_queue_event_sof(mali_c55); > > mali_c55_set_next_buffer(&mali_c55->cap_devs[MALI_C55_CAP_DEV_FR]); > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > index e128adf6ee37..dd3bce287a3d 100644 > --- a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > @@ -342,7 +342,6 @@ static int mali_c55_isp_enable_streams(struct v4l2_subdev *sd, > > src_sd = media_entity_to_v4l2_subdev(isp->remote_src->entity); > > - isp->frame_sequence = 0; > ret = mali_c55_isp_start(mali_c55, state); > if (ret) { > dev_err(mali_c55->dev, "Failed to start ISP\n"); > @@ -380,6 +379,7 @@ static int mali_c55_isp_disable_streams(struct v4l2_subdev *sd, > isp->remote_src = NULL; > > mali_c55_isp_stop(mali_c55); > + isp->frame_sequence = UINT_MAX; > > return 0; > } > @@ -584,6 +584,7 @@ int mali_c55_register_isp(struct mali_c55 *mali_c55) > int ret; > > isp->mali_c55 = mali_c55; > + isp->frame_sequence = UINT_MAX; The patch looks ok to me: Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> but I wish we could test it. Knowing the current frame counter stamping is broken already makes it easier for me to collect this patch. > > v4l2_subdev_init(sd, &mali_c55_isp_ops); > sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; > > base-commit: 95f76f51937fdfb0fc1e14cae606b1ef574a56f3 > -- > 2.55.0 > ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <CA+XhMqz--zg_rR8_TqziuPXLRDDP1Y1xcNV7WS9_004AfaBtuA@mail.gmail.com>]
* Re: [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware [not found] ` <CA+XhMqz--zg_rR8_TqziuPXLRDDP1Y1xcNV7WS9_004AfaBtuA@mail.gmail.com> @ 2026-11-10 14:12 ` Jacopo Mondi 0 siblings, 0 replies; 4+ messages in thread From: Jacopo Mondi @ 2026-11-10 14:12 UTC (permalink / raw) To: David CARLIER Cc: Jacopo Mondi, Daniel Scally, Mauro Carvalho Chehab, Nayden Kanchev, Hans Verkuil, linux-media, linux-kernel, stable Hi David On Tue, Nov 10, 2026 at 01:35:56PM +0000, David CARLIER wrote: > Hi, > > On Tue, 10 Nov 2026 at 13:22, Jacopo Mondi <jacopo.mondi@ideasonboard.com> > wrote: > > > Hi David > > > > On Wed, Sep 30, 2026 at 06:46:21PM +0100, David Carlier wrote: > > > The single frame_sequence counter in struct mali_c55_isp is incremented > > > in mali_c55_set_plane_done(), which runs once per completed buffer per > > > capture device rather than once per frame. Hardware fitted with the > > > downscale pipe always hits this: mali_c55_pipeline_ready() refuses to > > > start the ISP unless both the full-resolution and the downscale queues > > > are streaming, so the counter advances twice per frame. > > > > > > Each video node then reports sequence numbers 0, 2, 4, ..., which > > > userspace reads as a dropped frame between every pair of frames, and the > > > two pipes never number the same frame alike, contrary to > > > > Sorry to ask, this is not meant to be detrimental to the value of this > > patch, but in these days I feel like I should ask: > > > > - is this an error found running the system with an FR/DS pipeline > > - is this a report from an LLM > > > > I honestly use LLM to find this issue. > I paid attention however if the increment in mali_c55_set_plane_done() > and above all mali_c55_pipeline_ready() requires the queues when > MALI_C55_GPS_DS_PIPE_FITTED is set. Thanks, as said in the previous reply, we know the current handling of frame sequence is broken, which makes it easier for me to accept a patch not tested on real hw. Honestly, commit messages reporting such a precise analysis of an issue suggest the patch comes from from a real device, not from analysis, and I wonder if in 6 months, if we ever find an issue with this patch we'll remember it hasn't actually been tested. It's a general concern regarding the increasing amount of LLM generated fixes which come from code analysis rather than actual testing. Usage of LLM is now not required to be disclosed, but I wonder if for our own safety we shouldn't clearly say "This issue has been found by an LLM inspecting the code and not tested on a device." on all these automated patches. > > Cheers. > > > > > Mostly I'm curious to know as I can't test on a system with a DS pipe > > fitted, knowing you actually tested this would make me more confident > > in accepting the patch > > > > > Documentation/admin-guide/media/mali-c55.rst. The V4L2_EVENT_FRAME_SYNC > > > event and the statistics and parameters buffers only read the counter, > > > so their sequence numbers stop identifying a frame too. > > > > > > Increment the counter once per frame, when the ISP start interrupt is > > > handled, and stamp each capture buffer when mali_c55_set_next_buffer() > > > programs it, as it is written out during the following frame. Stamping > > > at completion would be off by one whenever DONE(n) and START(n+1) are > > > handled in the same interrupt, since ISP_START is processed first. Hold > > > the counter at UINT_MAX while the ISP is stopped, as the first buffers > > > are programmed before it starts, so the first frame gets sequence zero. > > > > > > Fixes: d5f281f3dd29 ("media: mali-c55: Add Mali-C55 ISP driver") > > > Cc: stable@vger.kernel.org > > > Assisted-by: Claude:claude-opus-5 > > > Signed-off-by: David Carlier <devnexen@gmail.com> > > > --- > > > v2: > > > - Stamp the buffer sequence in mali_c55_set_next_buffer() instead of > > > at completion, which broke when START(n+1) and DONE(n) are handled > > > together (Jacopo) > > > - Reset the counter when the ISP stops instead of when it starts > > > > > > v1: https://lore.kernel.org/r/20260801205311.386692-1-devnexen@gmail.com > > > --- > > > drivers/media/platform/arm/mali-c55/mali-c55-capture.c | 5 +++-- > > > drivers/media/platform/arm/mali-c55/mali-c55-common.h | 4 ++++ > > > drivers/media/platform/arm/mali-c55/mali-c55-core.c | 1 + > > > drivers/media/platform/arm/mali-c55/mali-c55-isp.c | 3 ++- > > > 4 files changed, 10 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > > b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > > > index ff01553026fb..fa073ce4b2bd 100644 > > > --- a/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > > > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-capture.c > > > @@ -413,6 +413,9 @@ void mali_c55_set_next_buffer(struct > > mali_c55_cap_dev *cap_dev) > > > return; > > > } > > > > > > + /* The buffer is written out during the frame following this one. > > */ > > > + buf->vb.sequence = cap_dev->mali_c55->isp.frame_sequence + 1; > > > + > > > pix_mp = &cap_dev->format.format; > > > > > > mali_c55_cap_dev_update_bits(cap_dev, MALI_C55_REG_Y_WRITER_MODE, > > > @@ -457,7 +460,6 @@ void mali_c55_set_next_buffer(struct > > mali_c55_cap_dev *cap_dev) > > > void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, > > > enum mali_c55_planes plane) > > > { > > > - struct mali_c55_isp *isp = &cap_dev->mali_c55->isp; > > > struct mali_c55_buffer *buf; > > > > > > scoped_guard(spinlock, &cap_dev->buffers.processing_lock) { > > > @@ -476,7 +478,6 @@ void mali_c55_set_plane_done(struct mali_c55_cap_dev > > *cap_dev, > > > > > > /* If the other plane is also done... */ > > > buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns(); > > > - buf->vb.sequence = isp->frame_sequence++; > > > vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); > > > } > > > > > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-common.h > > b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > > > index 13a3e9dc4243..50f2b7a85f62 100644 > > > --- a/drivers/media/platform/arm/mali-c55/mali-c55-common.h > > > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-common.h > > > @@ -76,6 +76,10 @@ struct mali_c55_isp { > > > struct media_pad *remote_src; > > > /* Mutex to guard vb2 start/stop streaming */ > > > struct mutex capture_lock; > > > + /* > > > + * Sequence of the frame being processed, incremented at SOF. Held > > at > > > + * UINT_MAX while stopped so the first frame gets sequence 0. > > > + */ > > > unsigned int frame_sequence; > > > }; > > > > > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-core.c > > b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > > > index fb81141d1653..be562156b295 100644 > > > --- a/drivers/media/platform/arm/mali-c55/mali-c55-core.c > > > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-core.c > > > @@ -573,6 +573,7 @@ static irqreturn_t mali_c55_isr(int irq, void > > *context) > > > for_each_set_bit(i, &interrupt_status, MALI_C55_NUM_IRQ_BITS) { > > > switch (i) { > > > case MALI_C55_IRQ_ISP_START: > > > + mali_c55->isp.frame_sequence++; > > > mali_c55_isp_queue_event_sof(mali_c55); > > > > > > > > mali_c55_set_next_buffer(&mali_c55->cap_devs[MALI_C55_CAP_DEV_FR]); > > > diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > > b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > > > index e128adf6ee37..dd3bce287a3d 100644 > > > --- a/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > > > +++ b/drivers/media/platform/arm/mali-c55/mali-c55-isp.c > > > @@ -342,7 +342,6 @@ static int mali_c55_isp_enable_streams(struct > > v4l2_subdev *sd, > > > > > > src_sd = media_entity_to_v4l2_subdev(isp->remote_src->entity); > > > > > > - isp->frame_sequence = 0; > > > ret = mali_c55_isp_start(mali_c55, state); > > > if (ret) { > > > dev_err(mali_c55->dev, "Failed to start ISP\n"); > > > @@ -380,6 +379,7 @@ static int mali_c55_isp_disable_streams(struct > > v4l2_subdev *sd, > > > isp->remote_src = NULL; > > > > > > mali_c55_isp_stop(mali_c55); > > > + isp->frame_sequence = UINT_MAX; > > > > > > return 0; > > > } > > > @@ -584,6 +584,7 @@ int mali_c55_register_isp(struct mali_c55 *mali_c55) > > > int ret; > > > > > > isp->mali_c55 = mali_c55; > > > + isp->frame_sequence = UINT_MAX; > > > > The patch looks ok to me: > > Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > > > > but I wish we could test it. > > > > Knowing the current frame counter stamping is broken already makes it > > easier for me to collect this patch. > > > > > > > > v4l2_subdev_init(sd, &mali_c55_isp_ops); > > > sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | > > V4L2_SUBDEV_FL_HAS_EVENTS; > > > > > > base-commit: 95f76f51937fdfb0fc1e14cae606b1ef574a56f3 > > > -- > > > 2.55.0 > > > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-10 14:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 17:46 [PATCH v2] media: mali-c55: Fix frame sequence numbers on dual-pipe hardware David Carlier
2026-10-07 10:29 ` Dan Scally
2026-11-10 13:22 ` Jacopo Mondi
[not found] ` <CA+XhMqz--zg_rR8_TqziuPXLRDDP1Y1xcNV7WS9_004AfaBtuA@mail.gmail.com>
2026-11-10 14:12 ` Jacopo Mondi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®