From patchwork Fri Jul 3 12:25:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 27166 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 C884BC328C for ; Fri, 3 Jul 2026 12:26:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 83E2965FD9; Fri, 3 Jul 2026 14:26:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GirQS2Hz"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4440C65FCA for ; Fri, 3 Jul 2026 14:26:25 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2404:7a81:160:2100:a2cc:2f45:3bd7:2589]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 636208E0; Fri, 3 Jul 2026 14:25:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1783081539; bh=0ERL9+WoD24amxrnY2dQ9id8zeeBTQq6BFut/3mpeKA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GirQS2HzD7jv2uBdsioD4VXb7Tgb+9A25oEi07ZJM2oAVS0fVC3ytH9/mBJZtjBtR yiWiA4kY4NoDnLSxCbu8ZdPbttTG+6d+VNFhV0hiG/Vo9M7ZLrNKfoHyA9YAdgCYSR ACtpj3IkpwAtHLHwWuHq9uA/m34NZbTAh9JV35OQ= From: Paul Elder To: laurent.pinchart@ideasonboard.com Cc: Paul Elder , michael.riesch@collabora.com, xuhf@rock-chips.com, stefan.klug@ideasonboard.com, kieran.bingham@ideasonboard.com, dan.scally@ideasonboard.com, jacopo.mondi@ideasonboard.com, nicolas.dufresne@collabora.com, libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 07/19] pipeline: rkisp2: Support shared media graph Date: Fri, 3 Jul 2026 21:25:13 +0900 Message-ID: <20260703122543.1991189-8-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20260703122543.1991189-1-paul.elder@ideasonboard.com> References: <20260703122543.1991189-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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" Make the rkisp2 pipeline handler use the shared media graph instead of separate graphs. This makes the rkisp2 pipeline handler incompatible with kernels that do not have shared media graph. Shared media graph puts the VICAP and the ISP in the same media graph, so that it can be switched between inline mode and memory-to-memory mode. The rkisp2 pipeline handler currently does not support inline mode however, so it will only function in memory-to-memory-mode. Signed-off-by: Paul Elder --- I put this in a separate patch so that it's easily revertible. Shared media graph patches for the kernel are here: https://lore.kernel.org/all/20260619052637.1110672-5-paul.elder@ideasonboard.com/ --- src/libcamera/pipeline/rkisp2/rkisp2.cpp | 67 ++++++++++++++++-------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/src/libcamera/pipeline/rkisp2/rkisp2.cpp b/src/libcamera/pipeline/rkisp2/rkisp2.cpp index 0d335a980e32..a89672075f40 100644 --- a/src/libcamera/pipeline/rkisp2/rkisp2.cpp +++ b/src/libcamera/pipeline/rkisp2/rkisp2.cpp @@ -255,7 +255,6 @@ private: std::unique_ptr cif_; std::unique_ptr video_; - std::shared_ptr ispMedia_; std::unique_ptr rawrd_; std::unique_ptr isp_; std::unique_ptr mainPath_; @@ -717,6 +716,36 @@ int PipelineHandlerRkISP2::configure(Camera *camera, const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); data->isRaw_ = info.colourEncoding == PixelFormatInfo::ColourEncodingRAW; + /* + * No need to check usingIsp_ || isRaw_, since if we're capturing from + * just VICAP we still don't want the link to the ISP, and if we're + * using the ISP then we don't support inline mode yet. + * \todo Support inline mode + */ + LOG(RkISP2, Debug) << "Disabling link from VICAP to ISP"; + MediaLink *link = media_->link(cif_->entity(), 2, isp_->entity(), 4); + ret = link->setEnabled(false); + if (ret < 0) { + LOG(RkISP2, Error) << "Failed to disable link between VICAP and ISP"; + return ret; + } + + LOG(RkISP2, Debug) << "Enabling link from VICAP to capture node"; + link = media_->link("rkcif-mipi2", 1, "rkcif-mipi2-id0", 0); + ret = link->setEnabled(true); + if (ret < 0) { + LOG(RkISP2, Error) << "Failed to enable link between VICAP and capture node"; + return ret; + } + + LOG(RkISP2, Debug) << "Enabling link from rawrd to ISP"; + link = media_->link("rkisp2_rawrd0", 0, "rkisp2_isp", 0); + ret = link->setEnabled(true); + if (ret < 0) { + LOG(RkISP2, Error) << "Failed to enable link between rawrd and ISP"; + return ret; + } + V4L2SubdeviceFormat format = config->sensorFormat(); LOG(RkISP2, Debug) << "Configuring sensor with " << format; @@ -1124,6 +1153,10 @@ bool PipelineHandlerRkISP2::createCamera(bool usingIsp) bool PipelineHandlerRkISP2::match(DeviceEnumerator *enumerator) { + /* + * \todo This needs to be reconciled with how shared media graphs are + * named + */ DeviceMatch dm("rockchip-cif"); /* \todo Generalize this for the other csi ports */ /* @@ -1136,6 +1169,12 @@ bool PipelineHandlerRkISP2::match(DeviceEnumerator *enumerator) dm.add("rkcif-mipi2-id0"); dm.add("dw-mipi-csi2rx fdd30000.csi"); + dm.add("rkisp2_isp"); + /* \todo Generalize this for the other channels */ + dm.add("rkisp2_rawrd0"); + /* \todo Support self path */ + dm.add("rkisp2_mainpath"); + media_ = acquireMediaDevice(enumerator, dm); if (!media_) return false; @@ -1179,49 +1218,35 @@ bool PipelineHandlerRkISP2::match(DeviceEnumerator *enumerator) return createCamera(usingIsp); } - /* Match ISP */ - - DeviceMatch dmIsp("rkisp2"); - dmIsp.add("rkisp2_isp"); - /* \todo Generalize this for the other channels */ - dmIsp.add("rkisp2_rawrd0"); - /* \todo Support self path */ - dmIsp.add("rkisp2_mainpath"); - - ispMedia_ = acquireMediaDevice(enumerator, dmIsp); - if (!ispMedia_) { - usingIsp = false; - LOG(RkISP2, Debug) << "ISP not found"; - return createCamera(usingIsp); - } + /* Acquire ISP */ /* \todo Support the other rawrd nodes */ - rawrd_ = V4L2VideoDevice::fromEntityName(ispMedia_.get(), "rkisp2_rawrd0"); + rawrd_ = V4L2VideoDevice::fromEntityName(media_.get(), "rkisp2_rawrd0"); if (!rawrd_ || rawrd_->open() < 0) { LOG(RkISP2, Error) << "Failed to open rkisp2 rawrd device"; return false; } - isp_ = V4L2Subdevice::fromEntityName(ispMedia_.get(), "rkisp2_isp"); + isp_ = V4L2Subdevice::fromEntityName(media_.get(), "rkisp2_isp"); if (!isp_ || isp_->open() < 0) { LOG(RkISP2, Error) << "Failed to open rkisp2 isp"; return false; } /* \todo Support self path */ - mainPath_ = V4L2VideoDevice::fromEntityName(ispMedia_.get(), "rkisp2_mainpath"); + mainPath_ = V4L2VideoDevice::fromEntityName(media_.get(), "rkisp2_mainpath"); if (!mainPath_ || mainPath_->open() < 0) { LOG(RkISP2, Error) << "Failed to open rkisp2 main path"; return false; } - param_ = V4L2VideoDevice::fromEntityName(ispMedia_.get(), "rkisp2_params"); + param_ = V4L2VideoDevice::fromEntityName(media_.get(), "rkisp2_params"); if (!param_ || param_->open() < 0) { LOG(RkISP2, Error) << "Failed to open rkisp2 params"; return false; } - stat_ = V4L2VideoDevice::fromEntityName(ispMedia_.get(), "rkisp2_stats"); + stat_ = V4L2VideoDevice::fromEntityName(media_.get(), "rkisp2_stats"); if (!stat_ || stat_->open() < 0) { LOG(RkISP2, Error) << "Failed to open rkisp2 stats"; return false;