From patchwork Wed Sep 28 10:27:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17448 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 B551BC0DA4 for ; Wed, 28 Sep 2022 10:27:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 18A5E622A4; Wed, 28 Sep 2022 12:27:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1664360866; bh=/KKPHWQTmRn+vXPyGwsYxhmOoZSlzoaLMmktl67GJ7U=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=LX6bnvGNIrhi3oKfluwb/HCIynEfUwsu9fnqRiS753k/b7U6E1FAfqVCr78XcmEZr CUC/pUF0HeEju83+UMRG7SDq2MnQJBstpDUHxiaJkwA541QtnwE+urohjMrg5NO/Bq NCeQxtSKSjsswvHZ1Vt4mgr7C9zXBSN5c62iljfrRNR9CGXnq6jm4mHi2EHhc3ZVFf 8W1ZcH/IM6zdNCAeKJslBYgxNT3y1cPY6LNPrWVbjPN7R98axsH8A53LKKTqYGgJvT DNbc6lhBj0Kt6qlsQ/BsyvAkzlTOc4pH5sOlkarWgfdOU/nUUWpVmeoq+uDAaG8mKW TWsdaoPE5YZNg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B6CD06224C for ; Wed, 28 Sep 2022 12:27:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nx/Samrt"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1C11B47C; Wed, 28 Sep 2022 12:27:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1664360864; bh=/KKPHWQTmRn+vXPyGwsYxhmOoZSlzoaLMmktl67GJ7U=; h=From:To:Cc:Subject:Date:From; b=nx/SamrtBgjBciovyOacDCig4PP3xZ/aYgTkk6skH6lgxSxoIEo3CCWsJ4MzvE53G gvyNdIQp6/K4hxrjwcKIUt3c1Cj++4sXuofLBFDlxEjaiMyd+g4XwAhMbpYfZzZUNO KQO08S/fdxarst709o+TrJ6hKIQouD79MgkNuUWY= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Sep 2022 13:27:43 +0300 Message-Id: <20220928102743.1484-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] cam: drm: Skip DRM devices not capable of mode setting 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: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The DRM helper picks the first DRM card that it can open. On platforms that have a standalone GPU, this risks selecting a device corresponding to the GPU instead of the display controller. Fix this by skipping devices that don't support the KMS mode setting API. Some legacy display controllers would be skipped as well, but libcamera doesn't run on those systems anyway. Signed-off-by: Laurent Pinchart Reviewed-by: Eric Curtin Reviewed-by: Jacopo Mondi --- Changes since v1: - Use DRM_CAP_DUMB_BUFFER instead of DRM_CLIENT_CAP_ATOMIC --- src/cam/drm.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/cam/drm.cpp b/src/cam/drm.cpp index b0602c942853..3bb950fd157a 100644 --- a/src/cam/drm.cpp +++ b/src/cam/drm.cpp @@ -430,7 +430,8 @@ int Device::init() int Device::openCard() { const std::string dirName = "/dev/dri/"; - int ret = -ENOENT; + bool found = false; + int ret; /* * Open the first DRM/KMS device beginning with /dev/dri/card. The @@ -449,24 +450,42 @@ int Device::openCard() } for (struct dirent *res; (res = readdir(folder));) { + uint64_t cap; + if (strncmp(res->d_name, "card", 4)) continue; const std::string devName = dirName + res->d_name; fd_ = open(devName.c_str(), O_RDWR | O_CLOEXEC); - if (fd_ >= 0) { - ret = 0; - break; + if (fd_ < 0) { + ret = -errno; + std::cerr << "Failed to open DRM/KMS device " << devName << ": " + << strerror(-ret) << std::endl; + continue; } - ret = -errno; - std::cerr << "Failed to open DRM/KMS device " << devName << ": " - << strerror(-ret) << std::endl; + /* + * Skip devices that don't support the modeset API, to avoid + * selecting a DRM device corresponding to a GPU. There is no + * modeset capability, but the kernel returns an error for most + * caps if mode setting isn't support but the driver. The + * DRM_CAP_DUMB_BUFFER capability is one of those, other would + * do as well. The capability value itself isn't relevant. + */ + ret = drmGetCap(fd_, DRM_CAP_DUMB_BUFFER, &cap); + if (ret < 0) { + drmClose(fd_); + fd_ = -1; + continue; + } + + found = true; + break; } closedir(folder); - return ret; + return found ? 0 : -ENOENT; } int Device::getResources()