Promoted newest 3dfx video driver by Gerald Zajac in place of the outdated tdfx driver.

Added to Haiku image.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37294 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin 2010-06-28 20:43:37 +00:00
parent e4eb2e7e45
commit 307ff45454
22 changed files with 2 additions and 4422 deletions

View File

@ -117,6 +117,7 @@ SYSTEM_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant
$(X86_ONLY)neomagic.accelerant $(X86_ONLY)intel_extreme.accelerant
$(X86_ONLY)s3.accelerant $(X86_ONLY)vesa.accelerant
$(X86_ONLY)ati.accelerant
$(X86_ONLY)3dfx.accelerant
#$(X86_ONLY)via.accelerant
#$(X86_ONLY)vmware.accelerant
;
@ -162,7 +163,7 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia sis7018 usb_audio ;
SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia
$(X86_ONLY)neomagic $(X86_ONLY)matrox $(X86_ONLY)intel_extreme
$(X86_ONLY)s3 $(X86_ONLY)vesa #$(X86_ONLY)via #$(X86_ONLY)vmware
$(X86_ONLY)ati
$(X86_ONLY)ati $(X86_ONLY)3dfx
;
SYSTEM_ADD_ONS_DRIVERS_MIDI = emuxki usb_midi ;
SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)atheros813x

View File

@ -1,188 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef DRIVERINTERFACE_H
#define DRIVERINTERFACE_H
#include <Accelerant.h>
#include <Drivers.h>
#include <PCI.h>
#include <OS.h>
/*
This is the info that needs to be shared between the kernel driver and
the accelerant for the sample driver.
*/
#if defined(__cplusplus)
extern "C" {
#endif
#define MAXBUFFERS 8
typedef struct
{
uint16 slopspace;
uint32 size;
} int_buf_info;
typedef struct
{
sem_id sem;
int32 ben;
} benaphore;
#define INIT_BEN(x) x.sem = create_sem(0, "VOODOO "#x" benaphore"); x.ben = 0;
#define AQUIRE_BEN(x) if((atomic_add(&(x.ben), 1)) >= 1) acquire_sem(x.sem);
#define RELEASE_BEN(x) if((atomic_add(&(x.ben), -1)) > 1) release_sem(x.sem);
#define DELETE_BEN(x) delete_sem(x.sem);
#define VOODOO_PRIVATE_DATA_MAGIC 0x1234 /* a private driver rev, of sorts */
#define MAX_VOODOO_DEVICE_NAME_LENGTH 32
#define SKD_MOVE_CURSOR 0x00000001
#define SKD_PROGRAM_CLUT 0x00000002
#define SKD_SET_START_ADDR 0x00000004
#define SKD_SET_CURSOR 0x00000008
#define SKD_HANDLER_INSTALLED 0x80000000
enum
{
VOODOO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
VOODOO_GET_PCI,
VOODOO_SET_PCI,
VOODOO_DEVICE_NAME,
VOODOO_RUN_INTERRUPTS,
VOODOO_DPRINTF,
VOODOO_INB,
VOODOO_INW,
VOODOO_INL,
VOODOO_OUTB,
VOODOO_OUTW,
VOODOO_OUTL
};
typedef struct
{
uint16 vendor_id; /* PCI vendor ID, from pci_info */
uint16 device_id; /* PCI device ID, from pci_info */
uint8 revision; /* PCI device revsion, from pci_info */
uint32 iobase; /* PCI IOBase */
area_id regs_area; /* Kernel's area_id for the memory mapped registers.
It will be cloned into the accelerant's address
space. */
area_id fb_area; /* Frame buffer's area_id. The addresses are shared
with all teams. */
void *framebuffer; /* As viewed from virtual memory */
void *framebuffer_pci; /* As viewed from the PCI bus (for DMA) */
area_id io_area; /* Mapped ROM's area_id */
uint32 io; /* As viewed from virtual memory. Shared by all teams */
area_id mode_area; /* Contains the list of display modes the driver supports */
uint32 mode_count; /* Number of display modes in the list */
sem_id vblank; /* The vertical blank semaphore. Ownership will be
transfered to the team opening the device first */
int32 flags;
int32 start_addr;
struct
{
uint8* data; /* Pointer into the frame buffer to where the
cursor data starts */
uint16 hot_x; /* Cursor hot spot. The top left corner of the cursor */
uint16 hot_y; /* is 0,0 */
uint16 x; /* The location of the cursor hot spot on the */
uint16 y; /* display (or desktop?) */
uint16 width; /* Width and height of the cursor shape */
uint16 height;
bool is_visible; /* Is the cursor currently displayed? */
} cursor;
uint16 first_color;
uint16 color_count;
bigtime_t refresh_period; /* Duration of one frame (ie 1/refresh rate) */
bigtime_t blank_period; /* Duration of the blanking period. These are
usefull when faking vertical blanking
interrupts. */
uint8 color_data[3 * 256]; /* */
uint8 cursor0[64*64/8]; /* AND mask for a 64x64 cursor */
uint8 cursor1[512]; /* XOR mask for a 64x64 cursor */
display_mode dm; /* current display mode configuration */
frame_buffer_config
fbc; /* bytes_per_row and start of frame buffer */
struct
{
uint64 count; /* last fifo slot used */
uint64 last_idle; /* last fifo slot we *know* the engine was idle after */
benaphore lock; /* for serializing access to the acceleration engine */
} engine;
struct
{
overlay_buffer myBuffer[MAXBUFFERS]; /* scaler input buffers */
int_buf_info myBufInfo[MAXBUFFERS]; /* extra info on scaler input buffers */
overlay_token myToken; /* scaler is free/in use */
benaphore lock; /* for creating buffers and aquiring overlay unit routines */
} overlay;
uint32 pix_clk_max8; /* The maximum speed the pixel clock should run */
uint32 pix_clk_max16; /* at for a given pixel width. Usually a function */
uint32 pix_clk_max32; /* of memory and DAC bandwidths. */
uint32 mem_size; /* Frame buffer memory, in bytes. */
} shared_info;
/* Read or write a value in PCI configuration space */
typedef struct
{
uint32 magic; /* magic number to make sure the caller groks us */
uint32 offset; /* Offset to read/write */
uint32 size; /* Number of bytes to transfer */
uint32 value; /* The value read or written */
} voodoo_get_set_pci;
/* Set some boolean condition (like enabling or disabling interrupts) */
typedef struct
{
uint32 magic; /* magic number to make sure the caller groks us */
bool do_it; /* state to set */
} voodoo_set_bool_state;
/* Retrieve the area_id of the kernel/accelerant shared info */
typedef struct
{
uint32 magic; /* magic number to make sure the caller groks us */
area_id shared_info_area; /* area_id containing the shared information */
} voodoo_get_private_data;
/* Retrieve the device name. Usefull for when we have a file handle, but want
to know the device name (like when we are cloning the accelerant) */
typedef struct
{
uint32 magic; /* magic number to make sure the caller groks us */
char *name; /* The name of the device, less the /dev root */
} voodoo_device_name;
typedef struct
{
uint32 port;
uint8 data8;
uint16 data16;
uint32 data32;
} voodoo_port_io;
enum
{
VOODOO_WAIT_FOR_VBLANK = (1 << 0)
};
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -12,7 +12,6 @@ SubInclude HAIKU_TOP src add-ons accelerants nvidia ;
SubInclude HAIKU_TOP src add-ons accelerants radeon ;
SubInclude HAIKU_TOP src add-ons accelerants radeon_hd ;
SubInclude HAIKU_TOP src add-ons accelerants s3 ;
SubInclude HAIKU_TOP src add-ons accelerants tdfx ;
SubInclude HAIKU_TOP src add-ons accelerants vesa ;
SubInclude HAIKU_TOP src add-ons accelerants via ;
SubInclude HAIKU_TOP src add-ons accelerants vmware ;

View File

@ -1,93 +0,0 @@
/*
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
#include "voodoo3_accelerant.h"
void
SCREEN_TO_SCREEN_BLIT (
engine_token *et, blit_params *list, uint32 count)
{
uint32 stride, bpp;
stride = si->fbc.bytes_per_row;
bpp = voodoo3_bits_per_pixel();
while (count--)
{
list_packet_blit packet;
packet.src_x = list->src_left;
packet.src_y = list->src_top;
packet.dest_x = list->dest_left;
packet.dest_y = list->dest_top;
packet.width = list->width + 1;
packet.height = list->height + 1;
voodoo3_screen_to_screen_blit(&packet, stride, bpp);
list ++;
}
}
void
FILL_RECTANGLE (
engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
{
uint32 stride, bpp;
stride = si->fbc.bytes_per_row;
bpp = voodoo3_bits_per_pixel();
while (count--)
{
list_packet packet;
packet.x = list->left;
packet.y = list->top;
packet.w = list->right - packet.x + 1;
packet.h = list->bottom - packet.y + 1;
voodoo3_fill_rect(&packet, color, stride, bpp);
list++;
}
}
void
INVERT_RECTANGLE (
engine_token *et, fill_rect_params *list, uint32 count)
{
uint32 stride, bpp, color;
stride = si->fbc.bytes_per_row;
bpp = voodoo3_bits_per_pixel();
color = 0;
while (count--)
{
list_packet packet;
packet.x = list->left;
packet.y = list->top;
packet.w = list->right - packet.x + 1;
packet.h = list->bottom - packet.y + 1;
voodoo3_invert_rect(&packet, color, stride, bpp);
list++;
}
}
void
FILL_SPAN (
engine_token *et, uint32 color, uint16 *list, uint32 count)
{
uint32 stride, bpp;
stride = si->fbc.bytes_per_row;
bpp = voodoo3_bits_per_pixel();
while (count--)
{
list_packet packet;
packet.y = *list ++;
packet.x = *list ++;
packet.w = *list - packet.x + 1;
packet.h = 1;
list ++;
voodoo3_fill_span(&packet, color, stride, bpp);
}
}

View File

@ -1,114 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
#include "voodoo3_accelerant.h"
void set_cursor_colors(void);
void set_cursor_colors(void)
{
/* it's only called by the INIT_ACCELERANT() */
voodoo3_set_cursor_colors(0, ~0);
}
status_t
SET_CURSOR_SHAPE (
uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
uint8 *andMask, uint8 *xorMask)
{
/* NOTE: Currently, for BeOS, cursor width and height must be equal to 16. */
if ((width != 16) || (height != 16))
{
return B_ERROR;
}
else if ((hot_x >= width) || (hot_y >= height))
{
return B_ERROR;
}
else
{
/* Update cursor variables appropriately. */
si->cursor.width = width;
si->cursor.height = height;
si->cursor.hot_x = hot_x;
si->cursor.hot_y = hot_y;
voodoo3_set_cursor((uint8 *)framebuffer, width, height, andMask, xorMask);
}
return B_OK;
}
/*
Move the cursor to the specified position on the desktop. If we're
using some kind of virtual desktop, adjust the display start position
accordingly and position the cursor in the proper "virtual" location.
*/
void MOVE_CURSOR (uint16 x_p, uint16 y_p)
{
int x = x_p, y = y_p;
bool move_screen = false;
/* the current horizontal starting pixel */
uint16 hds = si->dm.h_display_start;
/* the current vertical starting line */
uint16 vds = si->dm.v_display_start;
/* Need to set this value for 32 bit */
uint16 h_adjust = 3;
/* clamp cursor to virtual display */
if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
/* adjust h/v_display_start to move cursor onto screen */
if (x >= (si->dm.timing.h_display + hds))
{
hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
move_screen = true;
}
else if (x < hds)
{
hds = x & ~h_adjust;
move_screen = true;
}
if (y >= (si->dm.timing.v_display + vds))
{
vds = y - si->dm.timing.v_display + 1;
move_screen = true;
}
else if (y < vds)
{
vds = y;
move_screen = true;
}
/* reposition the desktop on the display if required */
if (move_screen) MOVE_DISPLAY(hds,vds);
/* put cursor in correct physical position */
x -= hds;
y -= vds;
x -= si->cursor.hot_x;
y -= si->cursor.hot_y;
/* position the cursor on the display */
voodoo3_move_cursor(x, y);
}
void SHOW_CURSOR (bool is_visible)
{
if (is_visible)
voodoo3_show_cursor();
else
voodoo3_hide_cursor();
/* record for our info */
si->cursor.is_visible = is_visible;
}

