[Haiku-commits] r30974 - in haiku/trunk: headers/private/graphics/vesa src/add-ons/accelerants/vesa src/add-ons/kernel/drivers/graphics/vesa
axeld at BerliOS
axeld at mail.berlios.de
Fri Jun 5 15:03:06 CEST 2009
Author: axeld
Date: 2009-06-05 15:03:05 +0200 (Fri, 05 Jun 2009)
New Revision: 30974
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=30974&view=rev
Modified:
haiku/trunk/headers/private/graphics/vesa/vesa.h
haiku/trunk/headers/private/graphics/vesa/vesa_info.h
haiku/trunk/src/add-ons/accelerants/vesa/dpms.cpp
haiku/trunk/src/add-ons/accelerants/vesa/mode.cpp
haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/device.cpp
haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp
haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa_private.h
Log:
* Added DPMS support to the VESA driver, in case the hardware/BIOS supports it.
* Minor cleanup.
Modified: haiku/trunk/headers/private/graphics/vesa/vesa.h
===================================================================
--- haiku/trunk/headers/private/graphics/vesa/vesa.h 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/headers/private/graphics/vesa/vesa.h 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2008, Axel Dörfler, axeld at pinc-software.de.
+ * Copyright 2004-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef VESA_H
@@ -141,6 +141,15 @@
#define CRTC_NEGATIVE_VSYNC 0x08
+/* Power Management */
+
+#define DPMS_ON 0x00
+#define DPMS_STANDBY 0x01
+#define DPMS_SUSPEND 0x02
+#define DPMS_OFF 0x04
+#define DPMS_REDUCED_ON 0x08
+
+
/* VBE 3.0 protected mode interface
* The BIOS area can be scanned for the protected mode
* signature that identifies the structure below.
Modified: haiku/trunk/headers/private/graphics/vesa/vesa_info.h
===================================================================
--- haiku/trunk/headers/private/graphics/vesa/vesa_info.h 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/headers/private/graphics/vesa/vesa_info.h 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef VESA_INFO_H
@@ -40,6 +40,7 @@
edid1_info edid_info;
bool has_edid;
+ uint32 dpms_capabilities;
};
//----------------- ioctl() interface ----------------
@@ -49,6 +50,8 @@
VESA_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
VESA_GET_DEVICE_NAME,
VESA_SET_DISPLAY_MODE,
+ VESA_GET_DPMS_MODE,
+ VESA_SET_DPMS_MODE,
VGA_SET_INDEXED_COLORS,
VGA_PLANAR_BLIT,
Modified: haiku/trunk/src/add-ons/accelerants/vesa/dpms.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/vesa/dpms.cpp 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/src/add-ons/accelerants/vesa/dpms.cpp 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,9 +1,11 @@
/*
- * Copyright 2005, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
+#include <errno.h>
+
#include "accelerant_protos.h"
#include "accelerant.h"
@@ -11,20 +13,27 @@
uint32
vesa_dpms_capabilities(void)
{
- return B_DPMS_ON;
+ return gInfo->shared_info->dpms_capabilities;
}
uint32
vesa_dpms_mode(void)
{
- return B_DPMS_ON;
+ uint32 mode;
+ if (ioctl(gInfo->device, VESA_GET_DPMS_MODE, &mode, sizeof(mode)) != 0)
+ return B_DPMS_ON;
+
+ return mode;
}
status_t
-vesa_set_dpms_mode(uint32 dpms_flags)
+vesa_set_dpms_mode(uint32 mode)
{
- return B_ERROR;
+ if (ioctl(gInfo->device, VESA_SET_DPMS_MODE, &mode, sizeof(mode)) != 0)
+ return errno;
+
+ return B_OK;
}
Modified: haiku/trunk/src/add-ons/accelerants/vesa/mode.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/vesa/mode.cpp 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/src/add-ons/accelerants/vesa/mode.cpp 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,8 +1,9 @@
/*
- * Copyright 2005-2008, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
+
#include <string.h>
#include <create_display_modes.h>
@@ -14,7 +15,7 @@
//#define TRACE_MODE
#ifdef TRACE_MODE
-extern "C" void _sPrintf(const char *format, ...);
+extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
#else
# define TRACE(x) ;
@@ -46,9 +47,9 @@
/*! Checks if the specified \a mode can be set using VESA. */
static bool
-is_mode_supported(display_mode *mode)
+is_mode_supported(display_mode* mode)
{
- vesa_mode *modes = gInfo->vesa_modes;
+ vesa_mode* modes = gInfo->vesa_modes;
for (uint32 i = gInfo->shared_info->vesa_mode_count; i-- > 0;) {
// search mode in VESA mode list
@@ -96,7 +97,7 @@
status_t
-vesa_get_mode_list(display_mode *modeList)
+vesa_get_mode_list(display_mode* modeList)
{
TRACE(("vesa_get_mode_info()\n"));
memcpy(modeList, gInfo->mode_list,
@@ -106,15 +107,15 @@
status_t
-vesa_propose_display_mode(display_mode *target, const display_mode *low,
- const display_mode *high)
+vesa_propose_display_mode(display_mode* target, const display_mode* low,
+ const display_mode* high)
{
TRACE(("vesa_propose_display_mode()\n"));
// just search for the specified mode in the list
for (uint32 i = 0; i < gInfo->shared_info->mode_count; i++) {
- display_mode *current = &gInfo->mode_list[i];
+ display_mode* current = &gInfo->mode_list[i];
if (target->virtual_width != current->virtual_width
|| target->virtual_height != current->virtual_height
@@ -129,7 +130,7 @@
status_t
-vesa_set_display_mode(display_mode *_mode)
+vesa_set_display_mode(display_mode* _mode)
{
TRACE(("vesa_set_display_mode()\n"));
@@ -137,8 +138,8 @@
if (vesa_propose_display_mode(&mode, &mode, &mode) != B_OK)
return B_BAD_VALUE;
- vesa_mode *modes = gInfo->vesa_modes;
- for (unsigned int i = gInfo->shared_info->vesa_mode_count; i-- > 0;) {
+ vesa_mode* modes = gInfo->vesa_modes;
+ for (uint32 i = gInfo->shared_info->vesa_mode_count; i-- > 0;) {
// search mode in VESA mode list
// TODO: list is ordered, we could use binary search
if (modes[i].width == mode.virtual_width
@@ -153,7 +154,7 @@
status_t
-vesa_get_display_mode(display_mode *_currentMode)
+vesa_get_display_mode(display_mode* _currentMode)
{
TRACE(("vesa_get_display_mode()\n"));
*_currentMode = gInfo->shared_info->current_mode;
@@ -162,7 +163,7 @@
status_t
-vesa_get_edid_info(void *info, size_t size, uint32 *_version)
+vesa_get_edid_info(void* info, size_t size, uint32* _version)
{
TRACE(("intel_get_edid_info()\n"));
@@ -178,7 +179,7 @@
status_t
-vesa_get_frame_buffer_config(frame_buffer_config *config)
+vesa_get_frame_buffer_config(frame_buffer_config* config)
{
TRACE(("vesa_get_frame_buffer_config()\n"));
@@ -191,20 +192,21 @@
status_t
-vesa_get_pixel_clock_limits(display_mode *mode, uint32 *low, uint32 *high)
+vesa_get_pixel_clock_limits(display_mode* mode, uint32* low, uint32* high)
{
TRACE(("vesa_get_pixel_clock_limits()\n"));
- // ToDo: do some real stuff here (taken from radeon driver)
- uint32 total_pix = (uint32)mode->timing.h_total * (uint32)mode->timing.v_total;
- uint32 clock_limit = 2000000;
+ // TODO: do some real stuff here (taken from radeon driver)
+ uint32 totalPixel = (uint32)mode->timing.h_total
+ * (uint32)mode->timing.v_total;
+ uint32 clockLimit = 2000000;
- /* lower limit of about 48Hz vertical refresh */
- *low = (total_pix * 48L) / 1000L;
- if (*low > clock_limit)
+ // lower limit of about 48Hz vertical refresh
+ *low = totalPixel * 48L / 1000L;
+ if (*low > clockLimit)
return B_ERROR;
- *high = clock_limit;
+ *high = clockLimit;
return B_OK;
}
@@ -218,7 +220,7 @@
status_t
-vesa_get_timing_constraints(display_timing_constraints *dtc)
+vesa_get_timing_constraints(display_timing_constraints* constraints)
{
TRACE(("vesa_get_timing_constraints()\n"));
return B_ERROR;
@@ -226,7 +228,7 @@
void
-vesa_set_indexed_colors(uint count, uint8 first, uint8 *colors, uint32 flags)
+vesa_set_indexed_colors(uint count, uint8 first, uint8* colors, uint32 flags)
{
TRACE(("vesa_set_indexed_colors()\n"));
vga_set_indexed_colors_args args;
Modified: haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/device.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/device.cpp 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/device.cpp 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@@ -32,53 +32,23 @@
#endif
-/* device hooks prototypes */
-
-static status_t device_open(const char *, uint32, void **);
-static status_t device_close(void *);
-static status_t device_free(void *);
-static status_t device_ioctl(void *, uint32, void *, size_t);
-static status_t device_read(void *, off_t, void *, size_t *);
-static status_t device_write(void *, off_t, const void *, size_t *);
-
-
-device_hooks gDeviceHooks = {
- device_open,
- device_close,
- device_free,
- device_ioctl,
- device_read,
- device_write,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-
-// #pragma mark -
-// the device will be accessed through the following functions (a.k.a. device hooks)
-
-
static status_t
-device_open(const char *name, uint32 flags, void **_cookie)
+device_open(const char* name, uint32 flags, void** _cookie)
{
int id;
// find accessed device
- {
- char *thisName;
+ char* thisName;
- // search for device name
- for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
- if (!strcmp(name, thisName))
- break;
- }
- if (!thisName)
- return EINVAL;
+ // search for device name
+ for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
+ if (!strcmp(name, thisName))
+ break;
}
+ if (thisName == NULL)
+ return B_BAD_VALUE;
- vesa_info *info = gDeviceInfo[id];
+ vesa_info* info = gDeviceInfo[id];
*_cookie = info;
acquire_lock(&gLock);
@@ -100,16 +70,16 @@
static status_t
-device_close(void *cookie)
+device_close(void* cookie)
{
return B_OK;
}
static status_t
-device_free(void *cookie)
+device_free(void* cookie)
{
- struct vesa_info *info = (vesa_info *)cookie;
+ struct vesa_info* info = (vesa_info*)cookie;
acquire_lock(&gLock);
@@ -124,26 +94,26 @@
static status_t
-device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength)
+device_ioctl(void* cookie, uint32 msg, void* buffer, size_t bufferLength)
{
- struct vesa_info *info = (vesa_info *)cookie;
+ struct vesa_info* info = (vesa_info*)cookie;
switch (msg) {
case B_GET_ACCELERANT_SIGNATURE:
dprintf(DEVICE_NAME ": acc: %s\n", VESA_ACCELERANT_NAME);
- if (user_strlcpy((char *)buffer, VESA_ACCELERANT_NAME,
+ if (user_strlcpy((char*)buffer, VESA_ACCELERANT_NAME,
B_FILE_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
return B_OK;
- // needed to share data between kernel and accelerant
+ // needed to share data between kernel and accelerant
case VESA_GET_PRIVATE_DATA:
return user_memcpy(buffer, &info->shared_area, sizeof(area_id));
// needed for cloning
case VESA_GET_DEVICE_NAME:
- if (user_strlcpy((char *)buffer, gDeviceNames[info->id],
+ if (user_strlcpy((char*)buffer, gDeviceNames[info->id],
B_PATH_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
@@ -151,15 +121,41 @@
case VESA_SET_DISPLAY_MODE:
{
- unsigned int mode;
+ if (bufferLength != sizeof(uint32))
+ return B_BAD_VALUE;
- if (bufferLength != sizeof(mode)
- || user_memcpy(&mode, buffer, sizeof(mode)) < B_OK)
+ uint32 mode;
+ if (user_memcpy(&mode, buffer, sizeof(uint32)) < B_OK)
return B_BAD_ADDRESS;
return vesa_set_display_mode(*info, mode);
}
+ case VESA_GET_DPMS_MODE:
+ {
+ if (bufferLength != sizeof(uint32))
+ return B_BAD_VALUE;
+
+ uint32 mode;
+ status_t status = vesa_get_dpms_mode(*info, mode);
+ if (status != B_OK)
+ return status;
+
+ return user_memcpy(buffer, &mode, sizeof(mode));
+ }
+
+ case VESA_SET_DPMS_MODE:
+ {
+ if (bufferLength != sizeof(uint32))
+ return B_BAD_VALUE;
+
+ uint32 mode;
+ if (user_memcpy(&mode, buffer, sizeof(uint32)) < B_OK)
+ return B_BAD_ADDRESS;
+
+ return vesa_set_dpms_mode(*info, mode);
+ }
+
case VGA_SET_INDEXED_COLORS:
{
vga_set_indexed_colors_args args;
@@ -181,7 +177,9 @@
}
default:
- TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n", msg, bufferLength));
+ TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n",
+ msg, bufferLength));
+ break;
}
return B_DEV_INVALID_IOCTL;
@@ -189,17 +187,31 @@
static status_t
-device_read(void */*cookie*/, off_t /*pos*/, void */*buffer*/, size_t *_length)
+device_read(void* /*cookie*/, off_t /*pos*/, void* /*buffer*/, size_t* _length)
{
- *_length = 0;
+ *_length = 0;
return B_NOT_ALLOWED;
}
static status_t
-device_write(void */*cookie*/, off_t /*pos*/, const void */*buffer*/, size_t *_length)
+device_write(void* /*cookie*/, off_t /*pos*/, const void* /*buffer*/,
+ size_t* _length)
{
- *_length = 0;
+ *_length = 0;
return B_NOT_ALLOWED;
}
+
+device_hooks gDeviceHooks = {
+ device_open,
+ device_close,
+ device_free,
+ device_ioctl,
+ device_read,
+ device_write,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
Modified: haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@@ -44,26 +44,26 @@
static status_t
-vbe_get_mode_info(struct vm86_state *vmState, uint16 mode,
- struct vbe_mode_info *modeInfo)
+vbe_get_mode_info(struct vm86_state& vmState, uint16 mode,
+ struct vbe_mode_info* modeInfo)
{
- struct vbe_mode_info *vbeModeInfo = (struct vbe_mode_info *)0x1000;
+ struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000;
memset(vbeModeInfo, 0, sizeof(vbe_mode_info));
- vmState->regs.eax = 0x4f01;
- vmState->regs.ecx = mode;
- vmState->regs.es = 0x1000 >> 4;
- vmState->regs.edi = 0x0000;
+ vmState.regs.eax = 0x4f01;
+ vmState.regs.ecx = mode;
+ vmState.regs.es = 0x1000 >> 4;
+ vmState.regs.edi = 0x0000;
- status_t status = vm86_do_int(vmState, 0x10);
+ status_t status = vm86_do_int(&vmState, 0x10);
if (status != B_OK) {
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode);
return status;
}
- if ((vmState->regs.eax & 0xffff) != 0x4f) {
+ if ((vmState.regs.eax & 0xffff) != 0x4f) {
dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n",
- vmState->regs.eax & 0xffff);
+ vmState.regs.eax & 0xffff);
return B_ENTRY_NOT_FOUND;
}
@@ -73,20 +73,20 @@
static status_t
-vbe_set_mode(struct vm86_state *vmState, uint16 mode)
+vbe_set_mode(struct vm86_state& vmState, uint16 mode)
{
- vmState->regs.eax = 0x4f02;
- vmState->regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
+ vmState.regs.eax = 0x4f02;
+ vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
- status_t status = vm86_do_int(vmState, 0x10);
+ status_t status = vm86_do_int(&vmState, 0x10);
if (status != B_OK) {
dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode);
return status;
}
- if ((vmState->regs.eax & 0xffff) != 0x4f) {
+ if ((vmState.regs.eax & 0xffff) != 0x4f) {
dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n",
- vmState->regs.eax & 0xffff);
+ vmState.regs.eax & 0xffff);
return B_ERROR;
}
@@ -94,26 +94,84 @@
}
+static uint32
+vbe_to_system_dpms(uint8 vbeMode)
+{
+ uint32 mode = 0;
+ if ((vbeMode & (DPMS_OFF | DPMS_REDUCED_ON)) != 0)
+ mode |= B_DPMS_OFF;
+ if ((vbeMode & DPMS_STANDBY) != 0)
+ mode |= B_DPMS_STAND_BY;
+ if ((vbeMode & DPMS_SUSPEND) != 0)
+ mode |= B_DPMS_SUSPEND;
+
+ return mode;
+}
+
+
+static status_t
+vbe_get_dpms_capabilities(uint32& vbeMode, uint32& mode)
+{
+ // we always return a valid mode
+ vbeMode = 0;
+ mode = B_DPMS_ON;
+
+ // Prepare vm86 mode environment
+ struct vm86_state vmState;
+ status_t status = vm86_prepare(&vmState, 0x20000);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME": vbe_get_dpms_capabilities(): vm86_prepare "
+ "failed: %s\n", strerror(status));
+ return status;
+ }
+
+ vmState.regs.eax = 0x4f10;
+ vmState.regs.ebx = 0;
+ vmState.regs.esi = 0;
+ vmState.regs.edi = 0;
+
+ status = vm86_do_int(&vmState, 0x10);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): vm86 failed\n");
+ goto out;
+ }
+
+ if ((vmState.regs.eax & 0xffff) != 0x4f) {
+ dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
+ "0x%04lx\n", vmState.regs.eax & 0xffff);
+ status = B_ERROR;
+ goto out;
+ }
+
+ vbeMode = vmState.regs.ebx >> 8;
+ mode = vbe_to_system_dpms(vbeMode);
+
+out:
+ vm86_cleanup(&vmState);
+ return status;
+}
+
+
// #pragma mark -
status_t
-vesa_init(vesa_info &info)
+vesa_init(vesa_info& info)
{
- frame_buffer_boot_info *bufferInfo
- = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
+ frame_buffer_boot_info* bufferInfo
+ = (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
if (bufferInfo == NULL)
return B_ERROR;
size_t modesSize = 0;
- vesa_mode *modes = (vesa_mode *)get_boot_item(VESA_MODES_BOOT_INFO,
+ vesa_mode* modes = (vesa_mode*)get_boot_item(VESA_MODES_BOOT_INFO,
&modesSize);
info.modes = modes;
size_t sharedSize = (sizeof(vesa_shared_info) + 7) & ~7;
info.shared_area = create_area("vesa shared info",
- (void **)&info.shared_info, B_ANY_KERNEL_ADDRESS,
+ (void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
ROUND_TO_PAGE_SIZE(sharedSize + modesSize), B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
if (info.shared_area < B_OK)
@@ -131,7 +189,7 @@
}
sharedInfo.frame_buffer_area = bufferInfo->area;
- sharedInfo.frame_buffer = (uint8 *)bufferInfo->frame_buffer;
+ sharedInfo.frame_buffer = (uint8*)bufferInfo->frame_buffer;
sharedInfo.current_mode.virtual_width = bufferInfo->width;
sharedInfo.current_mode.virtual_height = bufferInfo->height;
@@ -140,17 +198,19 @@
sharedInfo.bytes_per_row = bufferInfo->bytes_per_row;
// TODO: we might want to do this via vm86 instead
- edid1_info *edidInfo = (edid1_info *)get_boot_item(VESA_EDID_BOOT_INFO,
+ edid1_info* edidInfo = (edid1_info*)get_boot_item(VESA_EDID_BOOT_INFO,
NULL);
if (edidInfo != NULL) {
sharedInfo.has_edid = true;
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
}
+ vbe_get_dpms_capabilities(info.vbe_dpms_capabilities,
+ sharedInfo.dpms_capabilities);
+
physical_entry mapping;
- get_memory_map((void *)sharedInfo.frame_buffer, B_PAGE_SIZE,
- &mapping, 1);
- sharedInfo.physical_frame_buffer = (uint8 *)mapping.address;
+ get_memory_map((void*)sharedInfo.frame_buffer, B_PAGE_SIZE, &mapping, 1);
+ sharedInfo.physical_frame_buffer = (uint8*)mapping.address;
dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
return B_OK;
@@ -158,7 +218,7 @@
void
-vesa_uninit(vesa_info &info)
+vesa_uninit(vesa_info& info)
{
dprintf(DEVICE_NAME": vesa_uninit()\n");
@@ -168,7 +228,7 @@
status_t
-vesa_set_display_mode(vesa_info &info, unsigned int mode)
+vesa_set_display_mode(vesa_info& info, uint32 mode)
{
if (mode >= info.shared_info->vesa_mode_count)
return B_ENTRY_NOT_FOUND;
@@ -181,43 +241,42 @@
return status;
}
- area_id newFBArea;
- frame_buffer_boot_info *bufferInfo;
+ area_id frameBufferArea;
+ frame_buffer_boot_info* bufferInfo;
struct vbe_mode_info modeInfo;
// Get mode information
- status = vbe_get_mode_info(&vmState, info.modes[mode].mode, &modeInfo);
+ status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo);
if (status != B_OK) {
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
- goto error;
+ goto out;
}
// Set mode
- status = vbe_set_mode(&vmState, info.modes[mode].mode);
+ status = vbe_set_mode(vmState, info.modes[mode].mode);
if (status != B_OK) {
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
- goto error;
+ goto out;
}
// Map new frame buffer
- void *frameBuffer;
- newFBArea = map_physical_memory("vesa_fb",
- (void *)modeInfo.physical_base,
- modeInfo.bytes_per_row * modeInfo.height, B_ANY_KERNEL_ADDRESS,
- B_READ_AREA | B_WRITE_AREA, &frameBuffer);
- if (newFBArea < B_OK) {
- status = (status_t)newFBArea;
- goto error;
+ void* frameBuffer;
+ frameBufferArea = map_physical_memory("vesa_fb",
+ (void*)modeInfo.physical_base, modeInfo.bytes_per_row * modeInfo.height,
+ B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, &frameBuffer);
+ if (frameBufferArea < B_OK) {
+ status = (status_t)frameBufferArea;
+ goto out;
}
delete_area(info.shared_info->frame_buffer_area);
// Turn on write combining for the area
- vm_set_area_memory_type(newFBArea, modeInfo.physical_base, B_MTR_WC);
+ vm_set_area_memory_type(frameBufferArea, modeInfo.physical_base, B_MTR_WC);
// Update shared frame buffer information
- info.shared_info->frame_buffer_area = newFBArea;
- info.shared_info->frame_buffer = (uint8 *)frameBuffer;
- info.shared_info->physical_frame_buffer = (uint8 *)modeInfo.physical_base;
+ info.shared_info->frame_buffer_area = frameBufferArea;
+ info.shared_info->frame_buffer = (uint8*)frameBuffer;
+ info.shared_info->physical_frame_buffer = (uint8*)modeInfo.physical_base;
info.shared_info->bytes_per_row = modeInfo.bytes_per_row;
info.shared_info->current_mode.virtual_width = modeInfo.width;
info.shared_info->current_mode.virtual_height = modeInfo.height;
@@ -226,16 +285,107 @@
// Update boot item as it's used in vesa_init()
bufferInfo
- = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
- bufferInfo->area = newFBArea;
+ = (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
+ bufferInfo->area = frameBufferArea;
bufferInfo->frame_buffer = (addr_t)frameBuffer;
bufferInfo->width = modeInfo.width;
bufferInfo->height = modeInfo.height;
bufferInfo->depth = modeInfo.bits_per_pixel;
bufferInfo->bytes_per_row = modeInfo.bytes_per_row;
-error:
+out:
vm86_cleanup(&vmState);
return status;
}
+
+status_t
+vesa_get_dpms_mode(vesa_info& info, uint32& mode)
+{
+ mode = B_DPMS_ON;
+ // we always return a valid mode
+
+ // Prepare vm86 mode environment
+ struct vm86_state vmState;
+ status_t status = vm86_prepare(&vmState, 0x20000);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME": vesa_get_dpms_mode(): vm86_prepare failed: %s\n",
+ strerror(status));
+ return status;
+ }
+
+ vmState.regs.eax = 0x4f10;
+ vmState.regs.ebx = 2;
+ vmState.regs.esi = 0;
+ vmState.regs.edi = 0;
+
+ status = vm86_do_int(&vmState, 0x10);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): vm86 failed: %s\n",
+ strerror(status));
+ goto out;
+ }
+
+ if ((vmState.regs.eax & 0xffff) != 0x4f) {
+ dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned 0x%04lx\n",
+ vmState.regs.eax & 0xffff);
+ status = B_ERROR;
+ goto out;
+ }
+
+ mode = vbe_to_system_dpms(vmState.regs.ebx >> 8);
+
+out:
+ vm86_cleanup(&vmState);
+ return status;
+}
+
+
+status_t
+vesa_set_dpms_mode(vesa_info& info, uint32 mode)
+{
+ // Only let supported modes through
+ mode &= info.shared_info->dpms_capabilities;
+
+ uint8 vbeMode = 0;
+ if ((mode & B_DPMS_OFF) != 0)
+ vbeMode |= DPMS_OFF | DPMS_REDUCED_ON;
+ if ((mode & B_DPMS_STAND_BY) != 0)
+ vbeMode |= DPMS_STANDBY;
+ if ((mode & B_DPMS_SUSPEND) != 0)
+ vbeMode |= DPMS_SUSPEND;
+
+ vbeMode &= info.vbe_dpms_capabilities;
+
+ // Prepare vm86 mode environment
+ struct vm86_state vmState;
+ status_t status = vm86_prepare(&vmState, 0x20000);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME": vesa_set_dpms_mode(): vm86_prepare failed: %s\n",
+ strerror(status));
+ return status;
+ }
+
+ vmState.regs.eax = 0x4f10;
+ vmState.regs.ebx = (vbeMode << 8) | 1;
+ vmState.regs.esi = 0;
+ vmState.regs.edi = 0;
+
+ status = vm86_do_int(&vmState, 0x10);
+ if (status != B_OK) {
+ dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): vm86 failed: %s\n",
+ strerror(status));
+ goto out;
+ }
+
+ if ((vmState.regs.eax & 0xffff) != 0x4f) {
+ dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned 0x%04lx\n",
+ vmState.regs.eax & 0xffff);
+ status = B_ERROR;
+ goto out;
+ }
+
+out:
+ vm86_cleanup(&vmState);
+ return status;
+}
Modified: haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa_private.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa_private.h 2009-06-05 12:33:22 UTC (rev 30973)
+++ haiku/trunk/src/add-ons/kernel/drivers/graphics/vesa/vesa_private.h 2009-06-05 13:03:05 UTC (rev 30974)
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008, Axel Dörfler, axeld at pinc-software.de. All rights reserved.
+ * Copyright 2005-2009, Axel Dörfler, axeld at pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef VESA_PRIVATE_H
@@ -22,14 +22,17 @@
uint32 cookie_magic;
int32 open_count;
int32 id;
- pci_info *pci;
- struct vesa_shared_info *shared_info;
+ pci_info* pci;
+ struct vesa_shared_info* shared_info;
area_id shared_area;
- vesa_mode *modes;
+ vesa_mode* modes;
+ uint32 vbe_dpms_capabilities;
};
-extern status_t vesa_init(vesa_info &info);
-extern void vesa_uninit(vesa_info &info);
-extern status_t vesa_set_display_mode(vesa_info &info, unsigned int mode);
+extern status_t vesa_init(vesa_info& info);
+extern void vesa_uninit(vesa_info& info);
+extern status_t vesa_set_display_mode(vesa_info& info, uint32 mode);
+extern status_t vesa_get_dpms_mode(vesa_info& info, uint32& mode);
+extern status_t vesa_set_dpms_mode(vesa_info& info, uint32 mode);
#endif /* VESA_PRIVATE_H */
More information about the Haiku-commits
mailing list