From patchwork Tue Sep 2 19:23:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Padovan X-Patchwork-Id: 4827901 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 957939F314 for ; Tue, 2 Sep 2014 19:24:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 58991201BC for ; Tue, 2 Sep 2014 19:24:01 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 03E2E201CE for ; Tue, 2 Sep 2014 19:24:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6FB0E6E3AF; Tue, 2 Sep 2014 12:23:59 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-yk0-f176.google.com (mail-yk0-f176.google.com [209.85.160.176]) by gabe.freedesktop.org (Postfix) with ESMTP id 76A1E6E48E; Tue, 2 Sep 2014 12:23:58 -0700 (PDT) Received: by mail-yk0-f176.google.com with SMTP id 19so4294906ykq.7 for ; Tue, 02 Sep 2014 12:23:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QqF3QgeRmR6U6SnBuZubaAjRqi23UjHX0HG0JqtOTeI=; b=XJ9bJ/i/cHeNidn9j6gvlmORK/QuL63rcC9wc7kf9KR5umWCy6NzwY/jN1F0OBM10P mKM+YYw4KK1JBjmz/Zn/Hs+LtGB+hf9da84dK56jdINPWKYK/e94SUZWxKpd37j/wekt qwI9aNCvzGYHO1V3eqUSWvOhRhyR/peFJtWT4H3N7n8ViKLqz9SjDIx60BrfyUMc+mRE b4Jp7zaXoqV0vNT+ydit5G+JrPzen+mSHvgqf5qcxuMquE/GInEUYFWogmPiH+Lst3SE zi3fHH9yVfyGNGfuksyA8YWrOx4EGaZBDF6XUHt/EaXJ1lssnQ6TLtuz+/b8jaW74sUy sohA== X-Received: by 10.236.38.225 with SMTP id a61mr55548813yhb.35.1409685837948; Tue, 02 Sep 2014 12:23:57 -0700 (PDT) Received: from localhost.localdomain (200-158-3-16.dsl.telesp.net.br. [200.158.3.16]) by mx.google.com with ESMTPSA id d36sm6100071yho.20.2014.09.02.12.23.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Sep 2014 12:23:57 -0700 (PDT) From: Gustavo Padovan To: intel-gfx@lists.freedesktop.org Date: Tue, 2 Sep 2014 16:23:47 -0300 Message-Id: <1409685827-29067-4-git-send-email-gustavo@padovan.org> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1409685827-29067-1-git-send-email-gustavo@padovan.org> References: <1409685827-29067-1-git-send-email-gustavo@padovan.org> Cc: Gustavo Padovan , dri-devel@lists.freedesktop.org Subject: [Intel-gfx] [PATCH -v2 4/4] drm/i915: split intel_update_plane into check() and commit() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Gustavo Padovan Due to the upcoming atomic modesetting feature we need to separate some update functions into a check step that can fail and a commit step that should, ideally, never fail. This commit splits intel_update_plane() and its commit part can still fail due to the fb pinning procedure. v2: use the new struct intel_plane_state to store information between check and commit stages. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/i915/intel_sprite.c | 236 ++++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4cbe286..062eca2 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -845,57 +845,28 @@ static bool colorkey_enabled(struct intel_plane *intel_plane) } static int -intel_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, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +intel_check_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *pstate) { - struct drm_device *dev = plane->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(pstate->crtc); struct intel_plane *intel_plane = to_intel_plane(plane); - enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *fb = pstate->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; - struct drm_i915_gem_object *old_obj = intel_plane->obj; - int ret; - bool primary_enabled; - bool visible; + int crtc_x = pstate->crtc_x; + int crtc_y = pstate->crtc_y; + int crtc_w = pstate->crtc_w; + int crtc_h = pstate->crtc_h; + int src_x = pstate->src_x; + int src_y = pstate->src_y; + int src_w = pstate->src_w; + int src_h = pstate->src_h; + struct drm_rect *src = &pstate->src; + struct drm_rect *dst = &pstate->dst; + struct drm_rect *clip = &pstate->clip; int hscale, vscale; int max_scale, min_scale; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - struct drm_rect src = { - /* sample coordinates in 16.16 fixed point */ - .x1 = src_x, - .x2 = src_x + src_w, - .y1 = src_y, - .y2 = src_y + src_h, - }; - struct drm_rect dst = { - /* integer pixels */ - .x1 = crtc_x, - .x2 = crtc_x + crtc_w, - .y1 = crtc_y, - .y2 = crtc_y + crtc_h, - }; - const struct drm_rect clip = { - .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, - .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, - }; - const struct { - int crtc_x, crtc_y; - unsigned int crtc_w, crtc_h; - uint32_t src_x, src_y, src_w, src_h; - } orig = { - .crtc_x = crtc_x, - .crtc_y = crtc_y, - .crtc_w = crtc_w, - .crtc_h = crtc_h, - .src_x = src_x, - .src_y = src_y, - .src_w = src_w, - .src_h = src_h, - }; /* Don't modify another pipe's plane */ if (intel_plane->pipe != intel_crtc->pipe) { @@ -927,55 +898,55 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, max_scale = intel_plane->max_downscale << 16; min_scale = intel_plane->can_scale ? 1 : (1 << 16); - drm_rect_rotate(&src, fb->width << 16, fb->height << 16, + drm_rect_rotate(src, fb->width << 16, fb->height << 16, intel_plane->rotation); - hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); + hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(hscale < 0); - vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale); + vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(vscale < 0); - visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); + pstate->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); + crtc_x = dst->x1; + crtc_y = dst->y1; + crtc_w = drm_rect_width(dst); + crtc_h = drm_rect_height(dst); - if (visible) { + if (pstate->visible) { /* check again in case clipping clamped the results */ - hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); + 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, true); - drm_rect_debug_print(&dst, false); + drm_rect_debug_print(src, true); + drm_rect_debug_print(dst, false); return hscale; } - vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); + 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, true); - drm_rect_debug_print(&dst, false); + drm_rect_debug_print(src, true); + drm_rect_debug_print(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_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, + drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, intel_plane->rotation); /* sanity check to make sure the src viewport wasn't enlarged */ - WARN_ON(src.x1 < (int) src_x || - src.y1 < (int) src_y || - src.x2 > (int) (src_x + src_w) || - src.y2 > (int) (src_y + src_h)); + WARN_ON(src->x1 < (int) src_x || + src->y1 < (int) src_y || + src->x2 > (int) (src_x + src_w) || + src->y2 > (int) (src_y + src_h)); /* * Hardware doesn't handle subpixel coordinates. @@ -983,10 +954,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, * increase the source viewport size, because that could * push the downscaling factor out of bounds. */ - src_x = src.x1 >> 16; - src_w = drm_rect_width(&src) >> 16; - src_y = src.y1 >> 16; - src_h = drm_rect_height(&src) >> 16; + 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 (format_is_yuv(fb->pixel_format)) { src_x &= ~1; @@ -1000,12 +971,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, crtc_w &= ~1; if (crtc_w == 0) - visible = false; + pstate->visible = false; } } /* Check size restrictions when scaling */ - if (visible && (src_w != crtc_w || src_h != crtc_h)) { + if (pstate->visible && (src_w != crtc_w || src_h != crtc_h)) { unsigned int width_bytes; WARN_ON(!intel_plane->can_scale); @@ -1013,10 +984,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, /* FIXME interlacing min height is 6 */ if (crtc_w < 3 || crtc_h < 3) - visible = false; + pstate->visible = false; if (src_w < 3 || src_h < 3) - visible = false; + pstate->visible = false; width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size; @@ -1027,17 +998,55 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, } } - dst.x1 = crtc_x; - dst.x2 = crtc_x + crtc_w; - dst.y1 = crtc_y; - dst.y2 = crtc_y + crtc_h; + dst->x1 = crtc_x; + dst->x2 = crtc_x + crtc_w; + dst->y1 = crtc_y; + dst->y2 = crtc_y + crtc_h; + + pstate->src_x = src_x; + pstate->src_y = src_y; + pstate->src_w = src_w; + pstate->src_h = src_h; + pstate->crtc_x = crtc_x; + pstate->crtc_y = crtc_y; + pstate->crtc_w = crtc_w; + pstate->crtc_x = crtc_h; + + return 0; +} + +static int +intel_commit_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *pstate) +{ + struct drm_device *dev = plane->dev; + struct drm_crtc *crtc = pstate->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane *intel_plane = to_intel_plane(plane); + enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *fb = pstate->fb; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj = intel_fb->obj; + struct drm_i915_gem_object *old_obj = intel_plane->obj; + int crtc_x = pstate->crtc_x; + int crtc_y = pstate->crtc_y; + int crtc_w = pstate->crtc_w; + int crtc_h = pstate->crtc_h; + int src_x = pstate->src_x; + int src_y = pstate->src_y; + int src_w = pstate->src_w; + int src_h = pstate->src_h; + struct drm_rect *dst = &pstate->dst; + struct drm_rect *clip = &pstate->clip; + int ret; + bool primary_enabled; /* * If the sprite is completely covering the primary plane, * we can disable the primary and save power. */ - primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane); - WARN_ON(!primary_enabled && !visible && intel_crtc->active); + primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); + WARN_ON(!primary_enabled && !pstate->visible && intel_crtc->active); mutex_lock(&dev->struct_mutex); @@ -1055,14 +1064,14 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; - intel_plane->crtc_x = orig.crtc_x; - intel_plane->crtc_y = orig.crtc_y; - intel_plane->crtc_w = orig.crtc_w; - intel_plane->crtc_h = orig.crtc_h; - intel_plane->src_x = orig.src_x; - intel_plane->src_y = orig.src_y; - intel_plane->src_w = orig.src_w; - intel_plane->src_h = orig.src_h; + intel_plane->crtc_x = pstate->orig_dst.x1; + intel_plane->crtc_y = pstate->orig_dst.y1; + intel_plane->crtc_w = drm_rect_width(&pstate->orig_dst); + intel_plane->crtc_h = drm_rect_height(&pstate->orig_dst); + intel_plane->src_x = pstate->orig_src.x1; + intel_plane->src_y = pstate->orig_src.y1; + intel_plane->src_w = drm_rect_width(&pstate->orig_src); + intel_plane->src_h = drm_rect_height(&pstate->orig_src); intel_plane->obj = obj; if (intel_crtc->active) { @@ -1076,7 +1085,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (primary_was_enabled && !primary_enabled) intel_pre_disable_primary(crtc); - if (visible) + if (pstate->visible) intel_plane->update_plane(plane, crtc, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h); @@ -1109,6 +1118,53 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, } static int +intel_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, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct intel_plane_state pstate; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int ret; + + pstate.crtc = crtc; + pstate.fb = fb; + pstate.crtc_x = crtc_x; + pstate.crtc_y = crtc_y; + pstate.crtc_w = crtc_w; + pstate.crtc_h = crtc_h; + pstate.src_x = src_x; + pstate.src_y = src_y; + pstate.src_w = src_w; + pstate.src_h = src_h; + pstate.src.x1 = src_x, + pstate.src.x2 = src_x + src_w, + pstate.src.y1 = src_y, + pstate.src.y2 = src_y + src_h, + pstate.dst.x1 = crtc_x, + pstate.dst.x2 = crtc_x + crtc_w, + pstate.dst.y1 = crtc_y, + pstate.dst.y2 = crtc_y + crtc_h, + pstate.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, + pstate.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, + pstate.orig_src.x1 = src_x, + pstate.orig_src.x2 = src_x + src_w, + pstate.orig_src.y1 = src_y, + pstate.orig_src.y2 = src_y + src_h, + pstate.orig_dst.x1 = crtc_x, + pstate.orig_dst.x2 = crtc_x + crtc_w, + pstate.orig_dst.y1 = crtc_y, + pstate.orig_dst.y2 = crtc_y + crtc_h, + + ret = intel_check_sprite_plane(plane, &pstate); + if (ret) + return ret; + + return intel_commit_sprite_plane(plane, &pstate); +} + +static int intel_disable_plane(struct drm_plane *plane) { struct drm_device *dev = plane->dev;