From patchwork Mon Mar 26 03:58:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vidya Srinivas X-Patchwork-Id: 10307109 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 45715600F6 for ; Mon, 26 Mar 2018 04:02:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3704C2945B for ; Mon, 26 Mar 2018 04:02:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2BA8B29462; Mon, 26 Mar 2018 04:02:05 +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.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED 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 81F722945B for ; Mon, 26 Mar 2018 04:02:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 010FC6E35F; Mon, 26 Mar 2018 04:02:04 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3B19E6E35F for ; Mon, 26 Mar 2018 04:02:02 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Mar 2018 21:02:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,363,1517904000"; d="scan'208";a="27992135" Received: from vsrini4-ubuntu.iind.intel.com ([10.223.161.6]) by orsmga007.jf.intel.com with ESMTP; 25 Mar 2018 21:01:59 -0700 From: Vidya Srinivas To: intel-gfx@lists.freedesktop.org Date: Mon, 26 Mar 2018 09:28:25 +0530 Message-Id: <1522036705-10536-19-git-send-email-vidya.srinivas@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522036705-10536-1-git-send-email-vidya.srinivas@intel.com> References: <1522036705-10536-1-git-send-email-vidya.srinivas@intel.com> Subject: [Intel-gfx] [PATCH v15 18/18] drm/i915: Add checks to primary plane X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ville.syrjala@intel.com, Vidya Srinivas , maarten.lankhorst@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Patch adds checks to primary plane related to scaling, clipping, rotation and fb formats. These checks currently, were being done only for sprites. These are required for primary plane as well. Credits-to: Maarten Lankhorst Signed-off-by: Vidya Srinivas --- drivers/gpu/drm/i915/intel_display.c | 127 ++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2b87be1..837c5d7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12957,11 +12957,16 @@ intel_check_primary_plane(struct intel_plane *plane, { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_crtc *crtc = state->base.crtc; + struct drm_framebuffer *fb = state->base.fb; int min_scale = DRM_PLANE_HELPER_NO_SCALING; int max_scale = DRM_PLANE_HELPER_NO_SCALING; - bool can_position = false; - int ret; + bool can_position = false, can_scale = false; uint32_t pixel_format = 0; + int crtc_x, crtc_y, hscale, vscale, ret; + uint32_t src_x, src_y, src_w, src_h, crtc_w, crtc_h; + struct drm_rect *src = &state->base.src; + struct drm_rect *dst = &state->base.dst; + struct drm_rect clip = {}; if (INTEL_GEN(dev_priv) >= 9) { /* use scaler when colorkey is not required */ @@ -12973,6 +12978,7 @@ intel_check_primary_plane(struct intel_plane *plane, crtc_state, pixel_format); } can_position = true; + can_scale = true; } ret = drm_atomic_helper_check_plane_state(&state->base, @@ -12985,6 +12991,123 @@ intel_check_primary_plane(struct intel_plane *plane, if (!state->base.fb) return 0; + *src = drm_plane_state_src(&state->base); + *dst = drm_plane_state_dest(&state->base); + + drm_rect_rotate(src, fb->width << 16, fb->height << 16, + state->base.rotation); + + hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); + WARN_ON(hscale < 0); + + vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); + WARN_ON(vscale < 0); + + if (crtc_state->base.enable) + drm_mode_get_hv_timing(&crtc_state->base.mode, + &clip.x2, &clip.y2); + + state->base.visible = + drm_rect_clip_scaled(src, dst, &clip, hscale, vscale); + + crtc_x = dst->x1; + crtc_y = dst->y1; + crtc_w = drm_rect_width(dst); + crtc_h = drm_rect_height(dst); + + if (state->base.visible) { + /* check again in case clipping clamped the results */ + hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); + if (hscale < 0) { + DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); + drm_rect_debug_print("src: ", src, true); + drm_rect_debug_print("dst: ", dst, false); + + return hscale; + } + + vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); + if (vscale < 0) { + DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); + drm_rect_debug_print("src: ", src, true); + drm_rect_debug_print("dst: ", dst, false); + + return vscale; + } + + /* + * Make the source viewport size an exact + * multiple of the scaling factors. + */ + drm_rect_adjust_size(src, + drm_rect_width(dst) * hscale - drm_rect_width(src), + drm_rect_height(dst) * vscale - drm_rect_height(src)); + + drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, + state->base.rotation); + + /* + * sanity check to make sure the src + * viewport wasn't enlarged + */ + WARN_ON(src->x1 < (int) state->base.src_x || + src->y1 < (int) state->base.src_y || + src->x2 > (int) state->base.src_x + state->base.src_w || + src->y2 > (int) state->base.src_y + state->base.src_h); + + src_x = src->x1 >> 16; + src_w = drm_rect_width(src) >> 16; + src_y = src->y1 >> 16; + src_h = drm_rect_height(src) >> 16; + + if (intel_format_is_yuv(fb->format->format)) { + src_x &= ~1; + src_w &= ~1; + + if (!can_scale) + crtc_w &= ~1; + + if (crtc_w == 0) + state->base.visible = false; + } + } + + /* Check size restrictions when scaling */ + if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) { + unsigned int width_bytes; + int cpp = fb->format->cpp[0]; + + WARN_ON(!can_scale); + + /* FIXME interlacing min height is 6 */ + + if (crtc_w < 3 || crtc_h < 3) + state->base.visible = false; + + if (src_w < 3 || src_h < 3) + state->base.visible = false; + + width_bytes = ((src_x * cpp) & 63) + src_w * cpp; + + if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 || + width_bytes > 4096 || fb->pitches[0] > 4096)) { + DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); + return -EINVAL; + } + } + + if (state->base.visible) { + src->x1 = src_x << 16; + src->x2 = (src_x + src_w) << 16; + src->y1 = src_y << 16; + src->y2 = (src_y + src_h) << 16; + } + + dst->x1 = crtc_x; + dst->x2 = crtc_x + crtc_w; + dst->y1 = crtc_y; + dst->y2 = crtc_y + crtc_h; + if (INTEL_GEN(dev_priv) >= 9) { ret = skl_check_plane_surface(crtc_state, state); if (ret)