[PATCH 6/7] media: v4l2-isp: Introduce "reset buffer" concept
Daniel Scally
dan.scally at ideasonboard.com
Wed Nov 4 04:28:21 PST 2026
The extensible parameters format defined in the v4l2-isp framework
is designed to allow userspace to pass a truncated buffer of params
for an ISP, which need not include all of its available configuration
settings. This allows heavy configuration like lens shading tables to
be passed by userspace to the driver a single time, and subsequent
per-frame buffers to be much lighter. This is problematic in the case
of suspend or hibernate and resume, in which scenario the hardware
will lose all settings, but userspace has no way of knowing that they
need to be re-applied.
Introduce the concept of a "reset buffer" to v4l2-isp. Userspace can
pass a new flag that marks a parameter block as needing to be
re-applied. Where the validation process finds that flag, the marked
block is copied to a VB2Q-independent instance of a
v4l2_isp_params_buffer. If that block has been written to the reset
buffer before then the existing copy is overwritten.
The intention with using the existing v4l2_isp_params_buffer is to
facilitate a driver easily using the normal function to apply a
params buffer to also apply the reset buffer on device reset.
Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
Documentation/userspace-api/media/v4l/v4l2-isp.rst | 19 +++++++
drivers/media/v4l2-core/v4l2-isp.c | 66 ++++++++++++++++++++++
include/media/v4l2-isp.h | 15 +++++
include/uapi/linux/media/v4l2-isp.h | 1 +
4 files changed, 101 insertions(+)
diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
index 8a3f05b5e85fd335e68e349234e2cfe5e7e83099..6bd72c7741816676d22a3197ae72ae6796973a5f 100644
--- a/Documentation/userspace-api/media/v4l/v4l2-isp.rst
+++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
@@ -56,6 +56,25 @@ returns an error.
Extension to the parameters format can be implemented by adding new blocks
definition without invalidating the existing ones.
+ISP Reset buffers
+-----------------
+The parameters buffer format described by :c:type:`v4l2_isp_params_buffer`
+allows intentionally for userspace to pass a truncated buffer of parameters for
+an ISP which does not need to include all of its available configuration
+settings. This allows heavy configuration like lens shading tables to be passed
+by userspace a single time, and subsequent per-frame buffers to be much lighter.
+
+In the case of a suspend or hibernate action followed by a system resume this
+presents a problem. The hardware will have lost all settings, but userspace has
+no way of knowing that they were lost and need to be re-applied.
+
+The V4L2 ISP framework includes the concept of a "reset buffer". As part of the
+validation process, the framework will store the "last-seen" instance of each
+configuration block type in an instance of v4l2_isp_params_buffer. Drivers can
+then simply re-apply that "reset buffer" using their normal configuration
+function when resuming from hibernation with an active stream
+
+
ISP statistics
==============
diff --git a/drivers/media/v4l2-core/v4l2-isp.c b/drivers/media/v4l2-core/v4l2-isp.c
index 925632e1037db18f0948ceb0ce7c652e167516c9..1420aa0f48194ff04a29fbbf83d0646d3b9d23d2 100644
--- a/drivers/media/v4l2-core/v4l2-isp.c
+++ b/drivers/media/v4l2-core/v4l2-isp.c
@@ -54,6 +54,69 @@ int v4l2_isp_validate(struct v4l2_isp *isp)
}
EXPORT_SYMBOL_GPL(v4l2_isp_validate);
+int v4l2_isp_params_init_reset_buf(struct v4l2_isp *isp)
+{
+ isp->params.reset_buf = devm_kzalloc(isp->dev, isp->params.max_size,
+ GFP_KERNEL);
+ if (!isp->params.reset_buf)
+ return -ENOMEM;
+
+ isp->params.reset_buf->version = V4L2_ISP_PARAMS_VERSION_V0;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_isp_params_init_reset_buf);
+
+static void v4l2_isp_params_update_reset_buf(struct v4l2_isp *isp,
+ const struct v4l2_isp_params_block_header *block,
+ const struct v4l2_isp_params_block_type_info *info)
+{
+ struct v4l2_isp_params_buffer *buffer = isp->params.reset_buf;
+ struct v4l2_isp_params_block_header *new_block;
+ struct v4l2_isp_params_block_header *old_block;
+
+ /*
+ * If the reset buffer was never initialised then the driver didn't ask
+ * us to handle this and we can just do nothing.
+ */
+ if (!buffer) {
+ dev_dbg(isp->dev, "Reset buffer is not initialised\n");
+ return;
+ }
+
+ v4l2_isp_params_for_each_block(buffer, old_block) {
+ if (old_block->type != block->type)
+ continue;
+
+ memcpy(old_block, block, block->size);
+ return;
+ }
+
+ /*
+ * If we didn't find an existing stored copy for the given block type
+ * then we simply add it to the end of the array.
+ */
+ new_block = (struct v4l2_isp_params_block_header *)
+ &buffer->data[buffer->data_size];
+
+ /*
+ * This looks awkward! We're memcpy()ing with block->size but setting
+ * new_block->size with info->size. The reason is that the source buffer
+ * might have only contained the block header rather than a full block.
+ * In that case, we need to only memcpy() the amount of space that it
+ * actually used in the source buffer.
+ *
+ * In future though userspace might queue a buffer with a full block for
+ * the same block type. If we only reserved here enough space for the
+ * header then things would need to be rearranged in the reset buffer.
+ * Much easier to just reserve enough space for the full block right
+ * away.
+ */
+ memcpy(new_block, block, block->size);
+ new_block->size = info->size;
+ buffer->data_size += new_block->size;
+}
+
int v4l2_isp_params_validate_buffer_size(struct v4l2_isp *isp,
struct vb2_buffer *vb)
{
@@ -170,6 +233,9 @@ int v4l2_isp_params_validate_buffer(struct v4l2_isp *isp, struct vb2_buffer *vb,
if (info->block_validate && info->block_validate(dev, block))
return -EINVAL;
+ if (block->flags & V4L2_ISP_PARAMS_FL_BLOCK_REAPPLY)
+ v4l2_isp_params_update_reset_buf(isp, block, info);
+
block_offset += block->size;
buffer_size -= block->size;
}
diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
index 5f13651b53d3c06fc676b32826daa68ad77b5cf6..b2ad6d98a4c266c388db623ddd549307b7fd4b09 100644
--- a/include/media/v4l2-isp.h
+++ b/include/media/v4l2-isp.h
@@ -72,6 +72,8 @@ struct v4l2_isp_params_block_type_info {
* @dev: pointer to the &struct device associated with the ISP
* @params: sub-struct holding data related to the V4L2 ISP parameters
* @params.types_info: pointer to array of params block information structs
+ * @params.reset_buf: pointer to a buffer containing a copy of any block
+ * flagged as needing re-application on device reset
* @params.num_block_types: number of possible params block types
* @params.max_size: maximum size in bytes of the data member of
* &struct v4l2_isp_params_buffer
@@ -88,6 +90,7 @@ struct v4l2_isp {
struct {
const struct v4l2_isp_params_block_type_info *types_info;
+ struct v4l2_isp_params_buffer *reset_buf;
size_t num_block_types;
size_t max_size;
} params;
@@ -104,6 +107,18 @@ struct v4l2_isp {
*/
int v4l2_isp_validate(struct v4l2_isp *isp);
+/**
+ * v4l2_isp_params_init_reset_buf - Init a buffer to store device reset data
+ * @isp: pointer to the &struct v4l2_isp to allocate the buffer for
+ *
+ * This function allocates memory for &struct v4l2_isp.params.reset_buf, which
+ * is intended to be populated with parameter blocks that are flagged with
+ * %V4L2_ISP_PARAMS_FL_BLOCK_REAPPLY.
+ *
+ * @return 0 on success, -ENOMEM on failure
+ */
+int v4l2_isp_params_init_reset_buf(struct v4l2_isp *isp);
+
/**
* v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes
* @isp: the driver's &struct v4l2_isp pointer
diff --git a/include/uapi/linux/media/v4l2-isp.h b/include/uapi/linux/media/v4l2-isp.h
index e4607e1217e1a720f8f0a180abf3c064a0d81bf7..43059940edf1a2cad9868a4bc049ee32211cc465 100644
--- a/include/uapi/linux/media/v4l2-isp.h
+++ b/include/uapi/linux/media/v4l2-isp.h
@@ -42,6 +42,7 @@ enum v4l2_isp_version {
#define V4L2_ISP_PARAMS_FL_BLOCK_DISABLE (1U << 0)
#define V4L2_ISP_PARAMS_FL_BLOCK_ENABLE (1U << 1)
+#define V4L2_ISP_PARAMS_FL_BLOCK_REAPPLY (1U << 2)
/*
* Reserve the first 8 bits for V4L2_ISP_PARAMS_FL_* flag.
--
2.43.0
More information about the Linux-rockchip
mailing list