Patch "drm/i915/ilk: Don't disable SSC source if it's in use" has been added to the 3.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
drm/i915/ilk: Don't disable SSC source if it's in use
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-i915-ilk-don-t-disable-ssc-source-if-it-s-in-use.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
476490a945e1f0f6bd58e303058d2d8ca93a974cMon Sep 17 00:00:00 2001
From: Lyude <[email protected]>
Date: Tue, 14 Jun 2016 11:04:09 -0400
Subject: drm/i915/ilk: Don't disable SSC source if it's in use
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Lyude <[email protected]>
commit 476490a945e1f0f6bd58e303058d2d8ca93a974c upstream.
Thanks to Ville Syrjälä for pointing me towards the cause of this issue.
Unfortunately one of the sideaffects of having the refclk for a DPLL set to SSC is that as long as it's set to SSC, the GPU will prevent us from powering down any of the pipes or transcoders using it. A couple of BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL configurations. This causes issues on the first modeset, since we don't expect SSC to be left on and as a result, can't successfully power down the pipes or the transcoders using it. Here's an example from this Dell OptiPlex 990:
[drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled [drm:intel_modeset_init] 2 display pipes available.
[drm:intel_update_cdclk] Current CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz [drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz
vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem [drm:intel_crt_reset] crt adpa set to 0xf40000
[drm:intel_dp_init_connector] Adding DP connector on port C
[drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1 [drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0 [drm:ironlake_init_pch_refclk] Disabling SSC entirely
… later we try committing the first modeset …
[drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A [drm:intel_dump_pipe_config] cpu_transcoder: A
…
[drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07 [drm:intel_dump_pipe_config] planes on this crtc
[drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled
[drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258
[drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600
[drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0 [drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0 [drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A
[drm:intel_get_shared_dpll] using PCH DPLL A for pipe A
[drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A [drm:intel_disable_pipe] disabling pipe A
------------[ cut here ]------------ WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915] pipe_off wait timed out … ---[ end trace 94fc8aa03ae139e8 ]---
[drm:intel_dp_link_down]
[drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A
Later modesets succeed since they reset the DPLL's configuration anyway, but this is enough to get stuck with a big fat warning in dmesg.
A better solution would be to add refcounts for the SSC source, but for now leaving the source clock on should suffice.
Changes since v4:
- Fix calculation of final for systems with LVDS panels (fixes BUG() on CI test suite)
Changes since v3:
- Move temp variable into loop
- Move checks for using_ssc_source to after we've figured out has_ck505
- Add using_ssc_source to debug output
Changes since v2:
- Fix debug output for when we disable the CPU source
Changes since v1:
- Leave the SSC source clock on instead of just shutting it off on all of the DPLL configurations.
--- drivers/gpu/drm/i915/intel_display.c | 48 ++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 14 deletions(-)
drivers/gpu/drm/i915/intel_display.c +34 -14
@@ -5590,12 +5590,14 @@ static void ironlake_init_pch_refclk(strstruct drm_i915_private *dev_priv = dev->dev_private;struct drm_mode_config *mode_config = &dev->mode_config;struct intel_encoder *encoder; +int i;u32 val, final;bool has_lvds = false;bool has_cpu_edp = false;bool has_panel = false;bool has_ck505 = false;bool can_ssc = false; +bool using_ssc_source = false;/* We need to take the global config into account */ list_for_each_entry(encoder, &mode_config->encoder_list,
@@ -5621,8 +5623,22 @@ static void ironlake_init_pch_refclk(str can_ssc = true; } -DRM_DEBUG_KMS ("has_panel %d has_lvds %d has_ck505 %d\n" , - has_panel, has_lvds, has_ck505); +/* Check if any DPLLs are using the SSC source */ +for (i =0 ; i < dev_priv->num_shared_dpll; i++) { +u32 temp =I915_READ (PCH_DPLL (i)); + +if (!(temp &DPLL_VCO_ENABLE )) +continue ; + +if ((temp &PLL_REF_INPUT_MASK ) == +PLLB_REF_INPUT_SPREADSPECTRUMIN ) { + using_ssc_source = true; +break ; + } + } + +DRM_DEBUG_KMS ("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n" , + has_panel, has_lvds, has_ck505, using_ssc_source);/* Ironlake: try to setup display ref clock before DPLL * enabling. This is only under driver's control after
@@ -5659,9 +5675,9 @@ static void ironlake_init_pch_refclk(str final |=DREF_CPU_SOURCE_OUTPUT_NONSPREAD ; }else final |=DREF_CPU_SOURCE_OUTPUT_DISABLE ; - }else { - final |=DREF_SSC_SOURCE_DISABLE ; - final |=DREF_CPU_SOURCE_OUTPUT_DISABLE ; + }else if (using_ssc_source) { + final |=DREF_SSC_SOURCE_ENABLE ; + final |=DREF_SSC1_ENABLE ; }if (final == val)
@@ -5708,7 +5724,7 @@ static void ironlake_init_pch_refclk(strPOSTING_READ (PCH_DREF_CONTROL );udelay (200 ); }else { -DRM_DEBUG_KMS ("Disabling SSC entirely\n" ); +DRM_DEBUG_KMS ("Disabling CPU source output\n" ); val &= ~DREF_CPU_SOURCE_OUTPUT_MASK ;
@@ -5719,16 +5735,20 @@ static void ironlake_init_pch_refclk(strPOSTING_READ (PCH_DREF_CONTROL );udelay (200 ); -/* Turn off the SSC source */ - val &= ~DREF_SSC_SOURCE_MASK ; - val |=DREF_SSC_SOURCE_DISABLE ; +if (!using_ssc_source) { +DRM_DEBUG_KMS ("Disabling SSC source\n" ); -/* Turn off SSC1 */ - val &= ~DREF_SSC1_ENABLE ; +/* Turn off the SSC source */ + val &= ~DREF_SSC_SOURCE_MASK ; + val |=DREF_SSC_SOURCE_DISABLE ; -I915_WRITE (PCH_DREF_CONTROL , val); -POSTING_READ (PCH_DREF_CONTROL ); -udelay (200 ); +/* Turn off SSC1 */ + val &= ~DREF_SSC1_ENABLE ; + +I915_WRITE (PCH_DREF_CONTROL , val); +POSTING_READ (PCH_DREF_CONTROL ); +udelay (200 ); + } }BUG_ON (val != final);
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/drm-i915-ilk-don-t-disable-ssc-source-if-it-s-in-use.patch