From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A25F0C169C4 for ; Wed, 6 Feb 2019 07:10:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6E5C1218A4 for ; Wed, 6 Feb 2019 07:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726194AbfBFHK4 convert rfc822-to-8bit (ORCPT ); Wed, 6 Feb 2019 02:10:56 -0500 Received: from mga02.intel.com ([134.134.136.20]:20773 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726037AbfBFHK4 (ORCPT ); Wed, 6 Feb 2019 02:10:56 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Feb 2019 23:10:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,339,1544515200"; d="scan'208";a="144564134" Received: from itjeshor-mobl1.ger.corp.intel.com (HELO localhost) ([10.252.44.55]) by fmsmga001.fm.intel.com with ESMTP; 05 Feb 2019 23:10:53 -0800 From: Jani Nikula To: Ville Syrjala , intel-gfx@lists.freedesktop.org Cc: Daniel Kamil Kozar , stable@vger.kernel.org Subject: Re: [Intel-gfx] [PATCH -fixes] drm/i915: Try to sanitize bogus DPLL state left over by broken SNB BIOSen In-Reply-To: <20190205141846.6053-1-ville.syrjala@linux.intel.com> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo References: <87y36u73o2.fsf@intel.com> <20190205141846.6053-1-ville.syrjala@linux.intel.com> Date: Wed, 06 Feb 2019 09:11:45 +0200 Message-ID: <87r2cl75n2.fsf@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org On Tue, 05 Feb 2019, Ville Syrjala wrote: > From: Ville Syrjälä > > Certain SNB machines (eg. ASUS K53SV) seem to have a broken BIOS > which misprograms the hardware badly when encountering a suitably > high resolution display. The programmed pipe timings are somewhat > bonkers and the DPLL is totally misprogrammed (P divider == 0). > That will result in atomic commit timeouts as apparently the pipe > is sufficiently stuck to not signal vblank interrupts. > > IIRC something like this was also observed on some other SNB > machine years ago (might have been a Dell XPS 8300) but a BIOS > update cured it. Sadly looks like this was never fixed for the > ASUS K53SV as the latest BIOS (K53SV.320 11/11/2011) is still > broken. > > The quickest way to deal with this seems to be to shut down > the pipe+ports+DPLL. Unfortunately doing this during the > normal sanitization phase isn't quite soon enough as we > already spew several WARNs about the bogus hardware state. > But it's better than hanging the boot for a few dozen seconds. > Since this is limited to a few old machines it doesn't seem > entirely worthwile to try and rework the readout+sanitization > code to handle it more gracefully. > > v2: Fix potential NULL deref (kbuild test robot) > Constify has_bogus_dpll_config() > > Cc: stable@vger.kernel.org # v4.20+ > Cc: Daniel Kamil Kozar > Reported-by: Daniel Kamil Kozar > Tested-by: Daniel Kamil Kozar > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109245 > Fixes: 516a49cc1946 ("drm/i915: Fix assert_plane() warning on bootup with external display") > Signed-off-by: Ville Syrjälä > Link: https://patchwork.freedesktop.org/patch/msgid/20190111174950.10681-1-ville.syrjala@linux.intel.com > Reviewed-by: Mika Kahola > (cherry picked from commit 7bed8adcd9f86231bb69bbc02f88ad89330f99e3) Pushed to drm-intel-fixes, thanks. BR, Jani. > --- > drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++++++++++++++---- > 1 file changed, 44 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 3da9c0f9e948..248128126422 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -15415,16 +15415,45 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc, > } > } > > +static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state) > +{ > + struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); > + > + /* > + * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram > + * the hardware when a high res displays plugged in. DPLL P > + * divider is zero, and the pipe timings are bonkers. We'll > + * try to disable everything in that case. > + * > + * FIXME would be nice to be able to sanitize this state > + * without several WARNs, but for now let's take the easy > + * road. > + */ > + return IS_GEN6(dev_priv) && > + crtc_state->base.active && > + crtc_state->shared_dpll && > + crtc_state->port_clock == 0; > +} > + > static void intel_sanitize_encoder(struct intel_encoder *encoder) > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_connector *connector; > + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); > + struct intel_crtc_state *crtc_state = crtc ? > + to_intel_crtc_state(crtc->base.state) : NULL; > > /* We need to check both for a crtc link (meaning that the > * encoder is active and trying to read from a pipe) and the > * pipe itself being active. */ > - bool has_active_crtc = encoder->base.crtc && > - to_intel_crtc(encoder->base.crtc)->active; > + bool has_active_crtc = crtc_state && > + crtc_state->base.active; > + > + if (crtc_state && has_bogus_dpll_config(crtc_state)) { > + DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n", > + pipe_name(crtc->pipe)); > + has_active_crtc = false; > + } > > connector = intel_encoder_find_connector(encoder); > if (connector && !has_active_crtc) { > @@ -15435,16 +15464,25 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) > /* Connector is active, but has no active pipe. This is > * fallout from our resume register restoring. Disable > * the encoder manually again. */ > - if (encoder->base.crtc) { > - struct drm_crtc_state *crtc_state = encoder->base.crtc->state; > + if (crtc_state) { > + struct drm_encoder *best_encoder; > > DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", > encoder->base.base.id, > encoder->base.name); > + > + /* avoid oopsing in case the hooks consult best_encoder */ > + best_encoder = connector->base.state->best_encoder; > + connector->base.state->best_encoder = &encoder->base; > + > if (encoder->disable) > - encoder->disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state); > + encoder->disable(encoder, crtc_state, > + connector->base.state); > if (encoder->post_disable) > - encoder->post_disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state); > + encoder->post_disable(encoder, crtc_state, > + connector->base.state); > + > + connector->base.state->best_encoder = best_encoder; > } > encoder->base.crtc = NULL; -- Jani Nikula, Intel Open Source Graphics Center