From patchwork Wed Jul 22 11:23:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27436 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id F2809BDE17 for ; Wed, 22 Jul 2026 11:24:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A323967E8A; Wed, 22 Jul 2026 13:24:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="a6c9/H1P"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 99FDC67E8A for ; Wed, 22 Jul 2026 13:24:43 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3B9D0227; Wed, 22 Jul 2026 13:23:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719423; bh=lxR3DJXyq6m0F90hz/jSuiaOQi61Nmv7gwuhz0/38h8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=a6c9/H1PMc1EIGL6sYp+M6GJGukdp+ThsI834XyV9RY2T7IIYQZeRjSRW+FYDVY3I Q5H1Rhfr90ypFqURGqBjTnTw6O32VfWryrKZalqp8eOb0OQ2y1JMqn/CgeNG7MY3Ni AOegbwBwi3grMY2wzRPfZJxTMBvV+3rkG3BggP04= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:17 +0530 Subject: [PATCH v2 1/8] ipa: rpi: Drop unused params argument from platformPrepareIsp() MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-1-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3922; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=lxR3DJXyq6m0F90hz/jSuiaOQi61Nmv7gwuhz0/38h8=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhojL1BhHXdBTLlF13U5w/Ztw4lL0WL33mEZ BzoJXfQS3mJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCoaAAKCRBD3pH5JJpx RTxKEACj11Oz7P9paHbrInOQaRItIPackj34ewWIhn4TD11GOK7aiUfOujwIfG3sPZLBhN9a/Ui PTqLOJhiySqxqstJUzYL6WDKk6T9CvrJqvOcBTjl6GlmYMEtXrZinKyOD3CO10ClIuwINQkjUOD UCL1vqZMJZ0a9Qy0wIVSYOm6v2IJFOS6f48mQlv8CkbpDvb56npjjKYZ7EN2E1xttYWzDCMZsEi LjrHqEznVTbY+W/RdzIxkvAeqWj5nFUStJFUlBhwo1Agtozv3Ez9Li0EG+8uE9SvMFoFGJ+uNx+ uB4uNd9IieqEa0A7sNNPfdL0Wg8vFrmzWCI/vA7s5P6T8OHmn4Xe70jdQZYqnV4ypXf4XgxqNUe grP0LTLEuao38WvCv4W09rrvZizdWzhXPLW/DzcBe6RelOegLXZH++B54mDoCEGbVUvLZvQgSe+ sWSGkJIzimoZSWNHCBgMyfdm8XkRxIw9wYvoXNYJHknBWOxX6260zBk/nAGfj+X/rFYZl4weYYs I3GzpE7tJMKbf8lGsXjaZUytxkItfYIdJeSyI5KCXSID6nVQUrorVF3GPkT8nF9STuwFRI74MwD N0gjO3x8gOPm5qCVrAJxZK89WWtrfTvXw4iihJsGS3yO00MWl4mPh4RSeQ6uxFc8jG95CVdYRpH /4pNPFyhBGyNaOw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In IPABase::platformPrepareIsp() we pass PrepareParams but none of the IPAs (vc4 and pisp) use them. So drop it. Signed-off-by: Jai Luthra --- src/ipa/rpi/common/ipa_base.cpp | 2 +- src/ipa/rpi/common/ipa_base.h | 3 +-- src/ipa/rpi/pisp/pisp.cpp | 6 ++---- src/ipa/rpi/vc4/vc4.cpp | 5 ++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index dacafa578..e3f7b99a8 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -507,7 +507,7 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) if (processPending_) { controller_.prepare(&rpiMetadata); /* Actually prepare the ISP parameters for the frame. */ - platformPrepareIsp(params, rpiMetadata); + platformPrepareIsp(rpiMetadata); platformPrepareAgc(rpiMetadata); } else platformPrepareAgc(rpiMetadata); diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h index 90f018b28..f4157e9ec 100644 --- a/src/ipa/rpi/common/ipa_base.h +++ b/src/ipa/rpi/common/ipa_base.h @@ -87,8 +87,7 @@ private: virtual int32_t platformStart(const ControlList &controls, StartResult *result) = 0; virtual int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) = 0; - virtual void platformPrepareIsp(const PrepareParams ¶ms, - RPiController::Metadata &rpiMetadata) = 0; + virtual void platformPrepareIsp(RPiController::Metadata &rpiMetadata) = 0; virtual void platformPrepareAgc(RPiController::Metadata &rpiMetadata) = 0; virtual RPiController::StatisticsPtr platformProcessStats(Span mem) = 0; diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index fd28fc385..025103808 100644 --- a/src/ipa/rpi/pisp/pisp.cpp +++ b/src/ipa/rpi/pisp/pisp.cpp @@ -232,8 +232,7 @@ private: int32_t platformStart(const ControlList &controls, StartResult *result) override; int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) override; - void platformPrepareIsp(const PrepareParams ¶ms, - RPiController::Metadata &rpiMetadata) override; + void platformPrepareIsp(RPiController::Metadata &rpiMetadata) override; void platformPrepareAgc(RPiController::Metadata &rpiMetadata) override; RPiController::StatisticsPtr platformProcessStats(Span mem) override; @@ -354,8 +353,7 @@ int32_t IpaPiSP::platformConfigure([[maybe_unused]] const ConfigParams ¶ms, return 0; } -void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, - RPiController::Metadata &rpiMetadata) +void IpaPiSP::platformPrepareIsp(RPiController::Metadata &rpiMetadata) { std::scoped_lock l(rpiMetadata); diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index b6ca44e7a..052204d25 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -59,7 +59,7 @@ private: int32_t platformStart(const ControlList &controls, StartResult *result) override; int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) override; - void platformPrepareIsp(const PrepareParams ¶ms, RPiController::Metadata &rpiMetadata) override; + void platformPrepareIsp(RPiController::Metadata &rpiMetadata) override; void platformPrepareAgc([[maybe_unused]] RPiController::Metadata &rpiMetadata) override; RPiController::StatisticsPtr platformProcessStats(Span mem) override; @@ -144,8 +144,7 @@ int32_t IpaVc4::platformConfigure(const ConfigParams ¶ms, [[maybe_unused]] C return 0; } -void IpaVc4::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, - RPiController::Metadata &rpiMetadata) +void IpaVc4::platformPrepareIsp(RPiController::Metadata &rpiMetadata) { ControlList &ctrls = ctrls_; From patchwork Wed Jul 22 11:23:18 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27437 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7052BBDE17 for ; Wed, 22 Jul 2026 11:24:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1E7C967E95; Wed, 22 Jul 2026 13:24:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Sqc/Q1CI"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7E6FD67E8A for ; Wed, 22 Jul 2026 13:24:50 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1E922227; Wed, 22 Jul 2026 13:23:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719430; bh=Tom9zcr7m+uVm3IWfbKXSceiwM1Aev3qwGzYHJZHOFE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Sqc/Q1CIqT1xRl6UTMEIAGtuS3YHaYd6P5qaSbWaKw+lcncsMZTFQTw8Vn9kmmsE8 gLwcuhyYtf2RETx5IAxxQClR70mqcizy3bVffYsmtCLeMrky8Af4BLcik8Jp89I2Dx 7R4lgkwr5M2Ou2jC7pYRbwyWaozELw0qQgDVJJPo= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:18 +0530 Subject: [PATCH v2 2/8] include: uapi: bcm2835-isp: Add extensible parameter buffer interface MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-2-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9226; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=Tom9zcr7m+uVm3IWfbKXSceiwM1Aev3qwGzYHJZHOFE=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhpL2pRuan0OHdzOq/zZQL52urYiXgT+Ng97 4n49b5FuG6JAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCoaQAKCRBD3pH5JJpx RcOFD/4xw3OcrppbyJ3wClwVVIo5VaIv08lRW/jGlKEYKdg6aqHd/3atUVXG/YFS8DUkq9aXtpa O6rEDbUoHBn2DapqKf/ULmg9oDlql74laiemOWDFpY5y+hp7BcCyoCmUJNok6cXJkMpg9DOS9Ju uVN/8oPF70kdb9ezsagOtw5NfXci1sl/WXNiem7zbl1DFSqoU7SkuMeqmJC7B5By6C/tVZ6AztB OcgOh59hvKIu3HMv06+Wh3SRlg+nPalV90hKimyprPIRy/cUVJwZQIUnPXxrBY15RMD9l6rVl+O 2E9WvV2387Bf6Ztl0zPmn/RDdLU7848KzYw4AOQfSiNVyqRdKECFkrk8HUvWVfz2reCF211rmq/ AXq0et7xTxrfxkWOKfIUIADxfMw6GX/TUoI4dA3zrRWUd8sRXbwB5LAQbviRX6CPlKWcpuhHUNX x4zjLiskIKEzwlTjY1OJX34hEgpXXFia9zCjwiRJjzKsUtrLGE1i4NrkSxhUpOjhcRYkZnPNKqW dBoYLESmSopzrHuGdo8E+6PHVukhTs7a+nGljuc/sfcBW36hDMLYkjk4duKdNWj9AMqXtLSP0Pv QmH9MPgrBtYPUKcAm5D2TDTZLUniru6s3FAzkYWzisdBewx1p6u7PLLo8paGruh08f9j2TMoxE6 QDwFnBWUnl0wlrQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The mainline BCM2835 ISP driver expects per-frame configuration via parameter buffers rather than V4L2 controls; keep the legacy control IDs in place for now so libcamera keeps compiling during the switch. Signed-off-by: Jai Luthra --- include/linux/bcm2835-isp.h | 213 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/videodev2.h | 1 + 2 files changed, 214 insertions(+) diff --git a/include/linux/bcm2835-isp.h b/include/linux/bcm2835-isp.h index 5f0f78e3e..c49854cfa 100644 --- a/include/linux/bcm2835-isp.h +++ b/include/linux/bcm2835-isp.h @@ -14,6 +14,7 @@ #define __BCM2835_ISP_H_ #include +#include #define V4L2_CID_USER_BCM2835_ISP_CC_MATRIX \ (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0001) @@ -258,6 +259,218 @@ struct bcm2835_isp_dpc { __u32 strength; }; +/** + * struct bcm2835_isp_awb_gains - AWB gains configuration. + * + * @r_gain: Red channel AWB gain. + * @b_gain: Blue channel AWB gain. + */ +struct bcm2835_isp_awb_gains { + struct bcm2835_isp_rational r_gain; + struct bcm2835_isp_rational b_gain; +}; + +/** + * struct bcm2835_isp_digital_gain - Digital gain configuration. + * + * @gain: Digital gain value. + */ +struct bcm2835_isp_digital_gain { + struct bcm2835_isp_rational gain; +}; + +/* + * BCM2835 ISP extensible parameters buffer definitions. + * + * The extensible parameters mechanism allows userspace to submit ISP + * configuration parameters as a buffer containing a series of tagged + * blocks rather than individual V4L2 controls. This enables atomic + * application of multiple parameters in a single operation. + */ + +/** + * enum bcm2835_isp_param_buffer_version - BCM2835 ISP parameters buffer version + * + * @BCM2835_ISP_PARAM_BUFFER_V1: First version of parameters buffer format + */ +enum bcm2835_isp_param_buffer_version { + BCM2835_ISP_PARAM_BUFFER_V1 = V4L2_ISP_PARAMS_VERSION_V1, +}; + +/** + * enum bcm2835_isp_param_block_type - BCM2835 ISP parameter block types + * + * This enumeration defines the types of parameters blocks that can be + * included in the extensible parameters buffer. Each block type corresponds + * to a specific ISP processing block configuration. + * + * @BCM2835_ISP_PARAM_BLOCK_BLACK_LEVEL: Black level configuration + * @BCM2835_ISP_PARAM_BLOCK_GEQ: Green equalisation configuration + * @BCM2835_ISP_PARAM_BLOCK_GAMMA: Gamma curve configuration + * @BCM2835_ISP_PARAM_BLOCK_DENOISE: Denoise configuration + * @BCM2835_ISP_PARAM_BLOCK_SHARPEN: Sharpening configuration + * @BCM2835_ISP_PARAM_BLOCK_DPC: Defective pixel correction configuration + * @BCM2835_ISP_PARAM_BLOCK_CDN: Colour denoise configuration + * @BCM2835_ISP_PARAM_BLOCK_CC_MATRIX: Colour correction matrix configuration + * @BCM2835_ISP_PARAM_BLOCK_LENS_SHADING: Lens shading table configuration + * @BCM2835_ISP_PARAM_BLOCK_AWB_GAINS: AWB gains configuration + * @BCM2835_ISP_PARAM_BLOCK_DIGITAL_GAIN: Digital gain configuration + */ +enum bcm2835_isp_param_block_type { + BCM2835_ISP_PARAM_BLOCK_BLACK_LEVEL, + BCM2835_ISP_PARAM_BLOCK_GEQ, + BCM2835_ISP_PARAM_BLOCK_GAMMA, + BCM2835_ISP_PARAM_BLOCK_DENOISE, + BCM2835_ISP_PARAM_BLOCK_SHARPEN, + BCM2835_ISP_PARAM_BLOCK_DPC, + BCM2835_ISP_PARAM_BLOCK_CDN, + BCM2835_ISP_PARAM_BLOCK_CC_MATRIX, + BCM2835_ISP_PARAM_BLOCK_LENS_SHADING, + BCM2835_ISP_PARAM_BLOCK_AWB_GAINS, + BCM2835_ISP_PARAM_BLOCK_DIGITAL_GAIN, +}; + +/** + * struct bcm2835_isp_params_black_level - Black level parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_BLACK_LEVEL) + * @black_level: Black level configuration + */ +struct bcm2835_isp_params_black_level { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_black_level black_level; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_geq - Green equalisation parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_GEQ) + * @geq: Green equalisation configuration + */ +struct bcm2835_isp_params_geq { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_geq geq; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_gamma - Gamma parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_GAMMA) + * @gamma: Gamma curve configuration + */ +struct bcm2835_isp_params_gamma { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_gamma gamma; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_denoise - Denoise parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_DENOISE) + * @denoise: Denoise configuration + */ +struct bcm2835_isp_params_denoise { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_denoise denoise; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_sharpen - Sharpen parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_SHARPEN) + * @sharpen: Sharpening configuration + */ +struct bcm2835_isp_params_sharpen { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_sharpen sharpen; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_dpc - Defective pixel correction parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_DPC) + * @dpc: DPC configuration + */ +struct bcm2835_isp_params_dpc { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_dpc dpc; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_cdn - Colour denoise parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_CDN) + * @cdn: Colour denoise configuration + */ +struct bcm2835_isp_params_cdn { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_cdn cdn; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_cc_matrix - Colour correction matrix parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_CC_MATRIX) + * @ccm: Colour correction matrix configuration + */ +struct bcm2835_isp_params_cc_matrix { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_custom_ccm ccm; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_lens_shading - Lens shading parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_LENS_SHADING) + * @ls: Lens shading configuration (includes dmabuf fd for table data) + */ +struct bcm2835_isp_params_lens_shading { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_lens_shading ls; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_awb_gains - AWB gains parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_AWB_GAINS) + * @awb_gains: AWB gains configuration + */ +struct bcm2835_isp_params_awb_gains { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_awb_gains awb_gains; +} __attribute__((aligned(8))); + +/** + * struct bcm2835_isp_params_digital_gain - Digital gain parameters block + * + * @header: Block header (type = BCM2835_ISP_PARAM_BLOCK_DIGITAL_GAIN) + * @digital_gain: Digital gain configuration + */ +struct bcm2835_isp_params_digital_gain { + struct v4l2_isp_params_block_header header; + struct bcm2835_isp_digital_gain digital_gain; +} __attribute__((aligned(8))); + +/** + * define BCM2835_ISP_PARAMS_MAX_SIZE - Maximum size of all ISP parameters + * + * This defines the maximum size needed to accommodate all possible parameter + * blocks in a single buffer. Drivers use this to allocate appropriately + * sized buffers. + */ +#define BCM2835_ISP_PARAMS_MAX_SIZE \ + (sizeof(struct bcm2835_isp_params_black_level) + \ + sizeof(struct bcm2835_isp_params_geq) + \ + sizeof(struct bcm2835_isp_params_gamma) + \ + sizeof(struct bcm2835_isp_params_denoise) + \ + sizeof(struct bcm2835_isp_params_sharpen) + \ + sizeof(struct bcm2835_isp_params_dpc) + \ + sizeof(struct bcm2835_isp_params_cdn) + \ + sizeof(struct bcm2835_isp_params_cc_matrix) + \ + sizeof(struct bcm2835_isp_params_lens_shading) + \ + sizeof(struct bcm2835_isp_params_awb_gains) + \ + sizeof(struct bcm2835_isp_params_digital_gain)) + /* * ISP statistics structures. * diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 8bccad84f..60133dcf9 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -845,6 +845,7 @@ struct v4l2_pix_format { #define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D') /* Vivid Metadata */ #define V4L2_META_FMT_SENSOR_DATA v4l2_fourcc('S', 'E', 'N', 'S') /* Sensor Ancillary metadata */ #define V4L2_META_FMT_BCM2835_ISP_STATS v4l2_fourcc('B', 'S', 'T', 'A') /* BCM2835 ISP image statistics output */ +#define V4L2_META_FMT_BCM2835_ISP_PARAMS v4l2_fourcc('B', 'C', 'M', 'P') /* BCM2835 ISP params */ /* Vendor specific - used for RK_ISP1 camera sub-system */ #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ From patchwork Wed Jul 22 11:23:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27438 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E9C0ABDE17 for ; Wed, 22 Jul 2026 11:24:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9892D67E9B; Wed, 22 Jul 2026 13:24:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="AcLkkLUu"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4FDA367E8A for ; Wed, 22 Jul 2026 13:24:57 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EC9B2227; Wed, 22 Jul 2026 13:23:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719437; bh=cf6wpGKR2KCk5BiqjCHllai+xyMyN8efOP8EN/jcD8o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=AcLkkLUuTmqEJ+AHBhLjhoqbyhmzScmXGxSs8+tvJnq9qfv54wxDj2PNEfdbibuUL 78lY+CqnUu7ITWi9fWb0BE2VBr/nOczlnAjbJPWC9zL6UER3EIPXpYwNGuPDl5zwqT +A67wxNssoHzOLWpGFDMTkzVnk4pC91civK0hKhw= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:19 +0530 Subject: [PATCH v2 3/8] ipa: rpi: vc4: Add Bcm2835Params helper MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-3-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2547; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=cf6wpGKR2KCk5BiqjCHllai+xyMyN8efOP8EN/jcD8o=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhpTo6Dh5fd3NGXI240oVCSmGg9KfB7V0MUP a78StGZr/SJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCoaQAKCRBD3pH5JJpx RRpVEACZHDKurSTE46kt1tGoiSwKyQ7A0ieM7sOvGNIigHh2bVrmckeLtQKtBk2d7EPBkOV+AAB iOynIAJNRoarNkVZcfp5Hmm/QpXRiuWgvEwNrIBu5S/t7CKoSg0Umq88t1BXUsp/pNvpV448Et0 Lrhf8cgzbRj5l7QJKc3uTxORQp7xd1fjSvJVmIAJDwlJJUs4qplYpY/A6VLWsxXv1J8+7yThcb9 //F8jxkVmexX2VSx9n55zg639f4UCB5xuVGdrKssnqCPWRrKb3KvRLxqDcZtfn2tFNSGkawWovW ILGzynDnfgZcplrzwan7ZVX+vxOk1BqbKFCLq8AF83L+40VuRbMDb/pI7piHoDVUvXLFGkjOM1l I7JvBoAaD6Eri4vMuGo202CpFqXfCd2h5QzD8qwxuFO3cubmo2fXJwW3oml5HlzbGCDFBGXOzPG y3lsP1TFDfaU5K+joVEO3qWG1Xf6hjANwsD+ZWScix9GvK261CHwRULuOLx/Pm2J/BhA8wF+Tu+ qUqGn/PA0YzZgcY1FFwi9KpPE1xYUPK1S5i/B6cTzJnH5orCM8buxY6P+fcmSVE1tpUE+gdtHwj ej/ya2D8KzNl+re9IkCDZGR/9xOqNScD/i08QJqtlv7IncP2cAjSs8+4eBZKlvY1HGL40sxautX Ta8vxPnS86hp20A== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement Bcm2835Params to derive from V4L2Params. The mailine driver uses extensible V4L2 parameter for configuration instead of custom V4L2 controls. Signed-off-by: Jai Luthra --- src/ipa/rpi/vc4/params.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/ipa/rpi/vc4/params.h b/src/ipa/rpi/vc4/params.h new file mode 100644 index 000000000..c936f8812 --- /dev/null +++ b/src/ipa/rpi/vc4/params.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * Raspberry Pi VC4/BCM2835 ISP Parameters + */ + +#pragma once + +#include + +#include + +#include + +namespace libcamera { + +namespace ipa::RPi { + +enum class BlockType : uint16_t { + BlackLevel, + Geq, + Gamma, + Denoise, + Sharpen, + Dpc, + Cdn, + CcMatrix, + LensShading, + AwbGains, + DGain, +}; + +namespace details { + +template +struct block_type { +}; + +#define BCM2835_DEFINE_BLOCK_TYPE(id, structName, blockId) \ + template<> \ + struct block_type { \ + using type = struct bcm2835_isp_params_##structName; \ + static constexpr bcm2835_isp_param_block_type blockType = \ + BCM2835_ISP_PARAM_BLOCK_##blockId; \ + }; + +BCM2835_DEFINE_BLOCK_TYPE(BlackLevel, black_level, BLACK_LEVEL) +BCM2835_DEFINE_BLOCK_TYPE(Geq, geq, GEQ) +BCM2835_DEFINE_BLOCK_TYPE(Gamma, gamma, GAMMA) +BCM2835_DEFINE_BLOCK_TYPE(Denoise, denoise, DENOISE) +BCM2835_DEFINE_BLOCK_TYPE(Sharpen, sharpen, SHARPEN) +BCM2835_DEFINE_BLOCK_TYPE(Dpc, dpc, DPC) +BCM2835_DEFINE_BLOCK_TYPE(Cdn, cdn, CDN) +BCM2835_DEFINE_BLOCK_TYPE(CcMatrix, cc_matrix, CC_MATRIX) +BCM2835_DEFINE_BLOCK_TYPE(LensShading, lens_shading, LENS_SHADING) +BCM2835_DEFINE_BLOCK_TYPE(AwbGains, awb_gains, AWB_GAINS) +BCM2835_DEFINE_BLOCK_TYPE(DGain, digital_gain, DIGITAL_GAIN) + +struct params_traits { + using id_type = BlockType; + template + using id_to_details = block_type; +}; + +} /* namespace details */ + +class Bcm2835Params : public V4L2Params +{ +public: + Bcm2835Params(Span data) : V4L2Params(data, + BCM2835_ISP_PARAM_BUFFER_V1) + { + } +}; + +} /* namespace ipa::RPi */ + +} /* namespace libcamera */ From patchwork Wed Jul 22 11:23:20 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27439 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 6CE59BDE17 for ; Wed, 22 Jul 2026 11:25:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1D57367E9E; Wed, 22 Jul 2026 13:25:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ldi4jh51"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2B5BC67E8A for ; Wed, 22 Jul 2026 13:25:03 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C0E06447; Wed, 22 Jul 2026 13:24:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719443; bh=4LNUMEB6mFPpD4zAvN1pO7+Tpb68w3zqahLeEQzRyxQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ldi4jh51HjMucP3xgeux+SyNc7w5f1OZKv+G9gD5nrA3GsYoEabIADa4FPcBLTbI+ o6wbwdGLrT0OS6Ev0NFNrg5XbLF1ZOLQ9eKNkTuzpKvxzBJkr8UvQ91GWivHYezsgY JdQ/EqU6DkJWSpPpEF+xfCGAe24iKSBzrUj4jxhw= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:20 +0530 Subject: [PATCH v2 4/8] ipa: rpi: Allow sharing params buffer to the IPA MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-4-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6404; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=4LNUMEB6mFPpD4zAvN1pO7+Tpb68w3zqahLeEQzRyxQ=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhqOECbV7LotjHUDVrzPJZdvF6PCsjrr8dEx CBRmEbZ5a+JAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCoagAKCRBD3pH5JJpx RfbtEACJAOOEwi/3WWXaxIZYan6fjBi1qwxHjG0yQgUnuU599iac6EMflImR/qT+0pxn/ldsFIu PLiU+n9I4SW78i/8o6mqrZJYTjFIN9Wq2MXMAakp4t48uatCV2uJ6nHt3HFxzjA27Pc/JIf+/Hv O79DgJIDIy5bE4h+MQqe1uA8jGQ07NE9WyMUkl859nuUclFw0dwxvBszobMj0r7tbSEUc6vREg3 bUxHtLG49gm2ZjIJHQOvvBiAQdNjNMqzdmLZreYYOImpG+tUDV8i0uwj+EL9N4RdUqwS+fZmRW9 U4vN9P/beSofL3XfZFozu8vIErz32zCfiSbNFDThzxzPONb+vno3hkZIVp3SfCHYurR2cy0FzB8 abhlwDssMhq7gBgTu0qH2khGrwHD0ixoV+OmpOxzZTmjftFyFj1xYFLYYi34j1j8rk7iFwQIWMm gjQjAdoIHLpkGrAWtrdLjnQNdxRUBy2fkAvlEU4F6XaH+OpyBtvYgBRvOfP+W1HRl3L+3cksoA1 oM2sY8hdc+4Dtc+5GkY71KdbS3vIHTrkuUeBb5I+uZmhQDTcSxmwZDJPMKhdz1luhLejmY0Id97 Lo2qN/PA+TMrHYBKX0EZHRitiU8ZCfD4Jc/lMm7JiA0XQC7gak2reljM26lz1U0pViAOfYcn5Eo U0WReqWRZjv/cZg== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" While the VC4 IPA currently writes control values for configuration, the mainline driver expects a parameter buffer. In preparation for the migration, add plumbing to pass the parameter buffer to the IPA, while reporting back how many bytes were filled through the prepareIspComplete() callback. This is unused for now, VC4 will use it in subsequent commits. Signed-off-by: Jai Luthra --- include/libcamera/ipa/raspberrypi.mojom | 3 ++- src/ipa/rpi/common/ipa_base.cpp | 11 ++++++++++- src/ipa/rpi/common/ipa_base.h | 4 ++++ src/libcamera/pipeline/rpi/pisp/pisp.cpp | 6 ++++-- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 6 ++++-- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index 1b7e03582..dcd3b2c66 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -33,6 +33,7 @@ struct BufferIds { uint32 bayer; uint32 embedded; uint32 stats; + uint32 params; }; struct ConfigParams { @@ -227,7 +228,7 @@ interface IPARPiEventInterface { * processing the frame. The embedded data buffer may be recycled after * this event. */ - prepareIspComplete(BufferIds buffers, bool stitchSwapBuffers); + prepareIspComplete(BufferIds buffers, bool stitchSwapBuffers, uint32 paramsBytesUsed); /** * \fn processStatsComplete() diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index e3f7b99a8..b3313f577 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -427,6 +427,7 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) unsigned int ipaContext = params.ipaContext % rpiMetadata_.size(); RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext]; Span embeddedBuffer; + Span paramsBuffer; rpiMetadata.clear(); fillDeviceStatus(params.sensorControls, ipaContext); @@ -450,6 +451,13 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) embeddedBuffer = it->second.planes()[0]; } + if (params.buffers.params) { + auto it = buffers_.find(params.buffers.params); + ASSERT(it != buffers_.end()); + paramsBuffer = it->second.planes()[0]; + platformParamsBufferInit(paramsBuffer); + } + /* * AGC wants to know the algorithm status from the time it actioned the * sensor exposure/gain changes. So fetch it from the metadata list @@ -519,7 +527,8 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) reportMetadata(ipaContext); /* Ready to push the input buffer into the ISP. */ - prepareIspComplete.emit(params.buffers, stitchSwapBuffers_); + prepareIspComplete.emit(params.buffers, stitchSwapBuffers_, + platformParamsBytesUsed()); } void IpaBase::processStats(const ProcessParams ¶ms) diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h index f4157e9ec..1e9b0e57e 100644 --- a/src/ipa/rpi/common/ipa_base.h +++ b/src/ipa/rpi/common/ipa_base.h @@ -79,6 +79,8 @@ protected: /* Whether the stitch block (if available) needs to swap buffers. */ bool stitchSwapBuffers_; + virtual size_t platformParamsBytesUsed() const { return 0; } + private: /* Number of metadata objects available in the context list. */ static constexpr unsigned int numMetadataContexts = 16; @@ -87,7 +89,9 @@ private: virtual int32_t platformStart(const ControlList &controls, StartResult *result) = 0; virtual int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) = 0; + virtual void platformParamsBufferInit([[maybe_unused]] Span paramsBuffer) {} virtual void platformPrepareIsp(RPiController::Metadata &rpiMetadata) = 0; + virtual void platformPrepareAgc(RPiController::Metadata &rpiMetadata) = 0; virtual RPiController::StatisticsPtr platformProcessStats(Span mem) = 0; diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp index 406d683dc..616014729 100644 --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp @@ -759,7 +759,8 @@ public: void beOutputDequeue(FrameBuffer *buffer); void processStatsComplete(const ipa::RPi::BufferIds &buffers); - void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers); + void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + unsigned int paramsBytesUsed); void setCameraTimeout(uint32_t maxFrameLengthMs); /* Array of CFE and ISP device streams and associated buffers/streams. */ @@ -1885,7 +1886,8 @@ void PiSPCameraData::setCameraTimeout(uint32_t maxFrameLengthMs) cfe_[Cfe::Output0].dev()->setDequeueTimeout(timeout); } -void PiSPCameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers) +void PiSPCameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + [[maybe_unused]] unsigned int paramsBytesUsed) { unsigned int embeddedId = buffers.embedded & RPi::MaskID; unsigned int bayerId = buffers.bayer & RPi::MaskID; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 3e9a49058..c18358876 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -79,7 +79,8 @@ public: void ispOutputDequeue(FrameBuffer *buffer); void processStatsComplete(const ipa::RPi::BufferIds &buffers); - void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers); + void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + unsigned int paramsBytesUsed); void setIspControls(const ControlList &controls); void setCameraTimeout(uint32_t maxFrameLengthMs); @@ -863,7 +864,8 @@ void Vc4CameraData::processStatsComplete(const ipa::RPi::BufferIds &buffers) } void Vc4CameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, - [[maybe_unused]] bool stitchSwapBuffers) + [[maybe_unused]] bool stitchSwapBuffers, + [[maybe_unused]] unsigned int paramsBytesUsed) { unsigned int embeddedId = buffers.embedded & RPi::MaskID; unsigned int bayer = buffers.bayer & RPi::MaskID; From patchwork Wed Jul 22 11:23:21 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27440 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 25876BDE17 for ; Wed, 22 Jul 2026 11:25:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BE51067E9E; Wed, 22 Jul 2026 13:25:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="p1FrjwJS"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3C37967E8A for ; Wed, 22 Jul 2026 13:25:09 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D2BD9227; Wed, 22 Jul 2026 13:24:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719449; bh=d+YQTS6n9HgC8Zb49pUpjQKeBNKxnzl/vTVWTVtNZE0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=p1FrjwJSYN9r/SBf9Cmp1V/DXbIfsljqNWSulq7jZ4vANuMRmaAA7+64kUlrm3dqS KoeKFKc0WjifH8jQAiv5apx554/VtxN1a5Skat+qwCSJIvY2fn4ef3TLBkUbNDjrWp 8OI2zMk625DpIB3LHFY2Ad57EvwJWGOjK1ZS8d9I= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:21 +0530 Subject: [PATCH v2 5/8] pipeline: rpi: vc4: Configure format on Unicam subdev MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-5-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7425; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=ietdfXWCu9WIQELry+xNGfG3JoQt36DW+JiF3miCcQo=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhr8M//hkxuVAMKsYnRRAgVtpPQtwTAxpfHd rcFYOb/jlmJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCoawAKCRBD3pH5JJpx RdIHEAClVMy/2cOVSlYS5vRfQklzzxZLYMkngKidZdXLgfhUG6CRg7asoMzovgWD1zHdZRtURQJ JfUKxDH8IvRyZlY8aau6peVhdjiJ764k3dqRN8WnX94PAQAPAhezRNN8xOv4jz5o4QAThAGj0SJ 09tJKKigGMDPw1H6+458n52+Z0COU3sE4oDSDu7mj+E8qtyyR5orYLqfP70wJMMNuiFgK7sA+6K HYKq1Tx7IXmG4sA8rj01g0aCkCIL+ZSuRnVeHbQN4jn+vChzX5QUyMMDkV2dWx88pjl7Nne24FS mK/YW4H6ySAGxqQTwIfL9PiLqOX2HX92qkL3RgqbDjHNJDSm/3khkzsjBr9YC/PC7NNtk+89Hx4 2KSlWiBUUujOr7LBOHxGP40wqFGeDe6Ac/y4qMmDGJm63pb6yNZsv7UF92wpuG6/ORBug8Vd/Q+ NoB0yqStQozdIRsGoIvsDoETg/CSmqe5kGFRj0jYhotEMwKnoi2ZizuZ2PPvFdcBivLqGPm6sFH yKBkOtjGMmc8qinzjhhzQkv297T+ItfVSJlv/aXVKrA6CAh0RwK4gTkulpMyol7jS7cOqgjAWQi pXZ2nfy54r/UR4Gm1Yzh2H/hOhUwT5EAnxGZ+XbiXCfUFZ8uSbqhsOdYqmTDGWXldMRIInNw1AG IpEUats8AIU3Vpw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Laurent Pinchart The mainline Unicam driver creates a V4L2 subdevice, which needs to be configured. Create and open a corresponding V4L2Subdevice instance and configure the format on its sink pad in the platformConfigure() function. Presence of the Unicam subdev is required, to avoid extra complexity. This drops support for the driver from the Raspberry Pi downstream kernel. Users are expected to update their kernel to use the mainline Unicam driver. Signed-off-by: Laurent Pinchart Signed-off-by: Jai Luthra --- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 100 ++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index c18358876..f06c439d5 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -15,6 +15,7 @@ #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/dma_buf_allocator.h" +#include "libcamera/internal/v4l2_subdevice.h" #include "../common/pipeline_base.h" #include "../common/rpi_stream.h" @@ -33,6 +34,10 @@ namespace { enum class Unicam : unsigned int { Image, Embedded }; enum class Isp : unsigned int { Input, Output0, Output1, Stats }; +static constexpr unsigned int kUnicamSinkPad = 0; +static constexpr unsigned int kUnicamSourceImagePad = 1; +static constexpr unsigned int kUnicamSourceMetadataPad = 2; + } /* namespace */ class Vc4CameraData final : public RPi::CameraData @@ -84,6 +89,8 @@ public: void setIspControls(const ControlList &controls); void setCameraTimeout(uint32_t maxFrameLengthMs); + std::unique_ptr unicamSubdev_; + /* Array of Unicam and ISP device streams and associated buffers/streams. */ RPi::Device unicam_; RPi::Device isp_; @@ -204,7 +211,7 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator) std::unique_ptr cameraData = std::make_unique(this); int ret = RPi::PipelineHandlerBase::registerCamera(cameraData, - unicamDevice, "unicam-image", + unicamDevice, "unicam", ispDevice, entity); if (ret) LOG(RPI, Error) << "Failed to register camera " @@ -316,16 +323,19 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer if (!data->dmaHeap_.isValid()) return -ENOMEM; + MediaEntity *unicamSubdev = unicam->getEntityByName("unicam"); MediaEntity *unicamImage = unicam->getEntityByName("unicam-image"); MediaEntity *ispOutput0 = isp->getEntityByName("bcm2835-isp0-output0"); MediaEntity *ispCapture1 = isp->getEntityByName("bcm2835-isp0-capture1"); MediaEntity *ispCapture2 = isp->getEntityByName("bcm2835-isp0-capture2"); MediaEntity *ispCapture3 = isp->getEntityByName("bcm2835-isp0-capture3"); - if (!unicamImage || !ispOutput0 || !ispCapture1 || !ispCapture2 || !ispCapture3) + if (!unicamSubdev || !unicamImage || !ispOutput0 || !ispCapture1 || + !ispCapture2 || !ispCapture3) return -ENOENT; - /* Locate and open the unicam video streams. */ + /* Create the unicam subdev and video streams. */ + data->unicamSubdev_ = std::make_unique(unicamSubdev); data->unicam_[Unicam::Image] = RPi::Stream("Unicam Image", unicamImage); /* An embedded data node will not be present if the sensor does not support it. */ @@ -364,6 +374,10 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer * The below grouping is just for convenience so that we can easily * iterate over all streams in one go. */ + int ret = data->unicamSubdev_->open(); + if (ret < 0) + return ret; + data->streams_.push_back(&data->unicam_[Unicam::Image]); if (data->sensorMetadata_) data->streams_.push_back(&data->unicam_[Unicam::Embedded]); @@ -372,7 +386,7 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer data->streams_.push_back(&stream); for (auto stream : data->streams_) { - int ret = stream->dev()->open(); + ret = stream->dev()->open(); if (ret) return ret; } @@ -543,9 +557,54 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr &r int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig) { + /* + * 1. Configure the Unicam subdev. + * + * Start by setting up routes, and then set the formats on the sink pad + * streams. They will be automatically propagated to the source pads by + * the kernel. + */ + + const V4L2Subdevice::Stream imageStream{ + kUnicamSinkPad, + sensor_->imageStream().stream + }; + const V4L2Subdevice::Stream embeddedDataStream{ + kUnicamSinkPad, + sensor_->embeddedDataStream().value_or(V4L2Subdevice::Stream{}).stream + }; + + V4L2Subdevice::Routing routing; + + routing.emplace_back(imageStream, V4L2Subdevice::Stream{ kUnicamSourceImagePad, 0 }, + V4L2_SUBDEV_ROUTE_FL_ACTIVE); + + if (sensorMetadata_) + routing.emplace_back(embeddedDataStream, + V4L2Subdevice::Stream{ kUnicamSourceMetadataPad, 0 }, + V4L2_SUBDEV_ROUTE_FL_ACTIVE); + + int ret = unicamSubdev_->setRouting(&routing); + if (ret) + return ret; + + V4L2SubdeviceFormat subdevFormat = rpiConfig->sensorFormat_; + ret = unicamSubdev_->setFormat(imageStream, &subdevFormat); + if (ret) + return ret; + + if (sensorMetadata_) { + subdevFormat = sensor_->embeddedDataFormat(); + ret = unicamSubdev_->setFormat(embeddedDataStream, &subdevFormat); + if (ret) + return ret; + } + + /* + * 2. Configure the Unicam video devices. + */ const std::vector &rawStreams = rpiConfig->rawStreams_; const std::vector &outStreams = rpiConfig->outStreams_; - int ret; V4L2VideoDevice *unicam = unicam_[Unicam::Image].dev(); V4L2DeviceFormat unicamFormat; @@ -569,14 +628,37 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi if (ret) return ret; - ret = isp_[Isp::Input].dev()->setFormat(&unicamFormat); - if (ret) - return ret; - LOG(RPI, Info) << "Sensor: " << sensor_->id() << " - Selected sensor format: " << rpiConfig->sensorFormat_ << " - Selected unicam format: " << unicamFormat; + /* + * Configure the Unicam embedded data output format only if the sensor + * supports it. + */ + if (sensorMetadata_) { + V4L2SubdeviceFormat embeddedFormat = sensor_->embeddedDataFormat(); + V4L2DeviceFormat format{}; + format.fourcc = V4L2PixelFormat(V4L2_META_FMT_SENSOR_DATA); + format.planes[0].size = embeddedFormat.size.width * embeddedFormat.size.height; + + LOG(RPI, Debug) << "Setting embedded data format " << format; + ret = unicam_[Unicam::Embedded].dev()->setFormat(&format); + if (ret) { + LOG(RPI, Error) << "Failed to set format on Unicam embedded: " + << format; + return ret; + } + } + + /* + * 3. Configure the ISP. + */ + + ret = isp_[Isp::Input].dev()->setFormat(&unicamFormat); + if (ret) + return ret; + /* Use a sensible small default size if no output streams are configured. */ Size maxSize = outStreams.empty() ? Size(320, 240) : outStreams[0].cfg->size; V4L2DeviceFormat format; From patchwork Wed Jul 22 11:23:22 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27441 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 8FC4DBDE17 for ; Wed, 22 Jul 2026 11:25:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 51FFB67EA6; Wed, 22 Jul 2026 13:25:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="r6C4ev6l"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CFBEC67E8A for ; Wed, 22 Jul 2026 13:25:15 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6ED26227; Wed, 22 Jul 2026 13:24:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719455; bh=SV/9yVphX7adVG0ztZJZ7TuJ/E0cAHbpcJoWQeJPWGk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=r6C4ev6lw66U4lCvcYVnOsazkS9l3i9qjcG2LdsQ0VtTPEQxCbJUJeBgdvna22Su9 gdTAaL/4jx2xPmiRstDhW1ePI3pYJpPTCeTmrlpO4N14hLD/qB3gBNXnU6bte1ymA+ mx7HdKHgsskj9fgPcbdGgqZrToY0ZxZrKJZxRM1g= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:22 +0530 Subject: [PATCH v2 6/8] pipeline: rpi: vc4: Switch to mainline media topology for bcm2835-isp MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-6-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6639; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=SV/9yVphX7adVG0ztZJZ7TuJ/E0cAHbpcJoWQeJPWGk=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhsGLlgbNPLA70Ws5ZTgbbfaJbZFXfn8gwRu keDPdqo8E6JAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCobAAKCRBD3pH5JJpx ReqyD/9AypqYUOM+wk8+7v9B2ggKbEnDqY0JLsEkgQWKbwOBBJQhFAPcTRWFMz+V+w4oqD+NoAP aC4PpPsNyGoOPqn/bH2zwpDqvJXq1nfTcdOiTQ5PZWeZe5tmX4ZNKqppobtKfCUb4DxiHsn79bS im65l/NabXhOVD9UyCGFjdOu35skarxFv9Nyxrftx9xl+/Pp/Vl2hmQeHPXTRBtCvCT1IyGeZTj zLQwbeuSWJUfjDWMMdShhIIhg9RL3iM9KLcNHKt6SMVTWLRl3OeWOUO2bE98CBDi5lC/oEpfdRL VvIFWCRWxP2fCQiPhCEtWV/THePuletjs9EA/fOaHC2Xd+bj27xlM36fb4iKj/9QjUt8a0TiPoW 7phZH2mXX5oSBxvjviw1qZ6Z3fT8niFDC7WLUcKHLqLapA3BWWl56z9LMChdOQPEKzXS+bQa63L CE1VqI4S9HqEy5cnsKmXAyev0Z3rflVn0oGm8kFsHQIUWL8NIDeojznEk62q2w+1lOKm+/BTd3p i+lrJxKc3z0IvD1/dZhAPJ9HBxC0K0sDimSExhg9F/pF+kONqW21FGvDVpjWjEs48eeL1MMt6qo HP3uWGNZnl2ZDz4ZmG2g2Ju8X1IqkV6RGASUNOzZzrDbrfjGOfKzjxqOoLXvrXcIdhL6hWJJRho cPcEMPs8ObQaE3g== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Switch from the downstream driver's video node naming scheme of bcm2835-isp0-output0,capture1..3 to the mainline scheme of bcm2835-isp-output0,capture0..1,stats2. Users are expected to update their kernel to use the mainline VC4 driver. For now we only initialize the new bcm2835-isp-params video node. Filling and queueing buffers to the node will be handled in a subsequent commit. Signed-off-by: Jai Luthra --- src/libcamera/pipeline/rpi/common/rpi_stream.h | 1 + src/libcamera/pipeline/rpi/vc4/vc4.cpp | 49 +++++++++++++++++++------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/rpi_stream.h b/src/libcamera/pipeline/rpi/common/rpi_stream.h index 300a352a7..cc18dcc8f 100644 --- a/src/libcamera/pipeline/rpi/common/rpi_stream.h +++ b/src/libcamera/pipeline/rpi/common/rpi_stream.h @@ -30,6 +30,7 @@ enum BufferMask { MaskStats = 0x010000, MaskEmbeddedData = 0x020000, MaskBayerData = 0x040000, + MaskParams = 0x080000, }; struct BufferObject { diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index f06c439d5..e9fae8890 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -32,7 +32,7 @@ using StreamParams = RPi::RPiCameraConfiguration::StreamParams; namespace { enum class Unicam : unsigned int { Image, Embedded }; -enum class Isp : unsigned int { Input, Output0, Output1, Stats }; +enum class Isp : unsigned int { Input, Output0, Output1, Stats, Params }; static constexpr unsigned int kUnicamSinkPad = 0; static constexpr unsigned int kUnicamSourceImagePad = 1; @@ -93,7 +93,7 @@ public: /* Array of Unicam and ISP device streams and associated buffers/streams. */ RPi::Device unicam_; - RPi::Device isp_; + RPi::Device isp_; /* DMAHEAP allocation helper. */ DmaBufAllocator dmaHeap_; @@ -267,6 +267,13 @@ int PipelineHandlerVc4::allocateBuffers(Camera *camera) std::max(data->config_.minUnicamBuffers, minBuffers - numRawBuffers); + } else if (stream == &data->isp_[Isp::Params]) { + /* + * Parameter buffers are dequeued immediately after + * sending the commands to VC4 firmware. Ideally, 1 + * buffer would be sufficient, but allot 2 to be safe. + */ + numBuffers = 2; } else if (stream == &data->unicam_[Unicam::Embedded]) { /* * Embedded data buffers are (currently) for internal use, and @@ -303,10 +310,11 @@ int PipelineHandlerVc4::allocateBuffers(Camera *camera) } /* - * Pass the stats and embedded data buffers to the IPA. No other - * buffers need to be passed. + * Pass the stats, embedded data and parameter buffers to the IPA. No + * other buffers need to be passed. */ mapBuffers(camera, data->isp_[Isp::Stats].getBuffers(), RPi::MaskStats); + mapBuffers(camera, data->isp_[Isp::Params].getBuffers(), RPi::MaskParams); if (data->sensorMetadata_) mapBuffers(camera, data->unicam_[Unicam::Embedded].getBuffers(), RPi::MaskEmbeddedData); @@ -325,13 +333,14 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer MediaEntity *unicamSubdev = unicam->getEntityByName("unicam"); MediaEntity *unicamImage = unicam->getEntityByName("unicam-image"); - MediaEntity *ispOutput0 = isp->getEntityByName("bcm2835-isp0-output0"); - MediaEntity *ispCapture1 = isp->getEntityByName("bcm2835-isp0-capture1"); - MediaEntity *ispCapture2 = isp->getEntityByName("bcm2835-isp0-capture2"); - MediaEntity *ispCapture3 = isp->getEntityByName("bcm2835-isp0-capture3"); + MediaEntity *ispOutput0 = isp->getEntityByName("bcm2835-isp-output0"); + MediaEntity *ispCapture0 = isp->getEntityByName("bcm2835-isp-capture0"); + MediaEntity *ispCapture1 = isp->getEntityByName("bcm2835-isp-capture1"); + MediaEntity *ispCapture2 = isp->getEntityByName("bcm2835-isp-stats2"); + MediaEntity *ispParams = isp->getEntityByName("bcm2835-isp-params"); - if (!unicamSubdev || !unicamImage || !ispOutput0 || !ispCapture1 || - !ispCapture2 || !ispCapture3) + if (!unicamSubdev || !unicamImage || !ispOutput0 || !ispCapture0 || + !ispCapture1 || !ispCapture2 || !ispParams) return -ENOENT; /* Create the unicam subdev and video streams. */ @@ -348,9 +357,12 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer /* Tag the ISP input stream as an import stream. */ data->isp_[Isp::Input] = RPi::Stream("ISP Input", ispOutput0, StreamFlag::ImportOnly); - data->isp_[Isp::Output0] = RPi::Stream("ISP Output0", ispCapture1); - data->isp_[Isp::Output1] = RPi::Stream("ISP Output1", ispCapture2); - data->isp_[Isp::Stats] = RPi::Stream("ISP Stats", ispCapture3); + data->isp_[Isp::Output0] = RPi::Stream("ISP Output0", ispCapture0); + data->isp_[Isp::Output1] = RPi::Stream("ISP Output1", ispCapture1); + data->isp_[Isp::Stats] = RPi::Stream("ISP Stats", ispCapture2); + /* Tag the ISP params stream as MMAP (for writing into it in the IPA) and recurrent. */ + data->isp_[Isp::Params] = RPi::Stream("ISP Params", ispParams, + StreamFlag::RequiresMmap | StreamFlag::Recurrent); /* Wire up all the buffer connections. */ data->unicam_[Unicam::Image].dev()->bufferReady.connect(data, &Vc4CameraData::unicamBufferDequeue); @@ -358,6 +370,7 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer data->isp_[Isp::Output0].dev()->bufferReady.connect(data, &Vc4CameraData::ispOutputDequeue); data->isp_[Isp::Output1].dev()->bufferReady.connect(data, &Vc4CameraData::ispOutputDequeue); data->isp_[Isp::Stats].dev()->bufferReady.connect(data, &Vc4CameraData::ispOutputDequeue); + data->isp_[Isp::Params].dev()->bufferReady.connect(data, &Vc4CameraData::ispOutputDequeue); if (data->sensorMetadata_ ^ !!data->unicam_[Unicam::Embedded].dev()) { LOG(RPI, Warning) << "Mismatch between Unicam and CamHelper for embedded data usage!"; @@ -758,6 +771,16 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi return ret; } + /* ISP parameters input format. */ + format = {}; + format.fourcc = V4L2PixelFormat(V4L2_META_FMT_BCM2835_ISP_PARAMS); + ret = isp_[Isp::Params].dev()->setFormat(&format); + if (ret) { + LOG(RPI, Error) << "Failed to set format on ISP params stream: " + << format; + return ret; + } + /* * Configure the Unicam embedded data output format only if the sensor * supports it. From patchwork Wed Jul 22 11:23:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27442 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 505C6BDE17 for ; Wed, 22 Jul 2026 11:25:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F3C4767EA6; Wed, 22 Jul 2026 13:25:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LhtdT3FF"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 60A9C67E8A for ; Wed, 22 Jul 2026 13:25:22 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B523F227; Wed, 22 Jul 2026 13:24:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719462; bh=y8j33FOrgj+T6MZNVixp4/FvB4vadVLWSH3lF6GKzdM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LhtdT3FFyWTiNnsoZYqpsIwL0aawRLAscgMGo4hxhTfzSV8NGXgS9Ut7za/FWbhwP aN3KbwVKC9G1b8uUJBfrOi6ajrtCfhxEpbdxYPsPSj9VjKR6Bc7+/mn5cPniKVcyaT Ee03DXq33FcO59BYVekIVpq7MdXLjtqO+U77hZyY= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:23 +0530 Subject: [PATCH v2 7/8] pipeline/ipa: rpi: vc4: Switch configuration from controls to param buffer MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-7-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=25001; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=y8j33FOrgj+T6MZNVixp4/FvB4vadVLWSH3lF6GKzdM=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhtsCpvteSZNTPgL32zDLZQOSEPIWRIjrHNd i6mEmpgN5uJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCobQAKCRBD3pH5JJpx RX8rEADVxWG/fxIYMh6gqeH0keBh8vM6r46hVbDbkMZvsuyWmDzpnJ1+CAZhCjYTUx0GIaed3Ln McGJe+uWjC8tlUkQ06Hfhca30h6e6YL8VaNGdDY/2WSQi4lEsPCCRQe19B7AFZJ3fhCyPTBIV6J KX7coZYpFjxVBjOLW4Mt5BaqXxFw8lMd73KbRlWve5SK3WPECw2dFuqiILW02mXssr+v0TjACCP mPjgpY7/EkfSSwv8T2UTZis8aOrwMuCprDVk6cxHeifmRRqOggVv2tvHl5Xio5t8seaTn/VY6Iu dNaXMqniSkbUzSKuELvFGfDuwxsYwFNRGGwuaStRsdeBLHDqliBAs7uCW1ECCfYXIP1tIsha1/a NmqQgqfKmezMGFRGxk9UHEjjkXmdek3vpI1U6zniyLrOWlnk/2mPnfcpO8dVk5GInj/ZdGD0xH+ WObpLfx3Wb6+iFr5GCab1WxlahMiWoBJVMd1iEGYILI2QEMwmg8PZS0DX+s1f0mt3Dd5G77GR4c tKtqA465E/BdbkZ1auYV54Q9V54EisuodaZedr1CcIMA7OWICQ1rALiLAAk227aUKGO1Kz/Jrn0 Hzis2XCiVooNLcrzN94+WmqG1opn+CmxJ3QRo9itPVuMim9lWKyCmW0NMxc6OqxKwXG+RmEjl19 5KoOkpzRrlLaVEg== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Let each algorithm write directly into typed parameter blocks using the Bcm2835Params helper. Acquire a parameter buffer in tryRunPipeline(), pass it to the IPA through BufferIds::params, and queue it back to the ISP once the IPA reports how many bytes it filled. Also patch the lens-shading dmabuf fd in the params buffer, similar to what setIspControls() did before. Finally, drop the dead-code that was used to configure the custom V4L2 controls for ISP configuration. Signed-off-by: Jai Luthra --- include/libcamera/ipa/raspberrypi.mojom | 12 -- src/ipa/rpi/vc4/vc4.cpp | 222 ++++++++++++++------------------ src/libcamera/pipeline/rpi/vc4/vc4.cpp | 89 +++++++++---- 3 files changed, 158 insertions(+), 165 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index dcd3b2c66..2b4855e4f 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -39,7 +39,6 @@ struct BufferIds { struct ConfigParams { uint32 transform; libcamera.ControlInfoMap sensorControls; - libcamera.ControlInfoMap ispControls; libcamera.ControlInfoMap lensControls; /* VC4 specific */ libcamera.SharedFD lsTableHandle; @@ -253,17 +252,6 @@ interface IPARPiEventInterface { */ metadataReady(libcamera.ControlList metadata); - /** - * \fn setIspControls() - * \brief Signal ISP controls to be applied. - * \param[in] controls List of controls to be applied. - * - * This asynchronous event is signalled to the pipeline handler during - * the \a prepareISP signal after all algorithms have been run and the - * IPA requires ISP controls to be applied for the frame. - */ - setIspControls(libcamera.ControlList controls); - /** * \fn setDelayedControls() * \brief Signal Sensor controls to be applied. diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index 052204d25..50fee538a 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -5,6 +5,7 @@ * Raspberry Pi VC4/BCM2835 ISP IPA. */ +#include #include #include @@ -30,6 +31,7 @@ #include "controller/lux_status.h" #include "controller/noise_status.h" #include "controller/sharpen_status.h" +#include "params.h" namespace libcamera { @@ -59,34 +61,38 @@ private: int32_t platformStart(const ControlList &controls, StartResult *result) override; int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) override; + void platformParamsBufferInit(Span paramsBuffer) override; void platformPrepareIsp(RPiController::Metadata &rpiMetadata) override; void platformPrepareAgc([[maybe_unused]] RPiController::Metadata &rpiMetadata) override; RPiController::StatisticsPtr platformProcessStats(Span mem) override; void handleControls(const ControlList &controls) override; - bool validateIspControls(); - void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls); - void applyDG(double digitalGain, const struct AwbStatus *awbStatus, ControlList &ctrls); - void applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls); - void applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls); - void applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls); - void applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls); - void applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList &ctrls); - void applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls); - void applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls); - void applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls); + void applyAWB(const struct AwbStatus *awbStatus, Bcm2835Params ¶ms); + void applyDG(double digitalGain, const struct AwbStatus *awbStatus, Bcm2835Params ¶ms); + void applyCCM(const struct CcmStatus *ccmStatus, Bcm2835Params ¶ms); + void applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, Bcm2835Params ¶ms); + void applyGamma(const struct ContrastStatus *contrastStatus, Bcm2835Params ¶ms); + void applyGEQ(const struct GeqStatus *geqStatus, Bcm2835Params ¶ms); + void applyDenoise(const struct DenoiseStatus *denoiseStatus, Bcm2835Params ¶ms); + void applySharpen(const struct SharpenStatus *sharpenStatus, Bcm2835Params ¶ms); + void applyDPC(const struct DpcStatus *dpcStatus, Bcm2835Params ¶ms); + void applyLS(const struct AlscStatus *lsStatus, Bcm2835Params ¶ms); void applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls); void resampleTable(uint16_t dest[], const std::vector &src, int destW, int destH); - /* VC4 ISP controls. */ - ControlInfoMap ispCtrls_; - ControlList ctrls_; + size_t platformParamsBytesUsed() const override + { + return (ispParams_.has_value()) ? ispParams_->bytesused() : 0; + } /* LS table allocation passed in from the pipeline handler. */ SharedFD lsTableHandle_; void *lsTable_; + /* Params buffer for the current frame. */ + std::optional ispParams_; + /* Remember the most recent AWB values. */ AwbStatus lastAwbStatus_; }; @@ -113,13 +119,6 @@ int32_t IpaVc4::platformStart([[maybe_unused]] const ControlList &controls, int32_t IpaVc4::platformConfigure(const ConfigParams ¶ms, [[maybe_unused]] ConfigResult *result) { - ispCtrls_ = params.ispControls; - ctrls_ = ControlList(ispCtrls_); - if (!validateIspControls()) { - LOG(IPARPI, Error) << "ISP control validation failed."; - return -1; - } - /* Store the lens shading table pointer and handle if available. */ if (params.lsTableHandle.isValid()) { /* Remove any previous table, if there was one. */ @@ -144,50 +143,54 @@ int32_t IpaVc4::platformConfigure(const ConfigParams ¶ms, [[maybe_unused]] C return 0; } +void IpaVc4::platformParamsBufferInit(Span paramsBuffer) +{ + /* Initialize the extensible parameter buffer */ + ispParams_.emplace(paramsBuffer); +} + void IpaVc4::platformPrepareIsp(RPiController::Metadata &rpiMetadata) { - ControlList &ctrls = ctrls_; - /* Lock the metadata buffer to avoid constant locks/unlocks. */ std::unique_lock lock(rpiMetadata); AwbStatus *awbStatus = rpiMetadata.getLocked("awb.status"); if (awbStatus) { - applyAWB(awbStatus, ctrls); + applyAWB(awbStatus, *ispParams_); lastAwbStatus_ = *awbStatus; } CcmStatus *ccmStatus = rpiMetadata.getLocked("ccm.status"); if (ccmStatus) - applyCCM(ccmStatus, ctrls); + applyCCM(ccmStatus, *ispParams_); AlscStatus *lsStatus = rpiMetadata.getLocked("alsc.status"); if (lsStatus) - applyLS(lsStatus, ctrls); + applyLS(lsStatus, *ispParams_); ContrastStatus *contrastStatus = rpiMetadata.getLocked("contrast.status"); if (contrastStatus) - applyGamma(contrastStatus, ctrls); + applyGamma(contrastStatus, *ispParams_); BlackLevelStatus *blackLevelStatus = rpiMetadata.getLocked("black_level.status"); if (blackLevelStatus) - applyBlackLevel(blackLevelStatus, ctrls); + applyBlackLevel(blackLevelStatus, *ispParams_); GeqStatus *geqStatus = rpiMetadata.getLocked("geq.status"); if (geqStatus) - applyGEQ(geqStatus, ctrls); + applyGEQ(geqStatus, *ispParams_); DenoiseStatus *denoiseStatus = rpiMetadata.getLocked("denoise.status"); if (denoiseStatus) - applyDenoise(denoiseStatus, ctrls); + applyDenoise(denoiseStatus, *ispParams_); SharpenStatus *sharpenStatus = rpiMetadata.getLocked("sharpen.status"); if (sharpenStatus) - applySharpen(sharpenStatus, ctrls); + applySharpen(sharpenStatus, *ispParams_); DpcStatus *dpcStatus = rpiMetadata.getLocked("dpc.status"); if (dpcStatus) - applyDPC(dpcStatus, ctrls); + applyDPC(dpcStatus, *ispParams_); const AfStatus *afStatus = rpiMetadata.getLocked("af.status"); if (afStatus) { @@ -204,10 +207,7 @@ void IpaVc4::platformPrepareAgc(RPiController::Metadata &rpiMetadata) double digitalGain = delayedAgcStatus ? delayedAgcStatus->digitalGain : agcStatus_.digitalGain; AwbStatus *awbStatus = rpiMetadata.getLocked("awb.status"); - applyDG(digitalGain, awbStatus, ctrls_); - - setIspControls.emit(ctrls_); - ctrls_ = ControlList(ispCtrls_); + applyDG(digitalGain, awbStatus, *ispParams_); } RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span mem) @@ -324,48 +324,26 @@ void IpaVc4::handleControls(const ControlList &controls) } } -bool IpaVc4::validateIspControls() +void IpaVc4::applyAWB(const struct AwbStatus *awbStatus, Bcm2835Params ¶ms) { - static const uint32_t ctrls[] = { - V4L2_CID_RED_BALANCE, - V4L2_CID_BLUE_BALANCE, - V4L2_CID_DIGITAL_GAIN, - V4L2_CID_USER_BCM2835_ISP_CC_MATRIX, - V4L2_CID_USER_BCM2835_ISP_GAMMA, - V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL, - V4L2_CID_USER_BCM2835_ISP_GEQ, - V4L2_CID_USER_BCM2835_ISP_DENOISE, - V4L2_CID_USER_BCM2835_ISP_SHARPEN, - V4L2_CID_USER_BCM2835_ISP_DPC, - V4L2_CID_USER_BCM2835_ISP_LENS_SHADING, - V4L2_CID_USER_BCM2835_ISP_CDN, - }; + auto block = params.block(); - for (auto c : ctrls) { - if (ispCtrls_.find(c) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Unable to find ISP control " - << utils::hex(c); - return false; - } - } - - return true; -} - -void IpaVc4::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) -{ LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gainR << " B: " << awbStatus->gainB; - ctrls.set(V4L2_CID_RED_BALANCE, - static_cast(awbStatus->gainR * 1000)); - ctrls.set(V4L2_CID_BLUE_BALANCE, - static_cast(awbStatus->gainB * 1000)); + block->awb_gains.r_gain.num = static_cast(awbStatus->gainR * 1000); + block->awb_gains.r_gain.den = 1000; + block->awb_gains.b_gain.num = static_cast(awbStatus->gainB * 1000); + block->awb_gains.b_gain.den = 1000; + + block.setEnabled(true); } void IpaVc4::applyDG(double digitalGain, - const struct AwbStatus *awbStatus, ControlList &ctrls) + const struct AwbStatus *awbStatus, Bcm2835Params ¶ms) { + auto block = params.block(); + if (awbStatus) { /* * We must apply sufficient extra digital gain to stop any of the channel gains being @@ -379,13 +357,16 @@ void IpaVc4::applyDG(double digitalGain, digitalGain *= extraGain; } - ctrls.set(V4L2_CID_DIGITAL_GAIN, - static_cast(digitalGain * 1000)); + block->digital_gain.gain.num = static_cast(digitalGain * 1000); + block->digital_gain.gain.den = 1000; + + block.setEnabled(true); } -void IpaVc4::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls) +void IpaVc4::applyCCM(const struct CcmStatus *ccmStatus, Bcm2835Params ¶ms) { - bcm2835_isp_custom_ccm ccm; + auto block = params.block(); + bcm2835_isp_custom_ccm &ccm = block->ccm; for (int i = 0; i < 9; i++) { ccm.ccm.ccm[i / 3][i % 3].den = 1000; @@ -394,30 +375,28 @@ void IpaVc4::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls) ccm.enabled = 1; ccm.ccm.offsets[0] = ccm.ccm.offsets[1] = ccm.ccm.offsets[2] = 0; - - ControlValue c(Span{ reinterpret_cast(&ccm), - sizeof(ccm) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_CC_MATRIX, c); + block.setEnabled(true); } -void IpaVc4::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls) +void IpaVc4::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, + Bcm2835Params ¶ms) { - bcm2835_isp_black_level blackLevel; + auto block = params.block(); + bcm2835_isp_black_level &blackLevel = block->black_level; blackLevel.enabled = 1; blackLevel.black_level_r = blackLevelStatus->blackLevelR; blackLevel.black_level_g = blackLevelStatus->blackLevelG; blackLevel.black_level_b = blackLevelStatus->blackLevelB; - - ControlValue c(Span{ reinterpret_cast(&blackLevel), - sizeof(blackLevel) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL, c); + block.setEnabled(true); } -void IpaVc4::applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls) +void IpaVc4::applyGamma(const struct ContrastStatus *contrastStatus, + Bcm2835Params ¶ms) { const unsigned int numGammaPoints = controller_.getHardwareConfig().numGammaPoints; - struct bcm2835_isp_gamma gamma; + auto block = params.block(); + struct bcm2835_isp_gamma &gamma = block->gamma; for (unsigned int i = 0; i < numGammaPoints - 1; i++) { int x = i < 16 ? i * 1024 @@ -430,31 +409,27 @@ void IpaVc4::applyGamma(const struct ContrastStatus *contrastStatus, ControlList gamma.x[numGammaPoints - 1] = 65535; gamma.y[numGammaPoints - 1] = 65535; gamma.enabled = 1; - - ControlValue c(Span{ reinterpret_cast(&gamma), - sizeof(gamma) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_GAMMA, c); + block.setEnabled(true); } -void IpaVc4::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls) +void IpaVc4::applyGEQ(const struct GeqStatus *geqStatus, Bcm2835Params ¶ms) { - bcm2835_isp_geq geq; + auto block = params.block(); + bcm2835_isp_geq &geq = block->geq; geq.enabled = 1; geq.offset = geqStatus->offset; geq.slope.den = 1000; geq.slope.num = 1000 * geqStatus->slope; - - ControlValue c(Span{ reinterpret_cast(&geq), - sizeof(geq) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_GEQ, c); + block.setEnabled(true); } -void IpaVc4::applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList &ctrls) +void IpaVc4::applyDenoise(const struct DenoiseStatus *denoiseStatus, Bcm2835Params ¶ms) { + auto blockDenoise = params.block(); using RPiController::DenoiseMode; - bcm2835_isp_denoise denoise; + bcm2835_isp_denoise &denoise = blockDenoise->denoise; DenoiseMode mode = static_cast(denoiseStatus->mode); denoise.enabled = mode != DenoiseMode::Off; @@ -463,9 +438,11 @@ void IpaVc4::applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList denoise.slope.den = 1000; denoise.strength.num = 1000 * denoiseStatus->strength; denoise.strength.den = 1000; + blockDenoise.setEnabled(denoise.enabled); /* Set the CDN mode to match the SDN operating mode. */ - bcm2835_isp_cdn cdn; + auto blockCdn = params.block(); + bcm2835_isp_cdn &cdn = blockCdn->cdn; switch (mode) { case DenoiseMode::ColourFast: cdn.enabled = 1; @@ -478,19 +455,13 @@ void IpaVc4::applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList default: cdn.enabled = 0; } - - ControlValue c(Span{ reinterpret_cast(&denoise), - sizeof(denoise) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_DENOISE, c); - - c = ControlValue(Span{ reinterpret_cast(&cdn), - sizeof(cdn) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_CDN, c); + blockCdn.setEnabled(cdn.enabled); } -void IpaVc4::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls) +void IpaVc4::applySharpen(const struct SharpenStatus *sharpenStatus, Bcm2835Params ¶ms) { - bcm2835_isp_sharpen sharpen; + auto block = params.block(); + bcm2835_isp_sharpen &sharpen = block->sharpen; sharpen.enabled = 1; sharpen.threshold.num = 1000 * sharpenStatus->threshold; @@ -499,25 +470,20 @@ void IpaVc4::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList sharpen.strength.den = 1000; sharpen.limit.num = 1000 * sharpenStatus->limit; sharpen.limit.den = 1000; - - ControlValue c(Span{ reinterpret_cast(&sharpen), - sizeof(sharpen) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_SHARPEN, c); + block.setEnabled(true); } -void IpaVc4::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls) +void IpaVc4::applyDPC(const struct DpcStatus *dpcStatus, Bcm2835Params ¶ms) { - bcm2835_isp_dpc dpc; + auto block = params.block(); + bcm2835_isp_dpc &dpc = block->dpc; dpc.enabled = 1; dpc.strength = dpcStatus->strength; - - ControlValue c(Span{ reinterpret_cast(&dpc), - sizeof(dpc) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_DPC, c); + block.setEnabled(true); } -void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) +void IpaVc4::applyLS(const struct AlscStatus *lsStatus, Bcm2835Params ¶ms) { /* * Program lens shading tables into pipeline. @@ -541,7 +507,14 @@ void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) /* We're going to supply corner sampled tables, 16 bit samples. */ w++, h++; - bcm2835_isp_lens_shading ls = { + + if (!lsTableHandle_.isValid() || !lsTable_ || w * h * 4 * sizeof(uint16_t) > MaxLsGridSize) { + LOG(IPARPI, Error) << "Do not have a correctly allocated lens shading table!"; + return; + } + + auto block = params.block(); + block->ls = { .enabled = 1, .grid_cell_size = cellSize, .grid_width = w, @@ -554,11 +527,6 @@ void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) .gain_format = GAIN_FORMAT_U4P10 }; - if (!lsTable_ || w * h * 4 * sizeof(uint16_t) > MaxLsGridSize) { - LOG(IPARPI, Error) << "Do not have a correctly allocate lens shading table!"; - return; - } - if (lsStatus) { /* Format will be u4.10 */ uint16_t *grid = static_cast(lsTable_); @@ -569,9 +537,7 @@ void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) resampleTable(grid + 3 * w * h, lsStatus->b, w, h); } - ControlValue c(Span{ reinterpret_cast(&ls), - sizeof(ls) }); - ctrls.set(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING, c); + block.setEnabled(true); } void IpaVc4::applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls) diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index e9fae8890..1818e314b 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -86,7 +86,6 @@ public: void processStatsComplete(const ipa::RPi::BufferIds &buffers); void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, unsigned int paramsBytesUsed); - void setIspControls(const ControlList &controls); void setCameraTimeout(uint32_t maxFrameLengthMs); std::unique_ptr unicamSubdev_; @@ -142,6 +141,8 @@ private: void tryRunPipeline() override; bool findMatchingBuffers(BayerFrame &bayerFrame, FrameBuffer *&embeddedBuffer); + void populateLensShadingFD(const RPi::BufferObject ¶msBufObj); + std::queue bayerQueue_; std::queue embeddedQueue_; }; @@ -412,7 +413,6 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer /* Write up all the IPA connections. */ data->ipa_->processStatsComplete.connect(data, &Vc4CameraData::processStatsComplete); data->ipa_->prepareIspComplete.connect(data, &Vc4CameraData::prepareIspComplete); - data->ipa_->setIspControls.connect(data, &Vc4CameraData::setIspControls); data->ipa_->setCameraTimeout.connect(data, &Vc4CameraData::setCameraTimeout); /* @@ -824,8 +824,6 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi int Vc4CameraData::platformConfigureIpa(ipa::RPi::ConfigParams ¶ms) { - params.ispControls = isp_[Isp::Input].dev()->controls(); - /* Allocate the lens shading table via dmaHeap and pass to the IPA. */ if (!lsTable_.isValid()) { lsTable_ = SharedFD(dmaHeap_.alloc("ls_grid", ipa::RPi::MaxLsGridSize)); @@ -968,17 +966,65 @@ void Vc4CameraData::processStatsComplete(const ipa::RPi::BufferIds &buffers) handleState(); } +/* + * Populate the lens shading table's dmabuf descriptor inside the params buffer. + * + * While the IPA fills the lens shading table, it may run in an isolated + * process context, so it does not populate the dmabuf file descriptor. + * + * Do that here. + */ +void Vc4CameraData::populateLensShadingFD(const RPi::BufferObject ¶msBufObj) +{ + Span plane = paramsBufObj.mapped->planes()[0]; + auto *paramsBuffer = + reinterpret_cast(plane.data()); + uint8_t *data = paramsBuffer->data; + uint32_t offset = 0; + + while (offset < paramsBuffer->data_size) { + auto *blockHeader = + reinterpret_cast(data + offset); + + if (blockHeader->type == BCM2835_ISP_PARAM_BLOCK_LENS_SHADING) { + auto *lsBlock = + reinterpret_cast(blockHeader); + lsBlock->ls.dmabuf = lsTable_.get(); + return; + } + + offset += blockHeader->size; + } + + LOG(RPI, Error) << "Unable to populate lens-shading dmabuf fd"; +} + void Vc4CameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, [[maybe_unused]] bool stitchSwapBuffers, - [[maybe_unused]] unsigned int paramsBytesUsed) + unsigned int paramsBytesUsed) { unsigned int embeddedId = buffers.embedded & RPi::MaskID; + unsigned int paramsId = buffers.params & RPi::MaskID; unsigned int bayer = buffers.bayer & RPi::MaskID; FrameBuffer *buffer; if (!isRunning()) return; + /* Queue params buffer */ + const RPi::BufferObject ¶msBufObj = isp_[Isp::Params].getBuffers().at(paramsId); + ASSERT(paramsBufObj.mapped); + populateLensShadingFD(paramsBufObj); + buffer = paramsBufObj.buffer; + buffer->_d()->metadata().planes()[0].bytesused = paramsBytesUsed; + + LOG(RPI, Debug) << "Queue params to ISP, buffer id " << paramsId + << ", timestamp: " << buffer->metadata().timestamp + << ", bytes used: " << paramsBytesUsed; + + isp_[Isp::Params].queueBuffer(buffer); + + /* Queue input buffer */ buffer = unicam_[Unicam::Image].getBuffers().at(bayer & RPi::MaskID).buffer; LOG(RPI, Debug) << "Input re-queue to ISP, buffer id " << (bayer & RPi::MaskID) << ", timestamp: " << buffer->metadata().timestamp; @@ -993,23 +1039,6 @@ void Vc4CameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, handleState(); } -void Vc4CameraData::setIspControls(const ControlList &controls) -{ - ControlList ctrls = controls; - - if (ctrls.contains(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING)) { - ControlValue &value = - const_cast(ctrls.get(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING)); - Span s = value.data(); - bcm2835_isp_lens_shading *ls = - reinterpret_cast(s.data()); - ls->dmabuf = lsTable_.get(); - } - - isp_[Isp::Input].dev()->setControls(&ctrls); - handleState(); -} - void Vc4CameraData::setCameraTimeout(uint32_t maxFrameLengthMs) { /* @@ -1037,6 +1066,11 @@ void Vc4CameraData::tryRunPipeline() if (!findMatchingBuffers(bayerFrame, embeddedBuffer)) return; + /* Request a parameter buffer, will be released by ispOutputDequeue */ + const RPi::BufferObject ¶mBufObj = isp_[Isp::Params].acquireBuffer(); + if (!paramBufObj.buffer || !paramBufObj.mapped) + return; + /* Take the first request from the queue and action the IPA. */ Request *request = requestQueue_.front(); ASSERT(request->metadata().empty()); @@ -1048,9 +1082,6 @@ void Vc4CameraData::tryRunPipeline() unsigned int bayer = unicam_[Unicam::Image].getBufferId(bayerFrame.buffer); - LOG(RPI, Debug) << "Signalling prepareIsp:" - << " Bayer buffer id: " << bayer; - ipa::RPi::PrepareParams params; params.buffers.bayer = RPi::MaskBayerData | bayer; params.sensorControls = std::move(bayerFrame.controls); @@ -1065,6 +1096,14 @@ void Vc4CameraData::tryRunPipeline() /* Set our state to say the pipeline is active. */ state_ = State::Busy; + unsigned int paramId = isp_[Isp::Params].getBufferId(paramBufObj.buffer); + ASSERT(paramId); + params.buffers.params = RPi::MaskParams | paramId; + + LOG(RPI, Debug) << "Signalling prepareIsp:" + << " Bayer buffer id: " << bayer + << " Param buffer id: " << paramId; + if (embeddedBuffer) { unsigned int embeddedId = unicam_[Unicam::Embedded].getBufferId(embeddedBuffer); From patchwork Wed Jul 22 11:23:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 27443 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0C4F3BDE17 for ; Wed, 22 Jul 2026 11:25:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB76167E9B; Wed, 22 Jul 2026 13:25:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="acNeNgF6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 20344660AE for ; Wed, 22 Jul 2026 13:25:28 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:25d4:fa24:78d1:31:7a56]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AEE53227; Wed, 22 Jul 2026 13:24:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1784719468; bh=TOULqoRW+YD3yRnY6lxYfZvEO2iG56NsbGi9c2xw2ro=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=acNeNgF6vQE8COcI8vTIoJLWGTwmsCbHBhRSfOgE6riaI8846SUUFQ/vr/mk4OqHJ mtb8fQO0lNNWof/eRNudOXVxsGyYn8krIrci6F1RrVTfWcBkbjHH+hMNmv5OHV5ai8 KbCK79Ltmu7s1JeR4PIhL+oNFFabESISTs3LIJ3s= From: Jai Luthra Date: Wed, 22 Jul 2026 16:53:24 +0530 Subject: [PATCH v2 8/8] include: uapi: bcm2835-isp: Drop legacy V4L2 controls MIME-Version: 1.0 Message-Id: <20260722-pi4-upstream-v2-8-eb44d3c6fd92@ideasonboard.com> References: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> In-Reply-To: <20260722-pi4-upstream-v2-0-eb44d3c6fd92@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Jacopo Mondi , Daniel Scally , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8103; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=TOULqoRW+YD3yRnY6lxYfZvEO2iG56NsbGi9c2xw2ro=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqYKhurBsUj1C7GOqHeT4pXtt4b1JGxyV2im9s6 cxSAjIUgN+JAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCamCobgAKCRBD3pH5JJpx RXSrD/9NDpHFATeiZwotIN/y8A0/BeppW4or8RYuTmjPKyk9cZCAkzSAI0/5971awsze+8/YGyn bIwjmEAkqEzJLL7hd6boM+kijRff6V0OvZD+5Ne4OnMDIj2w3y5wJXYrEJlVULorJGQHEWMipxM QCtX8qkf7F7QJzb52fxFqptd1XE5/ZBr203OfmcVk+7nCvdsCVZj9eQZq4yLgEf19zokwAD5HBC eQqwDS9Q4+xI6sjkPxEDhagBXTttSoA7kiFwxJm3i5Xx3eRDjWZfubvY2viBix2pe2kFoe6+arB GuIywCj+WVeEU2fHZiYQa79efO2tXhMzfUvXZxcZIhLF2RJl5+UBB01GtQ4yAqIq00hW3RHa9l2 ECyTkS0PqKgYjaZX77MAXS0UNfFIh81kD1ptcHYovho9dwp1sOLi0N1BfO88Ag5gcR6cTtAiMz0 xemDL/vImAL+8DvSHO9duUWSUdLfwHudwfUrenDjzrExhrhwMVZyn9lFPQ0+eJlHfNS1Z/ydUZp +N0sYeGN4abM4/YLzDnjRkyrZwukVdLDyMgg4mKuJP0TDfj8IO+3AV0CrZ2hMVrduOjeZH4LVIl jrwzydJ19pESB2Xh0U6DGvndFF7rv4KZFSOzAe+cgY4N6sa9nuX6ltw8T9w0FfwnNcxBHS8OGmh gIpX0JijAgicMXg== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the VC4 IPA and pipeline handler pass ISP configuration exclusively through parameter buffers, the V4L2_CID_USER_BCM2835_ISP_* custom controls are unused. Drop them, clean up the struct documentation that still referenced the controls, and fix the bcm2835_isp_params statistics fourcc comment to match the mainline kernel header. Signed-off-by: Jai Luthra --- include/linux/bcm2835-isp.h | 61 ++++++++++++------------------------------- include/linux/v4l2-controls.h | 3 --- include/linux/videodev2.h | 2 +- 3 files changed, 17 insertions(+), 49 deletions(-) diff --git a/include/linux/bcm2835-isp.h b/include/linux/bcm2835-isp.h index c49854cfa..0f3c1b4db 100644 --- a/include/linux/bcm2835-isp.h +++ b/include/linux/bcm2835-isp.h @@ -13,27 +13,8 @@ #ifndef __BCM2835_ISP_H_ #define __BCM2835_ISP_H_ -#include #include -#define V4L2_CID_USER_BCM2835_ISP_CC_MATRIX \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0001) -#define V4L2_CID_USER_BCM2835_ISP_LENS_SHADING \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0002) -#define V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0003) -#define V4L2_CID_USER_BCM2835_ISP_GEQ \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0004) -#define V4L2_CID_USER_BCM2835_ISP_GAMMA \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0005) -#define V4L2_CID_USER_BCM2835_ISP_DENOISE \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0006) -#define V4L2_CID_USER_BCM2835_ISP_SHARPEN \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0007) -#define V4L2_CID_USER_BCM2835_ISP_DPC \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0008) -#define V4L2_CID_USER_BCM2835_ISP_CDN \ - (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0009) /* * All structs below are directly mapped onto the equivalent structs in * drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h @@ -63,8 +44,7 @@ struct bcm2835_isp_ccm { }; /** - * struct bcm2835_isp_custom_ccm - Custom CCM applied with the - * V4L2_CID_USER_BCM2835_ISP_CC_MATRIX ctrl. + * struct bcm2835_isp_custom_ccm - Custom CCM configuration. * * @enabled: Enable custom CCM. * @ccm: Custom CCM coefficients and offsets. @@ -76,8 +56,7 @@ struct bcm2835_isp_custom_ccm { /** * enum bcm2835_isp_gain_format - format of the gains in the lens shading - * tables used with the - * V4L2_CID_USER_BCM2835_ISP_LENS_SHADING ctrl. + * tables. * * @GAIN_FORMAT_U0P8_1: Gains are u0.8 format, starting at 1.0 * @GAIN_FORMAT_U1P7_0: Gains are u1.7 format, starting at 0.0 @@ -100,9 +79,7 @@ enum bcm2835_isp_gain_format { }; /** - * struct bcm2835_isp_lens_shading - Lens shading tables supplied with the - * V4L2_CID_USER_BCM2835_ISP_LENS_SHADING - * ctrl. + * struct bcm2835_isp_lens_shading - Lens shading tables. * * @enabled: Enable lens shading. * @grid_cell_size: Size of grid cells in samples (16, 32, 64, 128 or 256). @@ -129,13 +106,13 @@ struct bcm2835_isp_lens_shading { }; /** - * struct bcm2835_isp_black_level - Sensor black level set with the - * V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL ctrl. + * struct bcm2835_isp_black_level - Sensor black level configuration. * * @enabled: Enable black level. * @black_level_r: Black level for red channel. * @black_level_g: Black level for green channels. * @black_level_b: Black level for blue channel. + * @padding: Unused padding. */ struct bcm2835_isp_black_level { __u32 enabled; @@ -146,8 +123,7 @@ struct bcm2835_isp_black_level { }; /** - * struct bcm2835_isp_geq - Green equalisation parameters set with the - * V4L2_CID_USER_BCM2835_ISP_GEQ ctrl. + * struct bcm2835_isp_geq - Green equalisation parameters. * * @enabled: Enable green equalisation. * @offset: Fixed offset of the green equalisation threshold. @@ -162,13 +138,12 @@ struct bcm2835_isp_geq { #define BCM2835_NUM_GAMMA_PTS 33 /** - * struct bcm2835_isp_gamma - Gamma parameters set with the - * V4L2_CID_USER_BCM2835_ISP_GAMMA ctrl. + * struct bcm2835_isp_gamma - Gamma parameters. * * @enabled: Enable gamma adjustment. - * @X: X values of the points defining the gamma curve. + * @x: X values of the points defining the gamma curve. * Values should be scaled to 16 bits. - * @Y: Y values of the points defining the gamma curve. + * @y: Y values of the points defining the gamma curve. * Values should be scaled to 16 bits. */ struct bcm2835_isp_gamma { @@ -180,9 +155,9 @@ struct bcm2835_isp_gamma { /** * enum bcm2835_isp_cdn_mode - Mode of operation for colour denoise. * - * @CDN_MODE_FAST: Fast (but lower quality) colour denoise + * @CDN_MODE_FAST: Fast (but lower quality) colour denoise * algorithm, typically used for video recording. - * @CDN_HIGH_QUALITY: High quality (but slower) colour denoise + * @CDN_MODE_HIGH_QUALITY: High quality (but slower) colour denoise * algorithm, typically used for stills capture. */ enum bcm2835_isp_cdn_mode { @@ -191,11 +166,10 @@ enum bcm2835_isp_cdn_mode { }; /** - * struct bcm2835_isp_cdn - Colour denoise parameters set with the - * V4L2_CID_USER_BCM2835_ISP_CDN ctrl. + * struct bcm2835_isp_cdn - Colour denoise parameters. * * @enabled: Enable colour denoise. - * @cdn_mode: Colour denoise operating mode (see enum &bcm2835_isp_cdn_mode) + * @mode: Colour denoise operating mode (see enum &bcm2835_isp_cdn_mode) */ struct bcm2835_isp_cdn { __u32 enabled; @@ -203,8 +177,7 @@ struct bcm2835_isp_cdn { }; /** - * struct bcm2835_isp_denoise - Denoise parameters set with the - * V4L2_CID_USER_BCM2835_ISP_DENOISE ctrl. + * struct bcm2835_isp_denoise - Denoise parameters. * * @enabled: Enable denoise. * @constant: Fixed offset of the noise threshold. @@ -219,8 +192,7 @@ struct bcm2835_isp_denoise { }; /** - * struct bcm2835_isp_sharpen - Sharpen parameters set with the - * V4L2_CID_USER_BCM2835_ISP_SHARPEN ctrl. + * struct bcm2835_isp_sharpen - Sharpen parameters. * * @enabled: Enable sharpening. * @threshold: Threshold at which to start sharpening pixels. @@ -248,8 +220,7 @@ enum bcm2835_isp_dpc_mode { }; /** - * struct bcm2835_isp_dpc - Defective pixel correction (DPC) parameters set - * with the V4L2_CID_USER_BCM2835_ISP_DPC ctrl. + * struct bcm2835_isp_dpc - Defective pixel correction (DPC) parameters. * * @enabled: Enable DPC. * @strength: DPC strength (see enum &bcm2835_isp_dpc_mode). diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h index c0d9cab3c..aff5280b6 100644 --- a/include/linux/v4l2-controls.h +++ b/include/linux/v4l2-controls.h @@ -178,9 +178,6 @@ enum v4l2_colorfx { */ #define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0) -/* The base for the bcm2835-isp driver controls. - * We reserve 16 controls for this driver. */ -#define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10e0) /* * The base for Allegro driver controls. * We reserve 16 controls for this driver. diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 60133dcf9..e14c78ed5 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -844,7 +844,7 @@ struct v4l2_pix_format { #define V4L2_META_FMT_UVC_MSXU_1_5 v4l2_fourcc('U', 'V', 'C', 'M') /* UVC MSXU metadata */ #define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D') /* Vivid Metadata */ #define V4L2_META_FMT_SENSOR_DATA v4l2_fourcc('S', 'E', 'N', 'S') /* Sensor Ancillary metadata */ -#define V4L2_META_FMT_BCM2835_ISP_STATS v4l2_fourcc('B', 'S', 'T', 'A') /* BCM2835 ISP image statistics output */ +#define V4L2_META_FMT_BCM2835_ISP_STATS v4l2_fourcc('B', 'S', 'T', 'A') /* BCM2835 ISP stats */ #define V4L2_META_FMT_BCM2835_ISP_PARAMS v4l2_fourcc('B', 'C', 'M', 'P') /* BCM2835 ISP params */ /* Vendor specific - used for RK_ISP1 camera sub-system */