[haiku-commits] haiku: hrev44212 - src/add-ons/accelerants/intel_810 src/add-ons/kernel/drivers/graphics/intel_810 headers/private/graphics/intel_810

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 30 May 2012 23:12:51 +0200 (CEST)

hrev44212 adds 2 changesets to branch 'master'
old head: 9c02217342b431de9ca99a3ad6a3febe423a32f1
new head: 0e8316cc908c3f24496bdf57855a6dcde483b82f

----------------------------------------------------------------------------

e0ee3b7: driver: New intel 810 video driver
  
  * Introduced by Gerald Zajac in #8615
  * Will need reviewed, tested, and some style cleanup
  * Not in images until steps above complete

                                     [ Gerald Zajac <zajacg@xxxxxxxxxxxxx> ]

0e8316c: intel_810: Style cleanup. No functional change
  
  * I think the FunctionNames need to change to function_name

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

16 files changed, 2431 insertions(+)
.../private/graphics/intel_810/DriverInterface.h   |  108 +++
src/add-ons/accelerants/Jamfile                    |    1 +
src/add-ons/accelerants/intel_810/Jamfile          |   19 +
src/add-ons/accelerants/intel_810/accelerant.cpp   |  235 ++++++
src/add-ons/accelerants/intel_810/accelerant.h     |  113 +++
src/add-ons/accelerants/intel_810/engine.cpp       |   82 ++
src/add-ons/accelerants/intel_810/hooks.cpp        |   86 ++
src/add-ons/accelerants/intel_810/i810_dpms.cpp    |  101 +++
src/add-ons/accelerants/intel_810/i810_init.cpp    |   69 ++
src/add-ons/accelerants/intel_810/i810_mode.cpp    |  288 +++++++
src/add-ons/accelerants/intel_810/i810_regs.h      |  173 ++++
.../accelerants/intel_810/i810_watermark.cpp       |  143 ++++
src/add-ons/accelerants/intel_810/mode.cpp         |  333 ++++++++
src/add-ons/kernel/drivers/graphics/Jamfile        |    1 +
.../kernel/drivers/graphics/intel_810/Jamfile      |    9 +
.../kernel/drivers/graphics/intel_810/driver.cpp   |  670 ++++++++++++++++

############################################################################

Commit:      e0ee3b7971889f4656b26baae75f6ee96f42c190
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e0ee3b7
Author:      Gerald Zajac <zajacg@xxxxxxxxxxxxx>
Date:        Wed May 30 20:21:18 2012 UTC
Committer:   Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Commit-Date: Wed May 30 20:21:18 2012 UTC

Ticket:      https://dev.haiku-os.org/ticket/8615

driver: New intel 810 video driver

* Introduced by Gerald Zajac in #8615
* Will need reviewed, tested, and some style cleanup
* Not in images until steps above complete

----------------------------------------------------------------------------

diff --git a/headers/private/graphics/intel_810/DriverInterface.h 
b/headers/private/graphics/intel_810/DriverInterface.h
new file mode 100644
index 0000000..a265aef
--- /dev/null
+++ b/headers/private/graphics/intel_810/DriverInterface.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#ifndef DRIVERINTERFACE_H
+#define DRIVERINTERFACE_H
+
+
+#include <Accelerant.h>
+#include <GraphicsDefs.h>
+#include <Drivers.h>
+#include <edid.h>
+
+
+// This file contains info that is shared between the kernel driver and the
+// accelerant, and info that is shared among the source files of the
+// accelerant.
+
+
+#define ENABLE_DEBUG_TRACE             // if defined, turns on debug output to 
syslog
+
+
+#define ARRAY_SIZE(a) (int(sizeof(a) / sizeof(a[0])))  // get number of 
elements in an array
+
+
+struct Benaphore {
+       sem_id  sem;
+       int32   count;
+
+       status_t Init(const char* name)
+       {
+               count = 0;
+               sem = create_sem(0, name);
+               return sem < 0 ? sem : B_OK;
+       }
+
+       status_t Acquire()
+       {
+               if (atomic_add(&count, 1) > 0)
+                       return acquire_sem(sem);
+               return B_OK;
+       }
+
+       status_t Release()
+       {
+               if (atomic_add(&count, -1) > 1)
+                       return release_sem(sem);
+               return B_OK;
+       }
+
+       void Delete()   { delete_sem(sem); }
+};
+
+
+
+enum {
+       INTEL_GET_SHARED_DATA = B_DEVICE_OP_CODES_END + 234,
+       INTEL_DEVICE_NAME,
+       INTEL_GET_EDID,
+};
+
+
+struct DisplayModeEx : display_mode {
+       uint8   bitsPerPixel;
+       uint8   bytesPerPixel;
+       uint16  bytesPerRow;            // number of bytes in one line/row
+};
+
+
+struct SharedInfo {
+       // Device ID info.
+       uint16  vendorID;                       // PCI vendor ID, from pci_info
+       uint16  deviceID;                       // PCI device ID, from pci_info
+       uint8   revision;                       // PCI device revsion, from 
pci_info
+       char    chipName[32];           // user recognizable name of chip
+
+       bool    bAccelerantInUse;       // true = accelerant has been 
initialized
+
+       // Memory mappings.
+       area_id regsArea;                       // area_id for the memory 
mapped registers. It will
+                                                               // be cloned 
into accelerant's address space.
+       area_id videoMemArea;           // video memory area_id.  Addr's shared 
with all teams.
+       addr_t  videoMemAddr;           // virtual video memory addr
+       phys_addr_t     videoMemPCI;    // physical video memory addr
+       uint32  videoMemSize;           // video memory size in bytes (for 
frame buffer).
+
+       uint32  maxFrameBufferSize;     // max available video memory for frame 
buffer
+
+       // Color spaces supported by current video chip/driver.
+       color_space     colorSpaces[6];
+       uint32  colorSpaceCount;        // number of color spaces in array 
colorSpaces
+
+       // List of screen modes.
+       area_id modeArea;                       // area containing list of 
display modes the driver supports
+       uint32  modeCount;                      // number of display modes in 
the list
+
+       DisplayModeEx displayMode;      // current display mode configuration
+
+       edid1_info      edidInfo;
+       bool            bHaveEDID;              // true = EDID info from device 
is in edidInfo
+
+       Benaphore       engineLock;             // for serializing access to 
the acceleration engine
+};
+
+
+#endif // DRIVERINTERFACE_H
diff --git a/src/add-ons/accelerants/Jamfile b/src/add-ons/accelerants/Jamfile
index 1b10992..442e4c1 100644
--- a/src/add-ons/accelerants/Jamfile
+++ b/src/add-ons/accelerants/Jamfile
@@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons accelerants 3dfx ;
 SubInclude HAIKU_TOP src add-ons accelerants ati ;
 SubInclude HAIKU_TOP src add-ons accelerants common ;
 SubInclude HAIKU_TOP src add-ons accelerants et6x00 ;
+SubInclude HAIKU_TOP src add-ons accelerants intel_810 ;
 SubInclude HAIKU_TOP src add-ons accelerants intel_extreme ;
 SubInclude HAIKU_TOP src add-ons accelerants matrox ;
 SubInclude HAIKU_TOP src add-ons accelerants neomagic ;
