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.