From patchwork Tue Jan 17 04:45:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9519953 X-Patchwork-Delegate: agross@codeaurora.org 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 70C1D601C3 for ; Tue, 17 Jan 2017 04:46:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64FFD2849E for ; Tue, 17 Jan 2017 04:46:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59D94284CE; Tue, 17 Jan 2017 04:46:53 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B47C92849B for ; Tue, 17 Jan 2017 04:46:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751091AbdAQEqv (ORCPT ); Mon, 16 Jan 2017 23:46:51 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:42322 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750916AbdAQEqs (ORCPT ); Mon, 16 Jan 2017 23:46:48 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 96AAE60798; Tue, 17 Jan 2017 04:45:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1484628336; bh=4dK8uWaWIInRdtbhehtGy6lgcsw9rFnk9BgdcUeLbkY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bxfiU9K1r5U8ffQd/1FZjCmejqZDg7rpMGuLdzARRVXqInSDh3oZkJVLfk4xjcqw8 Uj6pHvwKxOH6wIwDg91hhsA8P7o2GGfvB0G7r1kFj273jlJflvn0CjEE03ItUoHvzF J9s+nSwMVNRH6GUH8xlg0+4BqqyGDkahZ07lOq70= Received: from localhost (unknown [202.46.23.61]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: architt@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 65610600B9; Tue, 17 Jan 2017 04:45:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1484628336; bh=4dK8uWaWIInRdtbhehtGy6lgcsw9rFnk9BgdcUeLbkY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bxfiU9K1r5U8ffQd/1FZjCmejqZDg7rpMGuLdzARRVXqInSDh3oZkJVLfk4xjcqw8 Uj6pHvwKxOH6wIwDg91hhsA8P7o2GGfvB0G7r1kFj273jlJflvn0CjEE03ItUoHvzF J9s+nSwMVNRH6GUH8xlg0+4BqqyGDkahZ07lOq70= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 65610600B9 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=architt@codeaurora.org From: Archit Taneja To: robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, Archit Taneja Subject: [PATCH v2 3/8] drm/msm/mdp5: Use plane helpers to configure src/dst rectangles Date: Tue, 17 Jan 2017 10:15:07 +0530 Message-Id: <20170117044512.22934-4-architt@codeaurora.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170117044512.22934-1-architt@codeaurora.org> References: <1482149338-586-1-git-send-email-architt@codeaurora.org> <20170117044512.22934-1-architt@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The MDP5 plane's atomic_check ops doesn't perform clipping tests. This didn't hurt us much in the past, but clipping becomes important with cursor planes. Use drm_plane_helper_check_state, the way rockchip/intel/mtk drivers already do. Use these drivers as reference. Clipping requires knowledge of the crtc width and height. This requires us to call drm_atomic_helper_check_modeset before drm_atomic_helper_check_planes in the driver's atomic_check op, because check_modetest will populate the mode for the crtc, needed to populate the clip rectangle. We update the plane_enabled(state) local helper to use state->visible, since state->visible and 'state->fb && state->crtc' represent the same thing. One issue with the existing code is that we don't have a way to disable the plane when it's completely clipped out. Until there isn't an update on the crtc (which would de-stage the plane), we would still see the plane in its last 'visible' configuration. Signed-off-by: Archit Taneja --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 57 ++++++++++++++++++++++++------- drivers/gpu/drm/msm/msm_atomic.c | 21 ++++++++---- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index eb8dc7c36419..939991d5f346 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -29,10 +29,7 @@ struct mdp5_plane { static int mdp5_plane_mode_set(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 drm_rect *src, struct drm_rect *dest); static void set_scanout_locked(struct drm_plane *plane, struct drm_framebuffer *fb); @@ -45,7 +42,7 @@ static struct mdp5_kms *get_kms(struct drm_plane *plane) static bool plane_enabled(struct drm_plane_state *state) { - return state->fb && state->crtc; + return state->visible; } static void mdp5_plane_destroy(struct drm_plane *plane) @@ -272,6 +269,7 @@ static void mdp5_plane_cleanup_fb(struct drm_plane *plane, msm_framebuffer_cleanup(fb, mdp5_kms->id); } +#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) static int mdp5_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -281,10 +279,19 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, bool new_hwpipe = false; uint32_t max_width, max_height; uint32_t caps = 0; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_rect clip; + int min_scale, max_scale; + int ret; DBG("%s: check (%d -> %d)", plane->name, plane_enabled(old_state), plane_enabled(state)); + crtc = state->crtc ? state->crtc : plane->state->crtc; + if (!crtc) + return 0; + max_width = config->hw->lm.max_width << 16; max_height = config->hw->lm.max_height << 16; @@ -296,6 +303,22 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, return -ERANGE; } + crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; + + clip.x1 = 0; + clip.y1 = 0; + clip.x2 = crtc_state->adjusted_mode.hdisplay; + clip.y2 = crtc_state->adjusted_mode.vdisplay; + min_scale = FRAC_16_16(1, 8); + max_scale = FRAC_16_16(8, 1); + + ret = drm_plane_helper_check_state(state, &clip, min_scale, + max_scale, true, true); + if (ret) + return ret; + if (plane_enabled(state)) { unsigned int rotation; const struct mdp_format *format; @@ -368,10 +391,7 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane, ret = mdp5_plane_mode_set(plane, state->crtc, state->fb, - state->crtc_x, state->crtc_y, - state->crtc_w, state->crtc_h, - state->src_x, state->src_y, - state->src_w, state->src_h); + &state->src, &state->dst); /* atomic_check should have ensured that this doesn't fail */ WARN_ON(ret < 0); } @@ -664,10 +684,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe, static int mdp5_plane_mode_set(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 drm_rect *src, struct drm_rect *dest) { struct drm_plane_state *pstate = plane->state; struct mdp5_hw_pipe *hwpipe = to_mdp5_plane_state(pstate)->hwpipe; @@ -683,6 +700,10 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t pix_format; unsigned int rotation; bool vflip, hflip; + int crtc_x, crtc_y; + unsigned int crtc_w, crtc_h; + uint32_t src_x, src_y; + uint32_t src_w, src_h; unsigned long flags; int ret; @@ -695,6 +716,16 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, format = to_mdp_format(msm_framebuffer_format(fb)); pix_format = format->base.pixel_format; + src_x = src->x1; + src_y = src->y1; + src_w = drm_rect_width(src); + src_h = drm_rect_height(src); + + crtc_x = dest->x1; + crtc_y = dest->y1; + crtc_w = drm_rect_width(dest); + crtc_h = drm_rect_height(dest); + /* src values are in Q16 fixed point, convert to integer: */ src_x = src_x >> 16; src_y = src_y >> 16; diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 30b5d23e53b4..6924fa28f04f 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -151,20 +151,29 @@ static void commit_worker(struct work_struct *work) complete_commit(container_of(work, struct msm_commit, work), true); } +/* + * this func is identical to the drm_atomic_helper_check, but we keep this + * because we might eventually need to have a more finegrained check + * sequence without using the atomic helpers. + * + * In the past, we first called drm_atomic_helper_check_planes, and then + * drm_atomic_helper_check_modeset. We needed this because the MDP5 plane's + * ->atomic_check could update ->mode_changed for pixel format changes. + * This, however isn't needed now because if there is a pixel format change, + * we just assign a new hwpipe for it with a new SMP allocation. We might + * eventually hit a condition where we would need to do a full modeset if + * we run out of planes. There, we'd probably need to set mode_changed. + */ int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { int ret; - /* - * msm ->atomic_check can update ->mode_changed for pixel format - * changes, hence must be run before we check the modeset changes. - */ - ret = drm_atomic_helper_check_planes(dev, state); + ret = drm_atomic_helper_check_modeset(dev, state); if (ret) return ret; - ret = drm_atomic_helper_check_modeset(dev, state); + ret = drm_atomic_helper_check_planes(dev, state); if (ret) return ret;