Bug 5155

Summary: no LCD video after lid close-open-cycle- Dell Inspiron 6000, 640m
Product: ACPI Reporter: Remko Bijker (bijker007)
Component: Power-VideoAssignee: Zhang Rui (rui.zhang)
Status: REJECTED WILL_NOT_FIX    
Severity: normal CC: acpi-bugzilla, david.bonnafous, dsd, Matt_Domsch, protasnb
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.13, 2.6.8 and 2.6.12-rc6-mm2 Subsystem:
Regression: --- Bisected commit-id:
Attachments: acpidump for inspiron 640m
dmidecode for inspiron 640m

Description Remko Bijker 2005-08-30 06:30:21 UTC
Most recent kernel where this bug did not occur: got no clue yet

Distribution: Debian Unstable with vanilla kernel

Hardware Environment: Dell Inspiron 6000, see appendix 1, BIOS version A07, ACPI
DSDT (acpidump), see appendix 3

Software Environment: gcc 4.0.2 20050821 (prerelease), 955resolution, i8kmon,
ipw2200 1.0.6 (as module), ieee80211 1.0.3 (from ieee80211.sf.net), kernel
config, see appendix 2

Problem Description:
When booting the kernel without acpi disabled, i.e. no 'acpi=off' or not
compiling ACPI into the kernel at all, the screen does not come back after the
lid has been closed. The laptop is however not completly crashed, as it can
still be rebooted by CTRL-ALT-DELETE and accessed by SSH. The lid state
furthermore is correctly updated in /proc/acpi/button/lid/LID/state.

With acpi disabled, i.e. 'acpi=off' or not compiling it, it works correctly;
close lid -> screen out, open lid -> screen on. This also works in grub, so I
think it is the BIOS (or at least the hardware) itself which disables and
enables the screen. I can however not disable it in the BIOS.
The only drawback of the disabling of ACPI is the fact that cpu frequency
scaling does not work for me.

Steps to reproduce:
  - boot without 'acpi=pff'
  - close lid
  - open lid


Appendices:
(could not embed them, max of about 65000 characters)
[1] lspci:
http://rubidium.student.utwente.nl/kernel/lspci

[2] .config:
http://rubidium.student.utwente.nl/kernel/config

[3] acpidump:
http://rubidium.student.utwente.nl/kernel/acpi_dump

[3] dmesg:
http://rubidium.student.utwente.nl/kernel/dmesg
Comment 1 Remko Bijker 2005-08-31 06:51:29 UTC
Also 2.6.3 shows the same problems. 
I tried 2.4(.31) but could not get it to boot properly.
Using 'noacpi', 'noapic', 'nolapic' and 'noapm' alone and in _any_ combination
did not solve the problem. (Only 'acpi=off' does)
Comment 2 Remko Bijker 2005-08-31 12:13:12 UTC
Forgot dmidecode and interrupts, so here they are:
http://rubidium.student.utwente.nl/kernel/dmidecode

http://rubidium.student.utwente.nl/kernel/interrupts
Comment 3 Len Brown 2005-08-31 19:13:01 UTC
If you poke the LID button a few times does it wake up the LCD?

It is likely that this is a BIOS issue because Linux/ACPI doesn't
do anything with LID events except pass them along to user-space
(which may be configured via acpid.conf to suspend or something)

Please verify you are running the latest BIOS for this box.

Is it possible to run Windows on this box and tell it to take
no action on LID events and see if it has the same issue?
Comment 4 Remko Bijker 2005-09-01 11:27:46 UTC
There is no accessible LID button, i.e. it is somehow integrated in the hinge.
Opening and closing the screen several times (slow or fast) does not bring the
screen back.

