* Fixed some warnings.

* I forgot to mention it before, but this driver seems to have been written
  by Erdi Chen.
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18979 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-09-29 14:12:22 +00:00
parent b9ecaef57a
commit b83fe28463
4 changed files with 401 additions and 498 deletions

View File

@ -2,12 +2,13 @@
Copyright 1999, Be Incorporated. All Rights Reserved. Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#ifndef GLOBALDATA_H
#if !defined(GLOBALDATA_H)
#define GLOBALDATA_H #define GLOBALDATA_H
#include "DriverInterface.h" #include "DriverInterface.h"
extern int fd; extern int fd;
extern shared_info *si; extern shared_info *si;
extern area_id shared_info_area; extern area_id shared_info_area;
@ -22,4 +23,10 @@ extern int accelerantIsClone;
/* Print debug message through kernel driver. Should move to other location later. */ /* Print debug message through kernel driver. Should move to other location later. */
extern void dpf (const char * format, ...); extern void dpf (const char * format, ...);
/* ProposeDisplayMode.c */
extern status_t create_mode_list(void);
/* Cursor.c */
extern void set_cursor_colors(void);
#endif #endif

View File

@ -12,31 +12,35 @@
#include "s3mmio.h" #include "s3mmio.h"
#include "s3accel.h" #include "s3accel.h"
#include "errno.h"
#include "fcntl.h"
#include "string.h" #include "string.h"
#include "unistd.h" #include "unistd.h"
#include "sys/types.h" #include "sys/types.h"
#include "sys/stat.h" #include "sys/stat.h"
#include "fcntl.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
/* defined in ProposeDisplayMode.c */
extern status_t create_mode_list(void);
/* defined in Cursor.c */
extern void set_cursor_colors(void);
/* Get the linear address of an area. Workaround for BeOS bug that /*!
returns invalid pointer from clone_area. */ Get the linear address of an area. Workaround for BeOS bug that
static void * __get_area_address (area_id area) returns invalid pointer from clone_area.
*/
static void *
get_area_address(area_id area)
{ {
area_info ai; area_info ai;
get_area_info (area, &ai); get_area_info(area, &ai);
return ai.address; return ai.address;
} }
#if 0
// unused!
// Determines the amount of card memory available by seeing how far up // Determines the amount of card memory available by seeing how far up
// the frame buffer data can be written and read back reliably. Does a // the frame buffer data can be written and read back reliably. Does a
// paranoia check to make sure that it isn't just wrapping, either. // paranoia check to make sure that it isn't just wrapping, either.
unsigned long Get_Card_Mem_Size() unsigned long
Get_Card_Mem_Size()
{ {
// Allowed sizes actually go up to 16 megs, but clip at the // Allowed sizes actually go up to 16 megs, but clip at the
// register window for now. // register window for now.
@ -115,81 +119,73 @@ unsigned long Get_Card_Mem_Size()
return MaxMem; return MaxMem;
} }
#endif
static status_t init_common(int the_fd);
/* Initialization code shared between primary and cloned accelerants */ /* Initialization code shared between primary and cloned accelerants */
static status_t init_common(int the_fd) static status_t
init_common(int the_fd)
{ {
status_t result; status_t result;
savage_get_private_data gpd; savage_get_private_data gpd;
/* memorize the file descriptor */ /* memorize the file descriptor */
fd = the_fd; fd = the_fd;
dpf ("init_common begin\n"); dpf ("init_common begin\n");
/* set the magic number so the driver knows we're for real */ /* set the magic number so the driver knows we're for real */
gpd.magic = SAVAGE_PRIVATE_DATA_MAGIC; gpd.magic = SAVAGE_PRIVATE_DATA_MAGIC;
/* contact driver and get a pointer to the registers and shared data */ /* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, SAVAGE_GET_PRIVATE_DATA, &gpd, sizeof(gpd)); if (ioctl(fd, SAVAGE_GET_PRIVATE_DATA, &gpd, sizeof(gpd)) != 0)
if (result != B_OK) goto error0; return errno;
/* clone the shared area for our use */ /* clone the shared area for our use */
shared_info_area = clone_area ( shared_info_area = clone_area("SAVAGE shared info", (void **)&si,
"SAVAGE shared info", (void **)&si, B_ANY_ADDRESS, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area); if (shared_info_area < 0)
if (shared_info_area < 0) return shared_info_area;
{
result = shared_info_area;
goto error0;
}
/* clone the memory mapped registers for our use */
regs_area = clone_area (
"SAVAGE regs area", (void **)&regs, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, si->regs_area);
if (regs_area < 0)
{
result = regs_area;
goto error1;
}
regs = __get_area_address (regs_area);
dpf ("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n", /* clone the memory mapped registers for our use */
read16 ((byte_t*)regs + 0x8000), regs_area = clone_area("SAVAGE regs area", (void **)&regs, B_ANY_ADDRESS,
read16 ((byte_t*)regs + 0x8002)); B_READ_AREA | B_WRITE_AREA, si->regs_area);
if (regs_area < 0) {
result = regs_area;
goto error1;
}
regs = get_area_address(regs_area);
/* clone the framebuffer buffer for our use */ dpf("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n",
fb_area = clone_area ( read16((byte_t*)regs + 0x8000),
"SAVAGE fb area", (void **)&framebuffer, B_ANY_ADDRESS, read16((byte_t*)regs + 0x8002));
B_READ_AREA | B_WRITE_AREA, si->fb_area);
if (fb_area < 0)
{
result = regs_area;
goto error2;
}
framebuffer = __get_area_address (fb_area);
s3drv_init ((byte_t*)regs); /* clone the framebuffer buffer for our use */
dpf ("s3drv_init called\n"); fb_area = clone_area("SAVAGE fb area", (void **)&framebuffer,
s3accel_init (s3drv_get_context ()); B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, si->fb_area);
dpf ("s3accel_init called\n"); if (fb_area < 0) {
s3drv_unlock_regs (); result = regs_area;
goto error2;
}
framebuffer = get_area_address(fb_area);
/* all done */ s3drv_init((byte_t*)regs);
goto error0; dpf ("s3drv_init called\n");
s3accel_init(s3drv_get_context());
dpf ("s3accel_init called\n");
s3drv_unlock_regs();
/* all done */
return B_OK;
error2: error2:
delete_area(regs_area); delete_area(regs_area);
error1: error1:
delete_area(shared_info_area); delete_area(shared_info_area);
error0: return result;
dpf ("init_common done\n");
return result;
} }
/* Clean up code shared between primary and cloned accelrants */
static void uninit_common(void) /*! Clean up code shared between primary and cloned accelerants */
static void
uninit_common(void)
{ {
/* release framebuffer area */ /* release framebuffer area */
delete_area (fb_area); delete_area (fb_area);
@ -204,14 +200,15 @@ static void uninit_common(void)
} }
/* /*!
Initialize the accelerant. the_fd is the file handle of the device (in Initialize the accelerant. the_fd is the file handle of the device (in
/dev/graphics) that has been opened by the app_server (or some test harness). /dev/graphics) that has been opened by the app_server (or some test harness).
We need to determine if the kernel driver and the accelerant are compatible. We need to determine if the kernel driver and the accelerant are compatible.
If they are, get the accelerant ready to handle other hook functions and If they are, get the accelerant ready to handle other hook functions and
report success or failure. report success or failure.
*/ */
status_t INIT_ACCELERANT(int the_fd) status_t
INIT_ACCELERANT(int the_fd)
{ {
status_t result; status_t result;
/* note that we're the primary accelerant (accelerantIsClone is global) */ /* note that we're the primary accelerant (accelerantIsClone is global) */
@ -219,9 +216,8 @@ status_t INIT_ACCELERANT(int the_fd)
/* do the initialization common to both the primary and the clones */ /* do the initialization common to both the primary and the clones */
result = init_common(the_fd); result = init_common(the_fd);
if (result != B_OK)
/* bail out if the common initialization failed */ goto error0;
if (result != B_OK) goto error0;
/* /*
If there is a possiblity that the kernel driver will recognize a card that If there is a possiblity that the kernel driver will recognize a card that
@ -268,8 +264,9 @@ status_t INIT_ACCELERANT(int the_fd)
initialized with this routine) will own the "one true copy" of the list. initialized with this routine) will own the "one true copy" of the list.
Everybody else get's a read-only clone. Everybody else get's a read-only clone.
*/ */
result = create_mode_list(); result = create_mode_list();
if (result != B_OK) goto error2; if (result != B_OK)
goto error2;
/* /*
Initialize the frame buffer and cursor pointers. Most newer video cards Initialize the frame buffer and cursor pointers. Most newer video cards
@ -343,11 +340,13 @@ error0:
return result; return result;
} }
/*
Return the number of bytes required to hold the information required /*!
to clone the device. Return the number of bytes required to hold the information required
to clone the device.
*/ */
ssize_t ACCELERANT_CLONE_INFO_SIZE(void) ssize_t
ACCELERANT_CLONE_INFO_SIZE(void)
{ {
/* /*
Since we're passing the name of the device as the only required Since we're passing the name of the device as the only required
@ -357,11 +356,12 @@ ssize_t ACCELERANT_CLONE_INFO_SIZE(void)
} }
/* /*!
Return the info required to clone the device. void *data points to Return the info required to clone the device. void *data points to
a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length. a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
*/ */
void GET_ACCELERANT_CLONE_INFO(void *data) void
GET_ACCELERANT_CLONE_INFO(void *data)
{ {
savage_device_name dn; savage_device_name dn;
status_t result; status_t result;
@ -373,60 +373,54 @@ void GET_ACCELERANT_CLONE_INFO(void *data)
result = ioctl(fd, SAVAGE_DEVICE_NAME, &dn, sizeof(dn)); result = ioctl(fd, SAVAGE_DEVICE_NAME, &dn, sizeof(dn));
} }
/*
Initialize a copy of the accelerant as a clone. void *data points to /*!
a copy of the data returned by GET_ACCELERANT_CLONE_INFO(). Initialize a copy of the accelerant as a clone. void *data points to
a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
*/ */
status_t CLONE_ACCELERANT(void *data) status_t
CLONE_ACCELERANT(void *data)
{ {
status_t result; status_t result;
char path[MAXPATHLEN]; char path[MAXPATHLEN];
/* the data is the device name */ /* the data is the device name */
strcpy(path, "/dev"); strcpy(path, "/dev/");
strcat(path, (const char *)data); strcat(path, (const char *)data);
/* open the device, the permissions aren't important */ /* open the device, the permissions aren't important */
fd = open(path, B_READ_WRITE); fd = open(path, B_READ_WRITE);
if (fd < 0) if (fd < 0)
{ return errno;
result = fd;
goto error0;
}
/* note that we're a clone accelerant */ /* note that we're a clone accelerant */
accelerantIsClone = 1; accelerantIsClone = 1;
/* call the shared initialization code */ /* call the shared initialization code */
result = init_common(fd); result = init_common(fd);
if (result != B_OK)
goto error1;
/* bail out if the common initialization failed */ /* get shared area for display modes */
if (result != B_OK) goto error1; result = my_mode_list_area = clone_area("SAVAGE cloned display_modes",
(void **)&my_mode_list, B_ANY_ADDRESS, B_READ_AREA, si->mode_area);
if (result < B_OK)
goto error2;
/* get shared area for display modes */ /* all done */
result = my_mode_list_area = clone_area( return B_OK;
"SAVAGE cloned display_modes",
(void **)&my_mode_list,
B_ANY_ADDRESS,
B_READ_AREA,
si->mode_area
);
if (result < B_OK) goto error2;
/* all done */
result = B_OK;
goto error0;
error2: error2:
/* free up the areas we cloned */ /* free up the areas we cloned */
uninit_common(); uninit_common();
error1: error1:
/* close the device we opened */ /* close the device we opened */
close(fd); close(fd);
error0: return result;
return result;
} }
void UNINIT_ACCELERANT(void)
void
UNINIT_ACCELERANT(void)
{ {
/* free our mode list area */ /* free our mode list area */
delete_area(my_mode_list_area); delete_area(my_mode_list_area);
@ -435,10 +429,13 @@ void UNINIT_ACCELERANT(void)
/* release our cloned data */ /* release our cloned data */
uninit_common(); uninit_common();
/* close the file handle ONLY if we're the clone */ /* close the file handle ONLY if we're the clone */
if (accelerantIsClone) close(fd); if (accelerantIsClone)
close(fd);
} }
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
status_t
GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
{ {
status_t retval; status_t retval;
static const char * names1[] = static const char * names1[] =
@ -450,41 +447,34 @@ status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
{ "ProSavage PN133", "ProSavage KN133", "ProSavage P4M266", "ProSavage8 KM266" }; { "ProSavage PN133", "ProSavage KN133", "ProSavage P4M266", "ProSavage8 KM266" };
adi->version = 0x10000; adi->version = 0x10000;
if (si->device_id == PCI_PID_SAVAGE2000) if (si->device_id == PCI_PID_SAVAGE2000) {
{
strcpy (adi->name, "Savage2000"); strcpy (adi->name, "Savage2000");
strcpy (adi->chipset, "Savage2000"); strcpy (adi->chipset, "Savage2000");
} } else {
else
{
const char ** names = NULL; const char ** names = NULL;
int offset = 0; int offset = 0;
switch (si->device_id & 0xFFF0) switch (si->device_id & 0xFFF0) {
{ case 0x8a20:
case 0x8a20: names = names1;
names = names1; offset = si->device_id - PCI_PID_SAVAGE3D;
offset = si->device_id - PCI_PID_SAVAGE3D; break;
break; case 0x8c10:
case 0x8c10: names = names2;
names = names2; offset = si->device_id - PCI_PID_SAVAGEMXMV;
offset = si->device_id - PCI_PID_SAVAGEMXMV; break;
break; case 0x8d00:
case 0x8d00: names = names3;
names = names3; offset = si->device_id - PCI_PID_PN133;
offset = si->device_id - PCI_PID_PN133; break;
break;
} }
if (names != NULL) if (names != NULL) {
{ strcpy (adi->name, names[offset]);
strcpy (adi->name, names[offset]); strcpy (adi->chipset, names[offset]);
strcpy (adi->chipset, names[offset]); } else {
} strcpy (adi->name, "not supported");
else strcpy (adi->chipset, "Savage");
{ }
strcpy (adi->name, "not supported"); }
strcpy (adi->chipset, "Savage");
}
}
strcpy (adi->serial_no, "0"); strcpy (adi->serial_no, "0");
adi->memory = si->mem_size; adi->memory = si->mem_size;
adi->dac_speed = 250; adi->dac_speed = 250;

View File

@ -48,38 +48,34 @@ static const display_mode mode_list[] = {
/* create a mask of one "bits" bits wide */ /* create a mask of one "bits" bits wide */
#define MASKFROMWIDTH(bits) ((1 << bits) - 1) #define MASKFROMWIDTH(bits) ((1 << bits) - 1)
/* /*!
Validate a target display mode is both Validate a target display mode is both
a) a valid display mode for this device and a) a valid display mode for this device and
b) falls between the contraints imposed by "low" and "high" b) falls between the contraints imposed by "low" and "high"
If the mode is not (or cannot) be made valid for this device, return B_ERROR. If the mode is not (or cannot) be made valid for this device, return B_ERROR.
If a valid mode can be constructed, but it does not fall within the limits, If a valid mode can be constructed, but it does not fall within the limits,
return B_BAD_VALUE. return B_BAD_VALUE.
If the mode is both valid AND falls within the limits, return B_OK. If the mode is both valid AND falls within the limits, return B_OK.
*/ */
status_t PROPOSE_DISPLAY_MODE ( status_t
display_mode *target, const display_mode *low, const display_mode *high) PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low,
const display_mode *high)
{ {
const uint16 h_display_bits = MASKFROMWIDTH(8); //const uint16 h_display_bits = MASKFROMWIDTH(8);
const uint16 h_sync_bits = MASKFROMWIDTH(5); const uint16 h_sync_bits = MASKFROMWIDTH(5);
const uint16 h_total_bits = MASKFROMWIDTH(9); const uint16 h_total_bits = MASKFROMWIDTH(9);
const uint16 v_display_bits = MASKFROMWIDTH(11); const uint16 v_display_bits = MASKFROMWIDTH(11);
const uint16 v_sync_bits = MASKFROMWIDTH(5); const uint16 v_sync_bits = MASKFROMWIDTH(5);
const uint16 v_total_bits = MASKFROMWIDTH(11); //const uint16 v_total_bits = MASKFROMWIDTH(11);
status_t status_t result = B_OK;
result = B_OK; uint32 row_bytes, limit_clock;
uint32 double target_refresh = ((double)target->timing.pixel_clock * 1000.0)
row_bytes, / ((double)target->timing.h_total
limit_clock; * (double)target->timing.v_total);
double bool want_same_width = target->timing.h_display == target->virtual_width;
target_refresh = ((double)target->timing.pixel_clock * 1000.0) bool want_same_height = target->timing.v_display == target->virtual_height;
/ ((double)target->timing.h_total
* (double)target->timing.v_total);
bool
want_same_width = target->timing.h_display == target->virtual_width,
want_same_height = target->timing.v_display == target->virtual_height;
/* /*
NOTE: NOTE:
@ -101,86 +97,96 @@ status_t PROPOSE_DISPLAY_MODE (
*/ */
/* validate horizontal timings */ /* validate horizontal timings */
{ {
/* for most devices, horizontal parameters must be multiples of 8 */ /* for most devices, horizontal parameters must be multiples of 8 */
uint16 h_display = target->timing.h_display >> 3; uint16 h_display = target->timing.h_display >> 3;
uint16 h_sync_start = target->timing.h_sync_start >> 3; uint16 h_sync_start = target->timing.h_sync_start >> 3;
uint16 h_sync_end = target->timing.h_sync_end >> 3; uint16 h_sync_end = target->timing.h_sync_end >> 3;
uint16 h_total = target->timing.h_total >> 3; uint16 h_total = target->timing.h_total >> 3;
/* ensure reasonable minium display and sequential order of parms */ /* ensure reasonable minium display and sequential order of parms */
if (h_display < (320 >> 3)) h_display = 320 >> 3; if (h_display < (320 >> 3))
if (h_display > (2048 >> 3)) h_display = 2048 >> 3; h_display = 320 >> 3;
if (h_sync_start < (h_display + 2)) h_sync_start = h_display + 2; if (h_display > (2048 >> 3))
if (h_sync_end < (h_sync_start + 3)) h_display = 2048 >> 3;
h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/ if (h_sync_start < (h_display + 2))
if (h_total < (h_sync_end + 1)) h_total = h_sync_end + 1; h_sync_start = h_display + 2;
/* adjust for register limitations: */ if (h_sync_end < (h_sync_start + 3))
/* h_total is 9 bits */ h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/
if (h_total > h_total_bits) h_total = h_total_bits; if (h_total < (h_sync_end + 1))
/* h_display is 8 bits - handled above */ h_total = h_sync_end + 1;
/* h_sync_start is 9 bits */
/* h_sync_width is 5 bits */
if ((h_sync_end - h_sync_start) > h_sync_bits)
h_sync_end = h_sync_start + h_sync_bits;
/* shift back to the full width values */ /* adjust for register limitations: */
target->timing.h_display = h_display << 3; /* h_total is 9 bits */
target->timing.h_sync_start = h_sync_start << 3; if (h_total > h_total_bits)
target->timing.h_sync_end = h_sync_end << 3; h_total = h_total_bits;
target->timing.h_total = h_total << 3; /* h_display is 8 bits - handled above */
} /* h_sync_start is 9 bits */
/* h_sync_width is 5 bits */
if ((h_sync_end - h_sync_start) > h_sync_bits)
h_sync_end = h_sync_start + h_sync_bits;
/* shift back to the full width values */
target->timing.h_display = h_display << 3;
target->timing.h_sync_start = h_sync_start << 3;
target->timing.h_sync_end = h_sync_end << 3;
target->timing.h_total = h_total << 3;
}
/* did we fall out of one of the limits? */ /* did we fall out of one of the limits? */
if ( if (target->timing.h_display < low->timing.h_display
(target->timing.h_display < low->timing.h_display) || || target->timing.h_display > high->timing.h_display
(target->timing.h_display > high->timing.h_display) || || target->timing.h_sync_start < low->timing.h_sync_start
(target->timing.h_sync_start < low->timing.h_sync_start) || || target->timing.h_sync_start > high->timing.h_sync_start
(target->timing.h_sync_start > high->timing.h_sync_start) || || target->timing.h_sync_end < low->timing.h_sync_end
(target->timing.h_sync_end < low->timing.h_sync_end) || || target->timing.h_sync_end > high->timing.h_sync_end
(target->timing.h_sync_end > high->timing.h_sync_end) || || target->timing.h_total < low->timing.h_total
(target->timing.h_total < low->timing.h_total) || || target->timing.h_total > high->timing.h_total)
(target->timing.h_total > high->timing.h_total) result = B_BAD_VALUE;
) result = B_BAD_VALUE;
/* validate vertical timings */
{
uint16 v_display = target->timing.v_display;
uint16 v_sync_start = target->timing.v_sync_start;
uint16 v_sync_end = target->timing.v_sync_end;
uint16 v_total = target->timing.v_total;
/* validate vertical timings */ /* ensure reasonable minium display and sequential order of parms */
{ /* v_display is 11 bits */
uint16 v_display = target->timing.v_display; /* v_total is 11 bits */
uint16 v_sync_start = target->timing.v_sync_start; /* v_sync_start is 11 bits */
uint16 v_sync_end = target->timing.v_sync_end; /* v_sync_width is 5 bits */
uint16 v_total = target->timing.v_total; if (v_display < 200)
v_display = 200;
if (v_display > (v_display_bits - 5))
v_display = (v_display_bits - 5); /* leave room for the sync pulse */
if (v_sync_start < (v_display + 1))
v_sync_start = v_display + 1;
if (v_sync_end < v_sync_start)
v_sync_end = v_sync_start + 3;
if (v_total < (v_sync_end + 1))
v_total = v_sync_end + 1;
/* ensure reasonable minium display and sequential order of parms */ /* adjust for register limitations */
/* v_display is 11 bits */ if ((v_sync_end - v_sync_start) > v_sync_bits)
/* v_total is 11 bits */ v_sync_end = v_sync_start + v_sync_bits;
/* v_sync_start is 11 bits */
/* v_sync_width is 5 bits */ target->timing.v_display = v_display;
if (v_display < 200) v_display = 200; target->timing.v_sync_start = v_sync_start;
if (v_display > (v_display_bits - 5)) v_display = (v_display_bits - 5); /* leave room for the sync pulse */ target->timing.v_sync_end = v_sync_end;
if (v_sync_start < (v_display + 1)) v_sync_start = v_display + 1; target->timing.v_total = v_total;
if (v_sync_end < v_sync_start) v_sync_end = v_sync_start + 3; }
if (v_total < (v_sync_end + 1)) v_total = v_sync_end + 1;
/* adjust for register limitations */
if ((v_sync_end - v_sync_start) > v_sync_bits)
v_sync_end = v_sync_start + v_sync_bits;
target->timing.v_display = v_display;
target->timing.v_sync_start = v_sync_start;
target->timing.v_sync_end = v_sync_end;
target->timing.v_total = v_total;
}
/* did we fall out of one of the limits? */ /* did we fall out of one of the limits? */
if ( if (target->timing.v_display < low->timing.v_display
(target->timing.v_display < low->timing.v_display) || || target->timing.v_display > high->timing.v_display
(target->timing.v_display > high->timing.v_display) || || target->timing.v_sync_start < low->timing.v_sync_start
(target->timing.v_sync_start < low->timing.v_sync_start) || || target->timing.v_sync_start > high->timing.h_sync_start
(target->timing.v_sync_start > high->timing.h_sync_start) || || target->timing.v_sync_end < low->timing.v_sync_end
(target->timing.v_sync_end < low->timing.v_sync_end) || || target->timing.v_sync_end > high->timing.v_sync_end
(target->timing.v_sync_end > high->timing.v_sync_end) || || target->timing.v_total < low->timing.v_total
(target->timing.v_total < low->timing.v_total) || || target->timing.v_total > high->timing.v_total)
(target->timing.v_total > high->timing.v_total) result = B_BAD_VALUE;
) result = B_BAD_VALUE;
/* adjust pixel clock for DAC limits and target refresh rate */ /* adjust pixel clock for DAC limits and target refresh rate */
/* /*
@ -199,27 +205,26 @@ status_t PROPOSE_DISPLAY_MODE (
initialization code. initialization code.
This is also a convienient place to determine the number of bytes This is also a convienient place to determine the number of bytes
per pixel for a later display pitch calculation. per pixel for a later display pitch calculation.
*/ */
switch (target->space & 0x0fff) switch (target->space & 0x0fff) {
{ case B_CMAP8:
case B_CMAP8: limit_clock = si->pix_clk_max8;
limit_clock = si->pix_clk_max8; row_bytes = 1;
row_bytes = 1; break;
break; //case B_RGB15:
//case B_RGB15: case B_RGB16:
case B_RGB16: limit_clock = si->pix_clk_max16;
limit_clock = si->pix_clk_max16; row_bytes = 2;
row_bytes = 2; break;
break; case B_RGB32:
case B_RGB32: limit_clock = si->pix_clk_max32;
limit_clock = si->pix_clk_max32; row_bytes = 4;
row_bytes = 4; break;
break; default:
default: /* no amount of adjusting will fix not being able to support
/* no amount of adjusting will fix not being able to support the pixel format */
the pixel format */ return B_ERROR;
return B_ERROR; }
}
/* make sure we don't generate more pixel bandwidth than the device /* make sure we don't generate more pixel bandwidth than the device
can handle */ can handle */
if (target->timing.pixel_clock > limit_clock) if (target->timing.pixel_clock > limit_clock)
@ -228,97 +233,92 @@ status_t PROPOSE_DISPLAY_MODE (
but I'm lazy */ but I'm lazy */
/* note if we fell outside the limits */ /* note if we fell outside the limits */
if ( if (target->timing.pixel_clock < low->timing.pixel_clock
(target->timing.pixel_clock < low->timing.pixel_clock) || || target->timing.pixel_clock > high->timing.pixel_clock)
(target->timing.pixel_clock > high->timing.pixel_clock) result = B_BAD_VALUE;
) result = B_BAD_VALUE;
/* validate display vs. virtual */ /* validate display vs. virtual */
if ((target->timing.h_display > target->virtual_width) || want_same_width) if (target->timing.h_display > target->virtual_width || want_same_width)
target->virtual_width = target->timing.h_display; target->virtual_width = target->timing.h_display;
if ((target->timing.v_display > target->virtual_height) || want_same_height) if (target->timing.v_display > target->virtual_height || want_same_height)
target->virtual_height = target->timing.v_display; target->virtual_height = target->timing.v_display;
if (target->virtual_width > 2048) if (target->virtual_width > 2048)
target->virtual_width = 2048; target->virtual_width = 2048;
/* adjust virtual width for engine limitations */ /* adjust virtual width for engine limitations */
target->virtual_width = (target->virtual_width + 7) & ~7; target->virtual_width = (target->virtual_width + 7) & ~7;
if ( if (target->virtual_width < low->virtual_width
(target->virtual_width < low->virtual_width) || || target->virtual_width > high->virtual_width)
(target->virtual_width > high->virtual_width) result = B_BAD_VALUE;
) result = B_BAD_VALUE;
/* calculate rowbytes after we've nailed the virtual width */ /* calculate rowbytes after we've nailed the virtual width */
row_bytes *= target->virtual_width; row_bytes *= target->virtual_width;
/* memory requirement for frame buffer */ /* memory requirement for frame buffer */
if ((row_bytes * target->virtual_height) > si->mem_size) if ((row_bytes * target->virtual_height) > si->mem_size)
target->virtual_height = si->mem_size / row_bytes; target->virtual_height = si->mem_size / row_bytes;
if (target->virtual_height > 2048) if (target->virtual_height > 2048)
target->virtual_height = 2048; target->virtual_height = 2048;
if (target->virtual_height < target->timing.v_display) if (target->virtual_height < target->timing.v_display) {
/* not enough frame buffer memory for the mode */ /* not enough frame buffer memory for the mode */
return B_ERROR; return B_ERROR;
else if ( } else if (target->virtual_height < low->virtual_height
(target->virtual_height < low->virtual_height) || || target->virtual_height > high->virtual_height)
(target->virtual_height > high->virtual_height) result = B_BAD_VALUE;
) result = B_BAD_VALUE;
/* /*
Bit Flag Encoding Bit Flag Encoding
The way the bit flags works is as follows: The way the bit flags works is as follows:
low high meaning low high meaning
--- ---- ------- --- ---- -------
0 0 Feature must NOT be enabled 0 0 Feature must NOT be enabled
0 1 Feature MAY be enabled, prefered enabled 0 1 Feature MAY be enabled, prefered enabled
1 0 Feature MAY be enabled, prefered disabled 1 0 Feature MAY be enabled, prefered disabled
1 1 Feature MUST be enabled 1 1 Feature MUST be enabled
*/
*/
/* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */ /* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */
return result; return result;
} }
/*
Return the number of modes this device will return from GET_MODE_LIST().
*/
uint32 ACCELERANT_MODE_COUNT(void)
{
/* return the number of 'built-in' display modes */
return si->mode_count;
}
/* /*!
Copy the list of guaranteed supported video modes to the location Return the number of modes this device will return from GET_MODE_LIST().
provided.
*/ */
status_t GET_MODE_LIST(display_mode *dm) uint32
ACCELERANT_MODE_COUNT(void)
{ {
/* copy them to the buffer pointed at by *dm */ /* return the number of 'built-in' display modes */
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode)); return si->mode_count;
return B_OK;
} }
/* /*!
Copy the list of guaranteed supported video modes to the location
provided.
*/
status_t
GET_MODE_LIST(display_mode *dm)
{
/* copy them to the buffer pointed at by *dm */
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode));
return B_OK;
}
/*!
Create a list of display_modes to pass back to the caller. Create a list of display_modes to pass back to the caller.
*/ */
status_t create_mode_list(void) status_t
create_mode_list(void)
{ {
size_t max_size; size_t max_size;
uint32 uint32 i, j, pix_clk_range;
i, j, const display_mode *src;
pix_clk_range; display_mode *dst, low, high;
const display_mode
*src;
display_mode
*dst,
low,
high;
/* /*
We prefer frame buffers to have the same endianness as the host We prefer frame buffers to have the same endianness as the host
@ -336,49 +336,51 @@ status_t create_mode_list(void)
{B_CMAP8, B_RGB16_BIG, B_RGB32_BIG}; {B_CMAP8, B_RGB16_BIG, B_RGB32_BIG};
#endif #endif
/* figure out how big the list could be, and adjust up to nearest /* figure out how big the list could be, and adjust up to nearest
multiple of B_PAGE_SIZE */ multiple of B_PAGE_SIZE */
max_size = (((MODE_COUNT * sizeof (spaces) / sizeof (color_space)) max_size = (((MODE_COUNT * sizeof (spaces) / sizeof (color_space))
* sizeof(display_mode)) * sizeof(display_mode)) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
+ (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
/* create an area to hold the info */
si->mode_area = my_mode_list_area =
create_area (
"SAVAGE accelerant mode info", (void **)&my_mode_list,
B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (my_mode_list_area < B_OK) return my_mode_list_area;
/* walk through our predefined list and see which modes fit this device */ /* create an area to hold the info */
src = mode_list; si->mode_area = my_mode_list_area =
dst = my_mode_list; create_area("SAVAGE accelerant mode info", (void **)&my_mode_list,
si->mode_count = 0; B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
for (i = 0; i < MODE_COUNT; i++) if (my_mode_list_area < B_OK)
{ return my_mode_list_area;
/* set ranges for acceptable values */
low = high = *src; /* walk through our predefined list and see which modes fit this device */
/* range is 6.25% of default clock: arbitrarily picked */ src = mode_list;
pix_clk_range = low.timing.pixel_clock >> 5; dst = my_mode_list;
low.timing.pixel_clock -= pix_clk_range; si->mode_count = 0;
high.timing.pixel_clock += pix_clk_range; for (i = 0; i < MODE_COUNT; i++) {
/* some cards need wider virtual widths for certain modes */ /* set ranges for acceptable values */
high.virtual_width = 2048; low = high = *src;
/* do it once for each depth we want to support */
for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) { /* range is 6.25% of default clock: arbitrarily picked */
/* set target values */ pix_clk_range = low.timing.pixel_clock >> 5;
*dst = *src; low.timing.pixel_clock -= pix_clk_range;
/* poke the specific space */ high.timing.pixel_clock += pix_clk_range;
dst->space = low.space = high.space = spaces[j]; /* some cards need wider virtual widths for certain modes */
if (spaces[j] != B_CMAP8) dst->flags &= ~B_8_BIT_DAC; high.virtual_width = 2048;
/* ask for a compatible mode */
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) { /* do it once for each depth we want to support */
/* count it, and move on to next mode */ for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) {
dst++; /* set target values */
si->mode_count++; *dst = *src;
} /* poke the specific space */
dst->space = low.space = high.space = spaces[j];
if (spaces[j] != B_CMAP8)
dst->flags &= ~B_8_BIT_DAC;
/* ask for a compatible mode */
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) {
/* count it, and move on to next mode */
dst++;
si->mode_count++;
}
}
/* advance to next mode */
src++;
} }
/* advance to next mode */
src++;
}
return B_OK; return B_OK;
} }

View File

@ -2,12 +2,13 @@
Copyright 1999, Be Incorporated. All Rights Reserved. Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#ifndef GENERIC_H
#if !defined(GENERIC_H)
#define GENERIC_H #define GENERIC_H
#include <Accelerant.h> #include <Accelerant.h>
status_t INIT_ACCELERANT(int fd); status_t INIT_ACCELERANT(int fd);
ssize_t ACCELERANT_CLONE_INFO_SIZE(void); ssize_t ACCELERANT_CLONE_INFO_SIZE(void);
void GET_ACCELERANT_CLONE_INFO(void *data); void GET_ACCELERANT_CLONE_INFO(void *data);
@ -49,100 +50,3 @@ void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count); void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
#endif #endif
#if 0
typedef enum
{
B_NO_COLOR_SPACE = 0x0000, /* byte in memory order, high bit first */
/* linear color space (little endian is the default) */
B_RGB32 = 0x0008, /* B[7:0] G[7:0] R[7:0] -[7:0] */
B_RGBA32 = 0x2008, /* B[7:0] G[7:0] R[7:0] A[7:0] */
B_RGB24 = 0x0003, /* B[7:0] G[7:0] R[7:0] */
B_RGB16 = 0x0005, /* G[2:0],B[4:0] R[4:0],G[5:3] */
B_RGB15 = 0x0010, /* G[2:0],B[4:0] -[0],R[4:0],G[4:3] */
B_RGBA15 = 0x2010, /* G[2:0],B[4:0] A[0],R[4:0],G[4:3] */
B_CMAP8 = 0x0004, /* D[7:0] */
B_GRAY8 = 0x0002, /* Y[7:0] */
B_GRAY1 = 0x0001, /* Y0[0],Y1[0],Y2[0],Y3[0],Y4[0],Y5[0],Y6[0],Y7[0] */
/* big endian version, when the encoding is not endianess independant */
B_RGB32_BIG = 0x1008, /* -[7:0] R[7:0] G[7:0] B[7:0] */
B_RGBA32_BIG = 0x3008, /* A[7:0] R[7:0] G[7:0] B[7:0] */
B_RGB24_BIG = 0x1003, /* R[7:0] G[7:0] B[7:0] */
B_RGB16_BIG = 0x1005, /* R[4:0],G[5:3] G[2:0],B[4:0] */
B_RGB15_BIG = 0x1010, /* -[0],R[4:0],G[4:3] G[2:0],B[4:0] */
B_RGBA15_BIG = 0x3010, /* A[0],R[4:0],G[4:3] G[2:0],B[4:0] */
/* little-endian declarations, for completness */
B_RGB32_LITTLE = B_RGB32,
B_RGBA32_LITTLE = B_RGBA32,
B_RGB24_LITTLE = B_RGB24,
B_RGB16_LITTLE = B_RGB16,
B_RGB15_LITTLE = B_RGB15,
B_RGBA15_LITTLE = B_RGBA15,
/* non linear color space -- note that these are here for exchange purposes; */
/* a BBitmap or BView may not necessarily support all these color spaces. */
/* Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128) */
B_YCbCr422 = 0x4000, /* Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0]... */
/* Cb2[7:0] Y3[7:0] Cr2[7:0] */
B_YCbCr411 = 0x4001, /* Cb0[7:0] Y0[7:0] Cr0[7:0] Y1[7:0] Cb4[7:0]...*/
/* Y2[7:0] Cr4[7:0] Y3[7:0] Y4[7:0] Y5[7:0]... */
/* Y6[7:0] Y7[7:0] */
B_YCbCr444 = 0x4003, /* Y0[7:0] Cb0[7:0] Cr0[7:0] */
B_YCbCr420 = 0x4004, /* Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ... */
/* Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines */
/* Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128) */
/* note that YUV byte order is different from YCbCr */
/* USE YCbCr, not YUV, when that's what you mean! */
B_YUV422 = 0x4020, /* U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] ... */
/* U2[7:0] Y2[7:0] V2[7:0] Y3[7:0] */
B_YUV411 = 0x4021, /* U0[7:0] Y0[7:0] Y1[7:0] V0[7:0] Y2[7:0] Y3[7:0] */
/* U4[7:0] Y4[7:0] Y5[7:0] V4[7:0] Y6[7:0] Y7[7:0] */
B_YUV444 = 0x4023, /* U0[7:0] Y0[7:0] V0[7:0] U1[7:0] Y1[7:0] V1[7:0] */
B_YUV420 = 0x4024, /* Non-interlaced only, U0 Y0 Y1 U2 Y2 Y3 on even scan lines ... */
/* V0 Y0 Y1 V2 Y2 Y3 on odd scan lines */
B_YUV9 = 0x402C, /* planar? 410? */
B_YUV12 = 0x402D, /* planar? 420? */
B_UVL24 = 0x4030, /* U0[7:0] V0[7:0] L0[7:0] ... */
B_UVL32 = 0x4031, /* U0[7:0] V0[7:0] L0[7:0] X0[7:0]... */
B_UVLA32 = 0x6031, /* U0[7:0] V0[7:0] L0[7:0] A0[7:0]... */
B_LAB24 = 0x4032, /* L0[7:0] a0[7:0] b0[7:0] ... (a is not alpha!) */
B_LAB32 = 0x4033, /* L0[7:0] a0[7:0] b0[7:0] X0[7:0] ... (b is not alpha!) */
B_LABA32 = 0x6033, /* L0[7:0] a0[7:0] b0[7:0] A0[7:0] ... (A is alpha) */
/* red is at hue = 0 */
B_HSI24 = 0x4040, /* H[7:0] S[7:0] I[7:0] */
B_HSI32 = 0x4041, /* H[7:0] S[7:0] I[7:0] X[7:0] */
B_HSIA32 = 0x6041, /* H[7:0] S[7:0] I[7:0] A[7:0] */
B_HSV24 = 0x4042, /* H[7:0] S[7:0] V[7:0] */
B_HSV32 = 0x4043, /* H[7:0] S[7:0] V[7:0] X[7:0] */
B_HSVA32 = 0x6043, /* H[7:0] S[7:0] V[7:0] A[7:0] */
B_HLS24 = 0x4044, /* H[7:0] L[7:0] S[7:0] */
B_HLS32 = 0x4045, /* H[7:0] L[7:0] S[7:0] X[7:0] */
B_HLSA32 = 0x6045, /* H[7:0] L[7:0] S[7:0] A[7:0] */
B_CMY24 = 0xC001, /* C[7:0] M[7:0] Y[7:0] No gray removal done */
B_CMY32 = 0xC002, /* C[7:0] M[7:0] Y[7:0] X[7:0] No gray removal done */
B_CMYA32 = 0xE002, /* C[7:0] M[7:0] Y[7:0] A[7:0] No gray removal done */
B_CMYK32 = 0xC003, /* C[7:0] M[7:0] Y[7:0] K[7:0] */
/* compatibility declarations */
B_MONOCHROME_1_BIT = B_GRAY1,
B_GRAYSCALE_8_BIT = B_GRAY8,
B_COLOR_8_BIT = B_CMAP8,
B_RGB_32_BIT = B_RGB32,
B_RGB_16_BIT = B_RGB15,
B_BIG_RGB_32_BIT = B_RGB32_BIG,
B_BIG_RGB_16_BIT = B_RGB15_BIG
} color_space;
#endif