From patchwork Sat May 20 02:57:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilia Mirkin X-Patchwork-Id: 9738449 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D3C7D602DC for ; Sat, 20 May 2017 02:57:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AABC32837E for ; Sat, 20 May 2017 02:57:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8D4A928565; Sat, 20 May 2017 02:57:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D8EB12837E for ; Sat, 20 May 2017 02:57:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7E7196E085; Sat, 20 May 2017 02:57:56 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qk0-x242.google.com (mail-qk0-x242.google.com [IPv6:2607:f8b0:400d:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 64CE46E062; Sat, 20 May 2017 02:57:55 +0000 (UTC) Received: by mail-qk0-x242.google.com with SMTP id y128so12508175qka.3; Fri, 19 May 2017 19:57:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=WG+JL4Rjs4vb+Fj2vHgNGlqk3HiFlZrUuz8b0VrMK2I=; b=KU0MfBYtyDHl/eY7ZH+egmOOprDEbnwdccVwot4liiBUJ2ifW8qUu70yyT6BWB9g5y pmSmDuNaHyI117ZsOLknDvF3PCDKusCMp+Pp3YjLRBgSK1BUlZvB+YDh830CjjYHsTd0 fcF+PYVPL+8yaSPB/8J3bFWwt1q8dNO/vXyTcBDrDgZq8QYe3gUVB2iYxB3ttGYYiX5s xxT3SDENg73/xyOHa2YvBuJ+iFQx9kD68ANo1zPJX2nC3rJpGbTnUnmcT1x2hq2PCPbH x7rq115+t5x7w0azraVzOlSQBhn4ILlxaLPwAZgHavJ/HLt04DrPQl4OZpYvUKfa6/Xh KJ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=WG+JL4Rjs4vb+Fj2vHgNGlqk3HiFlZrUuz8b0VrMK2I=; b=hYpOaU/Ic0NqGyQXmNAhg28x4R0LhXcTF88dJf+H/dKuGhsyuYIO2MuMS94eWfCjXm Q1SfIaBaShuEbOydQGIxz42oce9lzah2Qds7/Y+x7XrMjh+JaZs/bkPfXmKWbVqwVLY3 n2T7yKBspG3q4+qVVjZCw9knzBwXBm+bwcS0tI0RRrC288n+A0KjypQMvYx8Bg0oqG7i Tuw1nDw0Eg7uXPbXmLmKOARb6WiFYliqPS5a754f9hA+/UmIECs1lwK2eBKWPgrDA1pv db03jLDhkCvkPvimQuTjwU1xGv47sgwQcfTbmpg6CEva4d7ZNrjKjqS9PF62LecQJqPZ 2zKw== X-Gm-Message-State: AODbwcDQK2S2QLy19DxsnrYK8hrisnJCBLIY7h+X7VrfEYbs77z2Qc0d UMRgIQJ8g/lMcQeN X-Received: by 10.55.176.71 with SMTP id z68mr10567495qke.277.1495249074176; Fri, 19 May 2017 19:57:54 -0700 (PDT) Received: from athos.fios-router.home (pool-72-80-62-166.nycmny.fios.verizon.net. [72.80.62.166]) by smtp.gmail.com with ESMTPSA id t5sm421095qkd.4.2017.05.19.19.57.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 19 May 2017 19:57:53 -0700 (PDT) From: Ilia Mirkin To: nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [RFC PATCH 1/3] drm/nouveau/overlay: improve error detection, fix pitch setting Date: Fri, 19 May 2017 22:57:47 -0400 Message-Id: <20170520025749.9291-2-imirkin@alum.mit.edu> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170520025749.9291-1-imirkin@alum.mit.edu> References: <20170520025749.9291-1-imirkin@alum.mit.edu> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP We were previously setting the pitch based on a perfectly packed buffer. This does not necessarily happen. Either modetest started generating such buffers recently, or earlier testing only happened with well-picked overlay sizes. While we're at it, beef up and refactor the error state detection. Signed-off-by: Ilia Mirkin --- drivers/gpu/drm/nouveau/dispnv04/overlay.c | 80 +++++++++++++++++++----------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index e54944d23268..ee7df9ef2695 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -90,6 +90,42 @@ cos_mul(int degrees, int factor) } static int +verify_fb(const struct drm_framebuffer *fb, uint32_t src_w, uint32_t src_h, + uint32_t crtc_w, uint32_t crtc_h, bool scale_fail, bool offset_fail) +{ + if (fb->pitches[0] & 0x3f) { + DRM_DEBUG_KMS("Unsuitable framebuffer for plane: align 64: 0x%x\n", + fb->pitches[0]); + return -EINVAL; + } + + if (fb->pitches[0] >= 0x10000) { + DRM_DEBUG_KMS("Unsuitable framebuffer for plane: pitch 0x%x >= 0x10000\n", + fb->pitches[0]); + return -EINVAL; + } + + if (fb->pitches[1] && fb->pitches[0] != fb->pitches[1]) { + DRM_DEBUG_KMS("Unsuitable framebuffer for plane: diff pitches: 0x%x != 0x%x\n", + fb->pitches[0], fb->pitches[1]); + return -ERANGE; + } + + if (scale_fail) { + DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n", + src_w, src_h, crtc_w, crtc_h); + return -ERANGE; + } + + if (offset_fail) { + DRM_DEBUG_KMS("Unsuitable framebuffer offset\n"); + return -ERANGE; + } + + return 0; +} + +static int nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -107,7 +143,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool flip = nv_plane->flip; int soff = NV_PCRTC0_SIZE * nv_crtc->index; int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; - int format, ret; + unsigned shift = drm->client.device.info.chipset >= 0x30 ? 1 : 3; + unsigned format = 0; + int ret; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -115,18 +153,11 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - format = ALIGN(src_w * 4, 0x100); - - if (format > 0xffff) - return -ERANGE; - - if (drm->client.device.info.chipset >= 0x30) { - if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) - return -ERANGE; - } else { - if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3)) - return -ERANGE; - } + ret = verify_fb(fb, src_w, src_h, crtc_w, crtc_h, + crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift), + false); + if (ret) + return ret; ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -160,7 +191,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset + fb->offsets[1]); } - nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format); + nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_STOP, 0); /* TODO: wait for vblank? */ nvif_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1); @@ -357,7 +388,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct nouveau_bo *cur = nv_plane->cur; uint32_t overlay = 1; int brightness = (nv_plane->brightness - 512) * 62 / 512; - int pitch, ret, i; + int ret, i; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -365,17 +396,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - pitch = ALIGN(src_w * 4, 0x100); - - if (pitch > 0xffff) - return -ERANGE; - - /* TODO: Compute an offset? Not sure how to do this for YUYV. */ - if (src_x != 0 || src_y != 0) - return -ERANGE; - - if (crtc_w < src_w || crtc_h < src_h) - return -ERANGE; + ret = verify_fb(fb, src_w, src_h, crtc_w, crtc_h, + crtc_w < src_w || crtc_h < src_h, + src_x != 0 || src_y != 0); ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -389,8 +412,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, for (i = 0; i < 2; i++) { nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i, - nv_fb->nvbo->bo.offset); - nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, pitch); + nv_fb->nvbo->bo.offset); + nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, + fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0); } nvif_wr32(dev, NV_PVIDEO_WINDOW_START, crtc_y << 16 | crtc_x);