From patchwork Mon Nov 12 16:59:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10678971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1690918F0 for ; Mon, 12 Nov 2018 17:00:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B829429FC2 for ; Mon, 12 Nov 2018 17:00:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ACB2E29FEC; Mon, 12 Nov 2018 17:00:16 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 420AD29FC2 for ; Mon, 12 Nov 2018 17:00:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 93FBE6E026; Mon, 12 Nov 2018 17:00:14 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id 928366E022; Mon, 12 Nov 2018 17:00:11 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Nov 2018 09:00:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,495,1534834800"; d="scan'208";a="107433098" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga001.fm.intel.com with SMTP; 12 Nov 2018 09:00:08 -0800 Received: by stinkbox (sSMTP sendmail emulation); Mon, 12 Nov 2018 19:00:07 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Mon, 12 Nov 2018 18:59:46 +0200 Message-Id: <20181112170000.27531-3-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20181112170000.27531-1-ville.syrjala@linux.intel.com> References: <20181112170000.27531-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 02/15] drm/i915: Don't try to use the hardware frame counter with i965gm TV output X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stable@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä On i965gm the hardware frame counter does not work when the TV encoder is active. So let's not try to consult the hardware frame counter in that case. Instead we'll fall back to the timestamp based guesstimation method used on gen2. Note that the pipe timings generated by the TV encoder are also rather peculiar. Apparently the pipe wants to run at a much higher speed (related to the oversample clock somehow it seems) but during the vertical active period the TV encoder stalls the pipe every few lines to keep its speed in check. But once the vertical blanking period is reached the pipe gets to run at full speed. This means our vblank timestamp estimates are suspect. Fixing all that would require quite a bit more work. This simple fix at least avoids the nasty vblank timeouts that are happening currently. Curiously the frame counter works just fine on i945gm and gm45. I don't really understand what kind of mishap occurred with the hardware design on i965gm. Sadly I wasn't able to find any chicken bits etc. that would fix the frame counter :( Cc: stable@vger.kernel.org Fixes: 51e31d49c890 ("drm/i915: Use generic vblank wait") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93782 Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_irq.c | 10 ++++++- drivers/gpu/drm/i915/intel_display.c | 40 +++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d447d7d508f4..019cb685986c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4843,8 +4843,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->driver->get_vblank_counter = g4x_get_vblank_counter; } else { + /* + * On i965gm the hardware frame counter reads zero + * when the TV encoder is used. Hence we configure + * max_vblank_count dynamically for each crtc. + */ + if (IS_I965GM(dev_priv)) + dev->max_vblank_count = 0; + else + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ dev->driver->get_vblank_counter = i915_get_vblank_counter; - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ } /* diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 940577f8c041..2dccb3310ad2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5504,6 +5504,32 @@ static void intel_encoders_post_pll_disable(struct drm_crtc *crtc, } } +static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); + u32 max_vblank_count = dev_priv->drm.max_vblank_count; + + /* + * On i965gm the hardware frame counter always + * reads zero when the TV encoder is used :( + * Otherwise we get the 24 bit frame counter. + */ + if (IS_I965GM(dev_priv) && + (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT)) == 0) + max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + + return max_vblank_count; +} + +static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + + drm_crtc_set_max_vblank_count(&crtc->base, + intel_crtc_max_vblank_count(crtc_state)); + drm_crtc_vblank_on(&crtc->base); +} + static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config, struct drm_atomic_state *old_state) { @@ -5577,7 +5603,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config, ironlake_pch_enable(old_intel_state, pipe_config); assert_vblank_disabled(crtc); - drm_crtc_vblank_on(crtc); + intel_crtc_vblank_on(pipe_config); intel_encoders_enable(crtc, pipe_config, old_state); @@ -5734,7 +5760,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, intel_ddi_set_vc_payload_alloc(pipe_config, true); assert_vblank_disabled(crtc); - drm_crtc_vblank_on(crtc); + intel_crtc_vblank_on(pipe_config); intel_encoders_enable(crtc, pipe_config, old_state); @@ -6074,7 +6100,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config, intel_enable_pipe(pipe_config); assert_vblank_disabled(crtc); - drm_crtc_vblank_on(crtc); + intel_crtc_vblank_on(pipe_config); intel_encoders_enable(crtc, pipe_config, old_state); } @@ -6133,7 +6159,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config, intel_enable_pipe(pipe_config); assert_vblank_disabled(crtc); - drm_crtc_vblank_on(crtc); + intel_crtc_vblank_on(pipe_config); intel_encoders_enable(crtc, pipe_config, old_state); } @@ -15752,10 +15778,12 @@ intel_modeset_setup_hw_state(struct drm_device *dev, * waits, so we need vblank interrupts restored beforehand. */ for_each_intel_crtc(&dev_priv->drm, crtc) { + crtc_state = to_intel_crtc_state(crtc->base.state); + drm_crtc_vblank_reset(&crtc->base); - if (crtc->base.state->active) - drm_crtc_vblank_on(&crtc->base); + if (crtc_state->base.active) + intel_crtc_vblank_on(crtc_state); } intel_sanitize_plane_mapping(dev_priv);