* [PATCH v2 1/9] media: qcom: camss: Introduce CPU latency QoS during streaming
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 14:20 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 2/9] media: qcom: camss: Introduce SOF sequence tracking bryan.odonoghue
` (7 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
On a quiescent system - for example the X1 CRD booted to a simple ramdisk
rootfs during development of V4L2_EVENT_FRAME_SYNC it was observed that
interrupt for buffer done could be delayed until after the SOF for the next
frame.
Fiddling about with the interrupt bits, clearing them and changing the
logic of V4L2_EVENT_FRAME_SYNC to buffer completion didn't work and besides
"felt wrong".
Tracing it looks like this:
<idle>-0 [000] d.h1. 36.374380: csid_isr: rdi0 sof=1 done=0
<idle>-0 [000] d.h1. 36.406601: csid_isr: rdi0 sof=1 done=1
<idle>-0 [000] d.h1. 36.439910: csid_isr: rdi0 sof=1 done=1
<idle>-0 [000] d.h1. 36.473245: csid_isr: rdi0 sof=1 done=1
<idle>-0 [000] d.h1. 36.504786: csid_isr: rdi0 sof=0 done=1
<idle>-0 [000] d.h1. 36.506350: csid_isr: rdi0 sof=1 done=0
Tracing with /dev/cpu_dma_latency = 0 looks like this:
<idle>-0 [000] d.h1. 556.149115: csid_isr: rdi0 sof=1 done=0
<idle>-0 [000] d.h1. 556.181338: csid_isr: rdi0 sof=0 done=1
<idle>-0 [000] d.h1. 556.182880: csid_isr: rdi0 sof=1 done=0
<idle>-0 [000] d.h1. 556.214643: csid_isr: rdi0 sof=0 done=1
<idle>-0 [000] d.h1. 556.216185: csid_isr: rdi0 sof=1 done=0
The second is the pattern you expect CSI SOF followed by data.
We will require SOF to track and understand which data-frame is correlated
to which camera stastics and parameters frame. On an ordinary system with
several things pinging off at once, WiFi, display, keyboard you will be
unlikely to hit deep idle and hence unlikely to see the long exit. However
we should design for the case where the system is otherwise quiescent with
only the camera streaming.
Choosing a request of 300us - 1000us seemed to work fine but cutting the
margin finer, similar to the value on IPU6.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss.c | 11 ++++++++++-
drivers/media/platform/qcom/camss/camss.h | 2 ++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index c54185c93a8a9..52bb19f5fbf3b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5834,6 +5834,8 @@ static const struct of_device_id camss_dt_match[] = {
MODULE_DEVICE_TABLE(of, camss_dt_match);
+#define CAMSS_CPU_LATENCY_US 300
+
static int __maybe_unused camss_runtime_suspend(struct device *dev)
{
struct camss *camss = dev_get_drvdata(dev);
@@ -5846,6 +5848,8 @@ static int __maybe_unused camss_runtime_suspend(struct device *dev)
return ret;
}
+ cpu_latency_qos_remove_request(&camss->cpu_latency);
+
#if IS_ENABLED(CONFIG_PM_CLK)
return pm_clk_suspend(dev);
#else
@@ -5866,12 +5870,17 @@ static int __maybe_unused camss_runtime_resume(struct device *dev)
return ret;
#endif
+ cpu_latency_qos_add_request(&camss->cpu_latency,
+ CAMSS_CPU_LATENCY_US);
+
for (i = 0; i < camss->res->icc_path_num; i++) {
ret = icc_set_bw(camss->icc_path[i],
icc_res[i].icc_bw_tbl.avg,
icc_res[i].icc_bw_tbl.peak);
- if (ret)
+ if (ret) {
+ cpu_latency_qos_remove_request(&camss->cpu_latency);
return ret;
+ }
}
return 0;
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 7dc2fd9f03e0d..7564a7c46fa24 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -11,6 +11,7 @@
#define QC_MSM_CAMSS_H
#include <linux/device.h>
+#include <linux/pm_qos.h>
#include <linux/types.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
@@ -141,6 +142,7 @@ struct camss {
struct icc_path *icc_path[ICC_SM8250_COUNT];
const struct camss_resources *res;
bool legacy_phy;
+ struct pm_qos_request cpu_latency;
};
struct camss_camera_interface {
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 1/9] media: qcom: camss: Introduce CPU latency QoS during streaming
2026-11-02 13:56 ` [PATCH v2 1/9] media: qcom: camss: Introduce CPU latency QoS during streaming bryan.odonoghue
@ 2026-11-02 14:20 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 14:20 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> On a quiescent system - for example the X1 CRD booted to a simple ramdisk
> rootfs during development of V4L2_EVENT_FRAME_SYNC it was observed that
> interrupt for buffer done could be delayed until after the SOF for the next
> frame.
>
> Fiddling about with the interrupt bits, clearing them and changing the
> logic of V4L2_EVENT_FRAME_SYNC to buffer completion didn't work and besides
> "felt wrong".
>
> Tracing it looks like this:
> <idle>-0 [000] d.h1. 36.374380: csid_isr: rdi0 sof=1 done=0
> <idle>-0 [000] d.h1. 36.406601: csid_isr: rdi0 sof=1 done=1
> <idle>-0 [000] d.h1. 36.439910: csid_isr: rdi0 sof=1 done=1
> <idle>-0 [000] d.h1. 36.473245: csid_isr: rdi0 sof=1 done=1
> <idle>-0 [000] d.h1. 36.504786: csid_isr: rdi0 sof=0 done=1
> <idle>-0 [000] d.h1. 36.506350: csid_isr: rdi0 sof=1 done=0
>
> Tracing with /dev/cpu_dma_latency = 0 looks like this:
> <idle>-0 [000] d.h1. 556.149115: csid_isr: rdi0 sof=1 done=0
> <idle>-0 [000] d.h1. 556.181338: csid_isr: rdi0 sof=0 done=1
> <idle>-0 [000] d.h1. 556.182880: csid_isr: rdi0 sof=1 done=0
> <idle>-0 [000] d.h1. 556.214643: csid_isr: rdi0 sof=0 done=1
> <idle>-0 [000] d.h1. 556.216185: csid_isr: rdi0 sof=1 done=0
>
> The second is the pattern you expect CSI SOF followed by data.
>
> We will require SOF to track and understand which data-frame is correlated
> to which camera stastics and parameters frame. On an ordinary system with
> several things pinging off at once, WiFi, display, keyboard you will be
> unlikely to hit deep idle and hence unlikely to see the long exit. However
> we should design for the case where the system is otherwise quiescent with
> only the camera streaming.
>
> Choosing a request of 300us - 1000us seemed to work fine but cutting the
> margin finer, similar to the value on IPU6.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss.c | 11 ++++++++++-
> drivers/media/platform/qcom/camss/camss.h | 2 ++
> 2 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index c54185c93a8a9..52bb19f5fbf3b 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -5834,6 +5834,8 @@ static const struct of_device_id camss_dt_match[] = {
>
> MODULE_DEVICE_TABLE(of, camss_dt_match);
>
> +#define CAMSS_CPU_LATENCY_US 300
> +
> static int __maybe_unused camss_runtime_suspend(struct device *dev)
> {
> struct camss *camss = dev_get_drvdata(dev);
> @@ -5846,6 +5848,8 @@ static int __maybe_unused camss_runtime_suspend(struct device *dev)
> return ret;
> }
>
> + cpu_latency_qos_remove_request(&camss->cpu_latency);
> +
> #if IS_ENABLED(CONFIG_PM_CLK)
> return pm_clk_suspend(dev);
> #else
> @@ -5866,12 +5870,17 @@ static int __maybe_unused camss_runtime_resume(struct device *dev)
> return ret;
> #endif
>
> + cpu_latency_qos_add_request(&camss->cpu_latency,
> + CAMSS_CPU_LATENCY_US);
> +
> for (i = 0; i < camss->res->icc_path_num; i++) {
> ret = icc_set_bw(camss->icc_path[i],
> icc_res[i].icc_bw_tbl.avg,
> icc_res[i].icc_bw_tbl.peak);
> - if (ret)
> + if (ret) {
> + cpu_latency_qos_remove_request(&camss->cpu_latency);
> return ret;
> + }
> }
>
> return 0;
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index 7dc2fd9f03e0d..7564a7c46fa24 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -11,6 +11,7 @@
> #define QC_MSM_CAMSS_H
>
> #include <linux/device.h>
> +#include <linux/pm_qos.h>
> #include <linux/types.h>
> #include <media/v4l2-async.h>
> #include <media/v4l2-device.h>
> @@ -141,6 +142,7 @@ struct camss {
> struct icc_path *icc_path[ICC_SM8250_COUNT];
> const struct camss_resources *res;
> bool legacy_phy;
> + struct pm_qos_request cpu_latency;
> };
>
> struct camss_camera_interface {
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 2/9] media: qcom: camss: Introduce SOF sequence tracking
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
2026-11-02 13:56 ` [PATCH v2 1/9] media: qcom: camss: Introduce CPU latency QoS during streaming bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 14:47 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 3/9] media: qcom: camss: Use SOF sequence tracking for vb.sequence bryan.odonoghue
` (6 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
In order to communicate to user-space CSI2 SOF events we will need to hook
into and control v4l2_ctrl_subdev_subscribe_event. In-line with other
implementations of FRAME_SYNC have CSI decoders which support the event
always generate it in our case if and only if an atomic user count
indicates it should be so.
A flag in the CSID descriptor indicates if frame_sync_en is supported so
for each SoC that supports it this flag should be true. Since bool is false
by default no negative enumeration of existing or in-flight CSID is
required.
Subsequent patches will enable on a per-CSID basis.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss-csid.c | 54 +++++++++++++++++++++++++-
drivers/media/platform/qcom/camss/camss-csid.h | 12 ++++++
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index a00791b00feb7..e9b399fcb9c7a 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -760,6 +760,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
static int csid_set_stream(struct v4l2_subdev *sd, int enable)
{
struct csid_device *csid = v4l2_get_subdevdata(sd);
+ unsigned int i;
int ret;
if (enable) {
@@ -778,6 +779,9 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
}
if (csid->phy.need_vc_update) {
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ atomic_set(&csid->sof_seq[i], -1);
+
csid->res->hw_ops->configure_stream(csid, enable);
csid->phy.need_vc_update = false;
}
@@ -1316,9 +1320,57 @@ static int csid_link_setup(struct media_entity *entity,
return 0;
}
+static int csid_frame_sync_add(struct v4l2_subscribed_event *sev, unsigned int elems)
+{
+ struct csid_device *csid = v4l2_get_subdevdata(vdev_to_v4l2_subdev(sev->fh->vdev));
+
+ atomic_inc(&csid->frame_sync_users[sev->id]);
+
+ return 0;
+}
+
+static void csid_frame_sync_del(struct v4l2_subscribed_event *sev)
+{
+ struct csid_device *csid = v4l2_get_subdevdata(vdev_to_v4l2_subdev(sev->fh->vdev));
+
+ atomic_dec(&csid->frame_sync_users[sev->id]);
+}
+
+static const struct v4l2_subscribed_event_ops csid_frame_sync_ops = {
+ .add = csid_frame_sync_add,
+ .del = csid_frame_sync_del,
+};
+
+static int csid_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ struct csid_device *csid = v4l2_get_subdevdata(sd);
+
+ if (sub->type != V4L2_EVENT_FRAME_SYNC)
+ return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
+
+ if (sub->id >= MSM_CSID_MAX_SRC_STREAMS || !csid->res->frame_sync_en)
+ return -EINVAL;
+
+ return v4l2_event_subscribe(fh, sub, 0, &csid_frame_sync_ops);
+}
+
+void csid_sof_event(struct csid_device *csid, unsigned int id)
+{
+ struct v4l2_event event = {
+ .type = V4L2_EVENT_FRAME_SYNC,
+ .id = id,
+ .u.frame_sync.frame_sequence =
+ atomic_inc_return(&csid->sof_seq[id]),
+ };
+
+ if (atomic_read(&csid->frame_sync_users[id]))
+ v4l2_event_queue(csid->subdev.devnode, &event);
+}
+
static const struct v4l2_subdev_core_ops csid_core_ops = {
.s_power = csid_set_power,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+ .subscribe_event = csid_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 5296b10f6bac8..2e48b08b93592 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -141,6 +141,7 @@ struct csid_hw_ops {
struct csid_subdev_resources {
bool is_lite;
+ bool frame_sync_en;
const struct csid_hw_ops *hw_ops;
const struct parent_dev_ops *parent_dev_ops;
const struct csid_formats *formats;
@@ -167,6 +168,8 @@ struct csid_device {
struct v4l2_ctrl_handler ctrls;
struct v4l2_ctrl *testgen_mode;
const struct csid_subdev_resources *res;
+ atomic_t frame_sync_users[MSM_CSID_MAX_SRC_STREAMS];
+ atomic_t sof_seq[MSM_CSID_MAX_SRC_STREAMS];
};
struct camss_subdev_resources;
@@ -248,4 +251,13 @@ u32 csid_hw_version(struct csid_device *csid);
u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
unsigned int match_format_idx, u32 match_code);
+/*
+ * csid_sof_event - Track SOF generate V4L2_EVENT_FRAME_SYNC
+ * @csid: CSID device
+ * @id: CSID src-stream ID
+ *
+ * Called from the CSID interrupt handler on SOF of the path driving the event.
+ */
+void csid_sof_event(struct csid_device *csid, unsigned int id);
+
#endif /* QC_MSM_CAMSS_CSID_H */
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 2/9] media: qcom: camss: Introduce SOF sequence tracking
2026-11-02 13:56 ` [PATCH v2 2/9] media: qcom: camss: Introduce SOF sequence tracking bryan.odonoghue
@ 2026-11-02 14:47 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 14:47 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> In order to communicate to user-space CSI2 SOF events we will need to hook
> into and control v4l2_ctrl_subdev_subscribe_event. In-line with other
> implementations of FRAME_SYNC have CSI decoders which support the event
> always generate it in our case if and only if an atomic user count
> indicates it should be so.
>
> A flag in the CSID descriptor indicates if frame_sync_en is supported so
> for each SoC that supports it this flag should be true. Since bool is false
> by default no negative enumeration of existing or in-flight CSID is
> required.
>
> Subsequent patches will enable on a per-CSID basis.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
> drivers/media/platform/qcom/camss/camss-csid.c | 54 +++++++++++++++++++++++++-
> drivers/media/platform/qcom/camss/camss-csid.h | 12 ++++++
> 2 files changed, 65 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index a00791b00feb7..e9b399fcb9c7a 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -760,6 +760,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
> static int csid_set_stream(struct v4l2_subdev *sd, int enable)
> {
> struct csid_device *csid = v4l2_get_subdevdata(sd);
> + unsigned int i;
> int ret;
>
> if (enable) {
> @@ -778,6 +779,9 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
> }
>
> if (csid->phy.need_vc_update) {
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
> + atomic_set(&csid->sof_seq[i], -1);
Should we introduce a `csid_sof_reset()` helper and only invoke it on
the enable path?
For example, on disable we currently reset the value before stopping
the CSID, so a late IRQ could still arrive and update `seq`. In
practice this is probably harmless since the value gets reset again on
the next enable...
Also, a short comment explaining why the sequence is initialized to
`-1` would be helpful.
> +
> csid->res->hw_ops->configure_stream(csid, enable);
> csid->phy.need_vc_update = false;
> }
> @@ -1316,9 +1320,57 @@ static int csid_link_setup(struct media_entity *entity,
> return 0;
> }
>
> +static int csid_frame_sync_add(struct v4l2_subscribed_event *sev, unsigned int elems)
> +{
> + struct csid_device *csid = v4l2_get_subdevdata(vdev_to_v4l2_subdev(sev->fh->vdev));
> +
> + atomic_inc(&csid->frame_sync_users[sev->id]);
> +
> + return 0;
> +}
> +
> +static void csid_frame_sync_del(struct v4l2_subscribed_event *sev)
> +{
> + struct csid_device *csid = v4l2_get_subdevdata(vdev_to_v4l2_subdev(sev->fh->vdev));
> +
> + atomic_dec(&csid->frame_sync_users[sev->id]);
> +}
> +
> +static const struct v4l2_subscribed_event_ops csid_frame_sync_ops = {
> + .add = csid_frame_sync_add,
> + .del = csid_frame_sync_del,
> +};
> +
> +static int csid_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
> + struct v4l2_event_subscription *sub)
> +{
> + struct csid_device *csid = v4l2_get_subdevdata(sd);
> +
> + if (sub->type != V4L2_EVENT_FRAME_SYNC)
> + return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
> +
> + if (sub->id >= MSM_CSID_MAX_SRC_STREAMS || !csid->res->frame_sync_en)
> + return -EINVAL;
> +
> + return v4l2_event_subscribe(fh, sub, 0, &csid_frame_sync_ops);
> +}
> +
> +void csid_sof_event(struct csid_device *csid, unsigned int id)
> +{
> + struct v4l2_event event = {
> + .type = V4L2_EVENT_FRAME_SYNC,
> + .id = id,
> + .u.frame_sync.frame_sequence =
> + atomic_inc_return(&csid->sof_seq[id]),
> + };
> +
> + if (atomic_read(&csid->frame_sync_users[id]))
> + v4l2_event_queue(csid->subdev.devnode, &event);
> +}
> +
> static const struct v4l2_subdev_core_ops csid_core_ops = {
> .s_power = csid_set_power,
> - .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> + .subscribe_event = csid_subscribe_event,
> .unsubscribe_event = v4l2_event_subdev_unsubscribe,
> };
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 5296b10f6bac8..2e48b08b93592 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -141,6 +141,7 @@ struct csid_hw_ops {
>
> struct csid_subdev_resources {
> bool is_lite;
> + bool frame_sync_en;
> const struct csid_hw_ops *hw_ops;
> const struct parent_dev_ops *parent_dev_ops;
> const struct csid_formats *formats;
> @@ -167,6 +168,8 @@ struct csid_device {
> struct v4l2_ctrl_handler ctrls;
> struct v4l2_ctrl *testgen_mode;
> const struct csid_subdev_resources *res;
> + atomic_t frame_sync_users[MSM_CSID_MAX_SRC_STREAMS];
> + atomic_t sof_seq[MSM_CSID_MAX_SRC_STREAMS];
> };
>
> struct camss_subdev_resources;
> @@ -248,4 +251,13 @@ u32 csid_hw_version(struct csid_device *csid);
> u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
> unsigned int match_format_idx, u32 match_code);
>
> +/*
> + * csid_sof_event - Track SOF generate V4L2_EVENT_FRAME_SYNC
> + * @csid: CSID device
> + * @id: CSID src-stream ID
> + *
> + * Called from the CSID interrupt handler on SOF of the path driving the event.
> + */
> +void csid_sof_event(struct csid_device *csid, unsigned int id);
> +
> #endif /* QC_MSM_CAMSS_CSID_H */
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 3/9] media: qcom: camss: Use SOF sequence tracking for vb.sequence
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
2026-11-02 13:56 ` [PATCH v2 1/9] media: qcom: camss: Introduce CPU latency QoS during streaming bryan.odonoghue
2026-11-02 13:56 ` [PATCH v2 2/9] media: qcom: camss: Introduce SOF sequence tracking bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 14:55 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 4/9] media: qcom: camss: csid-gen3: Enable RDI SOF driving bryan.odonoghue
` (5 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
We want to correlate statistics buffers with data-buffers. To do that we
will need to have a sequence number driven by the SOF signal.
Rather than incrementing vb.sequence when data arrives, we should increment
when SOF happens.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss-csid.c | 14 ++++++++++++++
drivers/media/platform/qcom/camss/camss-csid.h | 9 +++++++++
drivers/media/platform/qcom/camss/camss-vfe-17x.c | 5 ++++-
drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
5 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index e9b399fcb9c7a..4f4ed4fa46aac 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -1355,6 +1355,20 @@ static int csid_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
return v4l2_event_subscribe(fh, sub, 0, &csid_frame_sync_ops);
}
+atomic_t *csid_get_sof_seq(struct media_pad *pad)
+{
+ struct csid_device *csid;
+
+ if (!pad || pad->index < MSM_CSID_PAD_FIRST_SRC)
+ return NULL;
+
+ csid = v4l2_get_subdevdata(media_entity_to_v4l2_subdev(pad->entity));
+ if (!csid->res->frame_sync_en)
+ return NULL;
+
+ return &csid->sof_seq[pad->index - MSM_CSID_PAD_FIRST_SRC];
+}
+
void csid_sof_event(struct csid_device *csid, unsigned int id)
{
struct v4l2_event event = {
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 2e48b08b93592..f3199579e3442 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -260,4 +260,13 @@ u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
*/
void csid_sof_event(struct csid_device *csid, unsigned int id);
+/*
+ * csid_get_sof_seq - Get a pointer to the SOF frame sequence variable.
+ * @pad: Remote pad of a consumer's sink pad
+ *
+ * Return the counter or NULL if @pad isn't a CSID or the CSID doesn't support
+ * SOF tracking.
+ */
+atomic_t *csid_get_sof_seq(struct media_pad *pad);
+
#endif /* QC_MSM_CAMSS_CSID_H */
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-17x.c b/drivers/media/platform/qcom/camss/camss-vfe-17x.c
index 62c2405359a06..4972d3ab65078 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-17x.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-17x.c
@@ -491,7 +491,10 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
}
ready_buf->vb.vb2_buf.timestamp = ts;
- ready_buf->vb.sequence = output->sequence++;
+ if (line->sof_seq)
+ ready_buf->vb.sequence = atomic_read(line->sof_seq);
+ else
+ ready_buf->vb.sequence = output->sequence++;
index = 0;
output->buf[0] = output->buf[1];
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 2680a9914765f..da373024c847e 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -474,7 +474,10 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
}
ready_buf->vb.vb2_buf.timestamp = ts;
- ready_buf->vb.sequence = output->sequence++;
+ if (line->sof_seq)
+ ready_buf->vb.sequence = atomic_read(line->sof_seq);
+ else
+ ready_buf->vb.sequence = output->sequence++;
index = 0;
output->buf[0] = output->buf[1];
@@ -508,6 +511,7 @@ int vfe_enable_output_v2(struct vfe_line *line)
struct vfe_output *output = &line->output;
const struct vfe_hw_ops *ops = vfe->res->hw_ops;
struct media_pad *sensor_pad;
+ struct media_pad *csid_pad;
unsigned long flags;
unsigned int frame_skip = 0;
unsigned int i;
@@ -523,6 +527,9 @@ int vfe_enable_output_v2(struct vfe_line *line)
frame_skip = VFE_FRAME_DROP_VAL - 1;
}
+ csid_pad = media_pad_remote_pad_first(&line->pads[MSM_VFE_PAD_SINK]);
+ line->sof_seq = csid_get_sof_seq(csid_pad);
+
spin_lock_irqsave(&vfe->output_lock, flags);
ops->reg_update_clear(vfe, line->id);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index ae9dad353a378..0e2dfa58421ad 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -94,6 +94,7 @@ struct vfe_line {
struct vfe_output output;
const struct camss_format_info *formats;
unsigned int nformats;
+ atomic_t *sof_seq;
};
struct vfe_device;
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 3/9] media: qcom: camss: Use SOF sequence tracking for vb.sequence
2026-11-02 13:56 ` [PATCH v2 3/9] media: qcom: camss: Use SOF sequence tracking for vb.sequence bryan.odonoghue
@ 2026-11-02 14:55 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 14:55 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> We want to correlate statistics buffers with data-buffers. To do that we
> will need to have a sequence number driven by the SOF signal.
>
> Rather than incrementing vb.sequence when data arrives, we should increment
> when SOF happens.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid.c | 14 ++++++++++++++
> drivers/media/platform/qcom/camss/camss-csid.h | 9 +++++++++
> drivers/media/platform/qcom/camss/camss-vfe-17x.c | 5 ++++-
> drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
> drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
> 5 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index e9b399fcb9c7a..4f4ed4fa46aac 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -1355,6 +1355,20 @@ static int csid_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
> return v4l2_event_subscribe(fh, sub, 0, &csid_frame_sync_ops);
> }
>
> +atomic_t *csid_get_sof_seq(struct media_pad *pad)
> +{
> + struct csid_device *csid;
> +
> + if (!pad || pad->index < MSM_CSID_PAD_FIRST_SRC)
> + return NULL;
> +
> + csid = v4l2_get_subdevdata(media_entity_to_v4l2_subdev(pad->entity));
> + if (!csid->res->frame_sync_en)
> + return NULL;
> +
> + return &csid->sof_seq[pad->index - MSM_CSID_PAD_FIRST_SRC];
> +}
> +
> void csid_sof_event(struct csid_device *csid, unsigned int id)
> {
> struct v4l2_event event = {
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 2e48b08b93592..f3199579e3442 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -260,4 +260,13 @@ u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
> */
> void csid_sof_event(struct csid_device *csid, unsigned int id);
>
> +/*
> + * csid_get_sof_seq - Get a pointer to the SOF frame sequence variable.
> + * @pad: Remote pad of a consumer's sink pad
> + *
> + * Return the counter or NULL if @pad isn't a CSID or the CSID doesn't support
> + * SOF tracking.
> + */
> +atomic_t *csid_get_sof_seq(struct media_pad *pad);
> +
> #endif /* QC_MSM_CAMSS_CSID_H */
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-17x.c b/drivers/media/platform/qcom/camss/camss-vfe-17x.c
> index 62c2405359a06..4972d3ab65078 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-17x.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-17x.c
> @@ -491,7 +491,10 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
> }
>
> ready_buf->vb.vb2_buf.timestamp = ts;
> - ready_buf->vb.sequence = output->sequence++;
> + if (line->sof_seq)
> + ready_buf->vb.sequence = atomic_read(line->sof_seq);
> + else
> + ready_buf->vb.sequence = output->sequence++;
>
> index = 0;
> output->buf[0] = output->buf[1];
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 2680a9914765f..da373024c847e 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -474,7 +474,10 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
> }
>
> ready_buf->vb.vb2_buf.timestamp = ts;
> - ready_buf->vb.sequence = output->sequence++;
> + if (line->sof_seq)
> + ready_buf->vb.sequence = atomic_read(line->sof_seq);
> + else
> + ready_buf->vb.sequence = output->sequence++;
>
> index = 0;
> output->buf[0] = output->buf[1];
> @@ -508,6 +511,7 @@ int vfe_enable_output_v2(struct vfe_line *line)
> struct vfe_output *output = &line->output;
> const struct vfe_hw_ops *ops = vfe->res->hw_ops;
> struct media_pad *sensor_pad;
> + struct media_pad *csid_pad;
> unsigned long flags;
> unsigned int frame_skip = 0;
> unsigned int i;
> @@ -523,6 +527,9 @@ int vfe_enable_output_v2(struct vfe_line *line)
> frame_skip = VFE_FRAME_DROP_VAL - 1;
> }
>
> + csid_pad = media_pad_remote_pad_first(&line->pads[MSM_VFE_PAD_SINK]);
> + line->sof_seq = csid_get_sof_seq(csid_pad);
> +
> spin_lock_irqsave(&vfe->output_lock, flags);
>
> ops->reg_update_clear(vfe, line->id);
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index ae9dad353a378..0e2dfa58421ad 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -94,6 +94,7 @@ struct vfe_line {
> struct vfe_output output;
> const struct camss_format_info *formats;
> unsigned int nformats;
> + atomic_t *sof_seq;
> };
>
> struct vfe_device;
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 4/9] media: qcom: camss: csid-gen3: Enable RDI SOF driving
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (2 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 3/9] media: qcom: camss: Use SOF sequence tracking for vb.sequence bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 15:10 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 5/9] media: qcom: camss: csid-680: Enable RDI SOF tracking bryan.odonoghue
` (4 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Add in silicon enabling code to generate SOF and trigger the routine which
produces V4L2_EVENT_FRAME_SYNC based on SOF per standard v4l2 behaviour.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
.../media/platform/qcom/camss/camss-csid-gen3.c | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
index 0fdbf75fb27db..6a538d825f78b 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen3.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
@@ -34,6 +34,7 @@
#define CSID_RUP_AUP_RDI(rdi) ((BIT(4) | BIT(20)) << (rdi))
#define CSID_TOP_IRQ_STATUS 0x7C
+#define TOP_IRQ_RDI(rdi) BIT(8 + (rdi))
#define TOP_IRQ_STATUS_RESET_DONE BIT(0)
#define CSID_TOP_IRQ_MASK 0x80
@@ -58,6 +59,9 @@
#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi))
#define RUP_DONE_IRQ_STATUS BIT(23)
+#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0xF0 + 0x10 * (rdi))
+#define INFO_INPUT_SOF_IRQ BIT(12)
+
#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi))
#define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi))
@@ -219,6 +223,25 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
writel(val, csid->base + CSID_RDI_CFG0(port));
}
+static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
+{
+ u32 val = 0;
+
+ if (enable)
+ val = INFO_INPUT_SOF_IRQ;
+
+ writel(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
+
+ val = readl(csid->base + CSID_TOP_IRQ_MASK);
+
+ if (enable)
+ val |= TOP_IRQ_RDI(rdi);
+ else
+ val &= ~TOP_IRQ_RDI(rdi);
+
+ writel(val, csid->base + CSID_TOP_IRQ_MASK);
+}
+
static void csid_configure_stream(struct csid_device *csid, u8 enable)
{
u8 i;
@@ -230,6 +253,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
if (csid->phy.en_vc & BIT(i)) {
__csid_configure_rdi_stream(csid, enable, i, 0);
__csid_configure_rx(csid, &csid->phy, 0);
+ __csid_configure_rdi_irq(csid, enable, i);
__csid_ctrl_rdi(csid, enable, i);
}
}
@@ -279,6 +303,9 @@ static irqreturn_t csid_isr(int irq, void *dev)
val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+ if (val & INFO_INPUT_SOF_IRQ)
+ csid_sof_event(csid, i);
+
if (val & RUP_DONE_IRQ_STATUS)
/* clear the reg update bit */
csid_subdev_reg_update(csid, i, true);
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 4/9] media: qcom: camss: csid-gen3: Enable RDI SOF driving
2026-11-02 13:56 ` [PATCH v2 4/9] media: qcom: camss: csid-gen3: Enable RDI SOF driving bryan.odonoghue
@ 2026-11-02 15:10 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 15:10 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> Add in silicon enabling code to generate SOF and trigger the routine which
> produces V4L2_EVENT_FRAME_SYNC based on SOF per standard v4l2 behaviour.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> .../media/platform/qcom/camss/camss-csid-gen3.c | 27 ++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
> index 0fdbf75fb27db..6a538d825f78b 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid-gen3.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
> @@ -34,6 +34,7 @@
> #define CSID_RUP_AUP_RDI(rdi) ((BIT(4) | BIT(20)) << (rdi))
>
> #define CSID_TOP_IRQ_STATUS 0x7C
> +#define TOP_IRQ_RDI(rdi) BIT(8 + (rdi))
> #define TOP_IRQ_STATUS_RESET_DONE BIT(0)
>
> #define CSID_TOP_IRQ_MASK 0x80
> @@ -58,6 +59,9 @@
> #define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi))
> #define RUP_DONE_IRQ_STATUS BIT(23)
>
> +#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0xF0 + 0x10 * (rdi))
> +#define INFO_INPUT_SOF_IRQ BIT(12)
> +
> #define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi))
> #define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi))
>
> @@ -219,6 +223,25 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
> writel(val, csid->base + CSID_RDI_CFG0(port));
> }
>
> +static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
> +{
> + u32 val = 0;
> +
> + if (enable)
> + val = INFO_INPUT_SOF_IRQ;
> +
> + writel(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
> +
> + val = readl(csid->base + CSID_TOP_IRQ_MASK);
> +
> + if (enable)
> + val |= TOP_IRQ_RDI(rdi);
> + else
> + val &= ~TOP_IRQ_RDI(rdi);
> +
> + writel(val, csid->base + CSID_TOP_IRQ_MASK);
> +}
> +
> static void csid_configure_stream(struct csid_device *csid, u8 enable)
> {
> u8 i;
> @@ -230,6 +253,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
> if (csid->phy.en_vc & BIT(i)) {
> __csid_configure_rdi_stream(csid, enable, i, 0);
> __csid_configure_rx(csid, &csid->phy, 0);
> + __csid_configure_rdi_irq(csid, enable, i);
> __csid_ctrl_rdi(csid, enable, i);
> }
> }
> @@ -279,6 +303,9 @@ static irqreturn_t csid_isr(int irq, void *dev)
> val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
> writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
>
> + if (val & INFO_INPUT_SOF_IRQ)
> + csid_sof_event(csid, i);
> +
> if (val & RUP_DONE_IRQ_STATUS)
> /* clear the reg update bit */
> csid_subdev_reg_update(csid, i, true);
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 5/9] media: qcom: camss: csid-680: Enable RDI SOF tracking
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (3 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 4/9] media: qcom: camss: csid-gen3: Enable RDI SOF driving bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 15:11 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 6/9] media: qcom: camss: csid-gen2: " bryan.odonoghue
` (3 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Similarly to the sm8650 we can quite easily switch on V4L2_EVENT_FRAME_SYNC
for x1e/x2e which uses csid-680.
Do so now.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss-csid-680.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid-680.c b/drivers/media/platform/qcom/camss/camss-csid-680.c
index 345a67c8fb947..452640e72f6d5 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-680.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-680.c
@@ -296,6 +296,20 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
writel(val, csid->base + CSID_RDI_CFG0(port));
}
+static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
+{
+ u32 val;
+
+ val = readl(csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
+
+ if (enable)
+ val |= CSID_CSI2_RDIN_INFO_INPUT_SOF;
+ else
+ val &= ~CSID_CSI2_RDIN_INFO_INPUT_SOF;
+
+ writel(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
+}
+
static void csid_configure_stream(struct csid_device *csid, u8 enable)
{
int i;
@@ -307,6 +321,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
if (csid->phy.en_vc & BIT(i)) {
__csid_configure_rdi_stream(csid, enable, i, 0);
__csid_configure_rx(csid, &csid->phy, 0);
+ __csid_configure_rdi_irq(csid, enable, i);
__csid_ctrl_rdi(csid, enable, i);
}
}
@@ -395,6 +410,9 @@ static irqreturn_t csid_isr(int irq, void *dev)
if (val)
writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+ if (val & CSID_CSI2_RDIN_INFO_INPUT_SOF)
+ csid_sof_event(csid, i);
+
if (val & CSID_CSI2_RDIN_RUP_DONE)
csid_rup_complete(csid, i);
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 5/9] media: qcom: camss: csid-680: Enable RDI SOF tracking
2026-11-02 13:56 ` [PATCH v2 5/9] media: qcom: camss: csid-680: Enable RDI SOF tracking bryan.odonoghue
@ 2026-11-02 15:11 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 15:11 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> Similarly to the sm8650 we can quite easily switch on V4L2_EVENT_FRAME_SYNC
> for x1e/x2e which uses csid-680.
>
> Do so now.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid-680.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-680.c b/drivers/media/platform/qcom/camss/camss-csid-680.c
> index 345a67c8fb947..452640e72f6d5 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid-680.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid-680.c
> @@ -296,6 +296,20 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
> writel(val, csid->base + CSID_RDI_CFG0(port));
> }
>
> +static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
> +{
> + u32 val;
> +
> + val = readl(csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
> +
> + if (enable)
> + val |= CSID_CSI2_RDIN_INFO_INPUT_SOF;
> + else
> + val &= ~CSID_CSI2_RDIN_INFO_INPUT_SOF;
> +
> + writel(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
> +}
> +
> static void csid_configure_stream(struct csid_device *csid, u8 enable)
> {
> int i;
> @@ -307,6 +321,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
> if (csid->phy.en_vc & BIT(i)) {
> __csid_configure_rdi_stream(csid, enable, i, 0);
> __csid_configure_rx(csid, &csid->phy, 0);
> + __csid_configure_rdi_irq(csid, enable, i);
> __csid_ctrl_rdi(csid, enable, i);
> }
> }
> @@ -395,6 +410,9 @@ static irqreturn_t csid_isr(int irq, void *dev)
> if (val)
> writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
>
> + if (val & CSID_CSI2_RDIN_INFO_INPUT_SOF)
> + csid_sof_event(csid, i);
> +
> if (val & CSID_CSI2_RDIN_RUP_DONE)
> csid_rup_complete(csid, i);
>
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 6/9] media: qcom: camss: csid-gen2: Enable RDI SOF tracking
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (4 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 5/9] media: qcom: camss: csid-680: Enable RDI SOF tracking bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 15:18 ` Loic Poulain
2026-11-02 13:56 ` [PATCH v2 7/9] media: qcom: camss: Switch on frame_sync_en logic for csid-gen3 bryan.odonoghue
` (2 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Add silicon specific changes to get SOF triggering V4L2_EVENT_FRAME_SYNC
'gen2' CSID. Covers SDM845, SDM670, SM6150, SM6350, SC7280, SC8280XP,
SM8250.
Tested thoroughly on sm8250 only for now. An additional patch is required
in camss.c to enable this functionality on a per-SoC basis.
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss-csid-gen2.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
index eadcb2f7e3aaa..a351ac4b91728 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -38,6 +38,8 @@
#define CSID_CSI2_RDIN_IRQ_SET(rdi) ((csid_is_lite(csid) ? 0x3C : 0x4C) \
+ 0x10 * (rdi))
+#define RDIN_IRQ_INFO_INPUT_SOF BIT(12)
+
#define CSID_TOP_IRQ_STATUS 0x70
#define TOP_IRQ_STATUS_RESET_DONE 0
#define CSID_TOP_IRQ_MASK 0x74
@@ -322,6 +324,16 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
writel_relaxed(val, csid->base + CSID_RDI_CFG0(port));
}
+static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
+{
+ u32 val = 0;
+
+ if (enable)
+ val = RDIN_IRQ_INFO_INPUT_SOF;
+
+ writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
+}
+
static void csid_configure_stream(struct csid_device *csid, u8 enable)
{
struct csid_testgen_config *tg = &csid->testgen;
@@ -335,6 +347,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
__csid_configure_rdi_stream(csid, enable, i, 0);
__csid_configure_rx(csid, &csid->phy, 0);
+ __csid_configure_rdi_irq(csid, enable, i);
__csid_ctrl_rdi(csid, enable, i);
}
}
@@ -373,6 +386,8 @@ static irqreturn_t csid_isr(int irq, void *dev)
if (csid->phy.en_vc & BIT(i)) {
val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+ if (val & RDIN_IRQ_INFO_INPUT_SOF)
+ csid_sof_event(csid, i);
}
val = 1 << IRQ_CMD_CLEAR;
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 6/9] media: qcom: camss: csid-gen2: Enable RDI SOF tracking
2026-11-02 13:56 ` [PATCH v2 6/9] media: qcom: camss: csid-gen2: " bryan.odonoghue
@ 2026-11-02 15:18 ` Loic Poulain
0 siblings, 0 replies; 19+ messages in thread
From: Loic Poulain @ 2026-11-02 15:18 UTC (permalink / raw)
To: bryan.odonoghue
Cc: Vladimir Zapolskiy, Mauro Carvalho Chehab, linux-media,
linux-arm-msm, linux-kernel, Bryan O'Donoghue
On Mon, Nov 2, 2026 at 2:57 PM <bryan.odonoghue@linaro.org> wrote:
>
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> Add silicon specific changes to get SOF triggering V4L2_EVENT_FRAME_SYNC
> 'gen2' CSID. Covers SDM845, SDM670, SM6150, SM6350, SC7280, SC8280XP,
> SM8250.
>
> Tested thoroughly on sm8250 only for now. An additional patch is required
> in camss.c to enable this functionality on a per-SoC basis.
>
> Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
I guess we don't perform a read-modify-write on the IRQ mask here
because SOF is the only interrupt we're interested in.
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid-gen2.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
> index eadcb2f7e3aaa..a351ac4b91728 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
> @@ -38,6 +38,8 @@
> #define CSID_CSI2_RDIN_IRQ_SET(rdi) ((csid_is_lite(csid) ? 0x3C : 0x4C) \
> + 0x10 * (rdi))
>
> +#define RDIN_IRQ_INFO_INPUT_SOF BIT(12)
> +
> #define CSID_TOP_IRQ_STATUS 0x70
> #define TOP_IRQ_STATUS_RESET_DONE 0
> #define CSID_TOP_IRQ_MASK 0x74
> @@ -322,6 +324,16 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8
> writel_relaxed(val, csid->base + CSID_RDI_CFG0(port));
> }
>
> +static void __csid_configure_rdi_irq(struct csid_device *csid, u8 enable, u8 rdi)
> +{
> + u32 val = 0;
> +
> + if (enable)
> + val = RDIN_IRQ_INFO_INPUT_SOF;
> +
> + writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_MASK(rdi));
> +}
> +
> static void csid_configure_stream(struct csid_device *csid, u8 enable)
> {
> struct csid_testgen_config *tg = &csid->testgen;
> @@ -335,6 +347,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
>
> __csid_configure_rdi_stream(csid, enable, i, 0);
> __csid_configure_rx(csid, &csid->phy, 0);
> + __csid_configure_rdi_irq(csid, enable, i);
> __csid_ctrl_rdi(csid, enable, i);
> }
> }
> @@ -373,6 +386,8 @@ static irqreturn_t csid_isr(int irq, void *dev)
> if (csid->phy.en_vc & BIT(i)) {
> val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
> writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
> + if (val & RDIN_IRQ_INFO_INPUT_SOF)
> + csid_sof_event(csid, i);
> }
>
> val = 1 << IRQ_CMD_CLEAR;
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 7/9] media: qcom: camss: Switch on frame_sync_en logic for csid-gen3.
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (5 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 6/9] media: qcom: camss: csid-gen2: " bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 13:56 ` [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e bryan.odonoghue
2026-11-02 13:56 ` [PATCH v2 9/9] media: qcom: camss: Switch on frame_sync_en for csid-gen2 bryan.odonoghue
8 siblings, 0 replies; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Switch frame_sync_en to true to track and consume SOF/EOF data.
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8650-hdk
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 52bb19f5fbf3b..b7821019241d7 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -3120,6 +3120,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3135,6 +3136,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3150,6 +3152,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3165,6 +3168,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.reg = { "csid_lite0" },
.interrupt = { "csid_lite0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3180,6 +3184,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.reg = { "csid_lite1" },
.interrupt = { "csid_lite1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3433,6 +3438,7 @@ static const struct camss_subdev_resources csid_res_sm8650[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2,
@@ -3447,6 +3453,7 @@ static const struct camss_subdev_resources csid_res_sm8650[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2,
@@ -3461,6 +3468,7 @@ static const struct camss_subdev_resources csid_res_sm8650[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2,
@@ -3476,6 +3484,7 @@ static const struct camss_subdev_resources csid_res_sm8650[] = {
.reg = { "csid_lite0" },
.interrupt = { "csid_lite0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3492,6 +3501,7 @@ static const struct camss_subdev_resources csid_res_sm8650[] = {
.reg = { "csid_lite1" },
.interrupt = { "csid_lite1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
.hw_ops = &csid_ops_gen3,
@@ -3790,6 +3800,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3807,6 +3818,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3825,6 +3837,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid_lite0" },
.interrupt = { "csid_lite0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3842,6 +3855,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid_lite1" },
.interrupt = { "csid_lite1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3859,6 +3873,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid_lite2" },
.interrupt = { "csid_lite2" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3876,6 +3891,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid_lite3" },
.interrupt = { "csid_lite3" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -3893,6 +3909,7 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
.reg = { "csid_lite4" },
.interrupt = { "csid_lite4" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen3,
.parent_dev_ops = &vfe_parent_dev_ops,
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (6 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 7/9] media: qcom: camss: Switch on frame_sync_en logic for csid-gen3 bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
2026-11-02 14:32 ` Konrad Dybcio
2026-11-02 13:56 ` [PATCH v2 9/9] media: qcom: camss: Switch on frame_sync_en for csid-gen2 bryan.odonoghue
8 siblings, 1 reply; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Switch frame_sync_en to true to track and consume SOF/EOF data.
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e CRD
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index b7821019241d7..7911b30494ac9 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -4255,6 +4255,7 @@ static const struct camss_subdev_resources csid_res_x1e80100[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_680,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -4275,6 +4276,7 @@ static const struct camss_subdev_resources csid_res_x1e80100[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_680,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -4295,6 +4297,7 @@ static const struct camss_subdev_resources csid_res_x1e80100[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_680,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -4316,6 +4319,7 @@ static const struct camss_subdev_resources csid_res_x1e80100[] = {
.interrupt = { "csid_lite0" },
.csid = {
.is_lite = true,
+ .frame_sync_en = true,
.hw_ops = &csid_ops_680,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -4338,6 +4342,7 @@ static const struct camss_subdev_resources csid_res_x1e80100[] = {
.interrupt = { "csid_lite1" },
.csid = {
.is_lite = true,
+ .frame_sync_en = true,
.hw_ops = &csid_ops_680,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e
2026-11-02 13:56 ` [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e bryan.odonoghue
@ 2026-11-02 14:32 ` Konrad Dybcio
2026-11-02 15:54 ` Bryan O'Donoghue
0 siblings, 1 reply; 19+ messages in thread
From: Konrad Dybcio @ 2026-11-02 14:32 UTC (permalink / raw)
To: bryan.odonoghue, Vladimir Zapolskiy, Loic Poulain, Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
On 11/2/26 2:56 PM, bryan.odonoghue@linaro.org wrote:
> From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> Switch frame_sync_en to true to track and consume SOF/EOF data.
>
> Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e CRD
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
Is there a reason why it's gated behind a feature flag? Will
exposing a SOF seq counter that's always zero (i.e. not
implemented, never bumped) have negative consequences on
userspace?
Conversely, what information (i.e. platform list) are you
lacking that would let us make this non-opt-in?
Konrad
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e
2026-11-02 14:32 ` Konrad Dybcio
@ 2026-11-02 15:54 ` Bryan O'Donoghue
2026-11-02 15:55 ` Bryan O'Donoghue
0 siblings, 1 reply; 19+ messages in thread
From: Bryan O'Donoghue @ 2026-11-02 15:54 UTC (permalink / raw)
To: Konrad Dybcio, Vladimir Zapolskiy, Loic Poulain, Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
On 02/11/2026 14:32, Konrad Dybcio wrote:
> On 11/2/26 2:56 PM,bryan.odonoghue@linaro.org wrote:
>> From: Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>>
>> Switch frame_sync_en to true to track and consume SOF/EOF data.
>>
>> Tested-by: Bryan O'Donoghue<bryan.odonoghue@linaro.org> # x1e CRD
>> Signed-off-by: Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>> ---
> Is there a reason why it's gated behind a feature flag? Will
> exposing a SOF seq counter that's always zero (i.e. not
> implemented, never bumped) have negative consequences on
> userspace?
>
> Conversely, what information (i.e. platform list) are you
> lacking that would let us make this non-opt-in?
>
> Konrad
Yes.
To be in-spece we should already be incrementing vb.sequence not on
every RX data-frame but on every MIPI_CSI2.SOF. You can't just return
zero as user-space wants to know about sequence numbers.
---
bod
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 9/9] media: qcom: camss: Switch on frame_sync_en for csid-gen2
2026-11-02 13:56 [PATCH v2 0/9] Add SOF sequence logic bryan.odonoghue
` (7 preceding siblings ...)
2026-11-02 13:56 ` [PATCH v2 8/9] media: qcom: camss: Switch on frame_sync_en for x1e/x2e bryan.odonoghue
@ 2026-11-02 13:56 ` bryan.odonoghue
8 siblings, 0 replies; 19+ messages in thread
From: bryan.odonoghue @ 2026-11-02 13:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Bryan O'Donoghue
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Switch frame_sync_en to true to track and consume SOF/EOF data.
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # rb5
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/camss/camss.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 7911b30494ac9..bfff28e789b04 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1132,6 +1132,7 @@ static const struct camss_subdev_resources csid_res_670[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1151,6 +1152,7 @@ static const struct camss_subdev_resources csid_res_670[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1170,6 +1172,7 @@ static const struct camss_subdev_resources csid_res_670[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -1361,6 +1364,7 @@ static const struct camss_subdev_resources csid_res_845[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1389,6 +1393,7 @@ static const struct camss_subdev_resources csid_res_845[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1417,6 +1422,7 @@ static const struct camss_subdev_resources csid_res_845[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -1573,6 +1579,7 @@ static const struct camss_subdev_resources csid_res_sm6150[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -1588,6 +1595,7 @@ static const struct camss_subdev_resources csid_res_sm6150[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -1603,6 +1611,7 @@ static const struct camss_subdev_resources csid_res_sm6150[] = {
.reg = { "csid_lite" },
.interrupt = { "csid_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -1775,6 +1784,7 @@ static const struct camss_subdev_resources csid_res_sm6350[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1790,6 +1800,7 @@ static const struct camss_subdev_resources csid_res_sm6350[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1805,6 +1816,7 @@ static const struct camss_subdev_resources csid_res_sm6350[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -1820,6 +1832,7 @@ static const struct camss_subdev_resources csid_res_sm6350[] = {
.reg = { "csid_lite" },
.interrupt = { "csid_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2058,6 +2071,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2075,6 +2089,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2092,6 +2107,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
.interrupt = { "csid2" },
.csid = {
.is_lite = true,
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2109,6 +2125,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
.interrupt = { "csid3" },
.csid = {
.is_lite = true,
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2349,6 +2366,7 @@ static const struct camss_subdev_resources csid_res_7280[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2368,6 +2386,7 @@ static const struct camss_subdev_resources csid_res_7280[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2387,6 +2406,7 @@ static const struct camss_subdev_resources csid_res_7280[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.is_lite = false,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2406,6 +2426,7 @@ static const struct camss_subdev_resources csid_res_7280[] = {
.reg = { "csid_lite0" },
.interrupt = { "csid_lite0" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2425,6 +2446,7 @@ static const struct camss_subdev_resources csid_res_7280[] = {
.reg = { "csid_lite1" },
.interrupt = { "csid_lite1" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2645,6 +2667,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid0" },
.interrupt = { "csid0" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2664,6 +2687,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid1" },
.interrupt = { "csid1" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2683,6 +2707,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid2" },
.interrupt = { "csid2" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2702,6 +2727,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid3" },
.interrupt = { "csid3" },
.csid = {
+ .frame_sync_en = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
.formats = &csid_formats_gen2
@@ -2720,6 +2746,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid0_lite" },
.interrupt = { "csid0_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2739,6 +2766,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid1_lite" },
.interrupt = { "csid1_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2758,6 +2786,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid2_lite" },
.interrupt = { "csid2_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
@@ -2777,6 +2806,7 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = {
.reg = { "csid3_lite" },
.interrupt = { "csid3_lite" },
.csid = {
+ .frame_sync_en = true,
.is_lite = true,
.hw_ops = &csid_ops_gen2,
.parent_dev_ops = &vfe_parent_dev_ops,
--
2.56.0
^ permalink raw reply [flat|nested] 19+ messages in thread