No userspace acpi daemons/handlers are running (only kacpid).
The disabling and enabling of the screen is, as far as I can figure out, done by
the BIOS or something else, which is very low-level. This because the screen is
disabled when closing the lid in grub (and enabled when you open it). It
furthermore works correctly when ACPI is completly disabled, i.e. 'acpi=off' or
CONFIG_ACPI=n.
This is the reason why I think it has something to do with the ACPI handling in
Linux. Can it be something in the DSDT [1,2]? The disassembled DSDT gives 7
compile warnings [3], but, as far as I (=google) found out, those warnings do
not really matter. Do you agree?
I have run a kernel (2.6.13) with the DSDT generated by iasl included
(CONFIG_ACPI_CUSTOM_DSDT=y and
CONFIG_ACPI_CUSTOM_DSDT_FILE="/usr/src/acpi/dsdt.hex"), but that did not solve
the problem

I have tried it with the newest version and a somewhat older version because I
found out that some people had problems with newer version. It does, however,
not solve the problem.

Got no Windows installed on this machine, so I can not change the settings.


[1]: /proc/acpi/dsdt
http://rubidium.student.utwente.nl/kernel/dsdt.dat

[2]: dsdt.dsl
http://rubidium.student.utwente.nl/kernel/dsdt.dsl

[3]: output of 'iasl -tc dsdt.dsl'
http://rubidium.student.utwente.nl/kernel/iasl-run
Comment 5 Remko Bijker 2005-09-02 15:37:22 UTC
I have captured the button events sent to the OS (in
button.c:acpi_button_notify). This showed me that an event is generated for
every LID open and LID close.

When I install/use acpid and configure it, so it sets DOMS on when the lid it
opened, it works correctly.
Note that I do not do/have configured _anything_ when the lid is closed, i.e.
the screen is placed in DPMS off by the computer itself (as far as I can tell).

This leaves me (again) by the 'bug' I see: screen is automatically turned off,
but not back again.

When I (try) to read the disassembled DSDT, I see some references to different
OS Interfaces (OSI), i.e. different codepaths are run for difference (Windows)
OSes. But I can not really comprehend (yet), what is precisely done on LID
close/open. 

I have a few possible suspects, but do not have a real proof (have read/browsed
through some ACPI specs, manuals and presentations):
- a Windows OS (well all OSes handled explictly by the DSDT are Windows) is
'impersonated', so it does not turn the screen on, as it expects/assumes that
Windows does it. (Could not really find which OS string is passed to the DSDT)
- the lid routines are somehow (for a part, i.e. the 'disable' part) in a legacy
mode (the mode when ACPI  turned off)

Any suggestions/ideas to (dis)prove any of my suspects?
Comment 6 Len Brown 2005-09-14 22:31:37 UTC
Yes, I guess if it works with "acpi=off", then there must
be an ACPI bug in there somewhere.

> When I install/use acpid and configure it,
> so it sets DOMS on when the lid it
> opened, it works correctly.

So you got this working?
What is DOMS, and what exactly did you have acpid do to it?

Poking at the DSDT...

Nothing special in the LID device -- curious that _LID is
not referenced:

        Device (LID)
        {
            Name (_HID, EisaId ("PNP0C0D"))
            Method (_LID, 0, NotSerialized)
            {
                Store (SMI (0x84, 0x00), Local0)
                Return (Local0)
            }

            Name (_PRW, Package (0x02)
            {
                0x1C,
                0x03
            })
            Method (_PSW, 1, NotSerialized)
            {
                PSW (Arg0, 0x02)
            }
        }

Here's the method that notifies the LID device:

    Method (LIDE, 0, NotSerialized)
    {
        Store (SMI (0x43, 0x00), Local0)
        If (LAnd (LNot (LEqual (Local0, 0x00)), LNot (LEqual (Local0, 0x0F))))
        {
            Store (SMI (0x6D, 0x00), Local0)
            If (LEqual (Local0, 0x03))
            {
                If (LEqual (OSID (), 0x10))
                {
                    Notify (\_SB.PCI0, 0x00)
                    Sleep (0x03E8)
                }
                Else
                {
                    If (LEqual (OSID (), 0x08))
                    {
                        Notify (\_SB.PCI0.VID, 0x00)
                        Notify (\_SB.PCI0.VID2, 0x00)
                        Sleep (0x02EE)
                    }
                }

                Notify (\_SB.PCI0.VID, 0x80)
                Notify (\_SB.PCI0.AGP.VID, 0x80)
            }
        }

        Notify (\_SB.LID, 0x80)
    }

