Very basic driver for the "Intel Extreme Graphics 2" chips, only supports i865G for now.

Only mode switches do work, doesn't yet make sure the mode is valid, though.
At this point, this driver only works on Haiku, the R5 app_server is crashing for some
reason I need to investigate some day (maybe tomorrow :)).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16872 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-03-24 21:46:40 +00:00
parent 342c2a73ab
commit e404297e56
19 changed files with 2067 additions and 0 deletions
@@ -0,0 +1,237 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
*/
#include "driver.h"
#include "device.h"
#include "intel_extreme.h"
#include "utility.h"
#include <OS.h>
#include <KernelExport.h>
#include <Drivers.h>
#include <PCI.h>
#include <SupportDefs.h>
#include <graphic_driver.h>
#include <image.h>
#include <stdlib.h>
#include <string.h>
#define TRACE_DEVICE
#ifdef TRACE_DEVICE
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
/* device hooks prototypes */
static status_t device_open(const char *name, uint32 flags, void **_cookie);
static status_t device_close(void *data);
static status_t device_free(void *data);
static status_t device_ioctl(void *data, uint32 opcode, void *buffer, size_t length);
static status_t device_read(void *data, off_t offset, void *buffer, size_t *length);
static status_t device_write(void *data, off_t offset, const void *buffer, size_t *length);
device_hooks gDeviceHooks = {
device_open,
device_close,
device_free,
device_ioctl,
device_read,
device_write,
NULL,
NULL,
NULL,
NULL
};
static status_t
checkDeviceInfo(struct intel_info *info)
{
if (!info || info->cookie_magic != INTEL_COOKIE_MAGIC)
return B_BAD_VALUE;
return B_OK;
}
// #pragma mark - Device Hooks
static status_t
device_open(const char *name, uint32 flags, void **_cookie)
{
TRACE((DEVICE_NAME ": open(name = %s)\n", name));
int32 id;
// find accessed device
{
char *thisName;
// search for device name
for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
if (!strcmp(name, thisName))
break;
}
if (!thisName)
return B_BAD_VALUE;
}
intel_info *info = gDeviceInfo[id];
*_cookie = info;
acquire_lock(&gLock);
status_t status = B_OK;
if (info->open_count++ == 0) {
// this device has been opened for the first time, so
// we allocate needed resources and initialize the structure
info->cookie_magic = INTEL_COOKIE_MAGIC;
info->id = id;
info->pci = gPCIInfo[id];
info->registers = (uint8 *)gPCIInfo[id]->u.h0.base_registers[0];
status = intel_extreme_init(*info);
}
release_lock(&gLock);
return status;
}
static status_t
device_close(void *data)
{
TRACE((DEVICE_NAME ": close\n"));
struct intel_info *info;
if (checkDeviceInfo(info = (intel_info *)data) != B_OK)
return B_BAD_VALUE;
info->cookie_magic = INTEL_FREE_COOKIE_MAGIC;
return B_OK;
}
static status_t
device_free(void *data)
{
struct intel_info *info = (intel_info *)data;
status_t retval = B_NO_ERROR;
if (info == NULL || info->cookie_magic != INTEL_FREE_COOKIE_MAGIC)
retval = B_BAD_VALUE;
acquire_lock(&gLock);
if (info->open_count-- == 1) {
// release info structure
info->cookie_magic = 0;
intel_extreme_uninit(*info);
}
release_lock(&gLock);
return retval;
}
static status_t
device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength)
{
struct intel_info *info;
if (checkDeviceInfo(info = (intel_info *)data) != B_OK)
return B_BAD_VALUE;
switch (op) {
case B_GET_ACCELERANT_SIGNATURE:
strcpy((char *)buffer, INTEL_ACCELERANT_NAME);
TRACE((DEVICE_NAME ": accelerant: %s\n", INTEL_ACCELERANT_NAME));
return B_OK;
// needed to share data between kernel and accelerant
case INTEL_GET_PRIVATE_DATA:
{
intel_get_private_data *data = (intel_get_private_data *)buffer;
if (data->magic == INTEL_PRIVATE_DATA_MAGIC) {
data->shared_info_area = info->shared_area;
return B_OK;
}
break;
}
// needed for cloning
case INTEL_GET_DEVICE_NAME:
#ifdef __HAIKU__
if (user_strlcpy((char *)buffer, gDeviceNames[info->id], B_PATH_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
#else
strncpy((char *)buffer, gDeviceNames[info->id], B_PATH_NAME_LENGTH);
((char *)buffer)[B_PATH_NAME_LENGTH - 1] = '\0';
#endif
return B_OK;
/*
// graphics mem manager
case INTEL_ALLOC_LOCAL_MEMORY:
{
intel_alloc_local_mem *allocMemory = (intel_alloc_local_mem *)buffer;
if (allocMemory->magic == INTEL_PRIVATE_DATA_MAGIC) {
return mem_alloc(di->local_memmgr, allocMemory->size, dev,
&allocMemory->handle, &am->fb_offset);
}
break;
}
case INTEL_FREE_LOCAL_MEMORY:
{
intel_free_local_mem *freeMemory = (intel_free_local_mem *)buffer;
if (freeMemory->magic == INTEL_PRIVATE_DATA_MAGIC)
return mem_free(di->local_memmgr, freeMemory->handle, dev);
break;
}
*/
default:
TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %ld)\n",
op, bufferLength));
break;
}
return B_DEV_INVALID_IOCTL;
}
static status_t
device_read(void */*data*/, off_t /*pos*/, void */*buffer*/, size_t *_length)
{
*_length = 0;
return B_NOT_ALLOWED;
}
static status_t
device_write(void */*data*/, off_t /*pos*/, const void */*buffer*/, size_t *_length)
{
*_length = 0;
return B_NOT_ALLOWED;
}