From patchwork Wed Dec 18 23:34:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 11302437 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6CDE3139A for ; Wed, 18 Dec 2019 23:34:27 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4BB8C21582 for ; Wed, 18 Dec 2019 23:34:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4BB8C21582 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 343DD6EAA2; Wed, 18 Dec 2019 23:34:25 +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 D7E646EAA2 for ; Wed, 18 Dec 2019 23:34:23 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2019 15:34:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,330,1571727600"; d="scan'208";a="218303569" Received: from ideak-desk.fi.intel.com ([10.237.72.183]) by orsmga003.jf.intel.com with ESMTP; 18 Dec 2019 15:34:21 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org Date: Thu, 19 Dec 2019 01:34:00 +0200 Message-Id: <20191218233400.9888-1-imre.deak@intel.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20191218161105.30638-9-imre.deak@intel.com> References: <20191218161105.30638-9-imre.deak@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 08/15] drm/i915: Skip rotated offset adjustment for unsupported modifiers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dhinakaran Pandiyan Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Dhinakaran Pandiyan During framebuffer creation, we pre-compute offsets for 90/270 plane rotation. However, only Y and Yf modifiers support 90/270 rotation. So, skip the calculations for other modifiers. To keep the gem buffer size check still working for tiled planes, factor out the logic needed for rotation setup and skip only this part for tiled planes other than Y/Yf. v2: Add a bounds check WARN for the rotation info array. v3: Keep the gem buffer size check working for tiled planes. Cc: Matt Roper Cc: Ville Syrjälä Signed-off-by: Dhinakaran Pandiyan Signed-off-by: Imre Deak Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_display.c | 117 ++++++++++++------- 1 file changed, 76 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3180c1817b60..9c0f22410c4a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2863,12 +2863,71 @@ intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int x, int y) return 0; } +/* + * Setup the rotated view for an FB plane and return the size the GTT mapping + * requires for this view. + */ +static u32 +setup_fb_rotation(int plane, const struct intel_remapped_plane_info *plane_info, + u32 gtt_offset_rotated, int x, int y, + unsigned int width, unsigned int height, + unsigned int tile_size, + unsigned int tile_width, unsigned int tile_height, + struct drm_framebuffer *fb) +{ + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct intel_rotation_info *rot_info = &intel_fb->rot_info; + unsigned int pitch_tiles; + struct drm_rect r; + + if (fb->modifier != I915_FORMAT_MOD_Y_TILED && + fb->modifier != I915_FORMAT_MOD_Yf_TILED) + return 0; + + if (WARN_ON(plane >= ARRAY_SIZE(rot_info->plane))) + return 0; + + rot_info->plane[plane] = *plane_info; + + intel_fb->rotated[plane].pitch = plane_info->height * tile_height; + + /* rotate the x/y offsets to match the GTT view */ + drm_rect_init(&r, x, y, width, height); + drm_rect_rotate(&r, + plane_info->width * tile_width, + plane_info->height * tile_height, + DRM_MODE_ROTATE_270); + x = r.x1; + y = r.y1; + + /* rotate the tile dimensions to match the GTT view */ + pitch_tiles = intel_fb->rotated[plane].pitch / tile_height; + swap(tile_width, tile_height); + + /* + * We only keep the x/y offsets, so push all of the + * gtt offset into the x/y offsets. + */ + intel_adjust_tile_offset(&x, &y, + tile_width, tile_height, + tile_size, pitch_tiles, + gtt_offset_rotated * tile_size, 0); + + /* + * First pixel of the framebuffer from + * the start of the rotated gtt mapping. + */ + intel_fb->rotated[plane].x = x; + intel_fb->rotated[plane].y = y; + + return plane_info->width * plane_info->height; +} + static int intel_fill_fb_info(struct drm_i915_private *dev_priv, struct drm_framebuffer *fb) { struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct intel_rotation_info *rot_info = &intel_fb->rot_info; struct drm_i915_gem_object *obj = intel_fb_obj(fb); u32 gtt_offset_rotated = 0; unsigned int max_size = 0; @@ -2926,23 +2985,21 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, tile_size); offset /= tile_size; + /* Y or Yf modifiers required for 90/270 rotation */ if (!is_surface_linear(fb, i)) { + struct intel_remapped_plane_info plane_info; unsigned int tile_width, tile_height; - unsigned int pitch_tiles; - struct drm_rect r; intel_tile_dims(fb, i, &tile_width, &tile_height); - rot_info->plane[i].offset = offset; - rot_info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i], tile_width * cpp); - rot_info->plane[i].width = DIV_ROUND_UP(x + width, tile_width); - rot_info->plane[i].height = DIV_ROUND_UP(y + height, tile_height); - - intel_fb->rotated[i].pitch = - rot_info->plane[i].height * tile_height; + plane_info.offset = offset; + plane_info.stride = DIV_ROUND_UP(fb->pitches[i], + tile_width * cpp); + plane_info.width = DIV_ROUND_UP(x + width, tile_width); + plane_info.height = DIV_ROUND_UP(y + height, tile_height); /* how many tiles does this plane need */ - size = rot_info->plane[i].stride * rot_info->plane[i].height; + size = plane_info.stride * plane_info.height; /* * If the plane isn't horizontally tile aligned, * we need one more tile. @@ -2950,36 +3007,13 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, if (x != 0) size++; - /* rotate the x/y offsets to match the GTT view */ - drm_rect_init(&r, x, y, width, height); - drm_rect_rotate(&r, - rot_info->plane[i].width * tile_width, - rot_info->plane[i].height * tile_height, - DRM_MODE_ROTATE_270); - x = r.x1; - y = r.y1; - - /* rotate the tile dimensions to match the GTT view */ - pitch_tiles = intel_fb->rotated[i].pitch / tile_height; - swap(tile_width, tile_height); - - /* - * We only keep the x/y offsets, so push all of the - * gtt offset into the x/y offsets. - */ - intel_adjust_tile_offset(&x, &y, - tile_width, tile_height, - tile_size, pitch_tiles, - gtt_offset_rotated * tile_size, 0); - - gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height; - - /* - * First pixel of the framebuffer from - * the start of the rotated gtt mapping. - */ - intel_fb->rotated[i].x = x; - intel_fb->rotated[i].y = y; + gtt_offset_rotated += + setup_fb_rotation(i, &plane_info, + gtt_offset_rotated, + x, y, width, height, + tile_size, + tile_width, tile_height, + fb); } else { size = DIV_ROUND_UP((y + height) * fb->pitches[i] + x * cpp, tile_size); @@ -3063,6 +3097,7 @@ intel_plane_remap_gtt(struct intel_plane_state *plane_state) DRM_MODE_ROTATE_0, tile_size); offset /= tile_size; + WARN_ON(i >= ARRAY_SIZE(info->plane)); info->plane[i].offset = offset; info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i], tile_width * cpp);