Several things are interesting here.
Yes, OSID is a dependency on _OSI and _OS

    Method (OSID, 0, NotSerialized)
    {
        If (LEqual (MIS3, 0x00))
        {
            Store (0x01, MIS3)
            If (CondRefOf (\_OSI, Local0))
            {
                If (\_OSI (WXP))
                {
                    Store (0x10, MIS3)
                }
            }
            Else
            {
                If (STRE (\_OS, W98S))
                {
                    Store (0x02, MIS3)
                }

                If (STRE (\_OS, NT5S))
                {
                    Store (0x08, MIS3)
                }

                If (STRE (\_OS, WINM))
                {
                    Store (0x04, MIS3)
                }
            }
        }

        Return (MIS3)
    }

You can experiment with these a bit.
This code ignores _OS unless _OSI fails to include
    Name (WXP, "Windows 2001")

Linux include it:
/*
 * Strings supported by the _OSI predefined (internal) method.
 * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
 */
const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
        /* Operating System Vendor Strings */

        "Linux",
        "Windows 2000",
        "Windows 2001",
        "Windows 2001.1",
        "Windows 2001 SP0",
        "Windows 2001 SP1",
        "Windows 2001 SP2",
        "Windows 2001 SP3",
        "Windows 2001 SP4",

        /* Feature Group Strings */

        "Extended Address Space Descriptor"
};

But you can disable _OSI entirely in Linux by booting with
"acpi_osi=" -- and confirm it worked by finding this
string in dmesg: "ACPI: _OSI method disabled"

doing so will cause the code to not do this:

                    Notify (\_SB.PCI0, 0x00)
                    Sleep (0x03E8)

I don't know what that notify on PCI0 is for...
Then you enter the code where _OS is used.
The default _OS for Linux is:

#define ACPI_OS_NAME                    "Microsoft Windows NT"

You can modify it at boot time this way
acpi_os_name="my os name"

But it looks like the code above will do the same thing
for all of these choices:
    Name (W98S, "Microsoft Windows")
    Name (NT5S, "Microsoft Windows NT")
    Name (WINM, "Microsoft WindowsME: Millennium Edition")
ie. it will execute this:

                    If (LEqual (OSID (), 0x08))
                    {
                        Notify (\_SB.PCI0.VID, 0x00)
                        Notify (\_SB.PCI0.VID2, 0x00)
                        Sleep (0x02EE)
                    }

I don't know what these notifies on the video device are for.

Then it will do this:
                Notify (\_SB.PCI0.VID, 0x80)
                Notify (\_SB.PCI0.AGP.VID, 0x80)
again, notifies on the video device "shouldn't" have an effect here.
And finally we get our LID changed notification:

        Notify (\_SB.LID, 0x80)

Which will go to drivers/acpi/button.c -- but all it does is
turn around and send an event string to /proc/acpi/event.

If there were some magic tickling of registers in the
AML code path that Windows is able to provoke, it would
explain what happens there, but it isn't obvious from above
that the issue is in the DSDT.

Comment 7 Remko Bijker 2005-09-16 02:12:47 UTC
> What is DOMS, and what exactly did you have acpid do to it?
DOMS is a typo, should have been DPMS

I have a /etc/acpi/events/lm_lid (which is, AFAIK, from laptop-mode-tools)
"event=button[ /]lid
action=/etc/acpi/actions/lm_lid.sh %e
"

And a /etc/acpi/actions/lm_lid.sh (which I heavily editted):
"#!/bin/bash

#test -f /usr/sbin/laptop_mode || exit 0

# lid button pressed/released event handler

