From patchwork Tue Aug 11 14:05:32 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 40663 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7BE5lr9021902 for ; Tue, 11 Aug 2009 14:05:47 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E38FD9EDA2; Tue, 11 Aug 2009 07:05:46 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail.ffwll.ch (cable-static-49-187.intergga.ch [157.161.49.187]) by gabe.freedesktop.org (Postfix) with ESMTP id E95439EDDE for ; Tue, 11 Aug 2009 07:05:43 -0700 (PDT) Received: by mail.ffwll.ch (Postfix, from userid 1000) id 4A43020C219; Tue, 11 Aug 2009 23:59:12 +0200 (CEST) X-Spam-ASN: X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on orange.ffwll.ch X-Spam-Level: X-Spam-Hammy: 0.000-+--H*Ad:D*sourceforge.net, 0.000-+--H*Ad:D*lists.sourceforge.net, 0.000-+--struct X-Spam-Status: No, score=-4.4 required=6.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Spammy: Received: from biene (unknown [192.168.23.129]) by mail.ffwll.ch (Postfix) with ESMTP id 3763320C211; Tue, 11 Aug 2009 23:59:03 +0200 (CEST) Received: from daniel by biene with local (Exim 4.69) (envelope-from ) id 1Marz8-0003cG-9Z; Tue, 11 Aug 2009 16:05:54 +0200 From: Daniel Vetter To: intel-gfx@lists.freedesktop.org Date: Tue, 11 Aug 2009 16:05:32 +0200 Message-Id: <96d19ab778fc7b9ae5c6b94d8f4a83d6bc3609b7.1249997742.git.daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: References: <5434503048fa993f52889b4bc5281b5ebf81847c.1249997742.git.daniel.vetter@ffwll.ch> In-Reply-To: References: Cc: Daniel Vetter , dri-devel@lists.sourceforge.net Subject: [Intel-gfx] [PATCH 4/6] [drm/i915]: require_pipe_a helper functions X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org These will be used to ensure that the clock of pipe a is running when the overlay is switched on. Programming logic more or less directly ported over from userspace. Also export the already existing helper function drm_encoder_crtc_ok. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 3 +- drivers/gpu/drm/i915/intel_display.c | 83 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 5 ++ include/drm/drm_crtc_helper.h | 2 + 4 files changed, 92 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 6aaa2cb..2d837a5 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -511,7 +511,7 @@ static void drm_setup_crtcs(struct drm_device *dev) * * Return false if @encoder can't be driven by @crtc, true otherwise. */ -static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, +bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *crtc) { struct drm_device *dev; @@ -532,6 +532,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, return true; return false; } +EXPORT_SYMBOL(drm_encoder_crtc_ok); /* * Check the CRTC we're going to map each output to vs. its current diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 818c703..cb709b8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2936,6 +2936,89 @@ void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_ } } +/** Ensure that pipe A is enabled. Returns the crtc that runs pipe a or NULL + * if pipe a is already enabled */ +struct drm_crtc *intel_require_pipe_a_start(struct drm_device *dev, + int *dpms_mode) +{ + struct drm_crtc *crtc; + struct intel_crtc *intel_crtc; + struct drm_connector *connector; + struct drm_crtc_helper_funcs *crtc_funcs; + struct intel_output *intel_output; + + crtc = intel_get_crtc_from_pipe(dev, 0); + intel_crtc = to_intel_crtc(crtc); + BUG_ON(intel_crtc->pipe != 0); + + if (crtc->enabled && intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) + return NULL; + + DRM_DEBUG("i915: require PIPEA, switching on crtc ...\n"); + + *dpms_mode = intel_crtc->dpms_mode; + + if (crtc->enabled && intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { + /* just switch it on */ + crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); + + return crtc; + } + + if (!drm_helper_crtc_in_use(crtc)) { + /* look for an encoder/connector */ + list_for_each_entry(connector, + &dev->mode_config.connector_list, head) { + intel_output = to_intel_output(connector); + + if (intel_output->enc.crtc) + /* don't steal connectors */ + continue; + + if (!drm_encoder_crtc_ok(&intel_output->enc, crtc)) + continue; + + intel_output->enc.crtc = crtc; + break; + } + } + + drm_crtc_helper_set_mode(crtc, &load_detect_mode, 0, 0, crtc->fb); + BUG_ON(crtc->enabled); + + return crtc; +} + +void intel_require_pipe_a_end(struct drm_device *dev, + struct drm_crtc *crtc, + int dpms_mode) +{ + struct drm_encoder_helper_funcs *encoder_funcs; + struct drm_encoder *encoder; + struct drm_crtc_helper_funcs *crtc_funcs; + + if (!crtc) + return; + + crtc_funcs = crtc->helper_private; + + DRM_DEBUG("i915: require PIPEA, switching off crtc ...\n"); + + /* Switch crtc and output back off if necessary */ + if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { + list_for_each_entry(encoder, + &dev->mode_config.encoder_list, head) { + if (encoder->crtc != crtc) + continue; + encoder_funcs = encoder->helper_private; + encoder_funcs->dpms(encoder, dpms_mode); + } + + crtc_funcs->dpms(crtc, dpms_mode); + } +} + /* Returns the clock of the currently programmed mode of the given pipe. */ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d6f92ea..f747dd4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -142,6 +142,11 @@ extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_ou int *dpms_mode); extern void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode); +extern struct drm_crtc *intel_require_pipe_a_start(struct drm_device *dev, + int *dpms_mode); +extern void intel_require_pipe_a_end(struct drm_device *dev, + struct drm_crtc *crtc, + int dpms_mode); extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); extern int intel_sdvo_supports_hotplug(struct drm_connector *connector); diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 6769ff6..26c457f 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -123,4 +123,6 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, } extern int drm_helper_resume_force_mode(struct drm_device *dev); +extern bool drm_encoder_crtc_ok(struct drm_encoder *encoder, + struct drm_crtc *crtc); #endif