From patchwork Tue Mar 3 13:21:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Conselvan de Oliveira X-Patchwork-Id: 5922591 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1133ABF440 for ; Tue, 3 Mar 2015 13:22:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0209820173 for ; Tue, 3 Mar 2015 13:22:38 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CDE0B2013D for ; Tue, 3 Mar 2015 13:22:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5F7556E5AD; Tue, 3 Mar 2015 05:22:36 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 642016E5AB for ; Tue, 3 Mar 2015 05:22:34 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP; 03 Mar 2015 05:22:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,681,1418112000"; d="scan'208";a="461859567" Received: from linux.intel.com ([10.23.219.25]) by FMSMGA003.fm.intel.com with ESMTP; 03 Mar 2015 05:16:22 -0800 Received: from localhost (aconselv-mobl3.fi.intel.com [10.237.72.152]) by linux.intel.com (Postfix) with ESMTP id 1A69D6A408D; Tue, 3 Mar 2015 05:22:18 -0800 (PST) From: Ander Conselvan de Oliveira To: intel-gfx@lists.freedesktop.org Date: Tue, 3 Mar 2015 15:21:59 +0200 Message-Id: <1425388937-1247-6-git-send-email-ander.conselvan.de.oliveira@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1425388937-1247-1-git-send-email-ander.conselvan.de.oliveira@intel.com> References: <1425388937-1247-1-git-send-email-ander.conselvan.de.oliveira@intel.com> Cc: Ander Conselvan de Oliveira Subject: [Intel-gfx] [PATCH 05/23] drm/i915: Allocate a drm_atomic_state for the legacy modeset code X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 For the atomic conversion, the mode set paths need to be changed to rely on an atomic state instead of using the staged config. By using an atomic state for the legacy code, we will be able to convert the code base in small chunks. Signed-off-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_display.c | 118 +++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 798de7b..97d4df5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -37,6 +37,7 @@ #include #include "i915_drv.h" #include "i915_trace.h" +#include #include #include #include @@ -10290,10 +10291,22 @@ static bool check_digital_port_conflicts(struct drm_device *dev) return true; } -static struct intel_crtc_state * +static void +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) +{ + struct drm_crtc_state tmp_state; + + /* Clear only the intel specific part of the crtc state */ + tmp_state = crtc_state->base; + memset(crtc_state, 0, sizeof *crtc_state); + crtc_state->base = tmp_state; +} + +static int intel_modeset_pipe_config(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct drm_display_mode *mode) + struct drm_display_mode *mode, + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct intel_encoder *encoder; @@ -10303,17 +10316,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, if (!check_encoder_cloning(to_intel_crtc(crtc))) { DRM_DEBUG_KMS("rejecting invalid cloning configuration\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } if (!check_digital_port_conflicts(dev)) { DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); - if (!pipe_config) - return ERR_PTR(-ENOMEM); + pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc)); + if (IS_ERR(pipe_config)) + return PTR_ERR(pipe_config); + + clear_intel_crtc_state(pipe_config); pipe_config->base.crtc = crtc; drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -10408,10 +10423,9 @@ encoder_retry: DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", plane_bpp, pipe_config->pipe_bpp, pipe_config->dither); - return pipe_config; + return 0; fail: - kfree(pipe_config); - return ERR_PTR(ret); + return ret; } /* Computes which crtcs are affected and sets the relevant bits in the mask. For @@ -11089,17 +11103,19 @@ static struct intel_crtc_state * intel_modeset_compute_config(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_framebuffer *fb, + struct drm_atomic_state *state, unsigned *modeset_pipes, unsigned *prepare_pipes, unsigned *disable_pipes) { struct intel_crtc_state *pipe_config = NULL; + int ret = 0; intel_modeset_affected_pipes(crtc, modeset_pipes, prepare_pipes, disable_pipes); if ((*modeset_pipes) == 0) - goto out; + return NULL; /* * Note this needs changes when we start tracking multiple modes @@ -11107,14 +11123,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc, * (i.e. one pipe_config for each crtc) rather than just the one * for this crtc. */ - pipe_config = intel_modeset_pipe_config(crtc, fb, mode); - if (IS_ERR(pipe_config)) { - goto out; - } + ret = intel_modeset_pipe_config(crtc, fb, mode, state); + if (ret) + return ERR_PTR(ret); + + pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc)); + if (IS_ERR(pipe_config)) + return pipe_config; + intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]"); -out: return pipe_config; } @@ -11159,6 +11178,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *saved_mode; + struct intel_crtc_state *crtc_state_copy = NULL; struct intel_crtc *intel_crtc; int ret = 0; @@ -11166,6 +11186,12 @@ static int __intel_set_mode(struct drm_crtc *crtc, if (!saved_mode) return -ENOMEM; + crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL); + if (!crtc_state_copy) { + ret = -ENOMEM; + goto done; + } + *saved_mode = crtc->mode; if (modeset_pipes) @@ -11252,6 +11278,19 @@ done: if (ret && crtc->state->enable) crtc->mode = *saved_mode; + if (ret == 0 && pipe_config) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + /* The pipe_config will be freed with the atomic state, so + * make a copy. */ + memcpy(crtc_state_copy, intel_crtc->config, + sizeof *crtc_state_copy); + intel_crtc->config = intel_crtc->new_config = crtc_state_copy; + intel_crtc->base.state = &crtc_state_copy->base; + } else { + kfree(crtc_state_copy); + } + kfree(saved_mode); return ret; } @@ -11279,20 +11318,37 @@ static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *fb) { + struct drm_device *dev = crtc->dev; + struct drm_atomic_state *state; struct intel_crtc_state *pipe_config; unsigned modeset_pipes, prepare_pipes, disable_pipes; + int ret = 0; + + state = drm_atomic_state_alloc(dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx = dev->mode_config.acquire_ctx; - pipe_config = intel_modeset_compute_config(crtc, mode, fb, + pipe_config = intel_modeset_compute_config(crtc, mode, fb, state, &modeset_pipes, &prepare_pipes, &disable_pipes); - if (IS_ERR(pipe_config)) - return PTR_ERR(pipe_config); + if (IS_ERR(pipe_config)) { + ret = PTR_ERR(pipe_config); + goto out; + } + + ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config, + modeset_pipes, prepare_pipes, + disable_pipes); + if (ret) + goto out; - return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config, - modeset_pipes, prepare_pipes, - disable_pipes); +out: + drm_atomic_state_free(state); + return ret; } void intel_crtc_restore_mode(struct drm_crtc *crtc) @@ -11622,6 +11678,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set) { struct drm_device *dev; struct drm_mode_set save_set; + struct drm_atomic_state *state = NULL; struct intel_set_config *config; struct intel_crtc_state *pipe_config; unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11666,12 +11723,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set) * such cases. */ intel_set_config_compute_mode_changes(set, config); + state = drm_atomic_state_alloc(dev); + if (!state) { + ret = -ENOMEM; + goto out_config; + } + + state->acquire_ctx = dev->mode_config.acquire_ctx; + ret = intel_modeset_stage_output_state(dev, set, config); if (ret) goto fail; pipe_config = intel_modeset_compute_config(set->crtc, set->mode, - set->fb, + set->fb, state, &modeset_pipes, &prepare_pipes, &disable_pipes); @@ -11691,10 +11756,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) */ } - /* set_mode will free it in the mode_changed case */ - if (!config->mode_changed) - kfree(pipe_config); - intel_update_pipe_size(to_intel_crtc(set->crtc)); if (config->mode_changed) { @@ -11757,6 +11818,9 @@ fail: } out_config: + if (state) + drm_atomic_state_free(state); + intel_set_config_free(config); return ret; }