From patchwork Tue Jul 19 07:30:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 16677 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 E37C6BD1F1 for ; Tue, 19 Jul 2022 07:30:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B5CC63312; Tue, 19 Jul 2022 09:30:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658215829; bh=kxqd7uMyTOpgyxizOllZ/wV7/nsZacjfQCLCny3l7r0=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Mgjv9hP9vmrha4i5XV//gioSUZMqr/pFGdhPlf23TGbeI5eNEI5n5zfNgzVW68Ln0 Cd0Xe/RCpnGL4Wg8/RroiYzeD1ZBkx9WoaqTCMXjF+t+A9xeCfthJWOPoJBZVyqrQ4 A1BSqMIiv487+5+5qugPkKEDwecO1LdALVfI2yedZMDS5mCaSGjDKLaxRFNwOhRaW7 cOV61KB2gWgz+CZesBW/U8UjYdkAyHZhBFKXnVt/YI9vo4dHB6j98+B+8uHbwdM0E7 s6Kw/XgZou/UympIWJAnGVokdodwy8Vs7atIK2ogIgirkuPvdKMEjw5YkSslGO7OAI /6PLxx6svlEMg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E4E286330D for ; Tue, 19 Jul 2022 09:30:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="S/KWv/yo"; dkim-atps=neutral Received: from pyrite.rasen.tech (softbank036240121080.bbtec.net [36.240.121.80]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5A6FB6EE; Tue, 19 Jul 2022 09:30:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1658215826; bh=kxqd7uMyTOpgyxizOllZ/wV7/nsZacjfQCLCny3l7r0=; h=From:To:Cc:Subject:Date:From; b=S/KWv/yoF67jrGN7+JQ+rqh38uaGMIwCR8eBw1jyPBw2CeqE6bVIRdMf9/TuGD9Sn 3k4tSeVNg6yMIO4w3o2aEETpr86mHyJl61YbSzmNtymzgQi3VNDK3LiEJ5e23eCsXq dEvbv3Hc/HznqzTI09J1hm+aWKmJhUtdGi2/NDAw= To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jul 2022 16:30:12 +0900 Message-Id: <20220719073012.810184-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3] 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 Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- Changes in v3: - add more guards - add pathCount guard to generateConfiguration to allow making self path unavailable Just Work 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 | 49 ++++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 212fc76a..99eecd44 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -180,6 +180,8 @@ private: std::unique_ptr stat_; std::unique_ptr csi_; + bool hasSelfPath_; + RkISP1MainPath mainPath_; RkISP1SelfPath selfPath_; @@ -364,7 +366,7 @@ void RkISP1CameraData::paramFilled(unsigned int frame) if (info->mainPathBuffer) mainPath_->queueBuffer(info->mainPathBuffer); - if (info->selfPathBuffer) + if (selfPath_ && info->selfPathBuffer) selfPath_->queueBuffer(info->selfPathBuffer); } @@ -403,7 +405,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; @@ -412,6 +414,7 @@ bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) CameraConfiguration::Status RkISP1CameraConfiguration::validate() { const CameraSensor *sensor = data_->sensor_.get(); + unsigned int pathCount = data_->selfPath_ ? 2 : 1; Status status = Valid; if (config_.empty()) @@ -423,8 +426,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; } @@ -441,7 +444,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() std::reverse(order.begin(), order.end()); bool mainPathAvailable = true; - bool selfPathAvailable = true; + bool selfPathAvailable = data_->selfPath_; for (unsigned int index : order) { StreamConfiguration &cfg = config_[index]; @@ -520,7 +523,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager), hasSelfPath_(true) { } @@ -532,12 +535,19 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera const StreamRoles &roles) { RkISP1CameraData *data = cameraData(camera); + + unsigned int pathCount = data->selfPath_ ? 2 : 1; + if (roles.size() > pathCount) { + LOG(RkISP1, Error) << "Too many stream roles requested"; + return nullptr; + } + CameraConfiguration *config = new RkISP1CameraConfiguration(camera, data); if (roles.empty()) return config; bool mainPathAvailable = true; - bool selfPathAvailable = true; + bool selfPathAvailable = data->selfPath_; for (const StreamRole role : roles) { bool useMainPath; @@ -646,10 +656,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) @@ -697,7 +709,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; @@ -826,7 +838,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(); @@ -853,7 +865,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera) data->ipa_->stop(); - selfPath_.stop(); + if (hasSelfPath_) + selfPath_.stop(); mainPath_.stop(); ret = stat_->streamOff(); @@ -934,7 +947,7 @@ int PipelineHandlerRkISP1::initLinks(Camera *camera, for (const StreamConfiguration &cfg : config) { if (cfg.stream() == &data->mainPathStream_) ret = data->mainPath_->setEnabled(true); - else if (cfg.stream() == &data->selfPathStream_) + else if (hasSelfPath_ && cfg.stream() == &data->selfPathStream_) ret = data->selfPath_->setEnabled(true); else return -EINVAL; @@ -951,7 +964,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, @@ -1007,9 +1021,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"); @@ -1024,6 +1036,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) @@ -1058,11 +1072,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);