From patchwork Mon Mar 26 05:13:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vidya Srinivas X-Patchwork-Id: 10307155 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 3165F600CC for ; Mon, 26 Mar 2018 05:17:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C31628942 for ; Mon, 26 Mar 2018 05:17:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 110FC2897F; Mon, 26 Mar 2018 05:17:38 +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 991A128942 for ; Mon, 26 Mar 2018 05:17:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 830596E381; Mon, 26 Mar 2018 05:17:34 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id B8A3B6E37C for ; Mon, 26 Mar 2018 05:17:22 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Mar 2018 22:17:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,363,1517904000"; d="scan'208";a="40588775" Received: from vsrini4-ubuntu.iind.intel.com ([10.223.161.6]) by fmsmga004.fm.intel.com with ESMTP; 25 Mar 2018 22:17:20 -0700 From: Vidya Srinivas To: intel-gfx@lists.freedesktop.org Date: Mon, 26 Mar 2018 10:43:53 +0530 Message-Id: <1522041233-26726-19-git-send-email-vidya.srinivas@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522041233-26726-1-git-send-email-vidya.srinivas@intel.com> References: <1522041233-26726-1-git-send-email-vidya.srinivas@intel.com> Subject: [Intel-gfx] [PATCH v16 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 6120483..90cc101 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12956,11 +12956,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 */ @@ -12972,6 +12977,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, @@ -12984,6 +12990,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)