From patchwork Wed Sep 16 14:39:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 28306 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 10F89BDE6B for ; Wed, 16 Sep 2026 14:40:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A1DA168710; Wed, 16 Sep 2026 16:40:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="T+Em98O0"; 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 CAB28686F0 for ; Wed, 16 Sep 2026 16:40:41 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:85de:a3c9:9357:b164:bf0b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 00C2F558; Wed, 16 Sep 2026 16:38:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789569540; bh=oQu9rdoCN5F6BC5Mp+0ojWN836ZXuqaZWHDffn6Or9A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=T+Em98O0OCUKKKai/uVMasdfTG56/dTIXJ5j/110qUG5PHjAVfZMky4+jKYh0rNbn 7j8MPp6xM9Ehmu3/NEpQ9OO3PJEqCB6lH6J64kkfujjcQYxnntLJRsKgAKnu4V6XBL rL87TDFkIpYbFLpCWLnxpkJJcF81u0rVVnU3f3k8= From: Jai Luthra Date: Wed, 16 Sep 2026 20:09:42 +0530 Subject: [PATCH v3 6/8] pipeline: rpi: vc4: Switch to mainline media topology for bcm2835-isp MIME-Version: 1.0 Message-Id: <20260916-pi4-upstream-v3-6-4666708d8829@ideasonboard.com> References: <20260916-pi4-upstream-v3-0-4666708d8829@ideasonboard.com> In-Reply-To: <20260916-pi4-upstream-v3-0-4666708d8829@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Paul Elder , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6750; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=oQu9rdoCN5F6BC5Mp+0ojWN836ZXuqaZWHDffn6Or9A=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqqqpCBhK/KjpEv1L0iIQ9rfHO8LhCPidm+UESF tGSllyisMaJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCaqqqQgAKCRBD3pH5JJpx RfZmEACcnI/7wilJl8XEy5srWL+lZBbDVugGf0ENlowKt9bP8fXj+LfFgXSFpvFHY1jwYMNkoIL 3Y5KnZmYVh5lpc3QgwU4JPwPJzlPIIiA50g+nGTBmY9bRJVLmSBTUvT1GO/MkH45sb7VnA5IaL4 wJqYdnYreXeAUguMLb733R8J2pv3d9yY+Kv/rDXSpDyhmbiSf4zEs3WzSgMbQPQT3LL+CNBTN3m ieUQ5Kcd5fCoiCjGd41H/Z3x5mDoPbx1vP9X1csABH+I76SvnhGOmH4kEb9DE0zCDPZJsQlMDfa Et++xr1/JEIs7PTdm67DKysO8cSyGLhGqLjsnVgsI2OlYJEi/T64aptGcC02qb3TKFiiQnzGlun ZffOQajUD/cxy9liUxFCNQjXoLyO/m9gj1J6cSOpxIrQql7PjZA370EA3Kx6Tbh9XSe6p/rIEwN 8zH98Pq/AsdkE5aSHxkAvx4FEhNdAghJy8VqwmyXX3IrJw4JkrbWNxr+BeOi2ZFa1H+9/9SamuF GPwL2sHQCZxQEtoDAnXFRiCq3+QtfVK/yDYLsiVERE/X4q+lOnw/k+6BeVkLWKWTsR2ROLTavtT BdNsxQlvAIyqBQj6HAc/HYjXN51Z2M5s0bxa3kTRRVrLQc4UTvgGt/vPuHnFsLoK0jgIJv07MP8 a0C7Xe115MY8pwg== 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. Reviewed-by: Paul Elder Tested-by: Paul Elder 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 300a352a7d39..cc18dcc8fa8d 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 27cd59248451..d242157d58c5 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 *ispStats = 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 || !ispStats || !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", ispStats); + /* 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.