From patchwork Thu Jan 10 11:40:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1022853 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ARouPPk3"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="d+FGocRv"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43b3wb68r9z9sLt for ; Thu, 10 Jan 2019 22:41:03 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=Ttt0vX54L3D+FEPsIxR+ErLnYxwiFpKQnl5biylkCpA=; b=ARouPPk3hj35Y0 P17yOWmq24WfuwgoBgAXYJ2mYnxU3m7B187lRRcNDKbIp9G9JaKmeqkWzjlxOsK0iskIdM7cvjzw+ lvHNToyTyTDY4oR+VAroDN2YNxBczdtzSZGwy0zoPx9QVtqjFokQ7p2uPnnPQuGiThON31VJV5rYY O8F9f+DSwAwL5fV5WbotHBHp6V2tBJBsr/oXxx2sDGmq9Rd0Jn1Jhas/IG8VdX5DTrjThBXIdBpfK iHPmFBafzzGZp/2LEWmmUvV5w4y6+BJg5j7hSkCnUy7OIZCQeCwhVyksAI8X/xu3wh7rnCExjjhu2 n3Gi9CT92liCHwaTzOYQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghYhn-0004cI-P0; Thu, 10 Jan 2019 11:40:59 +0000 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ghYhj-0004bs-U4 for linux-arm-kernel@lists.infradead.org; Thu, 10 Jan 2019 11:40:57 +0000 Received: by mail-lf1-x141.google.com with SMTP id c16so8055308lfj.8 for ; Thu, 10 Jan 2019 03:40:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=IlDK8bGb/kRNe1UzuHHE+g8wvOU0YDJW7WMbCLP2uh0=; b=d+FGocRvhsD+gmzQW8HEJEv1gnpLdpOeJZQW4JLualBkev6vkye2YieO0ftmo4S1LZ 3NaeHEdVLiJ1F64qJQck7pL3MLX+mGPONC/cenzjYeQ4CMWPFL3ttvi0AwA2zPNpKhqn mgkPMjQvNAOD/rbvU4fNNritrslBMOTMzyWEM= 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:mime-version :content-transfer-encoding; bh=IlDK8bGb/kRNe1UzuHHE+g8wvOU0YDJW7WMbCLP2uh0=; b=NtP2d75ffbgTMQT2ey6Wk+yndlamLp/WxI8995cdQ+uhStNNZQnu3jHB3tErX/g7rJ Zn5UVI9JIbuEWEEKvDJ4NOQZ9NpEcR0aODPz3bJ61yMLv9Zft6rEWS4RGBmwY8gy+8Gc E3nvB3Q4mxasPmwFGqtk1iq/nLXLrnTl3zMS9g5u5rCdbW70OoJ5QxizE0lYzpdVlqZy 3tmx0ZfPuOj4e2BnIVdY440Yz/U+hG3pEikMps3LiU0b4LHTpPLTWfphTDZ/zdvlcDOf 6f6cp9oGfWn1EoshENTjaqbWCHFs4fg4j50F/ohViGG2bkoBTMAQiPo3HSaW8ptFxMMB iIWw== X-Gm-Message-State: AJcUukdV073NZHdHjgQuohTsiyw4zw7s+5hdGcpqFL8XodT1ZszkYVtx WWuAMuX8ObKpVv3Yv05+zG0MaQ== X-Google-Smtp-Source: ALg8bN58DACMjpRLx0nlXmAzkCQGoq7jXWdIzihg1A6aHe/BaExdkcz8HtWDy7/yZltzh50HnH3i3w== X-Received: by 2002:a19:5a05:: with SMTP id o5mr5974222lfb.140.1547120453263; Thu, 10 Jan 2019 03:40:53 -0800 (PST) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id k20sm7573177lfe.3.2019.01.10.03.40.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 10 Jan 2019 03:40:52 -0800 (PST) From: Linus Walleij To: Bartlomiej Zolnierkiewicz , Eric Anholt , =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Dave Airlie , David Lechner Subject: [PATCH v4] drm/fb-helper: Scale back depth to supported maximum Date: Thu, 10 Jan 2019 12:40:49 +0100 Message-Id: <20190110114049.10618-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190110_034055_973453_EC9DA244 X-CRM114-Status: GOOD ( 21.60 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2a00:1450:4864:20:0:0:0:141 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , linux-fbdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, dri-devel@lists.freedesktop.org, Linus Walleij Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org The following happened when migrating an old fbdev driver to DRM: The Integrator/CP PL111 supports 16BPP but only ARGB1555/ABGR1555 or XRGB1555/XBGR1555 i.e. the maximum depth is 15. This makes the initialization of the framebuffer fail since the code in drm_fb_helper_single_fb_probe() assigns the same value to sizes.surface_bpp and sizes.surface_depth. I.e. it simply assumes a 1-to-1 mapping between BPP and depth, which is true in most cases but not for this hardware that only support odd formats. To support the odd case of a driver supporting 16BPP with only 15 bits of depth, this patch will make the code loop over the formats supported on the primary plane on each CRTC managed by the FB helper and cap the depth to the maximum supported on any primary plane. On the PL110 Integrator, this makes drm_mode_legacy_fb_format() select DRM_FORMAT_XRGB1555 which is acceptable for this driver, and thus we get framebuffer, penguin and console on the Integrator/CP. Cc: Noralf Trønnes Cc: Ville Syrjälä Reviewed-by: Daniel Vetter Signed-off-by: Linus Walleij --- ChangeLog v3->v4: - Assign best_depth also when we have a perfect fit, duh. ChangeLog v2->v3: - Rebased and tested with v5.0-rc1 - Skip any formats with fmt->depth == 0 - Collected Daniels review tag. ChangeLog v1->v2: - Loop over the CRTCs managed by the helper and check the crtc->primary on each CRTC for the applicable formats and thus depths. - Skip over YUV formats. The framebuffer emulation cannot handle these formats. The v1 was sent some while back in february and I only recently got back to fixing this up to support the last CLCD displays. It was agreed that it is probably best to augment the framebuffer initializer to pass a desired pixel format instead of just BPP as today, but that is a bit daunting, and Daniel said that we would probably anyways need a fallback like this. --- drivers/gpu/drm/drm_fb_helper.c | 55 ++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d3af098b0922..f7f31ad5d3ee 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1797,6 +1797,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, int i; struct drm_fb_helper_surface_size sizes; int gamma_size = 0; + int best_depth = 0; memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); sizes.surface_depth = 24; @@ -1804,7 +1805,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, sizes.fb_width = (u32)-1; sizes.fb_height = (u32)-1; - /* if driver picks 8 or 16 by default use that for both depth/bpp */ + /* + * If driver picks 8 or 16 by default use that for both depth/bpp + * to begin with + */ if (preferred_bpp != sizes.surface_bpp) sizes.surface_depth = sizes.surface_bpp = preferred_bpp; @@ -1839,6 +1843,55 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, } } + /* + * If we run into a situation where, for example, the primary plane + * supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth + * 16) we need to scale down the depth of the sizes we request. + */ + for (i = 0; i < fb_helper->crtc_count; i++) { + struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; + struct drm_crtc *crtc = mode_set->crtc; + struct drm_plane *plane = crtc->primary; + int j; + + DRM_DEBUG("test CRTC %d primary plane\n", i); + + for (j = 0; j < plane->format_count; j++) { + const struct drm_format_info *fmt; + + fmt = drm_format_info(plane->format_types[j]); + + /* + * Do not consider YUV or other complicated formats + * for framebuffers. This means only legacy formats + * are supported (fmt->depth is a legacy field) but + * the framebuffer emulation can only deal with such + * formats, specifically RGB/BGA formats. + */ + if (fmt->depth == 0) + continue; + + /* We found a perfect fit, great */ + if (fmt->depth == sizes.surface_depth) { + best_depth = fmt->depth; + break; + } + + /* Skip depths above what we're looking for */ + if (fmt->depth > sizes.surface_depth) + continue; + + /* Best depth found so far */ + if (fmt->depth > best_depth) + best_depth = fmt->depth; + } + } + if (sizes.surface_depth != best_depth) { + DRM_INFO("requested bpp %d, scaled depth down to %d", + sizes.surface_bpp, best_depth); + sizes.surface_depth = best_depth; + } + crtc_count = 0; for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_display_mode *desired_mode;