Bug 28951

Summary: [Arrandale] Hard hang when undocking Thinkpad x201 with the LVDS on
Product: xorg Reporter: Olivier Crête <olivier.crete>
Component: Driver/intelAssignee: Carl Worth <cworth>
Status: VERIFIED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: ajax
Version: unspecifiedKeywords: NEEDINFO
Hardware: x86-64 (AMD64)   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Olivier Crête 2010-07-07 13:35:20 UTC
Using Fedora 13, when I try to undock only when the LVDS is on. If the LVDS is of (like if I stop it manually with xrandr or close the lid), then it works fine. It also works fine I just I plug/unplug the VGA cable directly from the laptop. It seems to only fail when undocking.

Ajax identified the freeze to be in intel_lvds_set_power(), after applying this patch (http://ajax.fedorapeople.org/patches/drm-i915-lvds-dpms-debug.patch) and fixing it, I get:

[drm:intel_lvds_set_power] *ERROR* lvds on timed out, control 00000003 status 0000000a
[drm:intel_lvds_set_power] *ERROR* on_delay 00fa09c4 off_delay 00fa09c4 divisor 00186903

Ajax also asked for the output of "intel_reg_snapshot", you can get it from http://people.collabora.co.uk/~tester/snap

Relevant package versions:
xorg-x11-drv-intel-2.11.0-5.fc13.x86_64
kernel-2.6.33.5-112.fc13.x86_64
xorg-x11-server-Xorg-1.8.0-17.fc13.x86_64
Comment 1 Chris Wilson 2010-08-09 06:42:33 UTC
Looks like PP_STATUS was reporting not ready when we attempted to turn on the panel, which implies that the programming was incomplete.

With anholt/drm-intel-next and my x201s undocking with LVDS/DP1 on/on, off/on, on/off seems to work fine and doesn't generate any warnings.

Can you either try a git clone of drm-intel-next, or a testing kernel when the current intel tree hits upstream?
Comment 2 Olivier Crête 2010-08-26 09:56:04 UTC
Using drm-next as of today (76be97c1), copying the .config file from F13 and doing make oldconfig and leaving everything new as default. The screen gets messed up right after grub (and I have an encrypted root, so I need the screen to boot).

Btw, did you try with a dock? It works fine in every case I've tried except undocking.
Comment 3 Chris Wilson 2010-09-06 10:13:21 UTC
Hmm, if you can test http://cgit.freedesktop.org/~ickle/drm-intel/log/?h=drm-intel-staging that would ideal. This x201s is quite happy either booting docked or undocked and attaching a DP monitor at will.
Comment 4 ncgvyhufdvvduk 2010-09-08 12:16:42 UTC
ppl,

This is really very interesting bug!

Spend few days to research this issue and found some ways to fix it.

My problem comes every time after external display used (tested with VGA1 output, not tested hdmi/dp).

After disconnecting external (or even with xrandr --off) the garbage coming to internal display!
Only mouse cursor is working and only one way to back internal picture is enable external display again and using both.

2.6.32.21-1 (old lts-kernel of archlinux) works fine without this problem.

2.6.35.4-1 (current) and 2.6.36-rc3 (even with 2.6.36-rc3-git1 snapshot) making the problem.

I found how to fix it with BIOS "CPU power management" = DISABLED but it adds 4-5 Watts of power usage (C-states disabled)...

Some magic: even when CPU power management is enabled just run "cat /dev/urandom >/dev/null" solves the problem!
So when CPU is loaded (even 1 core only) internal/external displays may be enabled/disabled without problems.

Finally if you need internal and external (via dockstation too) displays SEPARATELY there is better way I'm using now:

1) always start laptop without external display connected (just start it out of dock)

2) I'm using openbox so maybe you need to disable gnome/kde management of external displays (don't sure how)

3) add this line to /etc/acpi/handler.sh (calls lid-handler script every time when lid open/closed):

if [ "$1" == "button/lid" ]; then /etc/acpi/lid-handler; fi

4) make /etc/acpi/lid-handler shell script (maybe need to enable sleep and change LVDS1/VGA1, just run xrands to see details):

#!/bin/bash

export DISPLAY=:0.0

if grep -q closed /proc/acpi/button/lid/LID/state
then
# BAD (first need off then enable) xrandr --output LVDS1 --off --output VGA1 --auto
    xrandr --output LVDS1 --off
#   sleep 1
    xrandr --output VGA1 --auto
else
    xrandr --output VGA1 --off
#   sleep 1
    xrandr --output LVDS1 --auto
fi
Comment 5 ncgvyhufdvvduk 2010-09-09 12:44:54 UTC
today tested my /etc/acpi/lid-handler script with DisplayPort (DP1) output
it requires uncommented "sleep 1" delay between disconnect/connect
and works great
Comment 6 ncgvyhufdvvduk 2010-09-09 13:49:39 UTC
new issue with DP1 output...

seems docking must be always with open lid to prevent "blind" switching to DP1 before it's really connected

when docking with open lid, my script works ok and garbage-bug never happens (even without sleep in script)

today i'll try to improve script and post new results
Comment 7 ncgvyhufdvvduk 2010-09-09 15:18:10 UTC
Finally to fight this bug: more than one display must be never enabled at same time!

Workaround tested on thinkpad x201 with 2.6.35.4-1 (x86) with external vga and dockstation vga and displayport. Only one thing need to remember: you must start kernel and Xorg without external display.

Now I can flip internal/external display anytime and dock/undock laptop with open or closed lid anytime!

Seems all works beautiful but need more testings...

Changes:

1) catch lid and thinkpad dock/undock acpi events (small sleep need to identify external display before xrandr); add this lines to /etc/acpi/handler.sh:

if [ "$1" == "button/lid" ]; then /etc/acpi/lid-handler; fi
if [ "$1" == "ibm/hotkey" -a "$4" == "00006030" ]; then sleep 1; /etc/acpi/lid-handler; fi

2) /etc/acpi/lid-handler rewritten: now it auto detect names of internal/external display and fixed dock/undock with any case of lid open/closed

#!/bin/bash

export DISPLAY=:0.0

internal=`xrandr|grep -v disconnected|grep connected|grep LVDS|awk '{print $1}'`
external=`xrandr|grep -v disconnected|grep connected|grep -v LVDS|tail -1|awk '{print $1}'`

if grep -q closed /proc/acpi/button/lid/LID/state
then
    # lid is closed - take action only when external is connected - disable internal and enable external
    test -n "$external" && (xrandr --output $internal --off; xrandr --output $external --auto)
else
    # open: it is unknown which external was connected so disable all externals and enable internal
    xrandr|grep connected|grep -v LVDS|awk '{print $1}'|xargs -r -I@ -n1 xrandr --output @ --off
    xrandr --output $internal --auto
fi
Comment 8 Chris Wilson 2010-09-11 01:33:07 UTC
The first bug resolved through the bound waits and fixing the underlying bugs.

The second issue though we haven't fixed, just disabled the self-refresh that was causing the failure. [bug 30126]
Comment 9 Olivier Crête 2010-11-05 17:25:09 UTC
Seems to works with with whatever is in Fedora 14

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.