View File

@ -1,67 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
static engine_token voodoo_engine_token = { 1, B_2D_ACCELERATION, NULL };
uint32 ACCELERANT_ENGINE_COUNT(void)
{
return 1;
}
status_t
ACQUIRE_ENGINE (
uint32 capabilities, uint32 max_wait,
sync_token *st, engine_token **et)
{
/* acquire the shared benaphore */
AQUIRE_BEN(si->engine.lock)
/* sync if required */
if (st) SYNC_TO_TOKEN(st);
/* return an engine token */
*et = &voodoo_engine_token;
return B_OK;
}
status_t RELEASE_ENGINE (engine_token *et, sync_token *st)
{
/* update the sync token, if any */
if (st)
{
st->engine_id = et->engine_id;
st->counter = si->engine.count;
}
/* release the shared benaphore */
RELEASE_BEN(si->engine.lock)
return B_OK;
}
void WAIT_ENGINE_IDLE(void)
{
// note our current possition
si->engine.last_idle = si->engine.count;
}
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st)
{
st->engine_id = et->engine_id;
st->counter = si->engine.count;
return B_OK;
}
status_t SYNC_TO_TOKEN(sync_token *st)
{
si->engine.last_idle = st->counter;
return B_OK;
}

View File

@ -1,129 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "generic.h"
status_t check_overlay_capability(uint32 feature);
/*
The standard entry point. Given a uint32 feature identifier, this routine
returns a pointer to the function that implements the feature. Some features
require more information than just the identifier to select the proper
function. The extra information (which is specific to the feature) is
pointed at by the void *data parameter. By default, no extra information
is available. Any extra information available to choose the function will be
noted on a case by case below.
*/
void * get_accelerant_hook(uint32 feature, void *data) {
switch (feature) {
/*
These definitions are out of pure lazyness.
*/
#define HOOK(x) case B_##x: return (void *)x
#define ZERO(x) case B_##x: return (void *)0
/*
One of either B_INIT_ACCELERANT or B_CLONE_ACCELERANT will be requested and
subsequently called before any other hook is requested. All other feature
hook selections can be predicated on variables assigned during the accelerant
initialization process.
*/
/* initialization */
HOOK(INIT_ACCELERANT);
HOOK(CLONE_ACCELERANT);
HOOK(ACCELERANT_CLONE_INFO_SIZE);
HOOK(GET_ACCELERANT_CLONE_INFO);
HOOK(UNINIT_ACCELERANT);
HOOK(GET_ACCELERANT_DEVICE_INFO);
HOOK(ACCELERANT_RETRACE_SEMAPHORE);
/* mode configuration */
HOOK(ACCELERANT_MODE_COUNT);
HOOK(GET_MODE_LIST);
HOOK(PROPOSE_DISPLAY_MODE);
HOOK(SET_DISPLAY_MODE);
HOOK(GET_DISPLAY_MODE);
HOOK(GET_FRAME_BUFFER_CONFIG);
HOOK(GET_PIXEL_CLOCK_LIMITS);
HOOK(MOVE_DISPLAY);
HOOK(SET_INDEXED_COLORS);
HOOK(GET_TIMING_CONSTRAINTS);
HOOK(DPMS_CAPABILITIES);
HOOK(DPMS_MODE);
HOOK(SET_DPMS_MODE);
/* cursor managment */
HOOK(SET_CURSOR_SHAPE);
HOOK(MOVE_CURSOR);
HOOK(SHOW_CURSOR);
/* synchronization */
HOOK(ACCELERANT_ENGINE_COUNT);
HOOK(ACQUIRE_ENGINE);
HOOK(RELEASE_ENGINE);
HOOK(WAIT_ENGINE_IDLE);
HOOK(GET_SYNC_TOKEN);
HOOK(SYNC_TO_TOKEN);
/*
When requesting an acceleration hook, the calling application provides a
pointer to the display_mode for which the acceleration function will be used.
Depending on the engine architecture, you may choose to provide a different
function to be used with each bit-depth. In the sample driver we return
the same function all the time.
*/
/* 2D acceleration */
HOOK(SCREEN_TO_SCREEN_BLIT);
HOOK(FILL_RECTANGLE);
HOOK(INVERT_RECTANGLE);
HOOK(FILL_SPAN);
/* only export video overlay functions if card is capable of it */
HOOK(OVERLAY_COUNT);
HOOK(OVERLAY_SUPPORTED_SPACES);
HOOK(OVERLAY_SUPPORTED_FEATURES);
HOOK(ALLOCATE_OVERLAY_BUFFER);
HOOK(RELEASE_OVERLAY_BUFFER);
HOOK(GET_OVERLAY_CONSTRAINTS);
HOOK(ALLOCATE_OVERLAY);
HOOK(RELEASE_OVERLAY);
HOOK(CONFIGURE_OVERLAY);
#undef HOOK
#undef ZERO
}
/*
Return a null pointer for any feature we don't understand.
*/
return 0;
}
status_t check_overlay_capability(uint32 feature)
{
/* setup logmessage text */
switch (feature)
{
case B_OVERLAY_COUNT:
case B_OVERLAY_SUPPORTED_SPACES:
case B_OVERLAY_SUPPORTED_FEATURES:
case B_ALLOCATE_OVERLAY_BUFFER:
case B_RELEASE_OVERLAY_BUFFER:
case B_GET_OVERLAY_CONSTRAINTS:
case B_ALLOCATE_OVERLAY:
case B_RELEASE_OVERLAY:
case B_CONFIGURE_OVERLAY:
return B_OK;
default:
return B_ERROR;
}
}

View File

@ -1,97 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
/*
Return the current display mode. The only time you might return an
error is if a mode hasn't been set.
*/
status_t GET_DISPLAY_MODE (display_mode *current_mode)
{
/* easy for us, we return the last mode we set */
*current_mode = si->dm;
return B_OK;
}
/*
Return the frame buffer configuration information.
*/
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
{
/* easy again, as the last mode set stored the info in a convienient form */
*afb = si->fbc;
return B_OK;
}
/*
Return the maximum and minium pixel clock limits for the specified mode.
*/
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
{
/*
Note that we're not making any guarantees about the ability of the attached
display to handle pixel clocks within the limits we return. A future monitor
capablilities database will post-process this information.
*/
uint32 total_pix = (uint32)dm->timing.h_total * (uint32)dm->timing.v_total;
uint32 clock_limit;
/* max pixel clock is pixel depth dependant */
switch (dm->space & ~0x3000)
{
case B_RGB32: clock_limit = si->pix_clk_max32; break;
case B_RGB15:
case B_RGB16: clock_limit = si->pix_clk_max16; break;
case B_CMAP8: clock_limit = si->pix_clk_max8; break;
default:
clock_limit = 0;
}
/* lower limit of about 48Hz vertical refresh */
*low = (total_pix * 48L) / 1000L;
if (*low > clock_limit) return B_ERROR;
*high = clock_limit;
return B_OK;
}
status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc)
{
status_t retval;
dtc->h_res = 8;
dtc->h_sync_min = 2*8;
dtc->h_sync_max = 32*8 - 1;
dtc->h_blank_min = 0;
dtc->h_blank_max = 64*8 - 1;
dtc->v_res = 1;
dtc->v_sync_min = 2;
dtc->v_sync_max = 15;
dtc->v_blank_min = 0;
dtc->v_blank_max = 255;
retval = B_OK;
return retval;
}
/*
Return the semaphore id that will be used to signal a vertical retrace
occured.
*/
sem_id ACCELERANT_RETRACE_SEMAPHORE(void)
{
/*
NOTE:
The kernel driver created this for us. We don't know if the system is
using real interrupts, or if we're faking it, and we don't care.
If we choose not to support this at all, we'd just return B_ERROR here,
and the user wouldn't get any kind of vertical retrace support.
*/
return /*si->vblank*/B_ERROR;
}

View File

@ -1,89 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include <stdarg.h>
#include <stdio.h>
#include <sys/ioctl.h>
int fd;
shared_info *si;
area_id shared_info_area;
vuint32 *regs;
area_id regs_area;
vuint32 *framebuffer;
area_id fb_area;
display_mode *my_mode_list;
area_id my_mode_list_area;
int accelerantIsClone;
area_id iobase_area;
vuint32 *iobase;
#ifdef DEBUG
void dpf (const char * format, ...)
{
char buffer[4096] = "VOODOO: ";
va_list args;
va_start (args, format);
vsprintf (buffer + 8, format, args);
ioctl (fd, VOODOO_DPRINTF, buffer, 0);
va_end (args);
}
#endif
void outb(uint32 port, uint8 data)
{
voodoo_port_io io;
io.port = port;
io.data8 = data;
ioctl(fd, VOODOO_OUTB, &io, 0);
return;
}
void outw(uint32 port, uint16 data)
{
voodoo_port_io io;
io.port = port;
io.data16 = data;
ioctl(fd, VOODOO_OUTW, &io, 0);
return;
}
void outl(uint32 port, uint32 data)
{
voodoo_port_io io;
io.port = port;
io.data32 = data;
ioctl(fd, VOODOO_OUTL, &io, 0);
return;
}
uint8 inb(uint32 port)
{
voodoo_port_io io;
io.port = port;
ioctl(fd, VOODOO_INB, &io, 0);
return(io.data8);
}
uint16 inw(uint32 port)
{
voodoo_port_io io;
io.port = port;
ioctl(fd, VOODOO_INW, &io, 0);
return(io.data16);
}
uint32 inl(uint32 port)
{
voodoo_port_io io;
io.port = port;
ioctl(fd, VOODOO_INL, &io, 0);
return(io.data32);
}

View File

@ -1,45 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#if !defined(GLOBALDATA_H)
#define GLOBALDATA_H
#include <video_overlay.h>
#include <DriverInterface.h>
#include <strings.h>
extern int fd;
extern shared_info *si;
extern area_id shared_info_area;
extern vuint32 *regs;
extern area_id regs_area;
extern area_id iobase_area;
extern vuint32 *iobase;
extern vuint32 *framebuffer;
extern area_id fb_area;
extern display_mode *my_mode_list;
extern area_id my_mode_list_area;
extern int accelerantIsClone;
/* Print debug message through kernel driver. Should move to other location later. */
// #define DEBUG
#ifdef DEBUG
#define ddpf(a) dpf a
extern void dpf (const char * format, ...);
#else
#define ddpf(a)
#endif
extern void outb(uint32 port, uint8 data);
extern void outw(uint32 port, uint16 data);
extern void outl(uint32 port, uint32 data);
extern uint8 inb(uint32 port);
extern uint16 inw(uint32 port);
extern uint32 inl(uint32 port);
#endif

View File

