From patchwork Tue Jun 28 08:20:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 16398 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 41F2FBE173 for ; Tue, 28 Jun 2022 08:21:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9301B6559A; Tue, 28 Jun 2022 10:21:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656404468; bh=Rg53Xmbch1mHcJzr3EH+j2WO/BMNysz172fzVwgGhdc=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=0wkBeA9rEQ21pyuUCswipqcCMWH34X9rRIJnkBY4/Fm9iPesJRbvGZli/cTURWMkd bXdn5FW2cu98g4jnF9BTgMFC6geP/vzyOD9tl8XTQkc2V7eyoct5d5h/FLdy8/X36t 3ClfP29CutPKPKBijx/AeVbKpppe6FPPZOyISGyzqzbhc52iaf/BQKbWoAZFtXkrZQ /N76iOXa+AB8+RgYzGeUf+OQWQ2pfh1ZNjrbPBEKGrBL67b2LhBKtbsEfVgr7bA/kK MeuV+7Y4r6KvrJu43sW4mLw5tlZyCQnCa5ZVuBadd8Ca1UrTny+sSdY4tU18otQFOR wRM8xqwRqVDwQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E5F56559A for ; Tue, 28 Jun 2022 10:21:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="L2FVxIU0"; dkim-atps=neutral Received: from pyrite.rasen.tech (softbank036240122163.bbtec.net [36.240.122.163]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C303F55A; Tue, 28 Jun 2022 10:21:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656404466; bh=Rg53Xmbch1mHcJzr3EH+j2WO/BMNysz172fzVwgGhdc=; h=From:To:Cc:Subject:Date:From; b=L2FVxIU0Y2wRVPzLzi9NLoyeXi/amPBfP3+dAIrRaIk5ZBdOMb6BWSDXv8/niru2j E4KrWp35c0iogJaZoAnKD/Em23vn9wjdeuBwnbrxcw5ka47DpMEqPXU4nvk6EqTxhl hZOtptXxtfeNUYpvoO7LHsmU2hV8s0HA6DhnW8Vk= To: libcamera-devel@lists.libcamera.org Date: Tue, 28 Jun 2022 17:20:50 +0900 Message-Id: <20220628082050.1934904-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] pipeline: rkisp1: Support devices without self path 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: , X-Patchwork-Original-From: Paul Elder via libcamera-devel From: Paul Elder Reply-To: Paul Elder Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Some hardware supported by the rkisp1 driver, such as the ISP in the i.MX8MP, don't have a self path. Although at the moment the driver still exposes the self path, prepare the rkisp1 pipeline handler for when the self path will be removed for devices that don't support it. Signed-off-by: Paul Elder --- Changes in v2: - simplify matching - clean up self path availability in validate() - fix configure(), return -ENODEV if multiple roles but no self path --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 40 ++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 7cf36524..378b4977 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -179,6 +179,8 @@ private: std::unique_ptr param_; std::unique_ptr stat_; + bool hasSelfPath_; + RkISP1MainPath mainPath_; RkISP1SelfPath selfPath_; @@ -343,7 +345,7 @@ void RkISP1CameraData::paramFilled(unsigned int frame) if (info->mainPathBuffer) mainPath_->queueBuffer(info->mainPathBuffer); - if (info->selfPathBuffer) + if (info->selfPathBuffer && selfPath_) selfPath_->queueBuffer(info->selfPathBuffer); } @@ -382,7 +384,7 @@ bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) return false; config = cfg; - if (data_->selfPath_->validate(&config) != Valid) + if (data_->selfPath_ && data_->selfPath_->validate(&config) != Valid) return false; return true; @@ -392,6 +394,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() { const CameraSensor *sensor = data_->sensor_.get(); Status status = Valid; + unsigned int pathCount = data_->selfPath_ ? 2 : 1; if (config_.empty()) return Invalid; @@ -402,8 +405,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } /* Cap the number of entries to the available streams. */ - if (config_.size() > 2) { - config_.resize(2); + if (config_.size() > pathCount) { + config_.resize(pathCount); status = Adjusted; } @@ -420,7 +423,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() std::reverse(order.begin(), order.end()); bool mainPathAvailable = true; - bool selfPathAvailable = true; + bool selfPathAvailable = (pathCount == 2); for (unsigned int index : order) { StreamConfiguration &cfg = config_[index]; @@ -499,7 +502,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager), hasSelfPath_(true) { } @@ -516,7 +519,7 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera return config; bool mainPathAvailable = true; - bool selfPathAvailable = true; + bool selfPathAvailable = data->selfPath_; for (const StreamRole role : roles) { bool useMainPath; @@ -619,10 +622,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) ret = mainPath_.configure(cfg, format); streamConfig[0] = IPAStream(cfg.pixelFormat, cfg.size); - } else { + } else if (hasSelfPath_) { ret = selfPath_.configure(cfg, format); streamConfig[1] = IPAStream(cfg.pixelFormat, cfg.size); + } else { + return -ENODEV; } if (ret) @@ -670,7 +675,7 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S if (stream == &data->mainPathStream_) return mainPath_.exportBuffers(count, buffers); - else if (stream == &data->selfPathStream_) + else if (hasSelfPath_ && stream == &data->selfPathStream_) return selfPath_.exportBuffers(count, buffers); return -EINVAL; @@ -799,7 +804,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL } } - if (data->selfPath_->isEnabled()) { + if (hasSelfPath_ && data->selfPath_->isEnabled()) { ret = selfPath_.start(); if (ret) { mainPath_.stop(); @@ -826,7 +831,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera) data->ipa_->stop(); - selfPath_.stop(); + if (hasSelfPath_) + selfPath_.stop(); mainPath_.stop(); ret = stat_->streamOff(); @@ -917,7 +923,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) int ret; std::unique_ptr data = - std::make_unique(this, &mainPath_, &selfPath_); + std::make_unique(this, &mainPath_, + hasSelfPath_ ? &selfPath_ : nullptr); ControlInfoMap::Map ctrls; ctrls.emplace(std::piecewise_construct, @@ -973,9 +980,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) DeviceMatch dm("rkisp1"); dm.add("rkisp1_isp"); - dm.add("rkisp1_resizer_selfpath"); dm.add("rkisp1_resizer_mainpath"); - dm.add("rkisp1_selfpath"); dm.add("rkisp1_mainpath"); dm.add("rkisp1_stats"); dm.add("rkisp1_params"); @@ -990,6 +995,8 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) return false; } + hasSelfPath_ = !!media_->getEntityByName("rkisp1_selfpath"); + /* Create the V4L2 subdevices we will need. */ isp_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_isp"); if (isp_->open() < 0) @@ -1008,11 +1015,12 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (!mainPath_.init(media_)) return false; - if (!selfPath_.init(media_)) + if (hasSelfPath_ && !selfPath_.init(media_)) return false; mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); - selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); + if (hasSelfPath_) + selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);