diff --git a/src/add-ons/accelerants/intel_810/Jamfile 
b/src/add-ons/accelerants/intel_810/Jamfile
new file mode 100644
index 0000000..3fcb69e
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/Jamfile
@@ -0,0 +1,19 @@
+SubDir HAIKU_TOP src add-ons accelerants intel_810 ;
+
+UsePrivateHeaders graphics ;
+UsePrivateHeaders [ FDirName graphics intel_810 ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
+
+Addon intel_810.accelerant :
+       accelerant.cpp
+       engine.cpp
+       hooks.cpp
+       mode.cpp
+
+       i810_dpms.cpp
+       i810_init.cpp
+       i810_mode.cpp
+       i810_watermark.cpp
+
+       : be libaccelerantscommon.a
+;
diff --git a/src/add-ons/accelerants/intel_810/accelerant.cpp 
b/src/add-ons/accelerants/intel_810/accelerant.cpp
new file mode 100644
index 0000000..475847c
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/accelerant.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#include "accelerant.h"
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+
+
+AccelerantInfo gInfo;  // global data used by source files of accelerant
+
+static uint32 videoValue;
+
+
+static int32
+SuppressArtifacts(void* dataPtr)
+{
+       // The Intel 810 & 815 video chips create annoying artifacts which are
+       // most noticeable when the cursor is moved by itself or the user goes 
up
+       // and down through a menu.  However, if a large number of video memory
+       // locations are accessed frequently like when the GLTeapot demo is
+       // running, the artifacts are greatly suppressed.  Thus, that is the 
reason
+       // why this function accesses a large number of video memory locations
+       // frequently.  Note that the accessed memory locations are at the end 
of
+       // the video memory.  This is because some artifacts still occur at the
+       // top of the screen if the accessed memory is at the beginning of the
+       // video memory.
+       
+       // Note that this function will reduce the general performance of a
+       // computer somewhat, but it is much less of a hit than if double
+       // buffering was used for the video.  Base on the frame rate of the
+       // the GLTeapot demo, it is less than a 10% reduction.
+
+       SharedInfo& si = *((SharedInfo*)dataPtr);
+
+       while (true)
+       {
+               uint32* src = ((uint32*)(si.videoMemAddr)) + si.videoMemSize / 
4 - 1;
+               uint32 count = 65000;
+
+               while (count-- > 0)
+                       videoValue = *src--;
+
+               snooze(30000);          // sleep for 30 msec
+       }
+
+       return 0;
+}
+
+
+static status_t
+InitCommon(int fileDesc)
+{
+       // Initialization function used by primary and cloned accelerants.
+
+       gInfo.deviceFileDesc = fileDesc;
+
+       // Get area ID of shared data from driver.
+
+       area_id sharedArea;
+       status_t result = ioctl(gInfo.deviceFileDesc, INTEL_GET_SHARED_DATA,
+               &sharedArea, sizeof(sharedArea));
+       if (result != B_OK)
+               return result;
+
+       gInfo.sharedInfoArea = clone_area("i810 shared info",
+               (void**)&(gInfo.sharedInfo), B_ANY_ADDRESS, B_READ_AREA | 
B_WRITE_AREA,
+               sharedArea);
+       if (gInfo.sharedInfoArea < 0)
+               return gInfo.sharedInfoArea;    // sharedInfoArea has error code
+
+       gInfo.regsArea = clone_area("i810 regs area", (void**)&(gInfo.regs),
+               B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, 
gInfo.sharedInfo->regsArea);
+       if (gInfo.regsArea < 0) {
+               delete_area(gInfo.sharedInfoArea);
+               return gInfo.regsArea;          // regsArea has error code
+       }
+
+       return B_OK;
+}
+
+
+static void
+UninitCommon(void)
+{
+       // This function is used by both primary and cloned accelerants.
+
+       delete_area(gInfo.regsArea);
+       gInfo.regs = 0;
+
+       delete_area(gInfo.sharedInfoArea);
+       gInfo.sharedInfo = 0;
+}
+
+
+status_t
+InitAccelerant(int fileDesc)
+{
+       // Initialize the accelerant.   fileDesc is the file handle of the 
device
+       // (in /dev/graphics) that has been opened by the app_server.
+
+       TRACE("Enter InitAccelerant()\n");
+
+       gInfo.bAccelerantIsClone = false;       // indicate this is primary 
accelerant
+
+       status_t result = InitCommon(fileDesc);
+       if (result == B_OK) {
+               SharedInfo& si = *gInfo.sharedInfo;
+
+               TRACE("Vendor ID: 0x%X,  Device ID: 0x%X\n", si.vendorID, 
si.deviceID);
+
+               // Ensure that InitAccelerant is executed just once (copies 
should be
+               // clones)
+
+               if (si.bAccelerantInUse) {
+                       result = B_NOT_ALLOWED;
+               } else {
+                       result = I810_Init();   // perform init related to 
current chip
+                       if (result == B_OK) {
+                               result = si.engineLock.Init("i810 engine lock");
+                               if (result == B_OK) {
+                                       // Ensure that this function won't be 
executed again
+                                       // (copies should be clones)
+                                       si.bAccelerantInUse = true;
+                                       
+                                       thread_id threadID = 
spawn_thread(SuppressArtifacts,
+                                               "SuppressArtifacts_Thread", 
B_DISPLAY_PRIORITY,
+                                               gInfo.sharedInfo);
+                                       result = resume_thread(threadID);
+                               }
+                       }
+               }
+
+               if (result != B_OK)
+                       UninitCommon();
+       }
+
+       TRACE("Leave InitAccelerant(), result: 0x%X\n", result);
+       return result;
+}
+
+
+ssize_t
+AccelerantCloneInfoSize(void)
+{
+       // Return the number of bytes required to hold the information required
+       // to clone the device.  The information is merely the name of the 
device;
+       // thus, return the size of the name buffer.
+
+       return B_OS_NAME_LENGTH;
+}
+
+
+void
+GetAccelerantCloneInfo(void* data)
+{
+       // Return the info required to clone the device.  Argument data points 
to
+       // a buffer which is the size returned by AccelerantCloneInfoSize().
+
+       ioctl(gInfo.deviceFileDesc, INTEL_DEVICE_NAME, data, B_OS_NAME_LENGTH);
+}
+
+
+status_t
+CloneAccelerant(void* data)
+{
+       // Initialize a copy of the accelerant as a clone.  Argument data 
points to
+       // a copy of the data which was returned by GetAccelerantCloneInfo().
+
+       TRACE("Enter CloneAccelerant()\n");
+
+       char path[MAXPATHLEN] = "/dev/";
+       strcat(path, (const char*)data);
+
+       gInfo.deviceFileDesc = open(path, B_READ_WRITE);        // open the 
device
+       if (gInfo.deviceFileDesc < 0)
+               return errno;
+
+       gInfo.bAccelerantIsClone = true;
+
+       status_t result = InitCommon(gInfo.deviceFileDesc);
+       if (result != B_OK) {
+               close(gInfo.deviceFileDesc);
+               return result;
+       }
+
+       result = gInfo.modeListArea = clone_area("i810 cloned display_modes",
+               (void**) &gInfo.modeList, B_ANY_ADDRESS, B_READ_AREA,
+               gInfo.sharedInfo->modeArea);
+       if (result < 0) {
+               UninitCommon();
+               close(gInfo.deviceFileDesc);
+               return result;
+       }
+
+       TRACE("Leave CloneAccelerant()\n");
+       return B_OK;
+}
+
+
+void
+UninitAccelerant(void)
+{
+       delete_area(gInfo.modeListArea);
+       gInfo.modeList = NULL;
+
+       UninitCommon();
+
+       if (gInfo.bAccelerantIsClone)
+               close(gInfo.deviceFileDesc);
+}
+
+
+status_t
+GetAccelerantDeviceInfo(accelerant_device_info* adi)
+{
+       // Get info about the device.
+
+       SharedInfo& si = *gInfo.sharedInfo;
+
+       adi->version = 1;
+       strcpy(adi->name, "Intel 810/815 chipset");
+       strcpy(adi->chipset, si.chipName);
+       strcpy(adi->serial_no, "unknown");
+       adi->memory = si.maxFrameBufferSize;
+       adi->dac_speed = 270;
+
+       return B_OK;
+}
diff --git a/src/add-ons/accelerants/intel_810/accelerant.h 
b/src/add-ons/accelerants/intel_810/accelerant.h
new file mode 100644
index 0000000..9406337
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/accelerant.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#ifndef _ACCELERANT_H
+#define _ACCELERANT_H
+
+#include "DriverInterface.h"
+
+
+
+#undef TRACE
+
+#ifdef ENABLE_DEBUG_TRACE
+extern "C" void  _sPrintf(const char* format, ...);
+#      define TRACE(x...) _sPrintf("i810: " x)
+#else
+#      define TRACE(x...) ;
+#endif
+
+
+// Global data used by various source files of the accelerant.
+
+struct AccelerantInfo {
+       int                     deviceFileDesc;         // file descriptor of 
kernel driver
+
+       SharedInfo*     sharedInfo;                     // address of info 
shared between
+                                                                       // 
accelerants & driver
+       area_id         sharedInfoArea;         // shared info area ID
+
+       uint8*          regs;                           // base address of MMIO 
register area
+       area_id         regsArea;                       // MMIO register area ID
+
+       display_mode* modeList;                 // list of standard display 
modes
+       area_id         modeListArea;           // mode list area ID
+
+       bool            bAccelerantIsClone;     // true if this is a cloned 
accelerant
+};
+
+extern AccelerantInfo gInfo;
+
+
+// Prototypes of the interface functions called by the app_server.  Note that
+// the functions that are unique to a particular chip family, will be prefixed
+// with the name of the family, and the functions that are applicable to all
+// chips will have no prefix.
+//================================================================
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+// General
+status_t InitAccelerant(int fd);
+ssize_t  AccelerantCloneInfoSize(void);
+void    GetAccelerantCloneInfo(void* data);
+status_t CloneAccelerant(void* data);
+void    UninitAccelerant(void);
+status_t GetAccelerantDeviceInfo(accelerant_device_info* adi);
+
+// Mode Configuration
+uint32  AccelerantModeCount(void);
+status_t GetModeList(display_mode* dm);
+status_t ProposeDisplayMode(display_mode* target, const display_mode* low,
+                       const display_mode* high);
+status_t SetDisplayMode(display_mode* mode_to_set);
+status_t GetDisplayMode(display_mode* current_mode);
+status_t GetFrameBufferConfig(frame_buffer_config* a_frame_buffer);
+status_t GetPixelClockLimits(display_mode* dm, uint32* low, uint32* high);
+status_t MoveDisplay(uint16 h_display_start, uint16 v_display_start);
+void    I810_SetIndexedColors(uint count, uint8 first, uint8* color_data,
+                       uint32 flags);
+status_t GetEdidInfo(void* info, size_t size, uint32* _version);
+
+// DPMS
+uint32   I810_DPMSCapabilities(void);
+uint32   I810_GetDPMSMode(void);
+status_t I810_SetDPMSMode(uint32 dpms_flags);
+
+// Engine Management
+uint32   AccelerantEngineCount(void);
+status_t AcquireEngine(uint32 capabilities, uint32 max_wait, sync_token* st,
+                       engine_token** et);
+status_t ReleaseEngine(engine_token* et, sync_token* st);
+void    WaitEngineIdle(void);
+status_t GetSyncToken(engine_token* et, sync_token* st);
+status_t SyncToToken(sync_token* st);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+
+// Prototypes for other functions that are called from source files other than
+// where they are defined.
+//============================================================================
+
+status_t CreateModeList(bool (*checkMode)(const display_mode* mode));
+bool    IsModeUsable(const display_mode* mode);
+
+// Intel 810 functions.
+
+status_t I810_Init(void);
+bool    I810_GetColorSpaceParams(int colorSpace, uint8& bpp,
+                       uint32& maxPixelClk);
+uint32  I810_GetWatermark(const DisplayModeEx& mode);
+
+void    I810_AdjustFrame(const DisplayModeEx& mode);
+status_t I810_SetDisplayMode(const DisplayModeEx& mode);
+
+
+#endif // _ACCELERANT_H
diff --git a/src/add-ons/accelerants/intel_810/engine.cpp 
b/src/add-ons/accelerants/intel_810/engine.cpp
new file mode 100644
index 0000000..87e2413
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/engine.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#include "accelerant.h"
+#include "i810_regs.h"
+
+
+static engine_token sEngineToken = { 1, B_2D_ACCELERATION, NULL };
+
+
+uint32
+AccelerantEngineCount(void)
+{
+       return 1;
+}
+
+
+status_t
+AcquireEngine(uint32 capabilities, uint32 maxWait,
+                       sync_token* syncToken, engine_token** engineToken)
+{
+       (void)capabilities;     // avoid compiler warning for unused arg
+       (void)maxWait;          // avoid compiler warning for unused arg
+
+       if (gInfo.sharedInfo->engineLock.Acquire() != B_OK)
+               return B_ERROR;
+
+       if (syncToken)
+               SyncToToken(syncToken);
+
+       *engineToken = &sEngineToken;
+       return B_OK;
+}
+
+
+status_t
+ReleaseEngine(engine_token* engineToken, sync_token* syncToken)
+{
+       if (syncToken)
+               GetSyncToken(engineToken, syncToken);
+
+       gInfo.sharedInfo->engineLock.Release();
+       return B_OK;
+}
+
+
+void
+WaitEngineIdle(void)
+{
+       // Wait until engine is idle.
+
+       int k = 10000000;
+       
+       while ((INREG16(INST_DONE) & 0x7B) != 0x7B && k > 0)
+               k--; 
+}
+
+
+status_t
+GetSyncToken(engine_token* engineToken, sync_token* syncToken)
+{
+       syncToken->engine_id = engineToken->engine_id;
+       syncToken->counter = 0;
+       return B_OK;
+}
+
+
+status_t
+SyncToToken(sync_token* syncToken)
+{
+       (void)syncToken;                // avoid compiler warning for unused arg
+
+       WaitEngineIdle();
+       return B_OK;
+}
+
diff --git a/src/add-ons/accelerants/intel_810/hooks.cpp 
b/src/add-ons/accelerants/intel_810/hooks.cpp
new file mode 100644
index 0000000..b06a95a
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/hooks.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#include "accelerant.h"
+
+
+extern "C" void*
+get_accelerant_hook(uint32 feature, void* data)
+{
+       (void)data;             // avoid compiler warning for unused arg
+
+       switch (feature) {
+               // General
+               case B_INIT_ACCELERANT:
+                       return (void*)InitAccelerant;
+               case B_UNINIT_ACCELERANT:
+                       return (void*)UninitAccelerant;
+               case B_CLONE_ACCELERANT:
+                       return (void*)CloneAccelerant;
+               case B_ACCELERANT_CLONE_INFO_SIZE:
+                       return (void*)AccelerantCloneInfoSize;
+               case B_GET_ACCELERANT_CLONE_INFO:
+                       return (void*)GetAccelerantCloneInfo;
+               case B_GET_ACCELERANT_DEVICE_INFO:
+                       return (void*)GetAccelerantDeviceInfo;
+               case B_ACCELERANT_RETRACE_SEMAPHORE:
+                       return NULL;
+
+               // Mode Configuration
+               case B_ACCELERANT_MODE_COUNT:
+                       return (void*)AccelerantModeCount;
+               case B_GET_MODE_LIST:
+                       return (void*)GetModeList;
+               case B_PROPOSE_DISPLAY_MODE:
+                       return (void*)ProposeDisplayMode;
+               case B_SET_DISPLAY_MODE:
+                       return (void*)SetDisplayMode;
+               case B_GET_DISPLAY_MODE:
+                       return (void*)GetDisplayMode;
+#ifdef __HAIKU__
+               case B_GET_EDID_INFO:
+                       return (void*)GetEdidInfo;
+#endif
+               case B_GET_FRAME_BUFFER_CONFIG:
+                       return (void*)GetFrameBufferConfig;
+               case B_GET_PIXEL_CLOCK_LIMITS:
+                       return (void*)GetPixelClockLimits;
+               case B_MOVE_DISPLAY:
+                       return (void*)MoveDisplay;
+               case B_SET_INDEXED_COLORS:
+                       return (void*)(I810_SetIndexedColors);
+               case B_GET_TIMING_CONSTRAINTS:
+                       return NULL;
+
+               // DPMS
+               case B_DPMS_CAPABILITIES:
+                       return (void*)(I810_DPMSCapabilities);
+               case B_DPMS_MODE:
+                       return (void*)(I810_GetDPMSMode);
+               case B_SET_DPMS_MODE:
+                       return (void*)(I810_SetDPMSMode);
+
+               // Engine Management
+               case B_ACCELERANT_ENGINE_COUNT:
+                       return (void*)AccelerantEngineCount;
+               case B_ACQUIRE_ENGINE:
+                       return (void*)AcquireEngine;
+               case B_RELEASE_ENGINE:
+                       return (void*)ReleaseEngine;
+               case B_WAIT_ENGINE_IDLE:
+                       return (void*)WaitEngineIdle;
+               case B_GET_SYNC_TOKEN:
+                       return (void*)GetSyncToken;
+               case B_SYNC_TO_TOKEN:
+                       return (void*)SyncToToken;
+       }
+
+       return NULL;    // Return null pointer for any feature not handled above
+}
diff --git a/src/add-ons/accelerants/intel_810/i810_dpms.cpp 
b/src/add-ons/accelerants/intel_810/i810_dpms.cpp
new file mode 100644
index 0000000..f49361d
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/i810_dpms.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+/*!
+       Haiku Intel-810 video driver was adapted from the X.org intel driver 
which
+       has the following copyright.
+
+       Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+       All Rights Reserved.
+ */
+
+
+#include "accelerant.h"
+#include "i810_regs.h"
+
+
+#define DPMS_SYNC_SELECT       0x5002
+#define H_SYNC_OFF                     0x02
+#define V_SYNC_OFF                     0x08
+
+
+uint32
+I810_DPMSCapabilities(void)
+{
+       // Return DPMS modes supported by this device.
+
+       return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
+}
+
+
+uint32
+I810_GetDPMSMode(void)
+{
+       // Return the current DPMS mode.
+
+       uint32 tmp = INREG8(DPMS_SYNC_SELECT) & (H_SYNC_OFF | V_SYNC_OFF);
+       uint32 mode;
+
+       if (tmp == 0 )
+               mode = B_DPMS_ON;
+       else if (tmp == H_SYNC_OFF)
+               mode = B_DPMS_STAND_BY;
+       else if (tmp == V_SYNC_OFF)
+               mode = B_DPMS_SUSPEND;
+       else
+               mode = B_DPMS_OFF;
+
+       TRACE("I810_DPMSMode() mode: %d\n", mode);
+       return mode;
+}
+
+
+status_t
+I810_SetDPMSMode(uint32 dpmsMode)
+{
+       // Set the display into one of the Display Power Management modes,
+       // and return B_OK if successful, else return B_ERROR.
+
+       TRACE("I810_SetDPMSMode() mode: %d\n", dpmsMode);
+
+       uint8 seq01 = ReadSeqReg(1) & ~0x20;
+       uint8 dpmsSyncSelect = 0;
+
+       switch (dpmsMode) {
+               case B_DPMS_ON:
+                       // Screen: On; HSync: On, VSync: On.
+                       break;
+
+               case B_DPMS_STAND_BY:
+                       // Screen: Off; HSync: Off, VSync: On.
+                       seq01 |= 0x20;
+                       dpmsSyncSelect = H_SYNC_OFF;
+                       break;
+
+               case B_DPMS_SUSPEND:
+                       // Screen: Off; HSync: On, VSync: Off.
+                       seq01 |= 0x20;
+                       dpmsSyncSelect = V_SYNC_OFF;
+                       break;
+
+               case B_DPMS_OFF:
+                       // Screen: Off; HSync: Off, VSync: Off.
+                       seq01 |= 0x20;
+                       dpmsSyncSelect = H_SYNC_OFF | V_SYNC_OFF;
+                       break;
+
+               default:
+                       TRACE("Invalid DPMS mode %d\n", dpmsMode);
+                       return B_ERROR;
+       }
+
+       WriteSeqReg(1, seq01);          // turn the screen on/off
+       OUTREG8(DPMS_SYNC_SELECT, dpmsSyncSelect);              // set DPMS mode
+
+       return B_OK;
+}
diff --git a/src/add-ons/accelerants/intel_810/i810_init.cpp 
b/src/add-ons/accelerants/intel_810/i810_init.cpp
new file mode 100644
index 0000000..3c4f4c0
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/i810_init.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+/*!
+       Haiku Intel-810 video driver was adapted from the X.org intel driver 
which
+       has the following copyright.
+
+       Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+       All Rights Reserved.
+ */
+
+
+#include "accelerant.h"
+#include "i810_regs.h"
+
+
+
+bool
+I810_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel,
+                                                uint32& maxPixelClock)
+{
+       // Get parameters for a color space which is supported by the i810 
chips.
+       // Argument maxPixelClock is in KHz.
+       // Return true if the color space is supported;  else return false.
+
+       switch (colorSpace) {
+               case B_RGB16:
+                       bitsPerPixel = 16;
+                       maxPixelClock = 163000;
+                       break;
+                       break;
+               case B_CMAP8:
+                       bitsPerPixel = 8;
+                       maxPixelClock = 203000;
+                       break;
+               default:
+                       TRACE("Unsupported color space: 0x%X\n", colorSpace);
+                       return false;
+       }
+
+       return true;
+}
+
+
+status_t
+I810_Init(void)
+{
+       TRACE("I810_Init()\n");
+
+       SharedInfo& si = *gInfo.sharedInfo;
+
+       // Use all of video memory for the frame buffer.
+
+       si.maxFrameBufferSize = si.videoMemSize;
+
+       // Set up the array of the supported color spaces.
+
+       si.colorSpaces[0] = B_CMAP8;
+       si.colorSpaces[1] = B_RGB16;
+       si.colorSpaceCount = 2;
+
+       // Setup the mode list.
+
+       return CreateModeList(IsModeUsable);
+}
diff --git a/src/add-ons/accelerants/intel_810/i810_mode.cpp 
b/src/add-ons/accelerants/intel_810/i810_mode.cpp
new file mode 100644
index 0000000..3c95d5f
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/i810_mode.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+*/
+
+/*!
+       Haiku Intel-810 video driver was adapted from the X.org intel driver 
which
+       has the following copyright.
+
+       Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+       All Rights Reserved.
+ */
+
+#include "accelerant.h"
+#include "i810_regs.h"
+
+#include <create_display_modes.h>              // common accelerant header file
+#include <math.h>
+#include <unistd.h>
+
+
+
+// I810_CalcVCLK -- Determine closest clock frequency to the one requested.
+
+#define MAX_VCO_FREQ 600.0
+#define TARGET_MAX_N 30
+#define REF_FREQ        24.0
+
+#define CALC_VCLK(m,n,p) (double)m / ((double)n * (1 << p)) * 4 * REF_FREQ
+
+static void
+CalcVCLK(double freq, uint16& clkM, uint16& clkN, uint16& clkP) {
+       int m, n, p;
+       double f_out, f_best;
+       double f_err;
+       double f_vco;
+       int m_best = 0, n_best = 0, p_best = 0;
+       double f_target = freq;
+       double errMax = 0.005;
+       double errTarget = 0.001;
+       double errBest = 999999.0;
+
+       p_best = p = int(log(MAX_VCO_FREQ / f_target) / log((double)2));
+       // Make sure p is within range.
+       if (p_best > 5) {
+               p_best = p = 5;
+       }
+
+       f_vco = f_target * (1 << p);
+
+       n = 2;
+       do {
+               n++;
+               m = int(f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5);
+               if (m < 3)
+                       m = 3;
+               f_out = CALC_VCLK(m, n, p);
+               f_err = 1.0 - (f_target / f_out);
+               if (fabs(f_err) < errMax) {
+                       m_best = m;
+                       n_best = n;
+                       f_best = f_out;
+                       errBest = f_err;
+               }
+       } while ((fabs(f_err) >= errTarget) &&
+                        ((n <= TARGET_MAX_N) || (fabs(errBest) > errMax)));
+
+       if (fabs(f_err) < errTarget) {
+               m_best = m;
+               n_best = n;
+       }
+
+       clkM = (m_best - 2) & 0x3FF;
+       clkN = (n_best - 2) & 0x3FF;
+       clkP = (p_best << 4);
+
+       TRACE("Setting dot clock to %.1f MHz [ 0x%x 0x%x 0x%x ] [ %d %d %d ]\n",
+               CALC_VCLK(m_best, n_best, p_best),
+               clkM, clkN, clkP, m_best, n_best, p_best);
+}
+
+
+static void 
+SetCrtcTimingValues(const DisplayModeEx& mode)
+{
+       // Set the timing values for CRTC registers cr00 to cr18, and some 
extended
+       // CRTC registers.
+
+       int hTotal = mode.timing.h_total / 8 - 5;
+       int hDisp_e = mode.timing.h_display / 8 - 1;
+       int hSync_s = mode.timing.h_sync_start / 8;
+       int hSync_e = mode.timing.h_sync_end / 8;
+       int hBlank_s = hDisp_e + 1;             // start of horizontal blanking
+       int hBlank_e = hTotal;                  // end of horizontal blanking
+
+       int vTotal = mode.timing.v_total - 2;
+       int vDisp_e = mode.timing.v_display - 1;
+       int vSync_s = mode.timing.v_sync_start;
+       int vSync_e = mode.timing.v_sync_end;
+       int vBlank_s = vDisp_e;                 // start of vertical blanking
+       int vBlank_e = vTotal;                  // end of vertical blanking
+
+       uint16 offset = mode.bytesPerRow / 8;
+       
+       // CRTC Controller values
+
+       uint8 crtc[25];
+       crtc[0x00] = hTotal;
+       crtc[0x01] = hDisp_e;
+       crtc[0x02] = hBlank_s;
+       crtc[0x03] = (hBlank_e & 0x1f) | 0x80;
+       crtc[0x04] = hSync_s;
+       crtc[0x05] = ((hSync_e & 0x1f) | ((hBlank_e & 0x20) << 2));
+       crtc[0x06] = vTotal;
+       crtc[0x07] = (((vTotal & 0x100) >> 8)
+               | ((vDisp_e & 0x100) >> 7)
+               | ((vSync_s & 0x100) >> 6)
+               | ((vBlank_s & 0x100) >> 5)
+               | 0x10
+               | ((vTotal & 0x200) >> 4)
+               | ((vDisp_e & 0x200) >> 3)
+               | ((vSync_s & 0x200) >> 2));
+
+       crtc[0x08] = 0x00;
+       crtc[0x09] = ((vBlank_s & 0x200) >> 4) | 0x40;
+       crtc[0x0a] = 0x00;
+       crtc[0x0b] = 0x00;
+       crtc[0x0c] = 0x00;
+       crtc[0x0d] = 0x00;
+       crtc[0x0e] = 0x00;
+       crtc[0x0f] = 0x00;
+       crtc[0x10] = vSync_s;
+       crtc[0x11] = (vSync_e & 0x0f) | 0x20;
+       crtc[0x12] = vDisp_e;
+       crtc[0x13] = offset;
+       crtc[0x14] = 0x00;
+       crtc[0x15] = vBlank_s;
+       crtc[0x16] = vBlank_e;
+       crtc[0x17] = 0xc3;
+       crtc[0x18] = 0xff;
+
+       // Set the standard CRTC vga regs;  however, before setting them, unlock
+       // CRTC reg's 0-7 by clearing bit 7 of cr11
+
+       WriteCrtcReg(0x11, crtc[0x11] & ~0x80);
+
+       for (uint8 j = 0; j <= 0x18; j++)
+               WriteCrtcReg(j, crtc[j]);
+
+       // Set the extended CRTC reg's.
+       
+       WriteCrtcReg(EXT_VERT_TOTAL, vTotal >> 8);
+       WriteCrtcReg(EXT_VERT_DISPLAY, vDisp_e >> 8);
+       WriteCrtcReg(EXT_VERT_SYNC_START, vSync_s >> 8);
+       WriteCrtcReg(EXT_VERT_BLANK_START, vBlank_s >> 8);
+       WriteCrtcReg(EXT_HORIZ_TOTAL, hTotal >> 8);
+       WriteCrtcReg(EXT_HORIZ_BLANK, (hBlank_e & 0x40) >> 6);
+       WriteCrtcReg(EXT_OFFSET, offset >> 8);
+
+       WriteCrtcReg(INTERLACE_CNTL, INTERLACE_DISABLE);        // turn off 
interlace
+       
+       // Enable high resolution mode.
+       WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL);
+}
+
+
+status_t
+I810_SetDisplayMode(const DisplayModeEx& mode)
+{
+       if (mode.bitsPerPixel != 8 && mode.bitsPerPixel != 16) {
+               // Only 8 & 16 bits/pixel are suppoted.
+               TRACE("Unsupported color depth: %d bpp\n", mode.bitsPerPixel);
+               return B_ERROR;
+       }
+
+       snooze(50000);
+
+       // Turn off DRAM refresh.
+       uint8 temp = INREG8(DRAM_ROW_CNTL_HI) & ~DRAM_REFRESH_RATE;
+       OUTREG8(DRAM_ROW_CNTL_HI, temp | DRAM_REFRESH_DISABLE);
+
+       snooze(1000);                   // wait 1 ms
+
+       // Calculate the VCLK that most closely matches the requested pixel 
clock,
+       // and then set the M, N, and P values.
+
+       uint16 m, n, p;
+       CalcVCLK(mode.timing.pixel_clock / 1000.0, m, n, p);
+
+       OUTREG16(VCLK2_VCO_M, m);
+       OUTREG16(VCLK2_VCO_N, n);
+       OUTREG8(VCLK2_VCO_DIV_SEL, p);
+
+       // Setup HSYNC & VSYNC polarity and select clock source 2 (0x08) for
+       // programmable PLL.
+
+       uint8 miscOutReg = 0x08 | 0x01;
+       if (!(mode.timing.flags & B_POSITIVE_HSYNC))
+               miscOutReg |= 0x40;
+       if (!(mode.timing.flags & B_POSITIVE_VSYNC))
+               miscOutReg |= 0x80;
+
+       OUTREG8(MISC_OUT_W, miscOutReg);
+
+       SetCrtcTimingValues(mode);
+
+       OUTREG32(MEM_MODE, INREG32(MEM_MODE) | 4);
+
+       // Set the address mapping to use the frame buffer memory mapped via the
+       // GTT table instead of the VGA buffer.
+       
+       uint8 addrMapping = ReadGraphReg(ADDRESS_MAPPING);
+       addrMapping &= 0xE0;            // preserve reserved bits 7:5
+       addrMapping |= (GTT_MEM_MAP_ENABLE | LINEAR_MODE_ENABLE);
+       WriteGraphReg(ADDRESS_MAPPING, addrMapping);
+
+       // Turn on DRAM refresh.
+       temp = INREG8(DRAM_ROW_CNTL_HI) & ~DRAM_REFRESH_RATE;
+       OUTREG8(DRAM_ROW_CNTL_HI, temp | DRAM_REFRESH_60HZ);
+
+       temp = INREG8(BITBLT_CNTL) & ~COLEXP_MODE;
+       temp |= (mode.bitsPerPixel == 8 ? COLEXP_8BPP : COLEXP_16BPP);
+       OUTREG8(BITBLT_CNTL, temp);
+       
+       // Turn on 8 bit dac mode so that the indexed colors are displayed 
properly,
+       // and put display in high resolution mode.
+
+       uint32 temp32 = INREG32(PIXPIPE_CONFIG) & 0xF3E062FC;
+       temp32 |= (DAC_8_BIT | HIRES_MODE | NO_BLANK_DELAY |
+               (mode.bitsPerPixel == 8 ? DISPLAY_8BPP_MODE : 
DISPLAY_16BPP_MODE));
+       OUTREG32(PIXPIPE_CONFIG, temp32);
+
+       OUTREG16(EIR, 0);
+
+       temp32 = INREG32(FWATER_BLC);
+       temp32 &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK |
+                          MM_BURST_LENGTH | MM_FIFO_WATERMARK);
+       temp32 |= I810_GetWatermark(mode);
+       OUTREG32(FWATER_BLC, temp32);
+
+       // Enable high resolution mode.
+       WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL);
+
+       I810_AdjustFrame(mode);         
+       return B_OK;
+}
+
+
+void
+I810_AdjustFrame(const DisplayModeEx& mode)
+{
+       // Adjust start address in frame buffer.
+
+       uint32 address = ((mode.v_display_start * mode.virtual_width
+                       + mode.h_display_start) * mode.bytesPerPixel) >> 2;
+
+       WriteCrtcReg(START_ADDR_LO, address & 0xff);
+       WriteCrtcReg(START_ADDR_HI, (address >> 8) & 0xff);
+       WriteCrtcReg(EXT_START_ADDR_HI, (address >> 22) & 0xff);
+       WriteCrtcReg(EXT_START_ADDR,
+                       ((address >> 16) & 0x3f) | EXT_START_ADDR_ENABLE);
+}
+
+
+void
+I810_SetIndexedColors(uint count, uint8 first, uint8* colorData, uint32 flags)
+{
+       // Set the indexed color palette for 8-bit color depth mode.
+
+       (void)flags;            // avoid compiler warning for unused arg
+
+       if (gInfo.sharedInfo->displayMode.space != B_CMAP8)
+               return ;
+
+       OUTREG8(DAC_MASK, 0xff);
+       OUTREG8(DAC_W_INDEX, first);            // initial color index
+
+       while (count--) {
+               OUTREG8(DAC_DATA, colorData[0]);        // red
+               OUTREG8(DAC_DATA, colorData[1]);        // green
+               OUTREG8(DAC_DATA, colorData[2]);        // blue
+
+               colorData += 3;
+       }
+}
diff --git a/src/add-ons/accelerants/intel_810/i810_regs.h 
b/src/add-ons/accelerants/intel_810/i810_regs.h
new file mode 100644
index 0000000..61ddc91
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/i810_regs.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+/*!
+       Haiku Intel-810 video driver was adapted from the X.org intel driver 
which
+       has the following copyright.
+
+       Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+       All Rights Reserved.
+ */
+
+#ifndef __I810_REGS_H__
+#define __I810_REGS_H__
+
+
+// CRT Controller Registers.
+#define START_ADDR_HI                  0x0C
+#define START_ADDR_LO                  0x0D
+#define VERT_SYNC_END                  0x11
+#define EXT_VERT_TOTAL                 0x30
+#define EXT_VERT_DISPLAY               0x31
+#define EXT_VERT_SYNC_START            0x32
+#define EXT_VERT_BLANK_START   0x33
+#define EXT_HORIZ_TOTAL                        0x35
+#define EXT_HORIZ_BLANK                        0x39
+#define EXT_START_ADDR                 0x40
+#define EXT_START_ADDR_ENABLE  0x80 
+#define EXT_OFFSET                             0x41
+#define EXT_START_ADDR_HI              0x42
+#define INTERLACE_CNTL                 0x70
+#define INTERLACE_ENABLE               0x80
+#define INTERLACE_DISABLE              0x00
+
+// CR80 - IO Control
+#define IO_CTNL                                        0x80
+#define EXTENDED_ATTR_CNTL             0x02
+#define EXTENDED_CRTC_CNTL             0x01
+
+// GR10 - Address mapping
+#define ADDRESS_MAPPING                        0x10
+#define PAGE_TO_LOCAL_MEM_ENABLE 0x10
+#define GTT_MEM_MAP_ENABLE             0x08
+#define PACKED_MODE_ENABLE             0x04
+#define LINEAR_MODE_ENABLE             0x02
+#define PAGE_MAPPING_ENABLE            0x01
+
+#define FENCE                  0x2000
+
+#define INST_DONE              0x2090
+
+// General error reporting regs.
+#define EIR                            0x20B0
+#define EMR                            0x20B4
+#define ESR                            0x20B8
+
+// FIFO Watermark and Burst Length Control Register.
+#define FWATER_BLC                     0x20d8
+#define MM_BURST_LENGTH                        0x00700000
+#define MM_FIFO_WATERMARK              0x0001F000
+#define LM_BURST_LENGTH                        0x00000700
+#define LM_FIFO_WATERMARK              0x0000001F
+
+#define MEM_MODE                       0x020DC
+
+#define DRAM_ROW_CNTL_HI       0x3002
+#define DRAM_REFRESH_RATE              0x18
+#define DRAM_REFRESH_DISABLE   0x00
+#define DRAM_REFRESH_60HZ              0x08
+
+#define VCLK2_VCO_M                    0x6008
+#define VCLK2_VCO_N                    0x600a
+#define VCLK2_VCO_DIV_SEL      0x6012
+
+#define PIXPIPE_CONFIG         0x70008
+#define NO_BLANK_DELAY                 0x100000
+#define DISPLAY_8BPP_MODE              0x020000
+#define DISPLAY_15BPP_MODE             0x040000
+#define DISPLAY_16BPP_MODE             0x050000
+#define DAC_8_BIT                              0x008000
+#define HIRES_MODE                             0x000001
+
+// Blitter control.
+#define BITBLT_CNTL                    0x7000c
+#define COLEXP_MODE                            0x30
+#define COLEXP_8BPP                            0x00
+#define COLEXP_16BPP                   0x10
+
+// Color Palette Registers.
+#define DAC_MASK               0x3C6
+#define DAC_W_INDEX            0x3C8
+#define DAC_DATA               0x3C9
+
+
+#define MISC_OUT_R             0x3CC           // read
+#define MISC_OUT_W             0x3C2           // write
+#define SEQ_INDEX              0x3C4
+#define SEQ_DATA               0x3C5
+#define GRAPH_INDEX            0x3CE
+#define GRAPH_DATA             0x3CF
+#define CRTC_INDEX             0x3D4
+#define CRTC_DATA              0x3D5
+
+
+// Macros for memory mapped I/O.
+//==============================
+
+#define INREG8(addr)           (*((vuint8*)(gInfo.regs + (addr))))
+#define INREG16(addr)          (*((vuint16*)(gInfo.regs + (addr))))
+#define INREG32(addr)          (*((vuint32*)(gInfo.regs + (addr))))
+
+#define OUTREG8(addr, val)     (*((vuint8*)(gInfo.regs + (addr))) = (val))
+#define OUTREG16(addr, val)    (*((vuint16*)(gInfo.regs + (addr))) = (val))
+#define OUTREG32(addr, val)    (*((vuint32*)(gInfo.regs + (addr))) = (val))
+
+// Write a value to an 32-bit reg using a mask.  The mask selects the
+// bits to be modified.
+#define OUTREGM(addr, value, mask)     \
+       (OUTREG(addr, (INREG(addr) & ~mask) | (value & mask)))
+
+
+static inline uint8 ReadCrtcReg(uint8 index)
+{
+       OUTREG8(CRTC_INDEX, index);
+       return INREG8(CRTC_DATA);
+}
+
+static inline void WriteCrtcReg(uint8 index, uint8 value)
+{
+       OUTREG8(CRTC_INDEX, index);
+       OUTREG8(CRTC_DATA, value);
+}
+
+static inline uint8 ReadGraphReg(uint8 index)
+{
+       OUTREG8(GRAPH_INDEX, index);
+       return INREG8(GRAPH_DATA);
+}
+
+static inline void WriteGraphReg(uint8 index, uint8 value)
+{
+       OUTREG8(GRAPH_INDEX, index);
+       OUTREG8(GRAPH_DATA, value);
+}
+
+static inline uint8 ReadSeqReg(uint8 index)
+{
+       OUTREG8(SEQ_INDEX, index);
+       return INREG8(SEQ_DATA);
+}
+
+static inline void WriteSeqReg(uint8 index, uint8 value)
+{
+       OUTREG8(SEQ_INDEX, index);
+       OUTREG8(SEQ_DATA, value);
+}
+
+
+#endif // __I810_REGS_H__
diff --git a/src/add-ons/accelerants/intel_810/i810_watermark.cpp 
b/src/add-ons/accelerants/intel_810/i810_watermark.cpp
new file mode 100644
index 0000000..8d0cb1d
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/i810_watermark.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+// The code in this file was adapted from the X.org intel driver which had
+// the following copyright and license.
+
+/**************************************************************************
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************/
+
+#include "accelerant.h"
+
+
+struct WatermarkInfo {
+       double freq;
+       uint32 watermark;
+};
+
+static WatermarkInfo watermarks_8[] = {
+       {       0, 0x22003000},
+       {25.2, 0x22003000},
+       {28.0, 0x22003000},
+       {31.5, 0x22003000},
+       {36.0, 0x22007000},
+       {40.0, 0x22007000},
+       {45.0, 0x22007000},
+       {49.5, 0x22008000},
+       {50.0, 0x22008000},
+       {56.3, 0x22008000},
+       {65.0, 0x22008000},
+       {75.0, 0x22008000},
+       {78.8, 0x22008000},
+       {80.0, 0x22008000},
+       {94.0, 0x22008000},
+       {96.0, 0x22107000},
+       {99.0, 0x22107000},
+       {108.0, 0x22107000},
+       {121.0, 0x22107000},
+       {128.9, 0x22107000},
+       {132.0, 0x22109000},
+       {135.0, 0x22109000},
+       {157.5, 0x2210b000},
+       {162.0, 0x2210b000},
+       {175.5, 0x2210b000},
+       {189.0, 0x2220e000},
+       {202.5, 0x2220e000}
+};
+
+static WatermarkInfo watermarks_16[] = {
+       {       0, 0x22004000},
+       {25.2, 0x22006000},
+       {28.0, 0x22006000},
+       {31.5, 0x22007000},
+       {36.0, 0x22007000},
+       {40.0, 0x22007000},
+       {45.0, 0x22007000},
+       {49.5, 0x22009000},
+       {50.0, 0x22009000},
+       {56.3, 0x22108000},
+       {65.0, 0x2210e000},
+       {75.0, 0x2210e000},
+       {78.8, 0x2210e000},
+       {80.0, 0x22210000},
+       {94.5, 0x22210000},
+       {96.0, 0x22210000},
+       {99.0, 0x22210000},
+       {108.0, 0x22210000},
+       {121.0, 0x22210000},
+       {128.9, 0x22210000},
+       {132.0, 0x22314000},
+       {135.0, 0x22314000},
+       {157.5, 0x22415000},
+       {162.0, 0x22416000},
+       {175.5, 0x22416000},
+       {189.0, 0x22416000},
+       {195.0, 0x22416000},
+       {202.5, 0x22416000}
+};
+
+
+
+uint32
+I810_GetWatermark(const DisplayModeEx& mode)
+{
+       WatermarkInfo *table;
+       uint32 tableLen;
+
+       // Get burst length and FIFO watermark based upon the bus frequency and
+       // pixel clock.
+
+       switch (mode.bitsPerPixel) {
+       case 8:
+               table = watermarks_8;
+               tableLen = ARRAY_SIZE(watermarks_8);
+               break;
+       case 16:
+               table = watermarks_16;
+               tableLen = ARRAY_SIZE(watermarks_16);
+               break;
+       default:
+               return 0;
+       }
+
+       uint32 i;
+       double clockFreq = mode.timing.pixel_clock / 1000.0;
+
+       for (i = 0; i < tableLen && table[i].freq < clockFreq; i++)
+               ;
+
+       if (i == tableLen)
+               i--;
+
+       TRACE("chosen watermark 0x%lx  (freq %f)\n", table[i].watermark,
+               table[i].freq);
+
+       return table[i].watermark;
+}
diff --git a/src/add-ons/accelerants/intel_810/mode.cpp 
b/src/add-ons/accelerants/intel_810/mode.cpp
new file mode 100644
index 0000000..9f95ccc
--- /dev/null
+++ b/src/add-ons/accelerants/intel_810/mode.cpp
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#include "accelerant.h"
+
+#include <create_display_modes.h>              // common accelerant header file
+#include <string.h>
+#include <unistd.h>
+
+
+
+static bool
+IsThereEnoughFBMemory(const display_mode* mode, uint32 bitsPerPixel)
+{
+       // Test if there is enough Frame Buffer memory for the mode and color 
depth
+       // specified by the caller, and return true if there is sufficient 
memory.
+
+       uint32 maxWidth = mode->virtual_width;
+       if (mode->timing.h_display > maxWidth)
+               maxWidth = mode->timing.h_display;
+
+       uint32 maxHeight = mode->virtual_height;
+       if (mode->timing.v_display > maxHeight)
+               maxHeight = mode->timing.v_display;
+
+       uint32 bytesPerPixel = (bitsPerPixel + 7) / 8;
+
+       return (maxWidth * maxHeight * bytesPerPixel
+                       <= gInfo.sharedInfo->maxFrameBufferSize);
+}
+
+
+
+bool
+IsModeUsable(const display_mode* mode)
+{
+       // Test if the display mode is usable by the current video chip.  That 
is,
+       // does the chip have enough memory for the mode and is the pixel clock
+       // within the chips allowable range, etc.
+       //
+       // Return true if the mode is usable.
+
+       SharedInfo& si = *gInfo.sharedInfo;
+       uint8 bitsPerPixel;
+       uint32 maxPixelClock;
+
+       if (!I810_GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock))
+               return false;
+
+       // Is there enough frame buffer memory to handle the mode?
+
+       if (!IsThereEnoughFBMemory(mode, bitsPerPixel))
+               return false;
+
+       if (mode->timing.pixel_clock > maxPixelClock)
+               return false;
+
+       // Is the color space supported?
+
+       bool colorSpaceSupported = false;
+       for (uint32 j = 0; j < si.colorSpaceCount; j++) {
+               if (mode->space == uint32(si.colorSpaces[j])) {
+                       colorSpaceSupported = true;
+                       break;
+               }
+       }
+
+       if (!colorSpaceSupported)
+               return false;
+
+       // Reject modes with a width of 640 and a height < 480 since they do not
+       // work properly with the i810 chipsets.
+
+       if (mode->timing.h_display == 640 && mode->timing.v_display < 480)
+               return false;
+
+       return true;
+}
+
+
+status_t
+CreateModeList(bool (*checkMode)(const display_mode* mode))
+{
+       SharedInfo& si = *gInfo.sharedInfo;
+
+       // Obtain EDID info which is needed for for building the mode list.
+
+       si.bHaveEDID = false;
+
+       if (!si.bHaveEDID) {
+               edid1_raw rawEdid;      // raw EDID info to obtain
+
+               if (ioctl(gInfo.deviceFileDesc, INTEL_GET_EDID, &rawEdid,
+                               sizeof(rawEdid)) == B_OK) {
+                       if (rawEdid.version.version != 1 || 
rawEdid.version.revision > 4) {
+                               TRACE("CreateModeList(); EDID version %d.%d out 
of range\n",
+                                       rawEdid.version.version, 
rawEdid.version.revision);
+                       } else {
+                               edid_decode(&si.edidInfo, &rawEdid);    // 
decode & save EDID info
+                               si.bHaveEDID = true;
+                       }
+               }
+
+               if (si.bHaveEDID) {
+#ifdef ENABLE_DEBUG_TRACE
+                       edid_dump(&(si.edidInfo));
+#endif
+               } else {
+                       TRACE("CreateModeList(); Unable to get EDID info\n");
+               }
+       }
+
+       display_mode* list;
+       uint32 count = 0;
+       area_id listArea;
+
+       listArea = create_display_modes("i810 modes",
+               si.bHaveEDID ? &si.edidInfo : NULL,
+               NULL, 0, si.colorSpaces, si.colorSpaceCount,
+               (check_display_mode_hook)checkMode, &list, &count);
+
+       if (listArea < 0)
+               return listArea;                // listArea has error code
+
+       si.modeArea = gInfo.modeListArea = listArea;
+       si.modeCount = count;
+       gInfo.modeList = list;
+       return B_OK;
+}
+
+
+
+status_t
+ProposeDisplayMode(display_mode* target, const display_mode* low,
+       const display_mode* high)
+{
+       (void)low;              // avoid compiler warning for unused arg
+       (void)high;             // avoid compiler warning for unused arg
+
+       TRACE("ProposeDisplayMode()  %dx%d, pixel clock: %d kHz, space: 0x%X\n",
+               target->timing.h_display, target->timing.v_display,
+               target->timing.pixel_clock, target->space);
+
+       // Search the mode list for the specified mode.
+
+       uint32 modeCount = gInfo.sharedInfo->modeCount;
+
+       for (uint32 j = 0; j < modeCount; j++) {
+               display_mode& mode = gInfo.modeList[j];
+
+               if (target->timing.h_display == mode.timing.h_display
+                       && target->timing.v_display == mode.timing.v_display
+                       && target->space == mode.space)
+                       return B_OK;    // mode found in list
+       }
+
+       return B_BAD_VALUE;             // mode not found in list
+}
+
+
+status_t
+SetDisplayMode(display_mode* pMode)
+{
+       // First validate the mode, then call a function to set the registers.
+
+       TRACE("SetDisplayMode() begin\n");
+
+       SharedInfo& si = *gInfo.sharedInfo;
+       DisplayModeEx mode;
+       (display_mode&)mode = *pMode;
+
+       uint32 maxPixelClock;
+       if (!I810_GetColorSpaceParams(mode.space, mode.bitsPerPixel, 
maxPixelClock))
+               return B_BAD_VALUE;
+
+       if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK)
+               return B_BAD_VALUE;
+
+       mode.bytesPerPixel = (mode.bitsPerPixel + 7) / 8;
+       mode.bytesPerRow = mode.timing.h_display * mode.bytesPerPixel;
+
+       // Is there enough frame buffer memory for this mode?
+
+       if ( ! IsThereEnoughFBMemory(&mode, mode.bitsPerPixel))
+               return B_NO_MEMORY;
+
+       TRACE("Set display mode: %dx%d  virtual size: %dx%d  "
+               "color depth: %d bits/pixel\n",
+               mode.timing.h_display, mode.timing.v_display,
+               mode.virtual_width, mode.virtual_height, mode.bitsPerPixel);
+
+       TRACE("   mode timing: %d  %d %d %d %d  %d %d %d %d\n",
+               mode.timing.pixel_clock,
+               mode.timing.h_display,
+               mode.timing.h_sync_start, mode.timing.h_sync_end,
+               mode.timing.h_total,
+               mode.timing.v_display,
+               mode.timing.v_sync_start, mode.timing.v_sync_end,
+               mode.timing.v_total);
+
+       TRACE("   mode hFreq: %.1f kHz  vFreq: %.1f Hz  %chSync %cvSync\n",
+               double(mode.timing.pixel_clock) / mode.timing.h_total,
+               ((double(mode.timing.pixel_clock) / mode.timing.h_total) * 
1000.0)
+               / mode.timing.v_total,
+               (mode.timing.flags & B_POSITIVE_HSYNC) ? '+' : '-',
+               (mode.timing.flags & B_POSITIVE_VSYNC) ? '+' : '-');
+
+       status_t status = I810_SetDisplayMode(mode);
+       if (status != B_OK) {
+               TRACE("SetDisplayMode() failed;  status 0x%x\n", status);
+               return status;
+       }
+
+       si.displayMode = mode;
+
+       TRACE("SetDisplayMode() done\n");
+       return B_OK;
+}
+
+
+
+status_t
+MoveDisplay(uint16 horizontalStart, uint16 verticalStart)
+{
+       // Set which pixel of the virtual frame buffer will show up in the
+       // top left corner of the display device.       Used for page-flipping
+       // games and virtual desktops.
+
+       DisplayModeEx& mode = gInfo.sharedInfo->displayMode;
+
+       if (mode.timing.h_display + horizontalStart > mode.virtual_width
+               || mode.timing.v_display + verticalStart > mode.virtual_height)
+               return B_ERROR;
+
+       mode.h_display_start = horizontalStart;
+       mode.v_display_start = verticalStart;
+
+       I810_AdjustFrame(mode);
+       return B_OK;
+}
+
+
+uint32
+AccelerantModeCount(void)
+{
+       // Return the number of display modes in the mode list.
+
+       return gInfo.sharedInfo->modeCount;
+}
+
+
+status_t
+GetModeList(display_mode* dmList)
+{
+       // Copy the list of supported video modes to the location pointed at
+       // by dmList.
+
+       memcpy(dmList, gInfo.modeList,
+               gInfo.sharedInfo->modeCount * sizeof(display_mode));
+       return B_OK;
+}
+
+
+status_t
+GetDisplayMode(display_mode* current_mode)
+{
+       *current_mode = gInfo.sharedInfo->displayMode;  // return current 
display mode
+       return B_OK;
+}
+
+
+status_t
+GetFrameBufferConfig(frame_buffer_config* pFBC)
+{
+       SharedInfo& si = *gInfo.sharedInfo;
+
+       pFBC->frame_buffer = (void*)((addr_t)(si.videoMemAddr));
+       pFBC->frame_buffer_dma = (void*)((addr_t)(si.videoMemPCI));
+       pFBC->bytes_per_row = si.displayMode.virtual_width 
+               * si.displayMode.bytesPerPixel;
+
+       return B_OK;
+}
+
+
+status_t
+GetPixelClockLimits(display_mode* mode, uint32* low, uint32* high)
+{
+       // Return the maximum and minium pixel clock limits for the specified 
mode.
+
+       uint8 bitsPerPixel;
+       uint32 maxPixelClock;
+
+       if (!I810_GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock))
+               return B_ERROR;
+
+       if (low != NULL) {
+               // lower limit of about 48Hz vertical refresh
+               uint32 totalClocks = (uint32)mode->timing.h_total
+                       * (uint32)mode->timing.v_total;
+               uint32 lowClock = (totalClocks * 48L) / 1000L;
+               if (lowClock > maxPixelClock)
+                       return B_ERROR;
+
+               *low = lowClock;
+       }
+
+       if (high != NULL)
+               *high = maxPixelClock;
+
+       return B_OK;
+}
+
+
+
+#ifdef __HAIKU__
+
+status_t
+GetEdidInfo(void* info, size_t size, uint32* _version)
+{
+       SharedInfo& si = *gInfo.sharedInfo;
+
+       if ( ! si.bHaveEDID)
+               return B_ERROR;
+
+       if (size < sizeof(struct edid1_info))
+               return B_BUFFER_OVERFLOW;
+
+       memcpy(info, &si.edidInfo, sizeof(struct edid1_info));
+       *_version = EDID_VERSION_1;
+       return B_OK;
+}
+
+#endif // __HAIKU__
diff --git a/src/add-ons/kernel/drivers/graphics/Jamfile 
b/src/add-ons/kernel/drivers/graphics/Jamfile
index 79e0815..83781eb 100644
--- a/src/add-ons/kernel/drivers/graphics/Jamfile
+++ b/src/add-ons/kernel/drivers/graphics/Jamfile
@@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics 3dfx ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics ati ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics common ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics et6x00 ;
+SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_810 ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_extreme ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics matrox ;
 SubInclude HAIKU_TOP src add-ons kernel drivers graphics neomagic ;
diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile 
b/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile
new file mode 100644
index 0000000..b118373
--- /dev/null
+++ b/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile
@@ -0,0 +1,9 @@
+SubDir HAIKU_TOP src add-ons kernel drivers graphics intel_810 ;
+
+UsePrivateHeaders [ FDirName graphics intel_810 ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
+UsePrivateHeaders graphics kernel ;
+
+KernelAddon intel_810 :
+       driver.cpp
+;
diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp 
b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp
new file mode 100644
index 0000000..f411ae7
--- /dev/null
+++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp
@@ -0,0 +1,674 @@
+/*
+ * Copyright 2007-2012 Haiku, Inc.  All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Gerald Zajac
+ */
+
+#include <AGP.h>
+#include <KernelExport.h>
+#include <PCI.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <graphic_driver.h>
+#include <boot_item.h>
+#include <arch/x86/vm86.h>
+
+#include "DriverInterface.h"
+
+
+#undef TRACE
+
+#ifdef ENABLE_DEBUG_TRACE
+#      define TRACE(x...) dprintf("i810: " x)
+#else
+#      define TRACE(x...) ;
+#endif
+
+
+#define ACCELERANT_NAME    "intel_810.accelerant"
+
+#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 
1))
+
+#define MAX_DEVICES            4
+#define DEVICE_FORMAT  "%04X_%04X_%02X%02X%02X"
+
+#define VENDOR_ID      0x8086  // Intel vendor ID
+
+
+struct ChipInfo {
+       uint16          chipID;         // PCI device id of the chip
+       const char*     chipName;       // user recognizable name (must be < 32 
chars)
+};
+
+
+// This table maps a PCI device ID to a chip type identifier and the chip name.
+
+static const ChipInfo chipTable[] = {
+       { 0x7121, "i810"        },
+       { 0x7123, "i810-dc100"  },
+       { 0x7125, "i810e"       },
+       { 0x1132, "i815"        },
+       { 0,    NULL }
+};
+
+
+struct DeviceInfo {
+       uint32                  openCount;              // count of how many 
times device has been opened
+       int32                   flags;
+       area_id                 sharedArea;             // area shared between 
driver and accelerants
+       SharedInfo*     sharedInfo;             // pointer to shared info area 
memory
+       vuint8*                 regs;                   // pointer to memory 
mapped registers
+       const ChipInfo* pChipInfo;              // info about the selected chip
+       pci_info                pciInfo;                // copy of pci info for 
this device
+       area_id                 gttArea;                // area used for GTT
+       addr_t                  gttAddr;                // virtual address of 
GTT
+       char                    name[B_OS_NAME_LENGTH]; // name of device
+};
+
+
+static Benaphore               gLock;
+static DeviceInfo              gDeviceInfo[MAX_DEVICES];
+static char*                   gDeviceNames[MAX_DEVICES + 1];
+static pci_module_info*        gPCI;
+
+
+// Prototypes for device hook functions.
+
+static status_t device_open(const char* name, uint32 flags, void** cookie);
+static status_t device_close(void* dev);
+static status_t device_free(void* dev);
+static status_t device_read(void* dev, off_t pos, void* buf, size_t* len);
+static status_t device_write(void* dev, off_t pos, const void* buf,
+                                       size_t* len);
+static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len);
+
+static device_hooks gDeviceHooks =
+{
+       device_open,
+       device_close,
+       device_free,
+       device_ioctl,
+       device_read,
+       device_write,
+       NULL,
+       NULL,
+       NULL,
+       NULL
+};
+
+
+
+// Video chip register definitions.
+//=================================
+
+#define INTERRUPT_ENABLED              0x020a0
+#define INTERRUPT_MASK                 0x020a8
+
+// Graphics address translation table.
+#define PAGE_TABLE_CONTROL             0x02020
+#define PAGE_TABLE_ENABLED             0x01
+
+#define PTE_BASE                               0x10000
+#define PTE_VALID                              0x01
+
+
+// Macros for memory mapped I/O.
+//==============================
+
+#define INREG16(addr)          (*((vuint16*)(di.regs + (addr))))
+#define INREG32(addr)          (*((vuint32*)(di.regs + (addr))))
+
+#define OUTREG16(addr, val)    (*((vuint16*)(di.regs + (addr))) = (val))
+#define OUTREG32(addr, val)    (*((vuint32*)(di.regs + (addr))) = (val))
+
+
+
+static inline uint32
+GetPCI(pci_info& info, uint8 offset, uint8 size)
+{
+       return gPCI->read_pci_config(info.bus, info.device, info.function, 
offset,
+               size);
+}
+
+
+static inline void
+SetPCI(pci_info& info, uint8 offset, uint8 size, uint32 value)
+{
+       gPCI->write_pci_config(info.bus, info.device, info.function, offset, 
size,
+               value);
+}
+
+
+static status_t
+GetEdidFromBIOS(edid1_raw& edidRaw)
+{
+       // Get the EDID info from the video BIOS, and return B_OK if successful.
+
+#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
+#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
+
+       vm86_state vmState;
+
+       status_t status = vm86_prepare(&vmState, 0x2000);
+       if (status != B_OK) {
+               TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 
0x%lx\n",
+                       status);
+               return status;
+       }
+
+       vmState.regs.eax = 0x4f15;
+       vmState.regs.ebx = 0;           // 0 = report DDC service
+       vmState.regs.ecx = 0;
+       vmState.regs.es = 0;
+       vmState.regs.edi = 0;
+
+       status = vm86_do_int(&vmState, 0x10);
+       if (status == B_OK) {
+               // AH contains the error code, and AL determines wether or not 
the
+               // function is supported.
+               if (vmState.regs.eax != 0x4f)
+                       status = B_NOT_SUPPORTED;
+
+               // Test if DDC is supported by the monitor.
+               if ((vmState.regs.ebx & 3) == 0)
+                       status = B_NOT_SUPPORTED;
+       }
+
+       if (status == B_OK) {
+               // According to the author of the vm86 functions, the address 
of any
+               // object to receive data must be >= 0x1000 and within the ram 
size
+               // specified in the second argument of the vm86_prepare() call 
above.
+               // Thus, the address of the struct to receive the EDID info is 
set to
+               // 0x1000.
+
+               edid1_raw* edid = (edid1_raw*)0x1000;
+
+               vmState.regs.eax = 0x4f15;
+               vmState.regs.ebx = 1;           // 1 = read EDID
+               vmState.regs.ecx = 0;
+               vmState.regs.edx = 0;
+               vmState.regs.es  = ADDRESS_SEGMENT(edid);
+               vmState.regs.edi = ADDRESS_OFFSET(edid);
+
+               status = vm86_do_int(&vmState, 0x10);
+               if (status == B_OK) {
+                       if (vmState.regs.eax != 0x4f) {
+                               status = B_NOT_SUPPORTED;
+                       } else {
+                               // Copy the EDID info to the caller's location, 
and compute the
+                               // checksum of the EDID info while copying.
+
+                               uint8 sum = 0;
+                               uint8 allOr = 0;
+                               uint8* dest = (uint8*)&edidRaw;
+                               uint8* src = (uint8*)edid;
+
+                               for (uint32 j = 0; j < sizeof(edidRaw); j++) {
+                                       sum += *src;
+                                       allOr |= *src;
+                                       *dest++ = *src++;
+                               }
+
+                               if (allOr == 0) {
+                                       TRACE("GetEdidFromBIOS(); EDID info 
contains only zeros\n");
+                                       status = B_ERROR;
+                               } else if (sum != 0) {
+                                       TRACE("GetEdidFromBIOS(); Checksum 
error in EDID info\n");
+                                       status = B_ERROR;
+                               }
+                       }
+               }
+       }
+
+       vm86_cleanup(&vmState);
+
+       TRACE("GetEdidFromBIOS() status: 0x%lx\n", status);
+       return status;
+}
+
+
+static status_t
+InitDevice(DeviceInfo& di)
+{
+       // Perform initialization and mapping of the device, and return B_OK if
+       // sucessful;  else, return error code.
+
+       TRACE("enter InitDevice()\n");
+
+       // Create the area for shared info with NO user-space read or write
+       // permissions, to prevent accidental damage.
+
+       size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
+
+       di.sharedArea = create_area("i810 shared info",
+               (void**) &(di.sharedInfo),
+               B_ANY_KERNEL_ADDRESS,
+               ROUND_TO_PAGE_SIZE(sharedSize),
+               B_FULL_LOCK, 0);
+       if (di.sharedArea < 0)
+               return di.sharedArea;   // return error code
+
+       SharedInfo& si = *(di.sharedInfo);
+       memset(&si, 0, sharedSize);
+       si.regsArea = -1;                       // indicate area has not yet 
been created
+       si.videoMemArea = -1;
+
+       pci_info& pciInfo = di.pciInfo;
+
+       si.vendorID = pciInfo.vendor_id;
+       si.deviceID = pciInfo.device_id;
+       si.revision = pciInfo.revision;
+       strcpy(si.chipName, di.pChipInfo->chipName);
+
+       // Enable memory mapped IO and bus master.
+
+       SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2)
+               | PCI_command_io | PCI_command_memory | PCI_command_master);
+
+       // Map the MMIO register area.
+
+       phys_addr_t regsBase = pciInfo.u.h0.base_registers[1];
+       uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[1];
+
+       si.regsArea = map_physical_memory("i810 mmio registers",
+               regsBase,
+               regAreaSize,
+               B_ANY_KERNEL_ADDRESS,
+               B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
+               (void**)&di.regs);
+
+       if (si.regsArea < 0) {
+               TRACE("Unable to map MMIO, error: 0x%lx\n", si.regsArea);
+               return si.regsArea;
+       }
+
+       // Allocate memory for the GTT which must be 64K for the 810/815 chips.
+
+       uint32 gttSize = 64 * 1024;
+       di.gttArea = create_area("GTT memory", (void**) &(di.gttAddr),
+               B_ANY_KERNEL_ADDRESS, gttSize, B_FULL_LOCK | B_CONTIGUOUS,
+               B_READ_AREA | B_WRITE_AREA);
+
+       if (di.gttArea < B_OK) {
+               TRACE("Unable to create GTT, error: 0x%lx\n", di.gttArea);
+               return B_NO_MEMORY;
+       }       
+
+       memset((void*)(di.gttAddr), 0, gttSize);
+
+       // Get the physical address of the GTT, and set GTT address in the chip.
+       
+       physical_entry entry;
+       status_t status = get_memory_map((void *)(di.gttAddr),
+               B_PAGE_SIZE, &entry, 1);
+       if (status < B_OK) {
+               TRACE("Unable to get physical address of GTT, error: 0x%lx\n", 
status);
+               return status;
+       }
+
+       OUTREG32(PAGE_TABLE_CONTROL, entry.address | PAGE_TABLE_ENABLED);       
+       INREG32(PAGE_TABLE_CONTROL);    
+
+       // Allocate video memory to be used for the frame buffer.
+
+       si.videoMemSize = 4 * 1024 * 1024;
+       si.videoMemArea = create_area("video memory", 
(void**)&(si.videoMemAddr),
+               B_ANY_ADDRESS, si.videoMemSize, B_FULL_LOCK,
+               B_READ_AREA | B_WRITE_AREA);
+       if (si.videoMemArea < B_OK) {
+               TRACE("Unable to create video memory, error: 0x%lx\n", 
si.videoMemArea);
+               return B_NO_MEMORY;
+       }
+
+       // Get the physical address of each page of the video memory, and put
+       // the physical address of each page into the GTT table.
+
+       for (uint32 offset = 0; offset < si.videoMemSize; offset += 
B_PAGE_SIZE) {
+               status = get_memory_map((void *)(si.videoMemAddr + offset),
+                       B_PAGE_SIZE, &entry, 1);
+               if (status < B_OK) {
+                       TRACE("Unable to get physical address of video memory 
page, error:"
+                               " 0x%lx  offset: %ld\n", status, offset);
+                       return status;
+               }
+
+               if (offset == 0)
+                       si.videoMemPCI = entry.address;
+
+               OUTREG32(PTE_BASE + ((offset / B_PAGE_SIZE) * 4),
+                       entry.address | PTE_VALID);
+       }
+
+       TRACE("InitDevice() exit OK\n");
+       return B_OK;
+}
+
+
+static void
+DeleteAreas(DeviceInfo& di)
+{
+       // Delete all areas that were created.
+
+       if (di.sharedArea >= 0 && di.sharedInfo != NULL) {
+               SharedInfo& si = *(di.sharedInfo);
+               if (si.regsArea >= 0)
+                       delete_area(si.regsArea);
+               if (si.videoMemArea >= 0)
+                       delete_area(si.videoMemArea);
+       }
+
+       if (di.gttArea >= 0)
+               delete_area(di.gttArea);
+       di.gttArea = -1;
+       di.gttAddr = (addr_t)NULL;
+
+       if (di.sharedArea >= 0)
+               delete_area(di.sharedArea);
+       di.sharedArea = -1;
+       di.sharedInfo = NULL;
+}
+
+
+static const ChipInfo*
+GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo)
+{
+       // Search the PCI devices for a device that is supported by this driver.
+       // The search starts at the device specified by argument pciIndex, and
+       // continues until a supported device is found or there are no more 
devices
+       // to examine.  Argument pciIndex is incremented after each device is
+       // examined.
+
+       // If a supported device is found, return a pointer to the struct 
containing
+       // the chip info; else return NULL.
+
+       while (gPCI->get_nth_pci_info(pciIndex, &pciInfo) == B_OK) {
+
+               if (pciInfo.vendor_id == VENDOR_ID) {
+
+                       // Search the table of supported devices to find a 
chip/device that
+                       // matches device ID of the current PCI device.
+
+                       const ChipInfo* pDevice = chipTable;
+
+                       while (pDevice->chipID != 0) {  // end of table?
+                               if (pDevice->chipID == pciInfo.device_id)
+                                       return pDevice;         // matching 
device/chip found
+
+                               pDevice++;
+                       }
+               }
+
+               pciIndex++;
+       }
+
+       return NULL;            // no supported device found
+}
+
+
+
+//     #pragma mark - Kernel Interface
+
+
+status_t
+init_hardware(void)
+{
+       // Return B_OK if a device supported by this driver is found; otherwise,
+       // return B_ERROR so the driver will be unloaded.
+
+       status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI);
+       if (status != B_OK) {
+               TRACE("PCI module unavailable, error 0x%lx\n", status);
+               return status;
+       }
+
+       // Check pci devices for a device supported by this driver.
+
+       uint32 pciIndex = 0;
+       pci_info pciInfo;
+       const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, pciInfo);
+
+       TRACE("init_hardware() - %s\n",
+               pDevice == NULL ? "no supported devices" : "device supported");
+
+       put_module(B_PCI_MODULE_NAME);          // put away the module manager
+
+       return (pDevice == NULL ? B_ERROR : B_OK);
+}
+
+
+status_t
+init_driver(void)
+{
+       // Get handle for the pci bus.
+
+       status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI);
+       if (status != B_OK) {
+               TRACE("PCI module unavailable, error 0x%lx\n", status);
+               return status;
+       }
+
+       status = gLock.Init("i810 driver lock");
+       if (status < B_OK) {
+               put_module(B_AGP_GART_MODULE_NAME);
+               put_module(B_PCI_MODULE_NAME);
+               return status;
+       }
+
+       // Get info about all the devices supported by this driver.
+
+       uint32 pciIndex = 0;
+       uint32 count = 0;
+
+       while (count < MAX_DEVICES) {
+               DeviceInfo& di = gDeviceInfo[count];
+
+               const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, 
di.pciInfo);
+               if (pDevice == NULL)
+                       break;                  // all supported devices have 
been obtained
+
+               // Compose device name.
+               sprintf(di.name, "graphics/" DEVICE_FORMAT,
+                                 di.pciInfo.vendor_id, di.pciInfo.device_id,
+                                 di.pciInfo.bus, di.pciInfo.device, 
di.pciInfo.function);
+               TRACE("init_driver() match found; name: %s\n", di.name);
+
+               gDeviceNames[count] = di.name;
+               di.openCount = 0;               // mark driver as available for 
R/W open
+               di.sharedArea = -1;             // indicate shared area not yet 
created
+               di.sharedInfo = NULL;
+               di.gttArea = -1;                // indicate GTT area not yet 
created
+               di.gttAddr = (addr_t)NULL;
+               di.pChipInfo = pDevice;
+               count++;
+               pciIndex++;
+       }
+
+       gDeviceNames[count] = NULL;     // terminate list with null pointer
+
+       TRACE("init_driver() %ld supported devices\n", count);
+
+       return B_OK;
+}
+
+
+void
+uninit_driver(void)
+{
+       // Free the driver data.
+
+       gLock.Delete();
+       put_module(B_AGP_GART_MODULE_NAME);
+       put_module(B_PCI_MODULE_NAME);  // put the pci module away
+}
+
+
+const char**
+publish_devices(void)
+{
+       return (const char**)gDeviceNames;      // return list of supported 
devices
+}
+
+
+device_hooks*
+find_device(const char* name)
+{
+       int i = 0;
+       while (gDeviceNames[i] != NULL) {
+               if (strcmp(name, gDeviceNames[i]) == 0)
+                       return &gDeviceHooks;
+               i++;
+       }
+
+       return NULL;
+}
+
+
+
+//     #pragma mark - Device Hooks
+
+
+static status_t
+device_open(const char* name, uint32 /*flags*/, void** cookie)
+{
+       status_t status = B_OK;
+
+       TRACE("device_open() - name: %s, cookie: 0x%08lx)\n", name, 
(uint32)cookie);
+
+       // Find the device name in the list of devices.
+
+       int32 i = 0;
+       while (gDeviceNames[i] != NULL && (strcmp(name, gDeviceNames[i]) != 0))
+               i++;
+
+       if (gDeviceNames[i] == NULL)
+               return B_BAD_VALUE;             // device name not found in 
list of devices
+
+       DeviceInfo& di = gDeviceInfo[i];
+
+       gLock.Acquire();        // make sure no one else has write access to 
common data
+
+       if (di.openCount == 0) {
+               status = InitDevice(di);
+               if (status < B_OK)
+                       DeleteAreas(di);        // error occurred; delete any 
areas created
+       }
+       
+       gLock.Release();
+
+       if (status == B_OK) {
+               di.openCount++;         // mark device open
+               *cookie = &di;          // send cookie to opener
+       }
+
+       TRACE("device_open() returning 0x%lx,  open count: %ld\n", status,
+               di.openCount);
+       return status;
+}
+
+
+static status_t
+device_read(void* dev, off_t pos, void* buf, size_t* len)
+{
+       // Following 3 lines of code are here to eliminate "unused parameter"
+       // warnings.
+       (void)dev;
+       (void)pos;
+       (void)buf;
+
+       *len = 0;
+       return B_NOT_ALLOWED;
+}
+
+
+static status_t
+device_write(void* dev, off_t pos, const void* buf, size_t* len)
+{
+       // Following 3 lines of code are here to eliminate "unused parameter"
+       // warnings.
+       (void)dev;
+       (void)pos;
+       (void)buf;
+
+       *len = 0;
+       return B_NOT_ALLOWED;
+}
+
+
+static status_t
+device_close(void* dev)
+{
+       (void)dev;              // avoid compiler warning for unused arg
+
+       TRACE("device_close()\n");
+       return B_NO_ERROR;
+}
+
+
+static status_t
+device_free(void* dev)
+{
+       DeviceInfo& di = *((DeviceInfo*)dev);
+
+       TRACE("enter device_free()\n");
+
+       gLock.Acquire();                // lock driver
+
+       // If opened multiple times, merely decrement the open count and exit.
+
+       if (di.openCount <= 1)
+               DeleteAreas(di);
+
+       if (di.openCount > 0)
+               di.openCount--;         // mark device available
+
+       gLock.Release();        // unlock driver
+
+       TRACE("exit device_free() openCount: %ld\n", di.openCount);
+       return B_OK;
+}
+

[ *** diff truncated: 42 lines dropped *** ]


############################################################################

Revision:    hrev44212
Commit:      0e8316cc908c3f24496bdf57855a6dcde483b82f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=0e8316c
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Wed May 30 21:09:52 2012 UTC

intel_810: Style cleanup. No functional change

* I think the FunctionNames need to change to function_name

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] haiku: hrev44212 - src/add-ons/accelerants/intel_810 src/add-ons/kernel/drivers/graphics/intel_810 headers/private/graphics/intel_810 - kallisti5