@ -1,365 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
#include "voodoo3_accelerant.h"
#include "string.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.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);
static status_t init_common(int the_fd);
static int tty = 0;
/* Initialization code shared between primary and cloned accelerants */
static status_t init_common(int the_fd)
{
status_t result;
voodoo_get_private_data gpd;
/* memorize the file descriptor */
fd = the_fd;
ddpf(("TDFXV3:init_common_called: %d times\n", tty));
tty++;
ddpf (("TDFXV3:init_common begin\n"));
/* set the magic number so the driver knows we're for real */
gpd.magic = VOODOO_PRIVATE_DATA_MAGIC;
/* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, VOODOO_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
if (result != B_OK) goto error0;
/* clone the shared area for our use */
shared_info_area = clone_area (
"VOODOO shared info", (void **)&si, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
if (shared_info_area < 0)
{
result = shared_info_area;
goto error0;
}
/* clone the memory mapped registers for our use */
regs_area = clone_area (
"VOODOO 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;
}
// We don't use it here, we use it trough Kernel Driver
/*
iobase_area = clone_area(
"VOODOO io area", (void **)&iobase, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, si->io_area);
*/
/* clone the framebuffer buffer for our use */
fb_area = clone_area (
"VOODOO fb area", (void **)&framebuffer, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, si->fb_area);
if (fb_area < 0)
{
result = regs_area;
goto error2;
}
ddpf (("TDFXV3:starting voodoo3_init\n"));
voodoo3_init((uint8 *)regs, si->iobase);
/* all done */
goto error0;
error2:
delete_area(regs_area);
error1:
delete_area(shared_info_area);
error0:
ddpf (("TDFXV3:init_common done\n"));
return result;
}
/* Clean up code shared between primary and cloned accelrants */
static void uninit_common(void)
{
/* release framebuffer area */
delete_area (fb_area);
/* release the memory mapped registers */
delete_area(regs_area);
/* a little cheap paranoia */
// delete_area(iobase_area);
/* a little cheap paranoia */
framebuffer = 0;
regs = 0;
/* release our copy of the shared info from the kernel driver */
delete_area(shared_info_area);
/* more cheap paranoia */
si = 0;
}
/*
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).
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
report success or failure.
*/
status_t INIT_ACCELERANT(int the_fd)
{
status_t result;
uint32 cnt;
/* note that we're the primary accelerant (accelerantIsClone is global) */
accelerantIsClone = 0;
/* do the initialization common to both the primary and the clones */
result = init_common(the_fd);
/* bail out if the common initialization failed */
if (result != B_OK) goto error0;
/*
If there is a possiblity that the kernel driver will recognize a card that
the accelerant can't support, you should check for that here. Perhaps some
odd memory configuration or some such.
*/
/*
This is a good place to go and initialize your card. The details are so
device specific, we're not even going to pretend to provide you with sample
code. If this fails, we'll have to bail out, cleaning up the resources
we've already allocated.
*/
/* call the device specific init code */
ddpf (("TDFXV3:pixelclock 8: %li\n", si->pix_clk_max8));
ddpf (("TDFXV3:pixelclock 16: %li\n", si->pix_clk_max16));
ddpf (("TDFXV3:pixelclock 32: %li\n", si->pix_clk_max32));
voodoo3_set_monitor_defaults();
si->mem_size = voodoo3_get_memory_size();
ddpf (("TDFXV3:mem_size = %dMB\n", si->mem_size / 1024 / 1024));
if (!si->mem_size) {
result=-1;
goto error0;
}
/*
Now would be a good time to figure out what video modes your card supports.
We'll place the list of modes in another shared area so all of the copies
of the driver can see them. The primary copy of the accelerant (ie the one
initialized with this routine) will own the "one true copy" of the list.
Everybody else get's a read-only clone.
*/
result = create_mode_list();
if (result != B_OK) goto error2;
/*
Initialize the frame buffer and cursor pointers. Most newer video cards
have integrated the DAC into the graphics engine, and so the cursor shape
is stored in the frame buffer RAM. Also, newer cards tend not to have as
many restrictions about the placement of the start of the frame buffer in
frame buffer RAM. If you're supporting an older card with frame buffer
positioning restrictions, or one without an integrated DAC, you'll have to
change this accordingly.
*/
/*
Put the cursor at the start of the frame buffer. The typical 64x64 4 color
(black, white, transparent, inverse) takes up 1024 bytes of RAM.
*/
si->cursor.data = (uint8 *)si->framebuffer;// + 131072;
/* Initialize the rest of the cursor information while we're here */
si->cursor.width = 0;
si->cursor.height = 0;
si->cursor.hot_x = 0;
si->cursor.hot_y = 0;
si->cursor.x = 0;
si->cursor.y = 0;
/*
Put the frame buffer immediately following the cursor data. We store this
info in a frame_buffer_config structure to make it convienient to return
to the app_server later.
*/
si->fbc.frame_buffer = (void *)(((char *)si->framebuffer) + 1024);
si->fbc.frame_buffer_dma = (void *)(((char *)si->framebuffer_pci) + 1024);
si->start_addr = 1024;
/* init the shared semaphore */
INIT_BEN(si->engine.lock);
INIT_BEN(si->overlay.lock);
for (cnt = 0; cnt < MAXBUFFERS; cnt++)
{
/* make sure overlay buffers are 'marked' as being free */
si->overlay.myBuffer[cnt].buffer = NULL;
si->overlay.myBuffer[cnt].buffer_dma = NULL;
}
/* make sure overlay unit is 'marked' as being free */
si->overlay.myToken = NULL;
/* initialize the engine synchronization variables */
/* count of issued parameters or commands */
si->engine.last_idle = si->engine.count = 0;
/* set the cursor colors. You may or may not have to do this, depending
on the device. */
voodoo3_init_cursor_address();
set_cursor_colors();
/* ensure cursor state */
SHOW_CURSOR(false);
/* a winner! */
result = B_OK;
goto error0;
/* free up the benaphore */
DELETE_BEN(si->engine.lock);
DELETE_BEN(si->overlay.lock);
error2:
/*
Clean up any resources allocated in your device specific initialization
code.
*/
/*
Initialization failed after init_common() succeeded, so we need to clean
up before quiting.
*/
uninit_common();
error0:
return result;
}
/*
Return the number of bytes required to hold the information required
to clone the device.
*/
ssize_t ACCELERANT_CLONE_INFO_SIZE(void)
{
/*
Since we're passing the name of the device as the only required
info, return the size of the name buffer
*/
return MAX_VOODOO_DEVICE_NAME_LENGTH;
}
/*
Return the info required to clone the device. void *data points to
a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
*/
void GET_ACCELERANT_CLONE_INFO(void *data)
{
voodoo_device_name dn;
status_t result;
/* call the kernel driver to get the device name */
dn.magic = VOODOO_PRIVATE_DATA_MAGIC;
/* store the returned info directly into the passed buffer */
dn.name = (char *)data;
result = ioctl(fd, VOODOO_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().
*/
status_t CLONE_ACCELERANT(void *data)
{
status_t result;
char path[MAXPATHLEN];
/* the data is the device name */
strcpy(path, "/dev/");
strcat(path, (const char *)data);
/* open the device, the permissions aren't important */
fd = open(path, B_READ_WRITE);
if (fd < 0)
{
result = fd;
goto error0;
}
/* note that we're a clone accelerant */
accelerantIsClone = 1;
/* call the shared initialization code */
result = init_common(fd);
/* bail out if the common initialization failed */
if (result != B_OK) goto error1;
/* get shared area for display modes */
result = my_mode_list_area = clone_area(
"VOODOO 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:
/* free up the areas we cloned */
uninit_common();
error1:
/* close the device we opened */
close(fd);
error0:
return result;
}
void UNINIT_ACCELERANT(void)
{
/* free our mode list area */
delete_area(my_mode_list_area);
/* paranoia */
my_mode_list = 0;
/* release our cloned data */
uninit_common();
/* close the file handle ONLY if we're the clone */
if (accelerantIsClone) close(fd);
}
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
{
status_t retval;
char * names[] =
{ "Voodoo3" };
adi->version = 0x10000;
strcpy (adi->name, names[0]);
strcpy (adi->chipset, names[0]);
strcpy (adi->serial_no, "0");
adi->memory = si->mem_size;
adi->dac_speed = 300;
retval = B_OK;
return retval;
}

View File

@ -1,21 +0,0 @@
SubDir HAIKU_TOP src add-ons accelerants tdfx ;
UsePrivateHeaders graphics ;
UsePrivateHeaders [ FDirName graphics tdfx ] ;
Addon tdfx.accelerant :
voodoo3_accelerant.c
Acceleration.c
Cursor.c
EngineManagment.c
GetAccelerantHook.c
GetModeInfo.c
GlobalData.c
InitAccelerant.c
ProposeDisplayMode.c
SetDisplayMode.c
Overlay.c
;
Depends tdfx.accelerant : tdfx.driver ;

View File

@ -1,317 +0,0 @@
/* Overlay.c Framwork Taken from Rudolf Cornelissen (Open)BeOS MGA Driver
05/09-2002 V0.13 beta1 */
#include "GlobalData.h"
#include "generic.h"
#include "voodoo3_accelerant.h"
static uint32 overlay_colorspaces [] = {(uint32)B_YCbCr422,
#if defined(__POWERPC__)
(uint32)B_RGB16_BIG,
#else
(uint32)B_RGB16,
#endif
(uint32)B_NO_COLOR_SPACE };
// This method is never used AFAIK though it *is* exported on R5.0.3 and DANO.
// Does someone know howto invoke it?
// apparantly overlay count should report the number of 'overlay units' on the card
uint32 OVERLAY_COUNT(const display_mode *dm) {
if (dm == NULL)
ddpf( ("OVERLAY_COUNT:No DM given\n"));
return 1;
}
// This method is never used AFAIK though it *is* exported on R5.0.3 and DANO.
// Does someone know howto invoke it?
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm) {
if (dm == NULL) {
ddpf (("OVERLAY_SUPPORTED_SPACES:No DM given\n"));
return NULL;
}
/* return a B_NO_COLOR_SPACE terminated list */
return &overlay_colorspaces[0];
}
// This method is never used AFAIK. On R5.0.3 and DANO it is not even exported!
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space) {
switch (a_color_space){
default:
return
( B_OVERLAY_COLOR_KEY |
B_OVERLAY_HORIZONTAL_FILTERING |
B_OVERLAY_VERTICAL_FILTERING );
}
}
const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height) {
int offset = 0; // used to determine next buffer to create
uint32 adress, adress2, temp32; // used to calculate buffer adresses
uint32 oldsize = 0; // used to 'squeeze' new buffers between already existing ones
int cnt;
/* acquire the shared benaphore */
AQUIRE_BEN(si->overlay.lock)
/* find first empty slot (room for another buffer?) */
for (offset = 0; offset < MAXBUFFERS; offset++)
if (si->overlay.myBuffer[offset].buffer == NULL) break;
/* I just could make a lookup on overlay_colorspaces instead but its overhead I thing */
if (offset < MAXBUFFERS) {
switch (cs) {
case B_YCbCr422:
#if defined(__POWERPC__)
case B_RGB16_BIG:
#else
case B_RGB16:
#endif
si->overlay.myBuffer[offset].width = width;
si->overlay.myBuffer[offset].bytes_per_row = 2 * si->overlay.myBuffer[offset].width;
if (si->overlay.myBuffer[offset].width > 2048) {
// release the shared benaphore
RELEASE_BEN(si->overlay.lock)
return NULL;
}
break;
default:
// release the shared benaphore */
RELEASE_BEN(si->overlay.lock)
return NULL;
}
// store slopspace (in pixels) for each bitmap for use by 'overlay unit' (BES)
si->overlay.myBufInfo[offset].slopspace = si->overlay.myBuffer[offset].width - width;
si->overlay.myBuffer[offset].space = cs;
si->overlay.myBuffer[offset].height = height;
// we define the overlay buffers to reside 'in the back' of the cards RAM
// calculate first free RAM adress in card:
adress2 = (((uint32)((uint8*)si->fbc.frame_buffer)) +
(si->fbc.bytes_per_row * si->dm.virtual_height));
// calculate 'preliminary' buffer size including slopspace
oldsize = si->overlay.myBufInfo[offset].size;
si->overlay.myBufInfo[offset].size =
si->overlay.myBuffer[offset].bytes_per_row * si->overlay.myBuffer[offset].height;
// calculate virtual memory adress that would be needed for a new bitmap
adress = (((uint32)((uint8*)si->framebuffer)) + (si->mem_size));
for (cnt = 0; cnt <= offset; cnt++) adress -= si->overlay.myBufInfo[cnt].size;
// the > G200 scalers require buffers to be aligned to 16 byte pages cardRAM offset, G200 can do with
// 8 byte pages cardRAM offset. Compatible settings used, has no real downside consequences here
// Check if we need to modify the buffers starting adress and thus the size
// calculate 'would be' cardRAM offset
temp32 = (adress - ((uint32)((vuint32 *)si->framebuffer)));
// check if it is aligned //
if (temp32 != (temp32 & ~3)) {
// update the (already calculated) buffersize to get it aligned
si->overlay.myBufInfo[offset].size += (temp32 - (temp32 & ~3));
// update the (already calculated) adress to get it aligned
adress -= (temp32 - (temp32 & ~3));
}
// First check now if buffer to be defined is 'last one' in memory (speaking backwards):
// this is done to prevent a large buffer getting created in the space a small buffer
// occupied earlier, if not all buffers created were deleted.
for (cnt = offset; cnt < MAXBUFFERS; cnt++) {
if (si->overlay.myBuffer[cnt].buffer != NULL) {
// Check if the new buffer would fit into the space the single old one used here
if (si->overlay.myBufInfo[offset].size <= oldsize) {
// It does, so we reset to the old size and adresses to prevent the space from shrinking
// if we get here again...
adress -= (oldsize - si->overlay.myBufInfo[offset].size);
si->overlay.myBufInfo[offset].size = oldsize;
// force exiting the FOR loop
cnt = MAXBUFFERS;
} else {
// Reset to the old size to prevent the space from 'growing' if we get here again...
si->overlay.myBufInfo[offset].size = oldsize;
// release the shared benaphore
RELEASE_BEN(si->overlay.lock)
return NULL;
}
}
}
// check if we have enough space to setup this new bitmap
// (preventing overlap of desktop RAMspace & overlay bitmap RAMspace here)
if (adress < adress2) {
// nope, sorry
RELEASE_BEN(si->overlay.lock)
return NULL;
}
// continue buffer setup
si->overlay.myBuffer[offset].buffer = (void *) adress;
// calculate physical memory adress (for dma use)
adress = (((uint32)((uint8*)si->framebuffer_pci)) + (si->mem_size));
for (cnt = 0; cnt <= offset; cnt++)
adress -= si->overlay.myBufInfo[cnt].size;
// this adress is already aligned to the scaler's requirements (via the already modified sizes)
si->overlay.myBuffer[offset].buffer_dma = (void *) adress;
// release the shared benaphore
RELEASE_BEN(si->overlay.lock)
return &si->overlay.myBuffer[offset];
} else {
// sorry, no more room for buffers */
RELEASE_BEN(si->overlay.lock)
return NULL;
}
}
status_t RELEASE_OVERLAY_BUFFER(const overlay_buffer *ob) {
int offset = 0;
if (ob != NULL) {
//Find the buffer
for (offset = 0; offset < MAXBUFFERS; offset++)
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
if (offset < MAXBUFFERS) { // delete current buffer
si->overlay.myBuffer[offset].buffer = NULL;
si->overlay.myBuffer[offset].buffer_dma = NULL;
return B_OK;
} else {
return B_ERROR;
}
} else {
return B_ERROR;
}
}
status_t GET_OVERLAY_CONSTRAINTS (const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc) {
int offset = 0;
// Check for NULL Pointers
if ((dm == NULL) || (ob == NULL) || (oc == NULL)) {
return B_ERROR;
}
// find the buffer
for (offset = 0; offset < MAXBUFFERS; offset++)
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
if (offset < MAXBUFFERS) {
// scaler input (values are in pixels)
oc->view.h_alignment = 3;
oc->view.v_alignment = 3;
switch (ob->space) {
default:
// we should not be here, but set the worst-case value just to be safe anyway
oc->view.width_alignment = 3;
break;
}
oc->view.height_alignment = 3;
oc->view.width.min = 1;
oc->view.height.min = 2; // two fields
oc->view.width.max = ob->width;
oc->view.height.max = ob->height;
// scaler output restrictions
oc->window.h_alignment = 3;
oc->window.v_alignment = 3;
oc->window.width_alignment = 3;
oc->window.height_alignment = 3;
oc->window.width.min = 2;
if (dm->virtual_width > 2048) oc->window.width.max = 2048; else
oc->window.width.max = dm->virtual_width;
oc->window.height.min = 2;
if (dm->virtual_height > 2048) oc->window.height.max = 2048; else
oc->window.height.max = dm->virtual_height;
oc->h_scale.min = 1.0f;
oc->h_scale.max = 4.0f;
oc->v_scale.min = 1.0f;
oc->v_scale.max = 4.0f;
return B_OK;
} else {
return B_ERROR;
}
}
overlay_token ALLOCATE_OVERLAY(void)
{
uint32 tmpToken;
// come up with a token
tmpToken = 0x12345678;
// acquire the shared benaphore
AQUIRE_BEN(si->overlay.lock)
// overlay unit already in use?
if (si->overlay.myToken == NULL) {
// overlay unit is available
si->overlay.myToken = &tmpToken;
// release the shared benaphore
RELEASE_BEN(si->overlay.lock)
return si->overlay.myToken;
} else {
RELEASE_BEN(si->overlay.lock)
return NULL;
}
}
status_t RELEASE_OVERLAY(overlay_token ot) {
// is this call for real?
if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) {
return B_ERROR;
} else {
// Do really something here!
voodoo3_stop_overlay();
si->overlay.myToken = NULL;
return B_OK;
}
}
status_t CONFIGURE_OVERLAY (overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov) {
int offset = 0; // used for buffer index
// in BeOS R5.0.3 (maybe DANO works different):
// ov' is the output size on the desktop: does not change if clipped.
// h_start and v_start are always 0, width and heigth are the size of the window.
// Because the width and height can also be found in '*ow', '*ov' is not used.
if ((ow == NULL) || (ov == NULL)) {
return B_OK;
}
if (ob == NULL) {
return B_ERROR;
}
// is this call done by the app that owns us? */
if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) {
// nope, abort //
return B_ERROR;
} else {
// call is for real
for (offset = 0; offset < MAXBUFFERS; offset++)
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
if (offset < MAXBUFFERS) {
voodoo3_display_overlay(ow, ob, ov);
return B_OK;
} else {
return B_ERROR;
}
}
}