#/usr/sbin/laptop_mode auto
#exit 0
lidstate=at /proc/acpi/button/lid/LID/state | awk '{print $2}';
case "$lidstate" in
        open)
                /usr/sbin/vbetool dpms on
                ;;
        closed)
                #/usr/sbin/vbetool dpms off #not needed
                ;;
esac"

So what really happens is `vbetool dpms on` when the lid is opened, when the lid
is closed nothing is done from userspace, but the screen is placed in some kind
of 'DPMS off'.


I have added the MS Windows, MS Windows NT and MS Windows ME OSI names to the
acpi_gbl_valid_osi_strings table and changed the ACPI_NUM_OSI_STRINGS define.

I have tried booting with acpi_os_name={"Windows 2001", "Microsoft Windows NT",
"Microsoft Windows", "Linux"} with or without 'acpi_osi=' and only 'acpi_osi=',
but none of these solved the problem. Both acpi_os_name and acpi_osi did give a
dmesg-entry, so no doubt about mistyping something.


P.S. I have used 2.6.14-rc1, does that give any extra problems?
Comment 8 Matthew Garrett 2006-03-05 17:13:59 UTC
If you still have Windows installed, can you boot it in safe mode and test
there? Many Dells seem to have a BIOS bug where they fail to turn the backlight
on and expect the drivers to do it.
Comment 9 Daniel Drake 2006-06-17 07:39:16 UTC
Same problem here on my new Inspiron 640m:

- When ACPI is enabled, display does not come back after reopening the lid.
- The vbetool workaround works.
- Currently running 2.6.17-rc6

I do not have windows installed on it, but I tested a minimal Windows XP 'Live
CD' that we have at work. This should be similar to the safe mode test, as it
does not include the Dell drivers. The display does not come back after reopen.
Comment 10 Daniel Drake 2006-06-17 07:42:09 UTC
Created attachment 8328 [details]
acpidump for inspiron 640m
Comment 11 Daniel Drake 2006-06-17 07:42:46 UTC
Created attachment 8329 [details]
dmidecode for inspiron 640m
Comment 12 Daniel Drake 2006-07-02 02:40:58 UTC
I discussed this a little in-person with Matthew Garrett. He is of the opinion
that the only way to fix this properly is to get Dell to release BIOS updates.

Introducing some kind of ACPI <---> Video link in the kernel (to enable DPMS
after lid-open event) is not practical, and it is also asking for trouble if we
mess with DPMS registers behind X's back.

I'm going to try and contact Dell over this matter and I suggest others do the same.
Comment 13 Daniel Drake 2006-07-02 08:48:53 UTC
Possibly related: the screen is blank after resuming from suspend-to-RAM, see
bug #6784
Comment 14 Daniel Drake 2007-05-07 16:21:59 UTC
I posted a DSDT hack to fix this:
http://www.reactivated.net/weblog/archives/2007/05/dell-laptop-lcds-not-powering-up-on-lid-open-event/

Hoping that we can do the equivalent in the kernel somehow...
Comment 15 Len Brown 2007-05-07 21:20:32 UTC
Re: commment #9

> it does not include the Dell drivers.
> The display does not come back after reopen.

Interesting.  So regular XP is certainly working b/c of a 
Dell platform-specific driver.  Though it may still be a bug
in the Dell BIOS that the platform is depnding on that.

Re: comment #14

