Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Dec 2004 10:09:21 -0800
From:      "Kevin Oberman" <oberman@es.net>
To:        freebsd-acpi@freebsd.org
Subject:   Re: S3 on a Sony VGN-A290 
Message-ID:  <20041210180921.55D275D04@ptavv.es.net>
In-Reply-To: Your message of "Fri, 10 Dec 2004 09:45:34 PST." <20041210174534.DF64B5D04@ptavv.es.net> 

next in thread | previous in thread | raw e-mail | index | archive | help
> Date: Fri, 10 Dec 2004 09:45:34 -0800
> From: "Kevin Oberman" <oberman@es.net>
> Sender: owner-freebsd-acpi@freebsd.org
> 
> This is a multipart MIME message.
> 
> --==_Exmh_10231918290
> Content-Type: text/plain; charset=us-ascii
> 
> > Date: Fri, 10 Dec 2004 10:16:05 -0700 (MST)
> > From: "M. Warner Losh" <imp@bsdimp.com>
> > Sender: owner-freebsd-acpi@freebsd.org
> > 
> > In message: <20041210133615.GA1482@genius.tao.org.uk>
> >             Josef Karthauser <joe@freebsd.org> writes:
> > : Grump.  I leave my new Sony in S3 and come back to it in the morning to
> > : find that it's run out of battery :/.  I thought that S3 was a low
> > : energy state.  Anyone else got a similar machine?  Is it a problem with
> > : the machine or our ACPI?  (I'm running RELENG_5 on it).
> > 
> > It is a Low energy state.  However, it isn't a NO energy state.
> 
> What version are you running? I think that Nate has added support for PCI
> power states to current and will probably be MFCing them soon. I have
> been testing them for about 2 weeks.
> 
> You also want to use jhb's acpi_video_dpms patch if the back-light on
> your display does not turn off. This is a BIG power sink. I'll attach
> a copy that is clean against -stable of yesterday (and probably
> today). Be sure that you load acpi_video!

The mail list stripped off the attachment.

And I see that current is running ACPI power code that is updated from
what I have and shows no date to MFC. Still turning off the back-light
is a MUCH bigger power saver than almost anything else you can do.

I am appending the patch this time, so it should make it.

==== //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 <taku@cent.saitama-u.ac.jp>
+ * Copyright (c) 2004 Benjamin Close <Benjamin.Close@clearchain.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,10 +36,33 @@
 #include <sys/power.h>
 #include <sys/queue.h>
 #include <sys/sysctl.h>
+#ifdef __i386__
+#include <machine/vm86.h>
+#endif
 
 #include "acpi.h"
 #include <dev/acpica/acpivar.h>
 
+#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
@@ -139,6 +174,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 }
 };
 
@@ -245,6 +282,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);
 }
 
@@ -282,6 +326,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, UINT32 notify, void *context)
 {
@@ -896,3 +966,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

-- 
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041210180921.55D275D04>