View File

@ -1,388 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
status_t create_mode_list(void);
#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
#define MODE_FLAGS (B_SCROLL|B_8_BIT_DAC|B_HARDWARE_CURSOR|B_PARALLEL_ACCESS)
#define MODE_COUNT (sizeof (mode_list) / sizeof (display_mode))
static const display_mode mode_list[] = {
{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */
{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */
{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */
{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */
{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */
{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */
{ { 38100, 800, 832, 960, 1088, 600, 602, 606, 620, 0}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* SVGA_800X600X56HzNI */
{ { 40000, 800, 840, 968, 1056, 600, 601, 605, 628, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */
{ { 49500, 800, 816, 896, 1056, 600, 601, 604, 625, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(800X600X8.Z1) */
{ { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(800X600X8.Z1) */
{ { 56250, 800, 832, 896, 1048, 600, 601, 604, 631, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(800X600X8.Z1) */
{ { 65000, 1024, 1048, 1184, 1344, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1024X768X8.Z1) */
{ { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(1024X768X8.Z1) */
{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */
{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */
{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */
{ { 121500, 1152, 1216, 1344, 1568, 864, 865, 868, 911, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1152X864X8.Z1) */
{ { 108000, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X1024X8.Z1) */
{ { 135000, 1280, 1296, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1280X1024X8.Z1) */
{ { 157500, 1280, 1344, 1504, 1728, 1024, 1025, 1028, 1072, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X1024X8.Z1) */
{ { 162000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1600X1200X8.Z1) */
{ { 175500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@65Hz_(1600X1200X8.Z1) */
{ { 189000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1600X1200X8.Z1) */
{ { 202500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1600X1200X8.Z1) */
{ { 216000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@80Hz_(1600X1200X8.Z1) */
{ { 229500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(1600X1200X8.Z1) */
};
/* create a mask of one "bits" bits wide */
#define MASKFROMWIDTH(bits) ((1 << bits) - 1)
/*
Validate a target display mode is both
a) a valid display mode for this device and
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 a valid mode can be constructed, but it does not fall within the limits,
return B_BAD_VALUE.
If the mode is both valid AND falls within the limits, return B_OK.
*/
status_t PROPOSE_DISPLAY_MODE (
display_mode *target, const display_mode *low, const display_mode *high)
{
/* const uint16 h_display_bits = MASKFROMWIDTH(8); */
const uint16 h_sync_bits = MASKFROMWIDTH(5);
const uint16 h_total_bits = MASKFROMWIDTH(9);
const uint16 v_display_bits = MASKFROMWIDTH(11);
const uint16 v_sync_bits = MASKFROMWIDTH(5);
/* const uint16 v_total_bits = MASKFROMWIDTH(11); */
status_t
result = B_OK;
uint32
row_bytes,
limit_clock;
double
target_refresh = ((double)target->timing.pixel_clock * 1000.0)
/ ((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:
Different devices provide different levels of control over the
various CRTC values. This code should be used as a *GUIDELINE ONLY*.
The device you're controling may have very different constraints,
and the code below may be insufficient to insure that a particular
display_mode is valid for your device. You would do well to spend
quite a bit of time ensuring that you understand the limitations of
your device, as setting these values incorrectly can create a
display_mode that could turn your monitor into a useless slag of
molten components, burn up your card, lock up the PCI bus, cause
partialy or multiply repeating display images, or otherwise look
just plain wierd. Honest.
*/
/*
NOTE:
This code doesn't explicitly support interlaced video modes.
*/
/* validate horizontal timings */
{
/* for most devices, horizontal parameters must be multiples of 8 */
uint16 h_display = target->timing.h_display >> 3;
uint16 h_sync_start = target->timing.h_sync_start >> 3;
uint16 h_sync_end = target->timing.h_sync_end >> 3;
uint16 h_total = target->timing.h_total >> 3;
/* ensure reasonable minium display and sequential order of parms */
if (h_display < (320 >> 3)) h_display = 320 >> 3;
if (h_display > (2048 >> 3)) h_display = 2048 >> 3;
if (h_sync_start < (h_display + 2)) h_sync_start = h_display + 2;
if (h_sync_end < (h_sync_start + 3))
h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/
if (h_total < (h_sync_end + 1)) h_total = h_sync_end + 1;
/* adjust for register limitations: */
/* h_total is 9 bits */
if (h_total > h_total_bits) h_total = h_total_bits;
/* 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? */
if (
(target->timing.h_display < low->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 > high->timing.h_sync_start) ||
(target->timing.h_sync_end < low->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 > high->timing.h_total)
) 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;
/* ensure reasonable minium display and sequential order of parms */
/* v_display is 11 bits */
/* v_total is 11 bits */
/* v_sync_start is 11 bits */
/* v_sync_width is 5 bits */
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;
/* 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? */
if (
(target->timing.v_display < low->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 > high->timing.h_sync_start) ||
(target->timing.v_sync_end < low->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 > high->timing.v_total)
) result = B_BAD_VALUE;
/* adjust pixel clock for DAC limits and target refresh rate */
/*
We're re-calcuating the pixel_clock here because we might have
changed the h/v totals above. If we didn't change anything
the calculation is wasted, but it's no big deal.
*/
target->timing.pixel_clock = target_refresh
* ((double)target->timing.h_total)
* ((double)target->timing.v_total) / 1000.0;
/*
Select the maximum pixel clock based on the color space. Your
device may have other constraints. In this sample driver, we
calculated the maximum pixel clock for this device in the
initialization code.
This is also a convienient place to determine the number of bytes
per pixel for a later display pitch calculation.
*/
switch (target->space & 0x0fff)
{
case B_CMAP8:
limit_clock = si->pix_clk_max8;
row_bytes = 1;
break;
case B_RGB15:
case B_RGB16:
case B_RGB15_BIG:
case B_RGB16_BIG:
limit_clock = si->pix_clk_max16;
row_bytes = 2;
break;
case B_RGB32:
case B_RGB32_BIG:
limit_clock = si->pix_clk_max32;
row_bytes = 4;
break;
default:
/* no amount of adjusting will fix not being able to support
the pixel format */
return B_ERROR;
}
/* make sure we don't generate more pixel bandwidth than the device
can handle */
if (target->timing.pixel_clock > limit_clock)
target->timing.pixel_clock = limit_clock;
/* we probably ought to check against too low of a pixel rate,
but I'm lazy */
/* note if we fell outside the limits */
if (
(target->timing.pixel_clock < low->timing.pixel_clock) ||
(target->timing.pixel_clock > high->timing.pixel_clock)
) result = B_BAD_VALUE;
/* validate display vs. virtual */
if ((target->timing.h_display > target->virtual_width) || want_same_width)
target->virtual_width = target->timing.h_display;
if ((target->timing.v_display > target->virtual_height) || want_same_height)
target->virtual_height = target->timing.v_display;
if (target->virtual_width > 2048)
target->virtual_width = 2048;
/* adjust virtual width for engine limitations */
target->virtual_width = (target->virtual_width + 7) & ~7;
if (
(target->virtual_width < low->virtual_width) ||
(target->virtual_width > high->virtual_width)
) result = B_BAD_VALUE;
/* calculate rowbytes after we've nailed the virtual width */
row_bytes *= target->virtual_width;
/* memory requirement for frame buffer */
if ((row_bytes * target->virtual_height) > si->mem_size)
target->virtual_height = si->mem_size / row_bytes;
if (target->virtual_height > 2048)
target->virtual_height = 2048;
if (target->virtual_height < target->timing.v_display)
/* not enough frame buffer memory for the mode */
return B_ERROR;
else if (
(target->virtual_height < low->virtual_height) ||
(target->virtual_height > high->virtual_height)
) result = B_BAD_VALUE;
/*
Bit Flag Encoding
The way the bit flags works is as follows:
low high meaning
--- ---- -------
0 0 Feature must NOT be enabled
0 1 Feature MAY be enabled, prefered enabled
1 0 Feature MAY be enabled, prefered disabled
1 1 Feature MUST be enabled
*/
/* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */
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
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.
*/
status_t create_mode_list(void)
{
size_t max_size;
uint32
i, j,
pix_clk_range;
const display_mode
*src;
display_mode
*dst,
low,
high;
/*
We prefer frame buffers to have the same endianness as the host
CPU, but it's not required. You can even return both, although
there isn't a way for the current Screen preferences panel to
allow the user to choose which one to use.
*/
#if defined(__INTEL__)
color_space spaces[] =
{B_CMAP8, B_RGB16_LITTLE, B_RGB32_LITTLE};
#else
// We could replace LITTLE with BIG
color_space spaces[] =
{B_CMAP8, B_RGB16_BIG, B_RGB32_BIG};
#endif
/* figure out how big the list could be, and adjust up to nearest
multiple of B_PAGE_SIZE */
max_size = (((MODE_COUNT * sizeof (spaces) / sizeof (color_space))
* sizeof(display_mode))
+ (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
/* create an area to hold the info */
si->mode_area = my_mode_list_area =
create_area (
"VOODOO 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 */
src = mode_list;
dst = my_mode_list;
si->mode_count = 0;
for (i = 0; i < MODE_COUNT; i++)
{
/* set ranges for acceptable values */
low = high = *src;
/* range is 6.25% of default clock: arbitrarily picked */
pix_clk_range = low.timing.pixel_clock >> 5;
low.timing.pixel_clock -= pix_clk_range;
high.timing.pixel_clock += pix_clk_range;
/* some cards need wider virtual widths for certain modes */
high.virtual_width = 2048;
/* do it once for each depth we want to support */
for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) {
/* set target values */
*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++;
}
return B_OK;
}

View File

@ -1,254 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include "GlobalData.h"
#include "generic.h"
#include <sys/ioctl.h>
#include "voodoo3_accelerant.h"
#include <stdio.h>
/*
Enable/Disable interrupts. Just a wrapper around the
ioctl() to the kernel driver.
*/
static void interrupt_enable(bool flag)
{
status_t result;
voodoo_set_bool_state sbs;
/* set the magic number so the driver knows we're for real */
sbs.magic = VOODOO_PRIVATE_DATA_MAGIC;
sbs.do_it = flag;
/* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, VOODOO_RUN_INTERRUPTS, &sbs, sizeof(sbs));
}
/*
Calculates the number of bits for a given color_space.
Usefull for mode setup routines, etc.
*/
static uint32 calcBitsPerPixel(uint32 cs)
{
uint32 bpp = 0;
switch (cs)
{
case B_RGB32_BIG:
case B_RGBA32_BIG:
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
bpp = 32; break;
case B_RGB24_BIG:
case B_RGB24_LITTLE:
bpp = 24; break;
case B_RGB16_BIG:
case B_RGB16_LITTLE:
bpp = 16; break;
case B_RGB15_BIG:
case B_RGBA15_BIG:
case B_RGB15_LITTLE:
case B_RGBA15_LITTLE:
bpp = 15; break;
case B_CMAP8:
bpp = 8; break;
}
return bpp;
}
static void do_set_display_mode(display_mode *dm)
{
uint32 bpp;
/* disable interrupts using the kernel driver */
interrupt_enable(false);
bpp = calcBitsPerPixel (dm->space);
voodoo_set_desktop_regs(bpp, dm);
/* enable interrupts using the kernel driver */
interrupt_enable(true);
si->fbc.bytes_per_row = (dm->virtual_width * bpp + 7) / 8;
}
/*
The exported mode setting routine. First validate the mode,
then call our private routine to hammer the registers.
*/
status_t SET_DISPLAY_MODE (display_mode *mode_to_set)
{
display_mode bounds, target;
/* ask for the specific mode */
target = bounds = *mode_to_set;
if (PROPOSE_DISPLAY_MODE(&target, &bounds, &bounds) == B_ERROR)
return B_ERROR;
do_set_display_mode(&target);
si->dm = target;
return B_OK;
}
/*
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.
*/
status_t MOVE_DISPLAY (uint16 h_display_start, uint16 v_display_start)
{
/*
Many devices have limitations on the granularity of the horizontal offset.
Make any checks for this here. A future revision of the driver API will
add a hook to return the granularity for a given display mode.
*/
/* most cards can handle multiples of 8 */
if (h_display_start & 0x07)
return B_ERROR;
/* do not run past end of display */
if ((si->dm.timing.h_display + h_display_start) > si->dm.virtual_width)
return B_ERROR;
if ((si->dm.timing.v_display + v_display_start) > si->dm.virtual_height)
return B_ERROR;
/* everybody remember where we parked... */
si->dm.h_display_start = h_display_start;
si->dm.v_display_start = v_display_start;
/* actually set the registers */
return B_OK;
}
/*
Set the indexed color palette.
*/
void SET_INDEXED_COLORS (
uint count, uint8 first, uint8 *color_data, uint32 flags)
{
/*
Some cards use the indexed color regisers in the DAC for gamma correction.
If this is true with your device (and it probably is), you need to protect
against setting these registers when not in an indexed mode.
*/
if (si->dm.space != B_CMAP8) return;
/*
There isn't any need to keep a copy of the data being stored,
as the app_server will set the colors each time it switches to
an 8bpp mode, or takes ownership of an 8bpp mode after a GameKit
app has used it.
*/
while(count--) {
uint32 color = ((color_data[0] << 16) | (color_data[1] << 8) | (color_data[2]));
voodoo3_set_palette(first++, color);
color_data += 3;
}
}
/* masks for DPMS control bits */
enum
{
H_SYNC_OFF = 0x01,
V_SYNC_OFF = 0x02,
DISPLAY_OFF = 0x04,
BITSMASK = H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF
};
/*
Put the display into one of the Display Power Management modes.
*/
status_t SET_DPMS_MODE(uint32 dpms_flags)
{
uint32 LTemp;
/*
The register containing the horizontal and vertical sync control bits
usually contains other control bits, so do a read-modify-write.
*/
/* FIXME - read the bits */
LTemp = *regs;
/* this mask is device dependant */
LTemp &= ~BITSMASK; /* clear all disable bits (including display disable) */
/* now pick one of the DPMS configurations */
switch(dpms_flags)
{
case B_DPMS_ON: /* H: on, V: on */
/* do nothing, bits already clear */
/* usually, but it may be different for your device */
break;
case B_DPMS_STAND_BY: /* H: off, V: on, display off */
LTemp |= H_SYNC_OFF | DISPLAY_OFF;
break;
case B_DPMS_SUSPEND: /* H: on, V: off, display off */
LTemp |= V_SYNC_OFF | DISPLAY_OFF;
break;
case B_DPMS_OFF: /* H: off, V: off, display off */
LTemp |= H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF;
break;
default:
return B_ERROR;
}
/* FIXME - write the bits */
*regs = LTemp;
/*
NOTE: if you're driving a device with a backlight (like a digital
LCD), you may want to turn off the backlight here when in a DPMS
power saving mode.
*/
if (dpms_flags == B_DPMS_ON)
/* turn on the back light */
;
else
/* turn off the back light */
;
return B_OK;
}
/*
Report device DPMS capabilities. Most newer cards can do it all.
I've only seen one older card that can do a subset (ON and OFF).
Very early cards may not be able to do this at all.
*/
uint32 DPMS_CAPABILITIES (void)
{
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
}
/*
Return the current DPMS mode.
*/
uint32 DPMS_MODE (void)
{
uint32 LTemp;
uint32 mode = B_DPMS_ON;
/* read the control bits from the device */
/* FIXME - read the bits */
LTemp = *regs;
/* what mode is set? */
switch (LTemp & (H_SYNC_OFF | V_SYNC_OFF))
{
case 0: /* H: on, V: on */
mode = B_DPMS_ON;
break;
case H_SYNC_OFF: /* H: off, V: on */
mode = B_DPMS_STAND_BY;
break;
case V_SYNC_OFF: /* H: on, V: off */
mode = B_DPMS_SUSPEND;
break;
case (H_SYNC_OFF | V_SYNC_OFF): /* H: off, V: off */
mode = B_DPMS_OFF;
break;
}
return mode;
}

View File

@ -1,66 +0,0 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#if !defined(GENERIC_H)
#define GENERIC_H
#include <Accelerant.h>
#include <video_overlay.h>
status_t INIT_ACCELERANT(int fd);
ssize_t ACCELERANT_CLONE_INFO_SIZE(void);
void GET_ACCELERANT_CLONE_INFO(void *data);
status_t CLONE_ACCELERANT(void *data);
void UNINIT_ACCELERANT(void);
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi);
sem_id ACCELERANT_RETRACE_SEMAPHORE(void);
uint32 ACCELERANT_MODE_COUNT(void);
status_t GET_MODE_LIST(display_mode *dm);
status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const display_mode *high);
status_t SET_DISPLAY_MODE(display_mode *mode_to_set);
status_t GET_DISPLAY_MODE(display_mode *current_mode);
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *a_frame_buffer);
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high);
status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start);
status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc);
void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags);
uint32 DPMS_CAPABILITIES(void);
uint32 DPMS_MODE(void);
status_t SET_DPMS_MODE(uint32 dpms_flags);
status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
void MOVE_CURSOR(uint16 x, uint16 y);
void SHOW_CURSOR(bool is_visible);
uint32 ACCELERANT_ENGINE_COUNT(void);
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et);
status_t RELEASE_ENGINE(engine_token *et, sync_token *st);
void WAIT_ENGINE_IDLE(void);
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st);
status_t SYNC_TO_TOKEN(sync_token *st);
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count);
void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
/* video_overlay */
uint32 OVERLAY_COUNT(const display_mode *dm);
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm);
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space);
const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height);
status_t RELEASE_OVERLAY_BUFFER(const overlay_buffer *ob);
status_t GET_OVERLAY_CONSTRAINTS(const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc);
overlay_token ALLOCATE_OVERLAY(void);
status_t RELEASE_OVERLAY(overlay_token ot);
status_t CONFIGURE_OVERLAY(overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov);
#endif

View File

@ -1,812 +0,0 @@
/*
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#include <Accelerant.h>
#include "voodoo3_io.h"
#include "voodoo3_accelerant.h"
#include "GlobalData.h"
#include <ByteOrder.h>
static Voodoo3Accel accel = { 0, 0, 0, 0, 0};
#define abs(x) (x<0?-x:x)
static __inline__ void
write_crt_registers(uint8 reg, uint8 val)
{
outw(accel.io_base + CRTC_INDEX - 0x300, (val << 8) | reg);
}
static __inline__ void
write_seq_registers(uint8 reg, uint8 val)
{
outw(accel.io_base + SEQ_INDEX - 0x300, (val << 8) | reg);
}
static __inline__ void
write_graph_registers(uint8 reg, uint8 val)
{
outw(accel.io_base + GRA_INDEX - 0x300, (val << 8) | reg);
}
static __inline__ void
write_attr_registers(uint8 reg, uint8 val)
{
uint8 index;
inb (accel.io_base + IS1_R - 0x300);
index = inb(accel.io_base + ATT_IW - 0x300);
outb(accel.io_base + ATT_IW - 0x300, reg);
outb(accel.io_base + ATT_IW - 0x300, val);
outb(accel.io_base + ATT_IW - 0x300, index);
}
static inline void
vga_outb(unsigned long reg, unsigned char val)
{
outb(accel.io_base + reg - 0x300, val);
}
static inline void
voodoo3_write32(unsigned int reg, unsigned long val)
{
PCI_MEM_WR_32(accel.regs_base + reg, val);
}
static inline uint32
voodoo3_read32(unsigned int reg)
{
return PCI_MEM_RD_32(accel.regs_base + reg);
}
static inline void
voodoo3_make_room(unsigned int len)
{
while((voodoo3_read32(STATUS) & 0x1f) < len);
}
static void
voodoo3_initialize(void)
{
unsigned long vgainit0 = 0;
unsigned long vidcfg = 0;
unsigned long cpp = 16;
vgainit0 =
VGAINIT0_8BIT_DAC |
VGAINIT0_EXT_ENABLE |
VGAINIT0_WAKEUP_3C3 |
VGAINIT0_ALT_READBACK |
VGAINIT0_EXTSHIFTOUT;
vidcfg =
VIDCFG_VIDPROC_ENABLE |
VIDCFG_DESK_ENABLE |
((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
(cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
voodoo3_make_room(2);
voodoo3_write32(VGAINIT0, vgainit0);
voodoo3_write32(VIDPROCCFG, vidcfg);
voodoo3_wait_idle();
}
int
voodoo3_init(uint8 *registers_base, uint32 io_base)
{
if(!registers_base) return 0;
accel.regs_base = registers_base;
accel.io_base = io_base;
voodoo3_initialize();
return 1;
}
uint32
voodoo3_bits_per_pixel(void)
{
return accel.bpp;
}
void
voodoo3_set_monitor_defaults(void)
{
MonitorRegs m;
MonitorRegs *mode;
int i;
memset(&m, 0, sizeof(MonitorRegs));
mode = &m;
mode->crtc_regs[0] = 159;
mode->crtc_regs[1] = 127;
mode->crtc_regs[2] = 127;
mode->crtc_regs[3] = 131;
mode->crtc_regs[4] = 129;
mode->crtc_regs[5] = 141;
mode->crtc_regs[6] = 30;
mode->crtc_regs[7] = 245;
mode->crtc_regs[8] = 0;
mode->crtc_regs[9] = 96;
mode->crtc_regs[10] = 0;
mode->crtc_regs[11] = 0;
mode->crtc_regs[12] = 0;
mode->crtc_regs[13] = 0;
mode->crtc_regs[14] = 0;
mode->crtc_regs[15] = 0;
mode->crtc_regs[16] = 1;
mode->crtc_regs[17] = 36;
mode->crtc_regs[18] = 255;
mode->crtc_regs[19] = 127;
mode->crtc_regs[20] = 0;
mode->crtc_regs[21] = 255;
mode->crtc_regs[22] = 31;
mode->crtc_regs[23] = 128;
mode->crtc_regs[24] = 255;
vga_outb(MISC_W, 0x0f);
for (i = 0; i < 0x19; i ++)
write_crt_registers(i, mode->crtc_regs[i]);
}
void
voodoo3_wait_idle(void)
{
int i = 0;
voodoo3_make_room(1);
voodoo3_write32(COMMAND_3D, COMMAND_3D_NOP);
while(1) {
i = (voodoo3_read32(STATUS) & STATUS_BUSY) ? 0 : i + 1;
if(i == 3) break;
}
}
#define REFFREQ 14318.18
static int
voodoo3_calc_pll(int freq, int *f_out, int isBanshee)
{
int m, n, k, best_m, best_n, best_k, f_cur, best_error;
int minm, maxm;
best_error=freq;
best_n=best_m=best_k=0;
if (isBanshee) {
minm=24;
maxm=24;
} else {
minm=1;
maxm=57; /* This used to be 64, alas it seems the last 8 (funny that ?)
* values cause jittering at lower resolutions. I've not done
* any calculations to what the adjustment affects clock ranges,
* but I can still run at 1600x1200@75Hz */
}
for (n=1; n<256; n++) {
f_cur=REFFREQ*(n+2);
if (f_cur<freq) {
f_cur=f_cur/3;
if (freq-f_cur<best_error) {
best_error=freq-f_cur;
best_n=n;
best_m=1;
best_k=0;
continue;
}
}
for (m=minm; m<maxm; m++) {
for (k=0; k<4; k++) {
f_cur=REFFREQ*(n+2)/(m+2)/(1<<k);
if (abs(f_cur-freq)<best_error) {
best_error=abs(f_cur-freq);
best_n=n;
best_m=m;
best_k=k;
}
}
}
}
n=best_n;
m=best_m;
k=best_k;
*f_out=REFFREQ*(n+2)/(m+2)/(1<<k);
return (n<<8)|(m<<2)|k;
}
void
voodoo3_setup_monitor(display_mode *dm)
{
MonitorRegs mod; MonitorRegs *mode;
int i;
uint32 horizontal_display_end, horizontal_sync_start,
horizontal_sync_end, horizontal_total, horizontal_blanking_start,
horizontal_blanking_end;
uint32 vertical_display_enable_end, vertical_sync_start,
vertical_sync_end, vertical_total, vertical_blanking_start,
vertical_blanking_end;
uint32 wd; // CRTC offset
memset(&mod, 0, sizeof(mode));
mode = &mod;
wd = (dm->timing.h_display >> 3) - 1;
horizontal_display_end = (dm->timing.h_display >> 3) - 1;
horizontal_sync_start = (dm->timing.h_sync_start >> 3) - 1;
horizontal_sync_end = (dm->timing.h_sync_end >> 3) - 1;
horizontal_total = (dm->timing.h_total >> 3) - 1;
horizontal_blanking_start = horizontal_display_end;
horizontal_blanking_end = horizontal_total;
vertical_display_enable_end = dm->timing.v_display - 1;
vertical_sync_start = dm->timing.v_sync_start;// - 1;
vertical_sync_end = dm->timing.v_sync_end;// - 1;
vertical_total = dm->timing.v_total - 2;
vertical_blanking_start = vertical_display_enable_end;
vertical_blanking_end = vertical_total;
mode->misc =
0x0f |
(dm->timing.h_display < 400 ? 0xa0 :
dm->timing.h_display < 480 ? 0x60 :
dm->timing.h_display < 768 ? 0xe0 : 0x20);
mode->seq_regs[0] = 3;
mode->seq_regs[1] = 1;
mode->seq_regs[2] = 8;
mode->seq_regs[3] = 0;
mode->seq_regs[4] = 6;
// crtc regs start
mode->crtc_regs[0] = horizontal_total - 4;
mode->crtc_regs[1] = horizontal_display_end;
mode->crtc_regs[2] = horizontal_blanking_start;
mode->crtc_regs[3] = 0x80 | (horizontal_blanking_end & 0x1f);
mode->crtc_regs[4] = horizontal_sync_start;
mode->crtc_regs[5] = ((horizontal_blanking_end & 0x20) << 2) | (horizontal_sync_end & 0x1f);
mode->crtc_regs[6] = vertical_total;
mode->crtc_regs[7] = ((vertical_sync_start & 0x200) >> 2) |
((vertical_display_enable_end & 0x200) >> 3) |
((vertical_total & 0x200) >> 4) |
0x10 |
((vertical_blanking_start & 0x100) >> 5) |
((vertical_sync_start & 0x100) >> 6) |
((vertical_display_enable_end & 0x100) >> 7) |
((vertical_total & 0x100) >> 8);
mode->crtc_regs[8] = 0;
mode->crtc_regs[9] = 0x40 |
((vertical_blanking_start & 0x200) >> 4);
mode->crtc_regs[10] = 0;
mode->crtc_regs[11] = 0;
mode->crtc_regs[12] = 0;
mode->crtc_regs[13] = 0;
mode->crtc_regs[14] = 0;
mode->crtc_regs[15] = 0;
mode->crtc_regs[16] = vertical_sync_start;
mode->crtc_regs[17] = (vertical_sync_end & 0x0f) | 0x20;
mode->crtc_regs[18] = vertical_display_enable_end;
mode->crtc_regs[19] = wd; // CRTC offset
mode->crtc_regs[20] = 0;
mode->crtc_regs[21] = vertical_blanking_start;
mode->crtc_regs[22] = vertical_blanking_end + 1;
mode->crtc_regs[23] = 128;
mode->crtc_regs[24] = 255;
// attr regs start
mode->attr_regs[0] = 0;
mode->attr_regs[1] = 0;
mode->attr_regs[2] = 0;
mode->attr_regs[3] = 0;
mode->attr_regs[4] = 0;
mode->attr_regs[5] = 0;
mode->attr_regs[6] = 0;
mode->attr_regs[7] = 0;
mode->attr_regs[8] = 0;
mode->attr_regs[9] = 0;
mode->attr_regs[10] = 0;
mode->attr_regs[11] = 0;
mode->attr_regs[12] = 0;
mode->attr_regs[13] = 0;
mode->attr_regs[14] = 0;
mode->attr_regs[15] = 0;
mode->attr_regs[16] = 1;
mode->attr_regs[17] = 0;
mode->attr_regs[18] = 15;
mode->attr_regs[19] = 0;
// attr regs end
// graph regs start
mode->graph_regs[0] = 159;
mode->graph_regs[1] = 127;
mode->graph_regs[2] = 127;
mode->graph_regs[3] = 131;
mode->graph_regs[4] = 130;
mode->graph_regs[5] = 142;
mode->graph_regs[6] = 30;
mode->graph_regs[7] = 245;
mode->graph_regs[8] = 0;
vga_outb(MISC_W, mode->misc | 0x01);
for(i = 0; i < 5; i++)
write_seq_registers(i, mode->seq_regs[i]);
for (i = 0; i < 0x19; i ++)
write_crt_registers(i, mode->crtc_regs[i]);
for (i = 0; i < 0x14; i ++)
write_attr_registers(i, mode->attr_regs[i]);
for (i = 0; i < 0x09; i ++)
write_graph_registers(i, mode->graph_regs[i]);
}
void
voodoo_set_desktop_regs(uint32 bits_per_pixel, display_mode *dm)
{
uint32 miscinit0=0;
int vidpll, fout;
int vidproc = VIDPROCDEFAULT;
uint32 bpp = (bits_per_pixel + 7) / 8;
uint32 bytes_per_row = (dm->virtual_width * bits_per_pixel + 7) / 8;
accel.bpp = bits_per_pixel;
accel.width = dm->virtual_width;
accel.height = dm->virtual_height;
voodoo3_setup_monitor(dm);
vidproc &= ~(0x1c0000); // clear bits 18 to 20, bpp in vidproccfg
vidproc |= ((bpp - 1) << VIDCFG_PIXFMT_SHIFT); // enable bits 18 to 20 to the required bpp
vidpll = voodoo3_calc_pll(dm->timing.pixel_clock, &fout, 0);
switch(bits_per_pixel) { // bit 10 of vidproccfg, is enabled or disabled as needed for the Desktop
case 8:
vidproc &= ~(1 << 10); // bit 10 off for palettized modes only, off means palette is used
break;
case 16:
#if __POWERPC__
miscinit0 = 0xc0000000;
#endif
vidproc |= (1 << 10); // bypass palette for 16bit modes
break;
case 32:
#if __POWERPC__
miscinit0 = 0x40000000;
#endif
vidproc |= (1 << 10); // Same for 32bit modes
break;
}
voodoo3_wait_idle();
voodoo3_write32(MISCINIT1, voodoo3_read32(MISCINIT1) | 0x01);
voodoo3_make_room(4);
voodoo3_write32(VGAINIT0, 4928);
voodoo3_write32(DACMODE, 0);
voodoo3_write32(VIDDESKSTRIDE, bytes_per_row);
voodoo3_write32(PLLCTRL0, vidpll);
voodoo3_make_room(5);
voodoo3_write32(VIDSCREENSIZE, dm->virtual_width | (dm->virtual_height << 12));
voodoo3_write32(VIDDESKSTART, 1024);
voodoo3_write32(VIDPROCCFG, vidproc);
voodoo3_write32(VGAINIT1, 0);
voodoo3_write32(MISCINIT0, miscinit0);
voodoo3_make_room(8);
voodoo3_write32(SRCBASE, 1024);
voodoo3_write32(DSTBASE, 1024);
voodoo3_write32(COMMANDEXTRA_2D, 0);
voodoo3_write32(CLIP0MIN, 0);
voodoo3_write32(CLIP0MAX, 0x0fff0fff);
voodoo3_write32(CLIP1MIN, 0);
voodoo3_write32(CLIP1MAX, 0x0fff0fff);
voodoo3_write32(SRCXY, 0);
voodoo3_wait_idle();
}
#if __POWERPC__
// ToDo: use the standard ByteOrder.h macros!
static uint32
ppcSwap(uint32 val, uint32 bpp)
{
switch (bpp) {
default:
return val;
case 16:
return ((val & 0x00ff00ff) << 8) |
((val & 0xff00ff00) >> 8);
case 24:
case 32:
return ((((val) & 0x000000ff) << 24) |
(((val) & 0x0000ff00) << 8) |
(((val) & 0x00ff0000) >> 8) |
(((val) & 0xff000000) >> 24));
}
}
#endif
void
voodoo3_set_cursor(uint8 *data, uint16 width, uint8 height, uint8 *andMask,
uint8 *xorMask)
{
int i;
uint32 fbcurptr=voodoo3_read32(HWCURPATADDR);
uint8 *cursor = (uint8 *)data + fbcurptr;
uint16 *xordata = (uint16 *)xorMask;
uint16 *anddata = (uint16 *)andMask;
uint64 *cursor64 = (uint64 *)cursor;
#if __POWERPC__
uint32 *cursor32 = (uint32 *)data + fbcurptr;
#endif
for(i = 0; i < 16; i++) {
*cursor64++ = ((~0 << 16) | (*anddata++));
*cursor64++ = ((0 << 16) | (*xordata++));
}
for(i = 128; i < 176; i++) {
*cursor64++ = ~0;
*cursor64++ = 0;
}
// for PPC Byteswapping
#if __POWERPC__
for (i=0; i<256; i++) {
uint32 val = cursor32[i];
cursor32[i] = ppcSwap(val,accel.bpp);
}
#endif
}
void
voodoo3_init_cursor_address(void)
{
voodoo3_make_room(1);
voodoo3_write32(HWCURPATADDR, 0);
voodoo3_wait_idle();
}
void
voodoo3_set_cursor_colors(int fg, int bg)
{
voodoo3_make_room(2);
voodoo3_write32(HWCURC0, bg & 0xffffff);
voodoo3_write32(HWCURC1, fg & 0xffffff);
voodoo3_wait_idle();
}
void
voodoo3_show_cursor(void)
{
voodoo3_make_room(1);
voodoo3_write32(VIDPROCCFG, voodoo3_read32(VIDPROCCFG) | (1 << 27));
voodoo3_wait_idle();
}
void
voodoo3_hide_cursor(void)
{
voodoo3_make_room(1);
voodoo3_write32(VIDPROCCFG, voodoo3_read32(VIDPROCCFG) & ~(1 << 27));
voodoo3_wait_idle();
}
void
voodoo3_move_cursor(int x, int y)
{
#if __INTEL__
#define xoffset 63
#define yoffset 63
#else
#define xoffset 15
#define yoffset 63
#endif
x += xoffset;
y += yoffset;
voodoo3_write32(HWCURLOC, x | (y << 16));
}
void
voodoo3_screen_to_screen_blit(list_packet_blit *list, uint32 bytes_per_row,
uint32 bits_per_pixel)
{
uint32 fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
uint32 blitcmd = COMMAND_2D_S2S_BITBLT | (ROP_COPY << 24);
if (list->src_x <= list->dest_x) {
blitcmd |= BIT(14);
list->src_x += (list->width - 1); list->dest_x += (list->width - 1);
}
if (list->src_y <= list->dest_y) {
blitcmd |= BIT(15);
list->src_y += (list->height - 1); list->dest_y += (list->height - 1);
}
voodoo3_make_room(6);
voodoo3_write32(SRCFORMAT, fmt);
voodoo3_write32(DSTFORMAT, fmt);
voodoo3_write32(COMMAND_2D, blitcmd);
voodoo3_write32(DSTSIZE, list->width | (list->height << 16));
voodoo3_write32(DSTXY, list->dest_x | (list->dest_y << 16));
voodoo3_write32(LAUNCH_2D, list->src_x | (list->src_y << 16));
voodoo3_wait_idle();
}
void
voodoo3_fill_rect(list_packet *list, uint32 color, uint32 bytes_per_row,
uint32 bits_per_pixel)
{
uint32 fmt;
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
voodoo3_make_room(5);
voodoo3_write32(DSTFORMAT, fmt);
voodoo3_write32(COLORFORE, color);
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
voodoo3_wait_idle();
}
void
voodoo3_invert_rect(list_packet *list, uint32 color, uint32 bytes_per_row,
uint32 bits_per_pixel)
{
uint32 fmt;
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
voodoo3_make_room(5);
voodoo3_write32(DSTFORMAT, fmt);
voodoo3_write32(COLORFORE, color);
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_INVERT << 24));
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
voodoo3_wait_idle();
}
void
voodoo3_fill_span(list_packet *list, uint32 color, uint32 bytes_per_row,
uint32 bits_per_pixel)
{
uint32 fmt;
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
voodoo3_make_room(5);
voodoo3_write32(DSTFORMAT, fmt);
voodoo3_write32(COLORFORE, color);
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
voodoo3_wait_idle();
}
void
voodoo3_set_palette(int index, uint32 color)
{
voodoo3_make_room(2);
voodoo3_write32(DACADDR, index);
voodoo3_write32(DACDATA, color);
}
uint32
voodoo3_get_memory_size(void)
{
uint32 draminit0 = 0;
uint32 draminit1 = 0;
uint32 miscinit1 = 0;
uint32 lfbsize = 0;
int32 sgram_p = 0;
draminit0 = voodoo3_read32(DRAMINIT0);
draminit1 = voodoo3_read32(DRAMINIT1);
sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
lfbsize = sgram_p ?
(((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) *
((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
16 * 1024 * 1024;
/* disable block writes for SDRAM (why?) */
miscinit1 = voodoo3_read32(MISCINIT1);
miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
miscinit1 |= MISCINIT1_CLUT_INV;
voodoo3_make_room(1);
voodoo3_write32(MISCINIT1, miscinit1);
return lfbsize;
}
void
voodoo3_display_overlay(const overlay_window *ow, const overlay_buffer *ob,
const overlay_view *ov)
{
uint8 red, green, blue;
int32 offset;
int32 pitch;
int32 dudx, dvdy;
uint32 left=0;
uint32 srcwidth;
uint32 vidcfg, stride;
uint32 x1, y1, x2, y2;
uint32 offset_left, offset_top;
if (ow==NULL||ob==NULL||ov==NULL) return;
offset=(uint32)ob->buffer_dma; // Start OFFSET as PCI Space
pitch=((ob->width<<1) + 3) & ~3; // offset (of Desktop && Overlay)
offset_left=ow->h_start<0?-ow->h_start:0;
offset_top=ow->v_start<0?-ow->v_start:0;
dudx = (ob->width << 20) / (ow->width);
dvdy = (ob->height << 20) / (ow->height);
left = ((offset_left*dudx<<16) & 0x0001ffff) << 3;
x1=ow->h_start + offset_left;
y1=ow->v_start + offset_top;
x2=x1 + ow->width;
if (x2>=accel.width) x2=accel.width;
y2=y1 + ow->height;
if (y2>=accel.height) y2=accel.height;
offset+=((offset_left*dudx>>20) & ~1) << 1;
srcwidth=(ob->width<<20);
vidcfg=voodoo3_read32(VIDPROCCFG);
stride=voodoo3_read32(VIDDESKTOPOVERLAYSTRIDE);
vidcfg &= ~VIDPROCCFGMASK;
vidcfg |= VIDCFG_CHROMA_KEY | VIDCFG_OVL_ENABLE | VIDCFG_OVL_NOT_VIDEO_IN |
VIDCFG_OVL_CLUT_BYPASS;
if(ob->width != ow->width)
vidcfg |= VIDCFG_OVL_HSCALE;
if(ob->height != ow->height)
vidcfg |= VIDCFG_OVL_VSCALE;
switch( ob->space) {
case B_YCbCr422:
#if __POWERPC__
switch(accel.bpp) {
case 8:
vidcfg |= VIDCFG_OVL_FMT_YUYV422 << VIDCFG_OVL_FMT_SHIFT;
break;
case 16:
vidcfg |= VIDCFG_OVL_FMT_UYVY422 << VIDCFG_OVL_FMT_SHIFT;
break;
default:
ddpf(( "YCbCr overlays aren't supported in 32 bit mode" ));
return;
}
#else
vidcfg |= VIDCFG_OVL_FMT_YUYV422 << VIDCFG_OVL_FMT_SHIFT;
#endif
break;
#if __POWERPC__
case B_RGB16_BIG:
#else
case B_RGB16:
#endif
vidcfg |= VIDCFG_OVL_FMT_RGB565 << VIDCFG_OVL_FMT_SHIFT;
break;
default: return;
}
/* can't do bilinear filtering when in 2X mode */
if( (vidcfg & VIDCFG_2X) == 0 )
vidcfg |= VIDCFG_OVL_FILTER_BILIN << VIDCFG_OVL_FILTER_SHIFT;
voodoo3_make_room( 12 );
voodoo3_write32(VIDPROCCFG, vidcfg);
if ((ow->flags & B_OVERLAY_COLOR_KEY)==B_OVERLAY_COLOR_KEY) {
uint32 color=0;
red=ow->red.value & ow->red.mask;
green=ow->green.value & ow->green.mask;
blue=ow->blue.value & ow->blue.mask;
switch (voodoo3_bits_per_pixel()) {
case(8):
case(32):
color= (red << 16)+(green << 8)+(blue << 0);
break;
case(16):
color= (red << 11)+(green << 5)+(blue << 0);
break;
}
voodoo3_write32(VIDCHROMAMIN, color);
voodoo3_write32(VIDCHROMAMAX, color);
}
/* Setting up position of Overlaywindow on Screen */
voodoo3_write32(VIDOVERLAYSTARTCOORDS, x1 | (y1 << 12));
voodoo3_write32(VIDOVERLAYENDSCREENCOORDS, (x2 - 1) | ((y2 - 1) << 12));
/* Setting up scale and position of overlay in Graphics Memory */
voodoo3_write32(VIDOVERLAYDUDX, dudx);
voodoo3_write32(VIDOVERLAYDUDXOFFSETSRCWIDTH, left | srcwidth);
voodoo3_write32(VIDOVERLAYDVDY, dvdy);
voodoo3_write32(VIDOVERLAYDVDYOFFSET, (y1 & 0x0000ffff) << 3);
stride &= 0x0000ffff;
stride |= pitch << 16;
voodoo3_write32(VIDDESKTOPOVERLAYSTRIDE, stride);
voodoo3_write32(SST_3D_LEFTOVERLAYBUF, offset);
voodoo3_write32(VIDINADDR0, offset);
}
void
voodoo3_reset_overlay(void)
{
uint32 vidcfg, stride;
vidcfg=voodoo3_read32(VIDPROCCFG);
stride=voodoo3_read32(VIDDESKTOPOVERLAYSTRIDE);
/* reset the video */
vidcfg &= ~VIDPROCCFGMASK;
voodoo3_write32(VIDPROCCFG, vidcfg);
voodoo3_write32(RGBMAXDELTA, 0x0080808);
voodoo3_write32(VIDCHROMAMIN, 0);
voodoo3_write32(VIDCHROMAMAX, 0);
}
// To stop the overlay
void
voodoo3_stop_overlay(void)
{
uint32 vidcfg;
vidcfg=voodoo3_read32(VIDPROCCFG);
/* reset the video */
vidcfg &= ~VIDPROCCFGMASK;
voodoo3_write32(VIDPROCCFG, vidcfg);
}

View File

@ -1,82 +0,0 @@
/*
- Overlay support
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
*/
#ifndef __VOODOO3_ACCELERANT_H__
#define __VOODOO3_ACCELERANT_H__
#include <SupportDefs.h>
#include <video_overlay.h>
typedef struct
{
uint8 *regs_base;
uint32 io_base;
uint32 bpp, width, height;
} Voodoo3Accel;
typedef struct
{
uint8 seq_regs[5];
uint8 crtc_regs[25];
uint8 attr_regs[21];
uint8 graph_regs[9];
uint8 misc;
} MonitorRegs;
typedef struct
{
int x;
int y;
int w;
int h;
} list_packet;
typedef struct
{
int src_x;
int src_y;
int dest_x;
int dest_y;
int width;
int height;
} list_packet_blit;
// Initialize
int voodoo3_init(uint8 *registers_base, uint32 io_base);
void voodoo3_set_monitor_defaults(void);
void voodoo3_wait_idle(void);
void voodoo_set_desktop_regs(uint32 bpp, display_mode *dm);
// Cursor functionality
void voodoo3_show_cursor(void);
void voodoo3_hide_cursor(void);
void voodoo3_move_cursor(int x, int y);
void voodoo3_set_cursor(uint8 *data, uint16 width, uint8 height, uint8 *andMask, uint8 *xorMask);
void voodoo3_set_cursor_colors(int bg, int fg);
void voodoo3_init_cursor_address(void);
// handle colortable
void voodoo3_set_palette(int index, uint32 color);
// accelerated 2d functions
void voodoo3_screen_to_screen_blit(list_packet_blit *list, uint32 bytes_per_row, uint32 bits_per_pixel);
void voodoo3_fill_rect(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
void voodoo3_invert_rect(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
void voodoo3_fill_span(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
// Runtime information
uint32 voodoo3_bits_per_pixel(void);
uint32 voodoo3_get_memory_size(void);
void voodoo3_setup_monitor(display_mode *);
// Overlay
void voodoo3_display_overlay(const overlay_window *ow, const overlay_buffer *ob, const overlay_view* ov);
void voodoo3_reset_overlay(void);
void voodoo3_stop_overlay(void);
#endif

View File

@ -1,182 +0,0 @@
#ifndef __VOODOO3_IO_H__
#define __VOODOO3_IO_H__
#include <ByteOrder.h>
// voodoo3 register locations in pci memory space
/* membase0 register offsets */
#define STATUS 0x00
#define PCIINIT0 0x04
#define SIPMONITOR 0x08
#define LFBMEMORYCONFIG 0x0c
#define MISCINIT0 0x10
#define MISCINIT1 0x14
#define DRAMINIT0 0x18
#define DRAMINIT1 0x1c
#define AGPINIT 0x20
#define TMUGBEINIT 0x24
#define VGAINIT0 0x28
#define VGAINIT1 0x2c
#define DRAMCOMMAND 0x30
#define DRAMDATA 0x34
/* reserved 0x38 */
/* reserved 0x3c */
#define PLLCTRL0 0x40
#define PLLCTRL1 0x44
#define PLLCTRL2 0x48
#define DACMODE 0x4c
#define DACADDR 0x50
#define DACDATA 0x54
#define RGBMAXDELTA 0x58
#define VIDPROCCFG 0x5c
#define HWCURPATADDR 0x60
#define HWCURLOC 0x64
#define HWCURC0 0x68
#define HWCURC1 0x6c
#define VIDINFORMAT 0x70
#define VIDINSTATUS 0x74
#define VIDSERPARPORT 0x78
#define VIDINXDELTA 0x7c
#define VIDININITERR 0x80
#define VIDINYDELTA 0x84
#define VIDPIXBUFTHOLD 0x88
#define VIDCHRMIN 0x8c
#define VIDCHRMAX 0x90
#define VIDCURLIN 0x94
#define VIDSCREENSIZE 0x98
#define VIDOVRSTARTCRD 0x9c
#define VIDOVRENDCRD 0xa0
#define VIDOVRDUDX 0xa4
#define VIDOVRDUDXOFF 0xa8
#define VIDOVRDVDY 0xac
/* ... */
#define VIDOVRDVDYOFF 0xe0
#define VIDDESKSTART 0xe4
#define VIDDESKSTRIDE 0xe8
#define VIDINADDR0 0xec
#define VIDINADDR1 0xf0
#define VIDINADDR2 0xf4
#define VIDINSTRIDE 0xf8
#define VIDCUROVRSTART 0xfc
#define VIDOVERLAYSTARTCOORDS 0x9c
#define VIDOVERLAYENDSCREENCOORDS 0xa0
#define VIDOVERLAYDUDX 0xa4
#define VIDOVERLAYDUDXOFFSETSRCWIDTH 0xa8
#define VIDOVERLAYDVDY 0xac
#define VIDOVERLAYDVDYOFFSET 0xe0
#define SST_3D_OFFSET 0x200000
#define SST_3D_LEFTOVERLAYBUF SST_3D_OFFSET+0x250
#define INTCTRL (0x00100000 + 0x04)
#define CLIP0MIN (0x00100000 + 0x08)
#define CLIP0MAX (0x00100000 + 0x0c)
#define DSTBASE (0x00100000 + 0x10)
#define DSTFORMAT (0x00100000 + 0x14)
#define SRCBASE (0x00100000 + 0x34)
#define COMMANDEXTRA_2D (0x00100000 + 0x38)
#define CLIP1MIN (0x00100000 + 0x4c)
#define CLIP1MAX (0x00100000 + 0x50)
#define SRCFORMAT (0x00100000 + 0x54)
#define SRCSIZE (0x00100000 + 0x58)
#define SRCXY (0x00100000 + 0x5c)
#define COLORBACK (0x00100000 + 0x60)
#define COLORFORE (0x00100000 + 0x64)
#define DSTSIZE (0x00100000 + 0x68)
#define DSTXY (0x00100000 + 0x6c)
#define COMMAND_2D (0x00100000 + 0x70)
#define LAUNCH_2D (0x00100000 + 0x80)
#define COMMAND_3D (0x00200000 + 0x120)
/* register bitfields (not all, only as needed) */
#define BIT(x) (1UL << (x))
/* COMMAND_2D reg. values */
#define ROP_COPY 0xcc // src
#define ROP_INVERT 0x55 // NOT dst
#define ROP_XOR 0x66 // src XOR dst
#define AUTOINC_DSTX BIT(10)
#define AUTOINC_DSTY BIT(11)
#define COMMAND_2D_FILLRECT 0x05
#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen
#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen
#define COMMAND_3D_NOP 0x00
#define STATUS_RETRACE BIT(6)
#define STATUS_BUSY BIT(9)
#define MISCINIT1_CLUT_INV BIT(0)
#define MISCINIT1_2DBLOCK_DIS BIT(15)
#define DRAMINIT0_SGRAM_NUM BIT(26)
#define DRAMINIT0_SGRAM_TYPE BIT(27)
#define DRAMINIT1_MEM_SDRAM BIT(30)
#define VGAINIT0_VGA_DISABLE BIT(0)
#define VGAINIT0_EXT_TIMING BIT(1)
#define VGAINIT0_8BIT_DAC BIT(2)
#define VGAINIT0_EXT_ENABLE BIT(6)
#define VGAINIT0_WAKEUP_3C3 BIT(8)
#define VGAINIT0_LEGACY_DISABLE BIT(9)
#define VGAINIT0_ALT_READBACK BIT(10)
#define VGAINIT0_FAST_BLINK BIT(11)
#define VGAINIT0_EXTSHIFTOUT BIT(12)
#define VGAINIT0_DECODE_3C6 BIT(13)
#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
#define VGAINIT1_MASK 0x1fffff
#define VIDCFG_VIDPROC_ENABLE BIT(0)
#define VIDCFG_CURS_X11 BIT(1)
#define VIDCFG_HALF_MODE BIT(4)
#define VIDCFG_CHROMA_KEY BIT(5)
#define VIDCFG_CHROMA_KEY_INVERSION BIT(6)
#define VIDCFG_DESK_ENABLE BIT(7)
#define VIDCFG_OVL_ENABLE BIT(8)
#define VIDCFG_OVL_NOT_VIDEO_IN BIT(9)
#define VIDCFG_CLUT_BYPASS BIT(10)
#define VIDCFG_OVL_CLUT_BYPASS BIT(11)
#define VIDCFG_OVL_HSCALE BIT(14)
#define VIDCFG_OVL_VSCALE BIT(15)
#define VIDCFG_OVL_FILTER_SHIFT 16
#define VIDCFG_OVL_FILTER_POINT 0
#define VIDCFG_OVL_FILTER_2X2 1
#define VIDCFG_OVL_FILTER_4X4 2
#define VIDCFG_OVL_FILTER_BILIN 3
#define VIDCFG_OVL_FMT_SHIFT 21
#define VIDCFG_OVL_FMT_RGB565 1
#define VIDCFG_OVL_FMT_YUV411 4
#define VIDCFG_OVL_FMT_YUYV422 5
#define VIDCFG_OVL_FMT_UYVY422 6
#define VIDCFG_OVL_FMT_RGB565_DITHER 7
#define VIDCFG_2X BIT(26)
#define VIDCFG_HWCURSOR_ENABLE BIT(27)
#define VIDCFG_PIXFMT_SHIFT 18
#define DACMODE_2X BIT(0)
#define VIDPROCCFGMASK 0xa2e3eb6c
#define VIDPROCDEFAULT 134481025
#define VIDCHROMAMIN 0x8c
#define VIDCHROMAMAX 0x90
#define VIDDESKTOPOVERLAYSTRIDE 0xe8
#define CRTC_INDEX 0x3d4
#define CRTC_DATA 0x3d5
#define SEQ_INDEX 0x3c4
#define SEQ_DATA 0x3c5
#define MISC_W 0x3c2
#define GRA_INDEX 0x3ce
#define ATT_IW 0x3c0
#define IS1_R 0x3da
// pci read from memory
#define PCI_MEM_RD_8(address) (*(volatile uint8 *) (address))
#define PCI_MEM_RD_16(address) B_LENDIAN_TO_HOST_INT16((*(volatile uint16 *) (address)))
#define PCI_MEM_RD_32(address) B_LENDIAN_TO_HOST_INT32((*(volatile uint32 *) (address)))
// pci write to memory
#define PCI_MEM_WR_8(address, value) ((*(volatile uint8 *) (address)) = (uint8) (value))
#define PCI_MEM_WR_16(address, value) ((*(volatile uint16 *) (address)) = (uint16) B_HOST_TO_LENDIAN_INT16((value))
#define PCI_MEM_WR_32(address, value) ((*(volatile uint32 *) (address)) = (uint32) B_HOST_TO_LENDIAN_INT32(value))
#endif

View File

@ -13,7 +13,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics radeon ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics radeon_hd ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics s3 ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics skeleton ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics tdfx ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vesa ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics via ;
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vmware ;

View File

@ -1,9 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel drivers graphics tdfx ;
UsePrivateHeaders graphics ;
UsePrivateHeaders [ FDirName graphics tdfx ] ;
KernelAddon tdfx.driver :
driver.c
;

File diff suppressed because it is too large Load Diff