From owner-freebsd-mobile@FreeBSD.ORG Sun Nov 21 02:03:26 2004 Return-Path: Delivered-To: freebsd-mobile@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2058616A4CE for ; Sun, 21 Nov 2004 02:03:26 +0000 (GMT) Received: from postal2.es.net (postal2.es.net [198.128.3.206]) by mx1.FreeBSD.org (Postfix) with ESMTP id DBEDA43D2D for ; Sun, 21 Nov 2004 02:03:25 +0000 (GMT) (envelope-from oberman@es.net) Received: from ptavv.es.net ([198.128.4.29]) by postal2.es.net (Postal Node 2) with ESMTP id IBA74465; Sat, 20 Nov 2004 18:03:25 -0800 Received: from ptavv (localhost [127.0.0.1]) by ptavv.es.net (Tachyon Server) with ESMTP id 269D65D04; Sat, 20 Nov 2004 18:03:25 -0800 (PST) X-Mailer: exmh version 2.7.0 06/18/2004 with nmh-1.0.4 To: Dan Pelleg In-reply-to: Your message of "Fri, 19 Nov 2004 06:01:38 EST." Mime-Version: 1.0 Content-Type: multipart/mixed ; boundary="==_Exmh_-4527400770" Date: Sat, 20 Nov 2004 18:03:25 -0800 From: "Kevin Oberman" Message-Id: <20041121020325.269D65D04@ptavv.es.net> cc: Jochen Gensch cc: mobile@freebsd.org Subject: Re: acpi_video, 5.3-RELEASE, ThinkPad X31? X-BeenThere: freebsd-mobile@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Mobile computing with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Nov 2004 02:03:27 -0000 This is a multipart MIME message. --==_Exmh_-4527400770 Content-Type: text/plain; charset=us-ascii > From: Dan Pelleg > Date: Fri, 19 Nov 2004 06:01:38 -0500 > Sender: owner-freebsd-mobile@freebsd.org > > Jochen Gensch writes: > > > Brad Karp wrote: > > > >> Are there known problems with acpi_video attaching on ThinkPads of some > >> models? How about known fixes? > > > > On my X31 (2672-CBU) I see this in dmesg: > > acpi_video0: port 0x3000-0x30ff mem 0xc0100000-0xc010ffff,0xe0000000-0xe7ffffff irq 11 at device 0.0 on pci1 > > However the backlight stays on on suspend. acpi_video lacks DPMS support at this time. John Baldwin posted a patch some time ago that adds support. I will append a copy of the patch that has been updated to patch cleanly against 5.3-Stable. jhb has said that does not intend to commit this patch. He's working on more general VGA support as a better fix, but I don't think it's at the top of his priority list, so it may not show up real soon. -- R. Kevin Oberman, Network Engineer Energy Sciences Network (ESnet) Ernest O. Lawrence Berkeley National Laboratory (Berkeley Lab) E-mail: oberman@es.net Phone: +1 510 486-8634 --==_Exmh_-4527400770 Content-Type: text/plain ; name="acpi_video_dpms.patch"; charset=us-ascii Content-Description: acpi_video_dpms.patch Content-Disposition: attachment; filename="acpi_video_dpms.patch" ==== //depot/projects/power/sys/dev/acpica/acpi_video.c#2 - /home/john/work/p4/power/sys/dev/acpica/acpi_video.c ==== @@ -1,5 +1,6 @@ /*- * Copyright (c) 2002-2003 Taku YAMAMOTO + * Copyright (c) 2004 Benjamin Close * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,10 +36,33 @@ #include #include #include +#ifdef __i386__ +#include +#endif #include "acpi.h" #include +#ifdef __i386__ +#define USE_DPMS + +/* + * VESA DPMS States + */ +#define DPMS_ON 0x00 +#define DPMS_STANDBY 0x01 +#define DPMS_SUSPEND 0x02 +#define DPMS_OFF 0x04 +#define DPMS_REDUCEDON 0x08 + +#define VBE_DPMS_FUNCTION 0x4F10 +#define VBE_DPMS_GET_SUPPORTED_STATES 0x00 +#define VBE_DPMS_GET_STATE 0x02 +#define VBE_DPMS_SET_STATE 0x01 +#define VBE_MAJORVERSION_MASK 0x0F +#define VBE_MINORVERSION_MASK 0xF0 +#endif + /* ACPI video extension driver. */ struct acpi_video_output { ACPI_HANDLE handle; @@ -64,6 +88,10 @@ ACPI_HANDLE handle; struct acpi_video_output_queue vid_outputs; eventhandler_tag vid_pwr_evh; +#ifdef USE_DPMS + int vid_dpms_supported_states; + int vid_dpms_initial_state; +#endif }; /* interfaces */ @@ -72,6 +100,8 @@ static int acpi_video_attach(device_t); static int acpi_video_detach(device_t); static int acpi_video_shutdown(device_t); +static int acpi_video_suspend(device_t); +static int acpi_video_resume(device_t); static void acpi_video_notify_handler(ACPI_HANDLE, UINT32, void *); static void acpi_video_power_profile(void *); static void acpi_video_bind_outputs(struct acpi_video_softc *); @@ -93,6 +123,11 @@ static UINT32 vo_get_device_status(ACPI_HANDLE); static UINT32 vo_get_graphics_state(ACPI_HANDLE); static void vo_set_device_state(ACPI_HANDLE, UINT32); +#ifdef USE_DPMS +static int dpms_get_supported_states(int *); +static int dpms_get_current_state(int *); +static int dpms_set_state(int); +#endif /* events */ #define VID_NOTIFY_SWITCHED 0x80 @@ -140,6 +175,8 @@ DEVMETHOD(device_attach, acpi_video_attach), DEVMETHOD(device_detach, acpi_video_detach), DEVMETHOD(device_shutdown, acpi_video_shutdown), + DEVMETHOD(device_resume, acpi_video_resume), + DEVMETHOD(device_suspend, acpi_video_suspend), { 0, 0 } }; @@ -240,6 +277,13 @@ acpi_video_power_profile(sc); +#ifdef USE_DPMS + if (dpms_get_supported_states(&sc->vid_dpms_supported_states) == 0) + dpms_get_current_state(&sc->vid_dpms_initial_state); + else + sc->vid_dpms_supported_states = -1; +#endif + return (0); } @@ -277,6 +321,32 @@ return (0); } +static int +acpi_video_suspend(device_t dev) +{ + struct acpi_video_softc *sc; + + sc = device_get_softc(dev); +#ifdef USE_DPMS + if (sc->vid_dpms_supported_states != -1) + dpms_set_state(DPMS_OFF); +#endif + return (0); +} + +static int +acpi_video_resume(device_t dev) +{ + struct acpi_video_softc *sc; + + sc = device_get_softc(dev); +#ifdef USE_DPMS + if (sc->vid_dpms_supported_states != -1) + dpms_set_state(sc->vid_dpms_initial_state); +#endif + return (0); +} + static void acpi_video_notify_handler(ACPI_HANDLE handle __unused, UINT32 notify, void *context) @@ -887,3 +953,49 @@ printf("can't evaluate %s._DSS - %s\n", acpi_name(handle), AcpiFormatException(status)); } + +#ifdef USE_DPMS +/* XXX: Requires VM86 support in the kernel. */ +static int +dpms_call_bios(int subfunction, int *bh) +{ + struct vm86frame vmf; + int error; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_ax = VBE_DPMS_FUNCTION; + vmf.vmf_bl = subfunction; + vmf.vmf_bh = *bh; + vmf.vmf_es = 0; + vmf.vmf_di = 0; + error = vm86_intcall(0x10, &vmf); + if (error == 0 && (vmf.vmf_eax & 0xffff) != 0x004f) + error = ENXIO; + if (error == 0) + *bh = vmf.vmf_bh; + return (error); +} + +static int +dpms_get_supported_states(int *states) +{ + + *states = 0; + return (dpms_call_bios(VBE_DPMS_GET_SUPPORTED_STATES, states)); +} + +static int +dpms_get_current_state(int *state) +{ + + *state = 0; + return (dpms_call_bios(VBE_DPMS_GET_STATE, state)); +} + +static int +dpms_set_state(int state) +{ + + return (dpms_call_bios(VBE_DPMS_SET_STATE, &state)); +} +#endif --==_Exmh_-4527400770--