From patchwork Mon Jul 12 10:02:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 12907 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 8710BC3228 for ; Mon, 12 Jul 2021 10:02:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 10BAA68541; Mon, 12 Jul 2021 12:02:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="VGEbvU7E"; dkim-atps=neutral Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BF2A268513 for ; Mon, 12 Jul 2021 12:02:20 +0200 (CEST) Received: by mail-wm1-x32e.google.com with SMTP id g8-20020a1c9d080000b02901f13dd1672aso9486432wme.0 for ; Mon, 12 Jul 2021 03:02:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9yRgYhw3UKh19+/uNBMvathD7mePEk0qnePq4Nd1t/0=; b=VGEbvU7E5boc9nZ/cLbhVItqXts35gUcPxHpnWGbOSuLMjStnynl51TFuzbtzjeMDm 7DZ/bvMpL6d0i3Fw7L4pBwa2b1kQwzpKJrgb1OIbex+e1P+7T3IszPy2KFlkRyk1arrr Qe2lHM/9TGZ7TfNbNeBC272yFf00hGBPl4o6jBFxSZ62TX8mWL/E1v6umnU/ldIa//Js 2u2Nn+orSG3ts83WhP/Lqv1c4hVjaJIvHKx9d9J3pXo3u+1qsKHGxNkJ+rLhQWYpCElR aiHwEXP3gXUGSQcp6lNaZhAKbSvndr01H8JnpfqN3EKNKIJg+RTFrFxHVT3apdUJwdOm hJXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9yRgYhw3UKh19+/uNBMvathD7mePEk0qnePq4Nd1t/0=; b=RShdYGZsGRIg99eh8U2/eObvHI69rV+rVk4S9QoCteWswnQGxXDnUzsXFVVTeTO9Fp OzYLaVpuZfd+fm+814mGnbunNwr2WovJfHcFC45Z3o0OF33/hj+XEk+2zTneWgb7ZizB OBZe4xX2HnCjZ8vPleM+kUZ/EAPR60dfqL00r6+v97B0AkgGrl7nUBuqePZTRnBNs1PS NwLktKhaggrOiVEkW94bfe91mH/1t0Eeul9LVJS4e60nAsOLL0YUME/R7E1Qe6Yu5X6C Q0Cr13UkWcfP7PyAhPds33dfYvFynHVI3gN9bLS45AqNZ7Mbx67V/2lMN/q0aWlHwqp1 sgsw== X-Gm-Message-State: AOAM530ZDkgwAS1ogDLLnEwXH9j5cRTfHMiSCWjd+3CZgcE/BqcLXCRZ ZKsRsjLi9WkGq/BXooV3ZjhLvlPHoD+gZQ== X-Google-Smtp-Source: ABdhPJwUXfOdEIXNuOQFrlK2b+wEoajCXCBWmTqnYA+8J0yg4qMSiEQZTgVW8k9cI2/vnuRe60RNMw== X-Received: by 2002:a7b:c92b:: with SMTP id h11mr11130194wml.182.1626084140109; Mon, 12 Jul 2021 03:02:20 -0700 (PDT) Received: from naush-laptop.pitowers.org ([2a00:1098:3142:14:3395:5e50:10bb:f8fd]) by smtp.gmail.com with ESMTPSA id b16sm14249941wrs.51.2021.07.12.03.02.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jul 2021 03:02:19 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Mon, 12 Jul 2021 11:02:07 +0100 Message-Id: <20210712100209.447893-7-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210712100209.447893-1-naush@raspberrypi.com> References: <20210712100209.447893-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 6/8] pipeline: raspberrypi: Use priority write for vblank when writing sensor ctrls 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" When directly writing controls to the sensor device, ensure that VBLANK is written ahead of and before the EXPOSURE control. This is the same priority write mechanism used in DelayedControls. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- .../pipeline/raspberrypi/raspberrypi.cpp | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 082eb1ee1c23..c09352809c01 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -154,6 +154,7 @@ public: void embeddedComplete(uint32_t bufferId); void setIspControls(const ControlList &controls); void setDelayedControls(const ControlList &controls); + void setSensorControls(ControlList &controls); /* bufferComplete signal handlers. */ void unicamBufferDequeue(FrameBuffer *buffer); @@ -828,7 +829,7 @@ int PipelineHandlerRPi::start(Camera *camera, const ControlList *controls) /* Apply any gain/exposure settings that the IPA may have passed back. */ if (!startConfig.controls.empty()) - data->unicam_[Unicam::Image].dev()->setControls(&startConfig.controls); + data->setSensorControls(startConfig.controls); /* Configure the number of dropped frames required on startup. */ data->dropFrameCount_ = startConfig.dropFrameCount; @@ -1075,7 +1076,7 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) ControlList ctrls(dev->controls()); ctrls.set(V4L2_CID_HFLIP, 0); ctrls.set(V4L2_CID_VFLIP, 0); - dev->setControls(&ctrls); + data->setSensorControls(ctrls); } /* Look for a valid Bayer format. */ @@ -1294,22 +1295,20 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config) return -EPIPE; } - if (!controls.empty()) - unicam_[Unicam::Image].dev()->setControls(&controls); - /* * Configure the H/V flip controls based on the combination of * the sensor and user transform. */ if (supportsFlips_) { - ControlList ctrls(unicam_[Unicam::Image].dev()->controls()); - ctrls.set(V4L2_CID_HFLIP, - static_cast(!!(rpiConfig->combinedTransform_ & Transform::HFlip))); - ctrls.set(V4L2_CID_VFLIP, - static_cast(!!(rpiConfig->combinedTransform_ & Transform::VFlip))); - unicam_[Unicam::Image].dev()->setControls(&ctrls); + controls.set(V4L2_CID_HFLIP, + static_cast(!!(rpiConfig->combinedTransform_ & Transform::HFlip))); + controls.set(V4L2_CID_VFLIP, + static_cast(!!(rpiConfig->combinedTransform_ & Transform::VFlip))); } + if (!controls.empty()) + setSensorControls(controls); + return 0; } @@ -1379,6 +1378,28 @@ void RPiCameraData::setDelayedControls(const ControlList &controls) handleState(); } +void RPiCameraData::setSensorControls(ControlList &controls) +{ + /* + * We need to ensure that if both VBLANK and EXPOSURE are present, the + * former must be written ahead of, and separately from EXPOSURE to avoid + * V4L2 rejecting the latter. This is identical to what DelayedControls + * does with the priority write flag. + * + * As a consequence of the below logic, VBLANK gets set twice, and we + * rely on the v4l2 framework to not pass the second control set to the + * driver as the actual control value has not changed. + */ + if (controls.contains(V4L2_CID_EXPOSURE) && controls.contains(V4L2_CID_VBLANK)) { + ControlList vblank_ctrl; + + vblank_ctrl.set(V4L2_CID_VBLANK, controls.get(V4L2_CID_VBLANK)); + unicam_[Unicam::Image].dev()->setControls(&vblank_ctrl); + } + + unicam_[Unicam::Image].dev()->setControls(&controls); +} + void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer) { RPi::Stream *stream = nullptr;