From patchwork Thu Feb 21 23:56:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 2173671 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id C3866DF215 for ; Thu, 21 Feb 2013 23:57:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 961D8E612B for ; Thu, 21 Feb 2013 15:57:49 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ee0-f47.google.com (mail-ee0-f47.google.com [74.125.83.47]) by gabe.freedesktop.org (Postfix) with ESMTP id 9C41EE60F5 for ; Thu, 21 Feb 2013 15:57:03 -0800 (PST) Received: by mail-ee0-f47.google.com with SMTP id e52so39547eek.6 for ; Thu, 21 Feb 2013 15:57:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=jrV3ayNy4wI3q0htZ1ewZNG/7EuG6xYpT+oHTdokHDY=; b=VSmIJS6Mszunv+cr8WdINgaFab7pTrV9vds3VkExe9RH8pCtKsnzGz+9j0ETDz+ENn Vy39x24/99T1xMPJHidZPdqa0OUN+u1dv8phJ19Xf8vd1uEXkAqhmJRBOkpNcnhh24i+ fn+hwF+aRn4fsGGJ9CMQffVdr+/DzhXhNXmKA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=jrV3ayNy4wI3q0htZ1ewZNG/7EuG6xYpT+oHTdokHDY=; b=f28Hp1HdBVWKDt9vUgT/icbW9ZVH+YgNYQKzAa+BwhxJkA/sevylGdrzQao3C0Gr6Y dXP/2uzRVdvIDMkl65kpdX/m7w2PEganXhHe7fNQShQ8Ky6lh9rLbd0b9Hm2HU0X8hcO oqSRe1Qy4UQCnQJ3wRq/drIsl530ZyhUnreMp9GGojsbTm1oI+EKaGw0jtXrrAIGu1m3 o9ZcmHQaXyihB+S8nF1c2IX5ePrL2m9l1kjuLpTbkAPyBBIK0a3kTShzMgvwX+oqVksa fHGa9Jble6kMLBVerxOS2k/1nTQY/sAgV0h3HY5rc0RYz04mhA3nT1r8YUbWQJgNZao2 yRiA== X-Received: by 10.14.0.73 with SMTP id 49mr86333520eea.21.1361491022765; Thu, 21 Feb 2013 15:57:02 -0800 (PST) Received: from bremse.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPS id q5sm456579eep.11.2013.02.21.15.57.01 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 21 Feb 2013 15:57:01 -0800 (PST) From: Daniel Vetter To: Intel Graphics Development Date: Fri, 22 Feb 2013 00:56:45 +0100 Message-Id: <1361491014-13888-2-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1361491014-13888-1-git-send-email-daniel.vetter@ffwll.ch> References: <1361491014-13888-1-git-send-email-daniel.vetter@ffwll.ch> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQl5AHjrNp0Yi9DjPhJF9J8fdhUa1egDBWTnfiuzR0Z872SvUk41OB8AsCsK0MsSEh5kbfSf Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 01/10] drm/i915: introduce struct intel_crtc_config X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Currently only containing the requested and the adjusted mode. And only crtc callbacks are converted somewhat to it, encoders will be done on a as-needed basis (simply too much churn in one patch otherwise). Future patches will add tons more useful stuff to this struct, starting with the very simple. v2: Store the pipe_config in the intel_crtc, so that the ->mode-set, ->enable and also ->disable have easy access to it. v3: Store the pipe config in the right crtc ... v4: Rebased. v5: Fixup an OOPS when trying to kfree an ERR_PTR. v6: Used drm_moode_copy and some other small cleanups as suggested by Ville Syrjälä. Signed-off-by: Daniel Vetter Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/intel_display.c | 83 +++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_drv.h | 7 +++ 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e95337c..8fb14fb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -271,6 +271,8 @@ struct drm_i915_error_state { struct intel_display_error_state *display; }; +struct intel_crtc_config; + struct drm_i915_display_funcs { bool (*fbc_enabled)(struct drm_device *dev); void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); @@ -284,8 +286,6 @@ struct drm_i915_display_funcs { struct drm_display_mode *mode); void (*modeset_global_resources)(struct drm_device *dev); int (*crtc_mode_set)(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb); void (*crtc_enable)(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b521198..5a3e231 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector) return encoder->get_hw_state(encoder, &pipe); } -static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static bool intel_crtc_compute_config(struct drm_crtc *crtc, + struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; if (HAS_PCH_SPLIT(dev)) { /* FDI link clock is fixed at 2.7G */ - if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) + if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4) return false; } @@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc, } static int i9xx_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *fb) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; int refclk, num_connectors = 0; @@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, } static int ironlake_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *fb) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; int num_connectors = 0; @@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev) } static int haswell_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *fb) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; int num_connectors = 0; @@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, } static int intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *fb) { @@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_encoder_helper_funcs *encoder_funcs; struct intel_encoder *encoder; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; int pipe = intel_crtc->pipe; int ret; @@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_pre_modeset(dev, pipe); - ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, - x, y, fb); + ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb); + drm_vblank_post_modeset(dev, pipe); if (ret != 0) @@ -7478,19 +7482,24 @@ static void intel_modeset_commit_output_state(struct drm_device *dev) } } -static struct drm_display_mode * -intel_modeset_adjusted_mode(struct drm_crtc *crtc, - struct drm_display_mode *mode) +static struct intel_crtc_config * +intel_modeset_pipe_config(struct drm_crtc *crtc, + struct drm_display_mode *mode) { struct drm_device *dev = crtc->dev; - struct drm_display_mode *adjusted_mode; struct drm_encoder_helper_funcs *encoder_funcs; struct intel_encoder *encoder; + struct intel_crtc_config *pipe_config; - adjusted_mode = drm_mode_duplicate(dev, mode); - if (!adjusted_mode) + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) return ERR_PTR(-ENOMEM); + drm_mode_copy(&pipe_config->adjusted_mode, mode); + pipe_config->adjusted_mode.base.id = 0; + drm_mode_copy(&pipe_config->requested_mode, mode); + pipe_config->requested_mode.base.id = 0; + /* Pass our mode to the connectors and the CRTC to give them a chance to * adjust it according to limitations or connector properties, and also * a chance to reject the mode entirely. @@ -7501,22 +7510,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc, if (&encoder->new_crtc->base != crtc) continue; encoder_funcs = encoder->base.helper_private; - if (!(encoder_funcs->mode_fixup(&encoder->base, mode, - adjusted_mode))) { + if (!(encoder_funcs->mode_fixup(&encoder->base, + &pipe_config->requested_mode, + &pipe_config->adjusted_mode))) { DRM_DEBUG_KMS("Encoder fixup failed\n"); goto fail; } } - if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) { + if (!(intel_crtc_compute_config(crtc, pipe_config))) { DRM_DEBUG_KMS("CRTC fixup failed\n"); goto fail; } DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); - return adjusted_mode; + return pipe_config; fail: - drm_mode_destroy(dev, adjusted_mode); + kfree(pipe_config); return ERR_PTR(-EINVAL); } @@ -7782,7 +7792,8 @@ int intel_set_mode(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode; + struct drm_display_mode *saved_mode, *saved_hwmode; + struct intel_crtc_config *pipe_config = NULL; struct intel_crtc *intel_crtc; unsigned disable_pipes, prepare_pipes, modeset_pipes; int ret = 0; @@ -7809,11 +7820,12 @@ int intel_set_mode(struct drm_crtc *crtc, * Hence simply check whether any bit is set in modeset_pipes in all the * pieces of code that are not yet converted to deal with mutliple crtcs * changing their mode at the same time. */ - adjusted_mode = NULL; if (modeset_pipes) { - adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); - if (IS_ERR(adjusted_mode)) { - ret = PTR_ERR(adjusted_mode); + pipe_config = intel_modeset_pipe_config(crtc, mode); + if (IS_ERR(pipe_config)) { + ret = PTR_ERR(pipe_config); + pipe_config = NULL; + goto out; } } @@ -7826,8 +7838,12 @@ int intel_set_mode(struct drm_crtc *crtc, /* crtc->mode is already used by the ->mode_set callbacks, hence we need * to set it here already despite that we pass it down the callchain. */ - if (modeset_pipes) + if (modeset_pipes) { crtc->mode = *mode; + /* mode_set/enable/disable functions rely on a correct pipe + * config. */ + to_intel_crtc(crtc)->config = *pipe_config; + } /* Only after disabling all output pipelines that will be changed can we * update the the output configuration. */ @@ -7841,7 +7857,6 @@ int intel_set_mode(struct drm_crtc *crtc, */ for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { ret = intel_crtc_mode_set(&intel_crtc->base, - mode, adjusted_mode, x, y, fb); if (ret) goto done; @@ -7853,7 +7868,7 @@ int intel_set_mode(struct drm_crtc *crtc, if (modeset_pipes) { /* Store real post-adjustment hardware mode. */ - crtc->hwmode = *adjusted_mode; + crtc->hwmode = pipe_config->adjusted_mode; /* Calculate and store various constants which * are later needed by vblank and swap-completion @@ -7864,7 +7879,6 @@ int intel_set_mode(struct drm_crtc *crtc, /* FIXME: add subpixel order */ done: - drm_mode_destroy(dev, adjusted_mode); if (ret && crtc->enabled) { crtc->hwmode = *saved_hwmode; crtc->mode = *saved_mode; @@ -7873,6 +7887,7 @@ done: } out: + kfree(pipe_config); kfree(saved_mode); return ret; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e6f84d0..eca75b6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -199,6 +199,11 @@ struct intel_connector { struct edid *edid; }; +struct intel_crtc_config { + struct drm_display_mode requested_mode; + struct drm_display_mode adjusted_mode; +}; + struct intel_crtc { struct drm_crtc base; enum pipe pipe; @@ -232,6 +237,8 @@ struct intel_crtc { bool cursor_visible; unsigned int bpp; + struct intel_crtc_config config; + /* We can share PLLs across outputs if the timings match */ struct intel_pch_pll *pch_pll; uint32_t ddi_pll_sel;