--- DSDT.dsl.orig	2007-05-06 13:19:59.000000000 -0400
+++ DSDT.dsl	2007-05-06 13:19:59.000000000 -0400
@@ -448,6 +448,16 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
 
     Method (LIDE, 0, NotSerialized)
     {
+        // If lid open, enable video
+        If (LNotEqual(\_SB.LID._LID(), 0)) {
+            \_SB.PCI0.VID.LCD._DSS(0x80000001)
+            Notify (\_SB.LID, 0x80)
+            Return
+        }
+
+        // If lid closed, continue
+
+        // The following Store turns the LCD off
         Store (SMI (0x43, 0x00), Local0)
         If (LAnd (LNotEqual (Local0, 0x00), LNotEqual (Local0, 0x0F)))
         {

This works because of the _DSS, and would still work
if you excluded the Notify?

This is an exciting discovery indeed!
Perhaps we can get the acpi video driver to invoke _DSS
on lid events (or for that matter, on S3 resume)?
Comment 16 Daniel Drake 2007-05-08 05:10:12 UTC
Yes, the display returns because of the _DSS and not because of the Notify (the
same Notify happens anyway at the bottom of the LIDE method, this is just an
"exit early" codepath).

I have been trying to move this functionality into the kernel without much luck.
I know relatively little about the ACPI code. I am having trouble creating a
notify handler for the lid events, because the ACPI button driver is already
subscribed.

http://marc.info/?l=linux-acpi&m=117848419919889&w=2
Comment 17 Natalie Protasevich 2007-09-23 10:30:16 UTC
Any updates on this problem?
Thanks.
Comment 18 Zhang Rui 2007-09-23 18:29:32 UTC
Well, invoking _DSS on resume seems to be a good idea.
But I did some tests on HP and Thinkpad laptops but found that _DSS didn't work on these platforms.
I don't have a Dell laptop. Are you sure the _DSS can work on Dell laptops?
we can manually set the _DSS method via /proc/acpi/video/xxx/state.
can you do a simple test?
eg. after resume from S3, can "echo 0x80000001 > /proc/acpi/video/LCD/state" pull the screen back?
Comment 19 Daniel Drake 2007-09-24 01:36:04 UTC
Up until now this bug has been entirely about simply closing and opening the lid during regular operation. Should we open a new bug for the suspend/resume discussion?

As for the current status of my patch, I didn't get any feedback to the latest version I submitted however it doesn't work 100%: if I open and close the lid a few times in quick succession, sometimes the screen remains off when I open it up for the final time. I've been meaning to look into this...
Comment 20 Zhang Rui 2007-09-24 02:48:09 UTC
Hi, Daniel,

>Up until now this bug has been entirely about simply closing and
>opening the lid during regular operation.
Doesn't your laptop go to sleep after you close the lid?
can you try to "echo 0x80000001 > /proc/acpi/video/LCD/state" after opening the lid and see if the screen come back? 
Surely this should be done without your DSDT hack.

The key problem for us is to verify if _DSS can actually pull the screen back as _DSS didn't work on all the laptops I tested.
Comment 21 Daniel Drake 2007-09-24 03:18:35 UTC
(In reply to comment #20)
> Hi, Daniel,
> 
> >Up until now this bug has been entirely about simply closing and
> >opening the lid during regular operation.
> Doesn't your laptop go to sleep after you close the lid?

No, nothing in the kernel or in the hardware does that automatically.

> can you try to "echo 0x80000001 > /proc/acpi/video/LCD/state" after opening
> the
> lid and see if the screen come back? 

That does make it come back.

> Surely this should be done without your DSDT hack.

Yes, my DSDT hack was the first step, then I discovered the above, then I tried to automate this inside the kernel:

http://marc.info/?l=linux-acpi&m=118066855504362&w=2
http://marc.info/?l=linux-acpi&m=118203860230160&w=2

this approach work as long as you don't open/close/reopen the lid too fast, so it needs a little more work.
Comment 22 Zhang Rui 2007-09-26 22:55:47 UTC
Hi, Daniel,

For the blank screen issue, is this a usual case in all Dell laptops?
Is there any difference if you kill acpid before closing and opening the lid?

I can't reproduce this problem on other laptops like thinkpad and hp.
If this only happens on your laptop, do we have to fix it in the kernel?
A script to poke /proc/acpi/video/LCD/state in user space can fix the problem.
Thus I'm afraid that the second patch is too complex to be accepted in the mainline kernel. what's your opinion?

I'm more curious about what _DSS can do for the S3 video issue.
When resume from a S3 sleep, does the screen come back?
If not, can "echo 0x80000001 > /proc/acpi/video/LCD/state" poll the screen back for you?
Comment 23 Zhang Rui 2007-09-27 20:17:46 UTC
Hi, Len,
I don't have any DELL laptops on hand.
Can you help me do some tests to see if _DSS methods can work on HP laptops please?
1. If the laptop have S3 video issue, 
   can "echo 0x80000001 > /proc/acpi/video/LCD/state" poll the screen back 
   after resume?
2. For multiple displays, what do you see by "cat /proc/acpi/video/*/state"?
   can the LCD/CRT be actived/inactived by poking
   /proc/acpi/video/LCD(CRT)/state?
   PS: echo 0x80000001 should active the display and
       echo 0x80000000 should inactive the display.

I did these tests on other laptops like hp and thinkpad,
and _DSS failed to work. :(
This makes me doubt of the usability of _DSS methods.
Comment 24 Daniel Drake 2007-09-29 05:44:13 UTC
(In reply to comment #22)
> Hi, Daniel,
> 
> For the blank screen issue, is this a usual case in all Dell laptops?

Yes, most modern dell laptops have this issue. 

> Is there any difference if you kill acpid before closing and opening the lid?

No. As detailed in some links above, the DSDT blanks the screen when the lid is closed (and also blanks it again when it is opened!)

> I can't reproduce this problem on other laptops like thinkpad and hp.
> If this only happens on your laptop, do we have to fix it in the kernel?

It would be nice. Len Brown suggested this approach in comment #15 and http://marc.info/?l=linux-acpi&m=117872589707718&w=2

> A script to poke /proc/acpi/video/LCD/state in user space can fix the
> problem.
> Thus I'm afraid that the second patch is too complex to be accepted in the
> mainline kernel. what's your opinion?

I don't feel it is too complex (but would happily take feedback on it). Also I feel it is realistic and best to fix it in the kernel. Consider minimal install media, which is very unlikely to ship acpid. If the user shuts the lid during installation, they are in trouble...

> I'm more curious about what _DSS can do for the S3 video issue.
> When resume from a S3 sleep, does the screen come back?
> If not, can "echo 0x80000001 > /proc/acpi/video/LCD/state" poll the screen
> back
> for you?

I will look into this in the week.
Comment 25 Fu Michael 2007-10-08 07:38:57 UTC
Daniel, Can S3 work well on your laptop? any result from your test on _DSS effect on S3? 
Comment 26 Daniel Drake 2007-10-09 11:45:00 UTC
Sorry for the delay. I still feel the S3 issues should be discussed on another bug, but anyway:

S3 works fine on my laptop apart from the blank screen issue. After resuming, using s2ram's VBE_POST quirk will restore video, as will "vbetool post".

"echo 0x80000001 > /proc/acpi/video/LCD/state" does NOT cause the display to come back after resume, however. Neither does "vbetool dpms on", whereas both of these options work well when opening the lid after closing it during regular operation.
Comment 27 Zhang Rui 2007-10-28 09:47:33 UTC
Hi, Daniel,
For the Dell LCD issue after lid close-open-cycle,
I don't think we will fix it in ACPI video driver.
First, this can be fixed in user space.
Further more, ACPI video driver will not take any actions even for hotkey events like video switch and brightness change. ACPI will only export the events to user space via input layer to avoid the potential conflicts between ACPI and Graphics driver.

And this is more a bios bug than Linux/acpi problem to me, so I'll close it and mark it as WILL_NOT_FIX.

Please reopen it if you still have any questions. :)
Comment 28 Daniel Drake 2007-10-28 10:03:48 UTC
Thanks for looking into this. A quick comment though: the lid events are still only exported via the input layer, it's just that ACPI video now hooks into the input layer. If that's not an option then that's fair enough.

Has Len Brown acknowledged this? Just seems a little odd given that he suggested the approach in the first place -- although I'm fully aware that opinions can change when we come to consider actual implementation details.
Comment 29 Zhang Rui 2007-10-28 10:12:48 UTC
I think what Len is interested in is the role that _DSS can play in video s3 issue.

Len, any comments on this issue?