Hi,
My setup is an embedded GM45 based board with a screen connected via 24 bit LVDS. When trying a to use a newer kernel (3.14.57) with KMS, the screen stays blank. I'm only testing KMS so far, no X. Older, pre-KMS versions of the kernel worked fine.
I'm hoping that a resident Intel DRM guru has an idea of what might be wrong here, or can tell me where to continue troubleshooting :)
I've uploaded a kernel log (drm.debug=0xe) here: http://pastebin.com/nYNRGW5B
The video kernel parameter for this log is: video=LVDS-1:1920x1080. I've tried others, M and/or R suffixes, loading edid/1920x1080.bin etc, but nothing works. I'm not sure if all this EDID timing stuff is even used for LVDS..
One line in the log mentions a mode that is promising:
[ 5.534021] [drm:intel_dump_crtc_timings], crtc timings: 148571 1920 2040 2080 2200 1080 1097 1108 1125, type: 0x0 flags: 0xa
In the BIOS, the panel type is configured as "1920x1080@148.5M", so that looks good. I have no idea where that modeline came from though.
From what I can see, LVDS-1 and CRTC 3 are connected, but when it's time to set the mode, it seems to have been modified into a bogus adjusted mode:
[ 5.570523] [drm:intel_dump_pipe_config], requested mode: [ 5.570525] [drm:drm_mode_debug_printmodeline], Modeline 0:"1920x1080" 0 172780 1920 2040 2248 2576 1080 1081 1084 1118 0x0 0x6 [ 5.570526] [drm:intel_dump_pipe_config], adjusted mode: [ 5.570529] [drm:drm_mode_debug_printmodeline], Modeline 0:"640x480" 0 148571 640 656 752 800 480 490 492 525 0x8 0x0 [ 5.570531] [drm:intel_dump_crtc_timings], crtc timings: 148571 640 656 752 800 480 490 492 525, type: 0x8 flags: 0x0
Also, the dot-clock mentioned in the HD mode is now 172780, for some reason..
All sorts of kernel warnings follow, after this (what is LVDS-6?):
[ 5.570569] [drm:intel_crtc_mode_set], [ENCODER:6:LVDS-6] set [MODE:0:1920x1080]
Please let me know if you'd like more logging or details.
Cheers,
Rob
On Fri, 01 Apr 2016, Rob Kramer rob@solution-space.com wrote:
I'll put it bluntly, I don't think anyone's interested in troubleshooting v3.14 anymore. Please try v4.5.
BR, Jani.
Here's the same issue on a more reasonable kernel. The log looks quite different, but the end result is still a blank screen. Uploaded here: http://pastebin.com/WLpT5mPc
This section looks promising:
[ 4.763951] [drm:intel_dump_pipe_config] requested mode: [ 4.763953] [drm:drm_mode_debug_printmodeline] Modeline 0:"1920x1080" 60 148571 1920 2040 2080 2200 1080 1097 1108 1125 0x40 0xa [ 4.763955] [drm:intel_dump_pipe_config] adjusted mode: [ 4.763958] [drm:drm_mode_debug_printmodeline] Modeline 0:"1920x1080" 60 148571 1920 2040 2080 2200 1080 1097 1108 1125 0x40 0xa [ 4.763961] [drm:intel_dump_crtc_timings] crtc timings: 148571 1920 2040 2080 2200 1080 1097 1108 1125, type: 0x40 flags: 0xa
.. but I don't know how relevant it is. I also have no idea where those timings came from.
Could anyone tell me what I could try next?
Cheers!
Rob
On 04/01/2016 12:49 PM, Rob Kramer wrote:
On Fri, 01 Apr 2016, Rob Kramer rob@solution-space.com wrote:
Apr 1 11:32:21 vides user.err kernel: [ 4.896341] [drm:i9xx_crtc_compute_clock [i915]] *ERROR* Couldn't find PLL settings for mode!
Please try without the kernel command line mode.
BR, Jani.
I've tried again without video parameter -- same outcome. I've also applied Ville's patch "drm/i915: Read timings from the correct transcoder in intel_crtc_mode_get()" (with teeny backport fix). It seems this code is never called in my case though, since intel_lvds_init() chooses to use the VBT mode instead. Log is uploaded here: http://pastebin.com/bGa2UvLu
Since this VBT mode is probably junk anyway, I commented out the if-statement that selects it (in intel_lvds.c), so that the code will pick the mode as set by BIOS. The result is much better, I actually get proper looking output! X also runs well on top of that.
There are still several errors in the log file though (probably caused by my little hack), see here: http://pastebin.com/UbCjizSV.
Is using the mode as set up by BIOS the way to go for LVDS? If so, is there a module parameter that can force this, or force the bogus VBT to be disregarded?
Cheers!
Rob
On 04/01/2016 07:11 PM, Jani Nikula wrote:
On Mon, Apr 04, 2016 at 11:14:45AM +0800, Rob Kramer wrote:
That's a bit odd. The 3.14 kernel definitely chose to use the current pipe timings instead of the VBT mode: [ 5.504033] [drm:intel_lvds_init], using current (BIOS) mode: [ 5.504037] [drm:drm_mode_debug_printmodeline], Modeline 0:"640x480" 0 148571 640 656 752 800 480 490 492 525 0x0 0x0
Although it looks like it did find a mode in the VBT as well: [ 5.502056] [drm:parse_lfp_panel_data], Found panel mode in BIOS VBT tables: [ 5.502060] [drm:drm_mode_debug_printmodeline], Modeline 0:"1024x768" 0 65000 1024 1048 1184 1344 768 771 777 806 0x8 0xa so now I'm rather confused as to how it managed to not use it.
Can you provide a dump of /sys/kernel/debug/dri/0/i915_opregion ?
Maybe file a bug in bugs.freedesktop.org and attach it (and the dmesg logs you already have) there so we don't lose these.
You also said you can choose the panel type in the BIOS? Does it have some predefined set of panels or something? I would have assumed changing that might patch the VBT to point at the correct timings.
On 04/04/2016 10:58 PM, Ville Syrjälä wrote:
Sure! I added the opregion blob to the newly opened bug here: https://bugs.freedesktop.org/show_bug.cgi?id=94825
Yes, there's a list of modes, and the correct one is selected. I've added an image to the bug entry. I don't know if the 1024x768 mode mentioned in the boot log is the same as the 1024x768 mode in that bios list, or why only that mode is found..
I assume that the 1920x1080@148.5M mode was added by the vendor of the display set to match the panel that they use.
Cheers,
Rob
From: Ville Syrjälä ville.syrjala@linux.intel.com
intel_crtc->config->cpu_transcoder isn't yet filled out when intel_crtc_mode_get() gets called during output probing, so we should not use it there. Instead intel_crtc_mode_get() figures out the correct transcoder on its own, and that's what we should use.
If the BIOS boots LVDS on pipe B, intel_crtc_mode_get() would actually end up reading the timings from pipe A instead (since PIPE_A==0), which clearly isn't what we want.
It looks to me like this may have been broken by commit eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") as that one removed the early initialization of cpu_transcoder from intel_crtc_init().
Cc: stable@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer rob@solution-space.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Reported-by: Rob Kramer rob@solution-space.com Fixes: eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") References: https://lists.freedesktop.org/archives/dri-devel/2016-April/104142.html Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e6b5ee51739b..b6f974dd43c9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10719,13 +10719,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; + enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - int htot = I915_READ(HTOTAL(cpu_transcoder)); - int hsync = I915_READ(HSYNC(cpu_transcoder)); - int vtot = I915_READ(VTOTAL(cpu_transcoder)); - int vsync = I915_READ(VSYNC(cpu_transcoder)); + u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10753,6 +10750,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, i9xx_crtc_clock_get(intel_crtc, pipe_config);
mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; + + cpu_transcoder = pipe_config->cpu_transcoder; + htot = I915_READ(HTOTAL(cpu_transcoder)); + hsync = I915_READ(HSYNC(cpu_transcoder)); + vtot = I915_READ(VTOTAL(cpu_transcoder)); + vsync = I915_READ(VSYNC(cpu_transcoder)); + mode->hdisplay = (htot & 0xffff) + 1; mode->htotal = ((htot & 0xffff0000) >> 16) + 1; mode->hsync_start = (hsync & 0xffff) + 1;
From: Ville Syrjälä ville.syrjala@linux.intel.com
Eliminate the duplicate code for pipe timing readout in intel_crtc_mode_get() by using the functions we use for the normal state readout.
Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer rob@solution-space.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b6f974dd43c9..9d3752accaa5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10719,10 +10719,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10749,24 +10747,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); i9xx_crtc_clock_get(intel_crtc, pipe_config);
- mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; - - cpu_transcoder = pipe_config->cpu_transcoder; - htot = I915_READ(HTOTAL(cpu_transcoder)); - hsync = I915_READ(HSYNC(cpu_transcoder)); - vtot = I915_READ(VTOTAL(cpu_transcoder)); - vsync = I915_READ(VSYNC(cpu_transcoder)); + mode->crtc_clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
- mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; + intel_get_pipe_timings(intel_crtc, pipe_config);
- drm_mode_set_name(mode); + intel_mode_from_pipe_config(mode, pipe_config);
kfree(pipe_config);
From: Ville Syrjälä ville.syrjala@linux.intel.com
Eliminate the duplicate code for pipe timing readout in intel_crtc_mode_get() by using the functions we use for the normal state readout.
v2: Store dotclock in adjusted_mode instead of the final mode
Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer rob@solution-space.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b6f974dd43c9..f42073837204 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10719,10 +10719,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10749,24 +10747,12 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); i9xx_crtc_clock_get(intel_crtc, pipe_config);
- mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; - - cpu_transcoder = pipe_config->cpu_transcoder; - htot = I915_READ(HTOTAL(cpu_transcoder)); - hsync = I915_READ(HSYNC(cpu_transcoder)); - vtot = I915_READ(VTOTAL(cpu_transcoder)); - vsync = I915_READ(VSYNC(cpu_transcoder)); + pipe_config->base.adjusted_mode.crtc_clock = + pipe_config->port_clock / pipe_config->pixel_multiplier;
- mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; + intel_get_pipe_timings(intel_crtc, pipe_config);
- drm_mode_set_name(mode); + intel_mode_from_pipe_config(mode, pipe_config);
kfree(pipe_config);
On Fri, Apr 01, 2016 at 09:48:50PM +0300, ville.syrjala@linux.intel.com wrote:
I also forgot to point out here that this should fix mode.flags readout for intel_crtc_mode_get(). Previously it just left tha t as 0.
Quoting ville.syrjala@linux.intel.com (2016-04-01 19:48:50)
Reviewed-by: Chris Wilson chris@chris-wilson.co.uk
Fixes a pipe-state warn for me, Tested-by: Chris Wilson chris@chris-wilson.co.uk -Chris
On Mon, Sep 25, 2017 at 08:19:12PM +0100, Chris Wilson wrote:
Thanks for the review. Patches pushed to dinq.
Fixes a pipe-state warn for me, Tested-by: Chris Wilson chris@chris-wilson.co.uk
However, now that I look at the code again I'm not 100% sure why this fixed anything. The readout still seems to fail at fully populating the mode flags. I'll post a more thorough solution that simply calls the normal state readout hooks for the crtc and encoder...
Quoting Ville Syrjälä (2017-10-09 17:18:17)
The first patch fixed up the implied A,B transcoder mixup. I just tested both patches together. Do you want me to double check if it was just the first patch that silenced the warnings? I'm just happy to have a clean boot! -Chris
On Mon, Oct 09, 2017 at 05:24:29PM +0100, Chris Wilson wrote:
I think the first patch should have been a nop for you since 845g only has the one pipe.
Quoting ville.syrjala@linux.intel.com (2016-04-01 16:37:25)
Matches the writing on the tin. The effect is to s/intel_crtc->config->cpu_transcoder/intel_crtc->pipe/ and aiui, the dvo path will call this before intel_crtc->config->cpu_transcoder is ever set.
Reviewed-by: Chris Wilson chris@chris-wilson.co.uk -Chris
dri-devel@lists.freedesktop.org