openBeOS_Matrox_V0.15_src

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5703 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty 2003-12-18 16:42:54 +00:00
parent 74e4cc72e5
commit 71194a68c7
17 changed files with 953 additions and 371 deletions

View File

@ -5,7 +5,7 @@
Other authors:
Mark Watson;
Apsed;
Rudolf Cornelissen 10/2002-4/2003.
Rudolf Cornelissen 10/2002-12/2003.
*/
#ifndef DRIVERINTERFACE_H
@ -51,6 +51,7 @@ typedef struct {
#define TV_PAL (1<<9)
#define TV_NTSC (2<<9)
#define TV_CAPABLE (1<<11)
#define TV_VIDEO (1<<12)
#define SKD_MOVE_CURSOR 0x00000001
#define SKD_PROGRAM_CLUT 0x00000002
@ -158,6 +159,9 @@ typedef struct {
uint32 count; /* last dwgsync slot used */
uint32 last_idle; /* last dwgsync slot we *know* the engine was idle after */
benaphore lock; /* for serializing access to the acceleration engine */
uint32 src_dst; /* G100 pre SRCORG/DSTORG registers */
uint8 y_lin; /* MIL1/2 adress linearisation does not always work */
uint8 depth;
} engine;
/* card info - information gathered from PINS (and other sources) */
@ -221,13 +225,20 @@ typedef struct {
uint16 v5_mem_type; /* pins v5 memory type info */
} ps;
/*mirror of the ROM (copied in driver, because may not be mapped permanently - only over fb)*/
/* mirror of the ROM (copied in driver, because may not be mapped permanently - only over fb) */
uint8 rom_mirror[32768];
/*CRTC delay -> used in timing for MAVEN, depending on which CRTC is driving it*/
/* CRTC delay -> used in timing for MAVEN, depending on which CRTC is driving it */
uint8 crtc_delay;
/* apsed: some configuration settings from ~/config/settings/kernel/drivers/mga.settings if exists */
/* MAVEN sync polarity offset from 'reset' situation: MAVEN sync polarity setup
* works in a serial fashion without readback or handy reset options! */
uint8 maven_syncpol_offset;
/* On G450/G550 we need this info for secondary head DPMS functionality */
bool crossed_conns;
/* apsed: some configuration settings from ~/config/settings/kernel/drivers/mga.settings if exists */
settings settings;
struct

View File

@ -20,6 +20,8 @@ status_t GET_DISPLAY_MODE(display_mode *current_mode)
/* check for NULL pointer */
if (current_mode == NULL) return B_ERROR;
LOG(4, ("GET_DISPLAY_MODE: returning current mode\n"));
*current_mode = si->dm;
return B_OK;
}

View File

@ -4,7 +4,7 @@
Other authors:
Mark Watson,
Rudolf Cornelissen 10/2002-3/2003.
Rudolf Cornelissen 10/2002-12/2003.
*/
#define MODULE_BIT 0x00800000
@ -75,7 +75,7 @@ error0:
return result;
}
/* Clean up code shared between primary and cloned accelrants */
/* Clean up code shared between primary and cloned accelerants */
static void uninit_common(void) {
/* release the memory mapped registers */
delete_area(regs_area);
@ -115,7 +115,10 @@ status_t INIT_ACCELERANT(int the_fd) {
/* bail out if the common initialization failed */
if (result != B_OK) goto error0;
// LOG now available: !NULL si
/* signal CRTC2 DPMS on G450/G550 which connector to program (before powerup) */
si->crossed_conns = false;
/* call the device specific init code */
result = gx00_general_powerup();
@ -235,11 +238,23 @@ status_t CLONE_ACCELERANT(void *data) {
char path[MAXPATHLEN];
/* the data is the device name */
strcpy(path, "/dev");
/* Note: the R4 graphics driver kit is in error here (missing trailing '/') */
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) {
if (fd < 0)
{
/* we can't use LOG because we didn't get the shared_info struct.. */
char fname[64];
FILE *myhand = NULL;
sprintf (fname, "/boot/home/" DRIVER_PREFIX ".accelerant.0.log");
myhand=fopen(fname,"a+");
fprintf(myhand, "CLONE_ACCELERANT: couldn't open kerneldriver %s! Aborting.\n", path);
fclose(myhand);
/* abort with resultcode from open attempt on kerneldriver */
result = fd;
goto error0;
}
@ -282,13 +297,18 @@ error0:
void UNINIT_ACCELERANT(void)
{
if (accelerantIsClone)
{
LOG(4,("UNINIT_ACCELERANT: shutting down clone accelerant.\n"));
}
else
{
LOG(4,("UNINIT_ACCELERANT: shutting down primary accelerant.\n"));
/*delete benaphore*/
DELETE_BEN(si->engine.lock);
DELETE_BEN(si->overlay.lock);
/* delete benaphores ONLY if we are the primary accelerant */
DELETE_BEN(si->engine.lock);
DELETE_BEN(si->overlay.lock);
}
/* free our mode list area */
delete_area(my_mode_list_area);
/* paranoia */

View File

@ -21,6 +21,10 @@ Addon mga.accelerant : accelerants :
: false : libmatrox_engine.a
;
Package openbeos-matrox-1.0 :
mga.accelerant :
boot home config add-ons accelerants ;
Depends mga.accelerant : mga.driver ;
SubInclude OBOS_TOP src add-ons accelerants matrox engine ;

View File

@ -4,7 +4,7 @@
Other authors for MGA driver:
Mark Watson,
Rudolf Cornelissen 9/2002-4/2003
Rudolf Cornelissen 9/2002-12/2003
*/
#define MODULE_BIT 0x00400000
@ -74,9 +74,10 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
{
status_t status = B_OK;
float pix_clock_found;
uint8 m,n,p;
uint8 m,n,p, bpp;
status_t result;
uint32 max_vclk, row_bytes, pointer_reservation;
bool acc_mode;
double target_refresh = ((double)target->timing.pixel_clock * 1000.0) /
(
(double)target->timing.h_total *
@ -164,7 +165,7 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
target->virtual_height = target->timing.v_display;
/* nail virtual size and 'subsequently' calculate rowbytes */
result = gx00_general_validate_pic_size (target, &row_bytes);
result = gx00_general_validate_pic_size (target, &row_bytes, &acc_mode);
if (result == B_ERROR)
{
LOG(4, ("PROPOSEMODE: could not validate virtual picture size, aborted.\n"));
@ -292,7 +293,8 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
* mode (fixed), and all modes support DPMS (fixed);
* We support scrolling and panning in every mode, so we 'send a signal' to
* BWindowScreen.CanControlFrameBuffer() by setting B_SCROLL. */
//fixme: secondary head does not support DPMS...
/* BTW: B_PARALLEL_ACCESS in combination with a hardcursor enables
* BDirectWindow windowed modes. */
target->flags |= (B_PARALLEL_ACCESS | B_8_BIT_DAC | B_DPMS | B_SCROLL);
/* determine the 'would be' max. pixelclock for the second DAC for the current videomode if dualhead were activated */
@ -300,33 +302,64 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
{
case B_CMAP8:
max_vclk = si->ps.max_dac2_clock_8;
bpp = 1;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
max_vclk = si->ps.max_dac2_clock_16;
bpp = 2;
break;
case B_RGB24_LITTLE:
max_vclk = si->ps.max_dac2_clock_24;
bpp = 3;
break;
case B_RGB32_LITTLE:
max_vclk = si->ps.max_dac2_clock_32dh;
bpp = 4;
break;
default:
/* use fail-safe value */
max_vclk = si->ps.max_dac2_clock_32dh;
bpp = 4;
break;
}
/* set DUALHEAD_CAPABLE if suitable */
//fixme: update for independant secondary head use! (reserve fixed memory then)
if (si->ps.secondary_head &&
(((si->ps.memory_size * 1024 * 1024) - pointer_reservation) >=
/* note: extra line for maven vblank included here! */
(row_bytes * (target->virtual_height + 1) * 2)) &&
((target->space == B_RGB16_LITTLE) || (target->space == B_RGB32_LITTLE)) &&
(target->timing.pixel_clock <= (max_vclk * 1000)))
{
target->flags |= DUALHEAD_CAPABLE;
/* extra line for G400 MAVEN vblank design fault workaround needed! */
uint16 vblank_fix = 0;
if (si->ps.card_type <= G400MAX) vblank_fix = 1;
switch (target->flags & DUALHEAD_BITS)
{
case DUALHEAD_ON:
case DUALHEAD_SWITCH:
if ((((si->ps.memory_size * 1024 * 1024) - pointer_reservation) >=
(row_bytes * (target->virtual_height + vblank_fix))) &&
((row_bytes / bpp) >= (target->timing.h_display * 2)))
{
target->flags |= DUALHEAD_CAPABLE;
}
break;
case DUALHEAD_CLONE:
if (((si->ps.memory_size * 1024 * 1024) - pointer_reservation) >=
(row_bytes * (target->virtual_height + vblank_fix)))
{
target->flags |= DUALHEAD_CAPABLE;
}
break;
case DUALHEAD_OFF:
if (((si->ps.memory_size * 1024 * 1024) - pointer_reservation) >=
(row_bytes * (target->virtual_height + vblank_fix) * 2))
{
target->flags |= DUALHEAD_CAPABLE;
}
break;
}
}
/* set TV_CAPABLE if suitable: pixelclock is not important (defined by TVstandard) */

View File

@ -5,7 +5,7 @@
Other authors:
Mark Watson,
Apsed,
Rudolf Cornelissen 11/2002-4/2003
Rudolf Cornelissen 11/2002-12/2003
*/
#define MODULE_BIT 0x00200000
@ -50,10 +50,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
uint8 colour_depth1 = 32;
status_t result;
uint32 startadd,startadd_right;
// apsed TODO startadd is 19 bits if < g200
uint8 display,h,v;
si->switched_crtcs = false;
bool display, h, v;
/* Adjust mode to valid one and fail if invalid */
target /*= bounds*/ = *mode_to_set;
@ -78,19 +75,23 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
}
LOG(1, ("SETMODE: (CONT.) validated command modeflags: $%08x\n", target.flags));
/* overlay engine, cursor and MOVE_DISPLAY need to know the status even when
* in singlehead mode */
si->switched_crtcs = false;
/* disable interrupts using the kernel driver */
interrupt_enable(false);
/* find current DPMS state, then turn off screen(s) */
gx00_crtc_dpms_fetch(&display,&h,&v);
gx00_crtc_dpms(0,0,0);
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,0);
gx00_crtc_dpms_fetch(&display, &h, &v);
gx00_crtc_dpms(false, false, false);
if (si->ps.secondary_head) g400_crtc2_dpms(false, false, false);
/*where in framebuffer the screen is (should this be dependant on previous MOVEDISPLAY?)*/
startadd = si->fbc.frame_buffer - si->framebuffer;
/* calculate and set new mode bytes_per_row */
gx00_general_validate_pic_size (&target, &si->fbc.bytes_per_row);
gx00_general_validate_pic_size (&target, &si->fbc.bytes_per_row, &si->acc_mode);
/*Perform the very long mode switch!*/
if (target.flags & DUALHEAD_BITS) /*if some dualhead mode*/
@ -169,15 +170,16 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/* calculate needed MAVEN-CRTC delay: formula valid for straight-through CRTC's */
si->crtc_delay = 44 + 0 * (colour_depth2 == 16);
/* setup vertical timing adjust for crtc1 and crtc2 for straight-through CRTC's */
/* (extra "blanking" line for MAVEN) */
target2.timing.v_display++;
/* set the outputs */
switch (si->ps.card_type)
{
case G400:
case G400MAX:
/* setup vertical timing adjust for crtc connected to the MAVEN:
* assuming connected straight through. */
/* (extra "blanking" line for MAVEN hardware design fault) */
target2.timing.v_display++;
switch (target.flags & DUALHEAD_BITS)
{
case DUALHEAD_ON:
@ -203,17 +205,15 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
si->switched_crtcs = false;
/* re-calculate MAVEN-CRTC delay: formula valid for crossed CRTC's */
si->crtc_delay = 17 + 4 * (colour_depth1 == 16);
/* re-setup vertical timing adjust for crtc1 and crtc2 for crossed CRTC's */
/* (extra "blanking" line for MAVEN) */
/* re-setup vertical timing adjust for crtc connected to the MAVEN:
* cross connected. */
/* (extra "blanking" line for MAVEN hardware design fault) */
target.timing.v_display++;
target2.timing.v_display--;
}
break;
}
break;
//fixme:
//setup crtc_delay and vertical timing adjust for G450(?)/G550,
//and remove the '+1' in crtc2 vertical timing(?)
case G450:
case G550:
if (!si->ps.primary_dvi)
@ -313,28 +313,12 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
}
/* set the timing */
result = gx00_crtc_set_timing /*crtc1*/
(
target.timing.h_display,
target.timing.h_sync_start,
target.timing.h_sync_end,
target.timing.h_total,
target.timing.v_display,
target.timing.v_sync_start,
target.timing.v_sync_end,
target.timing.v_total,
target.timing.flags&B_POSITIVE_HSYNC,
target.timing.flags&B_POSITIVE_VSYNC
);
gx00_crtc_set_timing(target);
/* we do not need to setup CRTC2 here for a head that's in TVout mode */
if (!(target2.flags & TV_BITS)) result = g400_crtc2_set_timing(target2);
/* TVout support: setup CRTC2 and it's pixelclock */
if (si->ps.secondary_tvout && (target2.flags & TV_BITS))
{
si->crtc_delay += 5;
maventv_init(target2);
}
if (si->ps.secondary_tvout && (target2.flags & TV_BITS)) maventv_init(target2);
}
else /* single head mode */
{
@ -389,21 +373,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
default:
break;
}
/* set the timing */
result = gx00_crtc_set_timing /*crtc1*/
(
target.timing.h_display,
target.timing.h_sync_start,
target.timing.h_sync_end,
target.timing.h_total,
target.timing.v_display,
target.timing.v_sync_start,
target.timing.v_sync_end,
target.timing.v_total,
target.timing.flags&B_POSITIVE_HSYNC,
target.timing.flags&B_POSITIVE_VSYNC
);
gx00_crtc_set_timing(target);
//fixme: shut-off the videoPLL if it exists...
}
@ -412,17 +384,17 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
si->dm = target;
/* turn screen one on */
gx00_crtc_dpms(display,h,v);
gx00_crtc_dpms(display, h, v);
/* turn screen two on if a dualhead mode is active */
if (target.flags & DUALHEAD_BITS) g400_crtc2_dpms(display,h,v);
if (target.flags & DUALHEAD_BITS) g400_crtc2_dpms(display, h, v);
/* set up acceleration for this mode */
si->dm.virtual_height += 1;//for clipping!
gx00_acc_init();
si->dm.virtual_height -= 1;
/* clear line at bottom of screen (for maven) if dualhead mode */
gx00_acc_rectangle(0,si->dm.virtual_width+1,si->dm.virtual_height,1,0);
/* clear line at bottom of screen if dualhead mode:
* MAVEN hardware design fault 'fix'. */
if ((target.flags & DUALHEAD_BITS) && (si->ps.card_type <= G400MAX))
gx00_maven_clrline();
MSG(("SETMODE: booted since %f mS\n", system_time()/1000.0));
@ -574,40 +546,88 @@ void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags
gx00_dac_palette(r,g,b);
}
/* 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) {
interrupt_enable(false);
LOG(4,("SET_DPMS_MODE: 0x%08x\n", dpms_flags));
if (si->dm.flags&DUALHEAD_BITS) /*dualhead*/
if (si->dm.flags & DUALHEAD_BITS) /* dualhead */
{
switch(dpms_flags)
{
case B_DPMS_ON: /* H: on, V: on */
gx00_crtc_dpms(1,1,1);
if (si->ps.secondary_head) g400_crtc2_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
if (si->ps.secondary_head) g400_crtc2_dpms(true, true, true);
break;
case B_DPMS_STAND_BY:
gx00_crtc_dpms(0,0,1);
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,1);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, false, true);
}
if (si->ps.secondary_head)
{
if ((si->dm.flags & TV_BITS) && (si->ps.card_type > G400MAX))
{
/* keep display enabled in TVout modes for G450 and G550! */
g400_crtc2_dpms(true, false, true);
}
else
{
g400_crtc2_dpms(false, false, true);
}
}
break;
case B_DPMS_SUSPEND:
gx00_crtc_dpms(0,1,0);
if (si->ps.secondary_head) g400_crtc2_dpms(0,1,0);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, true, false);
}
if (si->ps.secondary_head)
{
if ((si->dm.flags & TV_BITS) && (si->ps.card_type > G400MAX))
{
/* keep display enabled in TVout modes for G450 and G550! */
g400_crtc2_dpms(true, true, false);
}
else
{
g400_crtc2_dpms(false, true, false);
}
}
break;
case B_DPMS_OFF: /* H: off, V: off, display off */
gx00_crtc_dpms(0,0,0);
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,0);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, false, false);
}
if (si->ps.secondary_head)
{
if ((si->dm.flags & TV_BITS) && (si->ps.card_type > G400MAX))
{
/* keep display enabled in TVout modes for G450 and G550! */
g400_crtc2_dpms(true, false, false);
}
else
{
g400_crtc2_dpms(false, false, false);
}
}
break;
default:
LOG(8,("SET: Invalid DPMS settings (DH) 0x%08x\n", dpms_flags));
@ -615,24 +635,48 @@ status_t SET_DPMS_MODE(uint32 dpms_flags) {
return B_ERROR;
}
}
else /*singlehead*/
else /* singlehead */
{
switch(dpms_flags)
{
case B_DPMS_ON: /* H: on, V: on */
gx00_crtc_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
break;
case B_DPMS_STAND_BY:
gx00_crtc_dpms(0,0,1);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, false, true);
}
break;
case B_DPMS_SUSPEND:
gx00_crtc_dpms(0,1,0);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, true, false);
}
break;
case B_DPMS_OFF: /* H: off, V: off, display off */
gx00_crtc_dpms(0,0,0);
if (si->settings.greensync)
{
/* blank screen, but keep sync running */
gx00_crtc_dpms(false, true, true);
}
else
{
gx00_crtc_dpms(false, false, false);
}
break;
default:
LOG(8,("SET: Invalid DPMS settings (DH) 0x%08x\n", dpms_flags));
LOG(8,("SET: Invalid DPMS settings (SH) 0x%08x\n", dpms_flags));
interrupt_enable(true);
return B_ERROR;
}
@ -641,29 +685,34 @@ status_t SET_DPMS_MODE(uint32 dpms_flags) {
return B_OK;
}
/*
Report device DPMS capabilities.
*/
uint32 DPMS_CAPABILITIES(void) {
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND|B_DPMS_OFF;
/* Report device DPMS capabilities. */
uint32 DPMS_CAPABILITIES(void)
{
if (si->settings.greensync)
/* we can blank the screen on CRTC1, G400 CRTC2 does not support intermediate
* modes anyway. */
//fixme: G450/G550 support full DPMS on CRTC2...
return B_DPMS_ON | B_DPMS_OFF;
else
/* normally CRTC1 supports full DPMS (and on G450/G550 CRTC2 also).. */
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
}
/*
Return the current DPMS mode.
*/
/* Return the current DPMS mode. */
uint32 DPMS_MODE(void) {
uint8 display,h,v;
bool display, h, v;
interrupt_enable(false);
gx00_crtc_dpms_fetch(&display,&h,&v);
gx00_crtc_dpms_fetch(&display, &h, &v);
interrupt_enable(true);
if (display&h&v)
if (display && h && v)
return B_DPMS_ON;
else if(v)
else if (si->settings.greensync)
return B_DPMS_OFF;
else if (v)
return B_DPMS_STAND_BY;
else if(h)
else if (h)
return B_DPMS_SUSPEND;
else
return B_DPMS_OFF;

View File

@ -1,7 +1,7 @@
/* MGA Acceleration functions */
/* Authors:
Mark Watson 2/2000,
Rudolf Cornelissen 10/2002-4/2003.
Rudolf Cornelissen 10/2002-11/2003.
*/
#define MODULE_BIT 0x00080000
@ -17,27 +17,23 @@ invert rectangle
blit
*/
/* G100 pre SRCORG/DSTORG registers */
static uint32 src_dst;
/* MIL1/2 adress linearisation does not always work */
static uint8 y_lin;
static uint8 depth;
/* needed by MIL 1/2 because of adress linearisation constraints */
#define ACCW_YDSTLEN(dst, len) do { \
if (y_lin) { \
ACCW(YDST,((dst)* (si->fbc.bytes_per_row / (depth >> 3))) >> 5); \
if (si->engine.y_lin) { \
ACCW(YDST,((dst)* (si->fbc.bytes_per_row / (si->engine.depth >> 3))) >> 5); \
ACCW(LEN,len); \
} else ACCW(YDSTLEN,((dst)<<16)|(len)); \
} while (0)
status_t gx00_acc_wait_idle()
{
volatile int i;
while (ACCR(STATUS)&(1<<16))
/* wait until engine completely idle */
while (ACCR(STATUS) & 0x00010000)
{
for (i=0;i<10000;i++); /*spin in place so I do not hammer the bus*/
};
/* snooze a bit so I do not hammer the bus */
snooze (100);
}
return B_OK;
}
@ -55,9 +51,9 @@ status_t gx00_acc_init()
}
/* preset using hardware adress linearisation */
y_lin = 0x00;
si->engine.y_lin = 0x00;
/* reset depth */
depth = 0;
si->engine.depth = 0;
/* cleanup bitblt */
ACCW(OPMODE,0);
@ -70,15 +66,15 @@ status_t gx00_acc_init()
{
case B_CMAP8:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x00));
depth = 8;
si->engine.depth = 8;
break;
case B_RGB15_LITTLE:case B_RGB16_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x01));
depth = 16;
si->engine.depth = 16;
break;
case B_RGB32_LITTLE:case B_RGBA32_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x02));
depth = 32;
si->engine.depth = 32;
break;
default:
LOG(8,("ACC: init, invalid bit depth\n"));
@ -89,7 +85,7 @@ status_t gx00_acc_init()
switch (si->ps.card_type)
{
case MIL1:
switch (si->fbc.bytes_per_row / (depth >> 3))
switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{
case 640:
case 768:
@ -105,14 +101,15 @@ status_t gx00_acc_init()
break;
default:
/* we are using software adress linearisation */
y_lin = 0x01;
si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n"));
break;
}
ACCW(PITCH, (y_lin << 15) | ((si->fbc.bytes_per_row / (depth >> 3)) & 0x0FFF));
ACCW(PITCH, (si->engine.y_lin << 15) |
((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
case MIL2:
switch (si->fbc.bytes_per_row / (depth >> 3))
switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{
case 512:
case 640:
@ -131,22 +128,23 @@ status_t gx00_acc_init()
break;
default:
/* we are using software adress linearisation */
y_lin = 0x01;
si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n"));
break;
}
ACCW(PITCH, (y_lin << 15) | ((si->fbc.bytes_per_row / (depth >> 3)) & 0x0FFF));
ACCW(PITCH, (si->engine.y_lin << 15) |
((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
case G100:
/* always using hardware adress linearisation, because 2D/3D
* engine works on every pitch multiple of 32 */
ACCW(PITCH, ((si->fbc.bytes_per_row / (depth >> 3)) & 0x0FFF));
ACCW(PITCH, ((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
default:
/* G200 and up are equal.. */
/* always using hardware adress linearisation, because 2D/3D
* engine works on every pitch multiple of 32 */
ACCW(PITCH, ((si->fbc.bytes_per_row / (depth >> 3)) & 0x1FFF));
ACCW(PITCH, ((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x1FFF));
break;
}
@ -163,8 +161,8 @@ status_t gx00_acc_init()
}
/* init YDSTORG - apsed, if not inited, BitBlts may fails on <= G200 */
src_dst = 0;
ACCW(YDSTORG, src_dst);
si->engine.src_dst = 0;
ACCW(YDSTORG, si->engine.src_dst);
/* <= G100 uses this register as SRCORG/DSTORG replacement, but
* MIL 1/2 does not need framebuffer space for the hardcursor! */
@ -173,32 +171,32 @@ status_t gx00_acc_init()
switch (si->dm.space)
{
case B_CMAP8:
src_dst = 1024 / 1;
si->engine.src_dst = 1024 / 1;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
src_dst = 1024 / 2;
si->engine.src_dst = 1024 / 2;
break;
case B_RGB32_LITTLE:
src_dst = 1024 / 4;
si->engine.src_dst = 1024 / 4;
break;
default:
LOG(8,("ACC: G100 hardcursor not supported for current colorspace\n"));
return B_ERROR;
}
}
ACCW(YDSTORG,src_dst);
ACCW(YDSTORG, si->engine.src_dst);
/* clipping */
/* i.e. highest and lowest X pixel adresses */
ACCW(CXBNDRY,(((si->fbc.bytes_per_row / (depth >> 3)) - 1) << 16) | (0));
ACCW(CXBNDRY,(((si->fbc.bytes_per_row / (si->engine.depth >> 3)) - 1) << 16) | (0));
/* Y pixel addresses must be linear */
/* lowest adress */
ACCW(YTOP, 0 + src_dst);
ACCW(YTOP, 0 + si->engine.src_dst);
/* highest adress */
ACCW(YBOT,((si->dm.virtual_height - 1) *
(si->fbc.bytes_per_row / (depth >> 3))) + src_dst);
(si->fbc.bytes_per_row / (si->engine.depth >> 3))) + si->engine.src_dst);
return B_OK;
}
@ -211,12 +209,12 @@ status_t gx00_acc_blit(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint16 w,uint16 h
uint32 b_start,b_end;
/*find where the top,bottom and offset are*/
offset = (si->fbc.bytes_per_row / (depth >> 3));
offset = (si->fbc.bytes_per_row / (si->engine.depth >> 3));
t_end = t_start = xs + (offset*ys) + src_dst;
t_end = t_start = xs + (offset*ys) + si->engine.src_dst;
t_end += w;
b_end = b_start = xs + (offset*(ys+h)) + src_dst;
b_end = b_start = xs + (offset*(ys+h)) + si->engine.src_dst;
b_end +=w;
/* sgnzero bit _must_ be '0' before accessing SGN! */
@ -280,12 +278,12 @@ status_t gx00_acc_transparent_blit(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint1
return B_ERROR;
/*find where the top,bottom and offset are*/
offset = (si->fbc.bytes_per_row / (depth >> 3));
offset = (si->fbc.bytes_per_row / (si->engine.depth >> 3));
t_end = t_start = xs + (offset*ys) + src_dst;
t_end = t_start = xs + (offset*ys) + si->engine.src_dst;
t_end += w;
b_end = b_start = xs + (offset*(ys+h)) + src_dst;
b_end = b_start = xs + (offset*(ys+h)) + si->engine.src_dst;
b_end +=w;
/* sgnzero bit _must_ be '0' before accessing SGN! */

View File

@ -2,7 +2,7 @@
/* Authors:
Mark Watson 2/2000,
Apsed,
Rudolf Cornelissen 11/2002-4/2003
Rudolf Cornelissen 11/2002-12/2003
*/
#define MODULE_BIT 0x00040000
@ -15,82 +15,65 @@ status_t gx00_crtc_validate_timing(
uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt
)
{
/*horizontal*/
/*make all parameters multiples of 8 and confine to required number of bits*/
*hd_e&=0x7F8;
*hs_s&=0xFF8;
*hs_e&=0xFF8;
*ht &=0xFF8;
/* horizontal */
/* make all parameters multiples of 8 */
*hd_e &= 0x0ff8; /* 2048 is a valid value for this item! */
*hs_s &= 0x0ff8;
*hs_e &= 0x0ff8;
*ht &= 0x0ff8;
/*confine to a reasonable width*/
if (*hd_e<640) *hd_e=640;
if (*hd_e>2048) *hd_e=2048;
/* confine to required number of bits, taking logic into account */
if (*hd_e > ((0x00ff + 1) << 3)) *hd_e = ((0x00ff + 1) << 3);
if (*hs_s > ((0x01ff - 1) << 3)) *hs_s = ((0x01ff - 1) << 3);
if (*hs_e > ( 0x01ff << 3)) *hs_e = ( 0x01ff << 3);
if (*ht > ((0x01ff + 5) << 3)) *ht = ((0x01ff + 5) << 3);
/*if horizontal total does not leave room for a sensible sync pulse, increase it!*/
if (*ht<(*hd_e+80)) *ht=*hd_e+80;
/* NOTE: keep horizontal timing at multiples of 8! */
/* confine to a reasonable width */
if (*hd_e < 640) *hd_e = 640;
if (*hd_e > 2048) *hd_e = 2048;
/*make sure sync pulse is not during display*/
if (*hs_e>(*ht-0x8)) *hs_e=*ht-0x8;
if (*hs_s<(*hd_e+0x8)) *hs_e=*hd_e+0x8;
/* if hor. total does not leave room for a sensible sync pulse, increase it! */
if (*ht < (*hd_e + 80)) *ht = (*hd_e + 80);
/*correct sync pulse if it is too long*/
if (*hs_e>(*hs_s+0xF8)) *hs_e=*hs_s+0xF8;
/* make sure sync pulse is not during display */
if (*hs_e > (*ht - 8)) *hs_e = (*ht - 8);
if (*hs_s < (*hd_e + 8)) *hs_s = (*hd_e + 8);
/*fail if they are now outside required number of bits*/
if (
*hd_e!=(*hd_e&0x7F8) ||
*hs_s!=(*hs_s&0xFF8) ||
*hs_e!=(*hs_e&0xFF8) ||
*ht !=(*ht &0xFF8)
)
{
LOG(8,("CRTC:Horizontal timing fell out of bits\n"));
return B_ERROR;
}
/* correct sync pulse if it is too long:
* there are only 5 bits available to save this in the card registers! */
if (*hs_e > (*hs_s + 0xf8)) *hs_e = (*hs_s + 0xf8);
/*vertical*/
/*squish to required number of bits*/
*vd_e&=0x7FF;
*vs_s&=0xFFF;
*vs_e&=0xFFF;
*vt &=0xFFF;
/* confine to required number of bits, taking logic into account */
if (*vd_e > 0x7ff ) *vd_e = 0x7ff ; /* linecomp max value = 0x7ff! */
if (*vs_s > (0xfff - 1)) *vs_s = (0xfff - 1);
if (*vs_e > 0xfff ) *vs_e = 0xfff ;
if (*vt > (0xfff + 2)) *vt = (0xfff + 2);
/*confine to a reasonable height*/
if (*vd_e<400) *vd_e=400;
if (*vd_e>2048) *vd_e=2048;
/* confine to a reasonable height */
if (*vd_e < 480) *vd_e = 480;
if (*vd_e > 2047) *vd_e = 2047;
/*if vertical total does not leave room for a sync pulse, increase it!*/
if (*vt<(*vd_e+3)) *vt=*vd_e+3;
if (*vt < (*vd_e + 3)) *vt = (*vd_e + 3);
/*make sure sync pulse if not during display*/
if (*vs_e>(*vt-1)) *vs_e=*vt-1;
if (*vs_s<(*vd_e+1)) *vs_s=*vd_e+1;
/* make sure sync pulse is not during display */
if (*vs_e > (*vt - 1)) *vs_e = (*vt - 1);
if (*vs_s < (*vd_e + 1)) *vs_s = (*vd_e + 1);
/*correct sync pulse if it is too long*/
if (*vs_e>(*vs_s+0xF)) *vs_e=*vs_s+0xF;
/* correct sync pulse if it is too long:
* there are only 4 bits available to save this in the card registers! */
if (*vs_e > (*vs_s + 0x0f)) *vs_e = (*vs_s + 0x0f);
/*fail if now outside required number of bits*/
if (
*vd_e!=(*vd_e&0x7FF) ||
*vs_s!=(*vs_s&0xFFF) ||
*vs_e!=(*vs_e&0xFFF) ||
*vt !=(*vt &0xFFF)
)
{
LOG(8,("CRTC:Vertical timing fell out of bits\n"));
return B_ERROR;
}
return B_OK;
}
/*set a mode line - inputs are in pixels*/
status_t gx00_crtc_set_timing(
uint16 hd_e,uint16 hs_s,uint16 hs_e,uint16 ht,
uint16 vd_e,uint16 vs_s,uint16 vs_e,uint16 vt,
uint8 hsync_pos,uint8 vsync_pos
)
/* set a mode line - inputs are in pixels */
status_t gx00_crtc_set_timing(display_mode target)
{
uint8 temp;
uint32 htotal; /*total horizontal total VCLKs*/
uint32 hdisp_e; /*end of horizontal display (begins at 0)*/
uint32 hsync_s; /*begin of horizontal sync pulse*/
@ -109,23 +92,25 @@ status_t gx00_crtc_set_timing(
LOG(4,("CRTC: setting timing\n"));
/* Modify parameters as required by the G400/G200 */
htotal = ((ht >> 3) - 5);
hdisp_e = ((hd_e >> 3) -1); //so: timing - 8
hblnk_s = hdisp_e; //so: timing - 8
hblnk_e = (htotal + 4); //so: timing - 8
hsync_s = (hs_s >> 3);
hsync_e = (hs_e >> 3);
/* Modify parameters as required by standard VGA */
htotal = ((target.timing.h_total >> 3) - 5);
hdisp_e = ((target.timing.h_display >> 3) - 1);
hblnk_s = hdisp_e;
hblnk_e = (htotal + 4);
hsync_s = (target.timing.h_sync_start >> 3);
hsync_e = (target.timing.h_sync_end >> 3);
vtotal=vt-2;
vdisp_e=vd_e-1;
vsync_s=vs_s-1;
vsync_e=vs_e-1;
vblnk_s=vdisp_e;
vblnk_e=vtotal+1;
vtotal = target.timing.v_total - 2;
vdisp_e = target.timing.v_display - 1;
vblnk_s = vdisp_e;
vblnk_e = (vtotal + 1);
vsync_s = target.timing.v_sync_start - 1; /* Matrox */
vsync_e = target.timing.v_sync_end - 1; /* Matrox */
/* We use the Matrox linecomp INT function to detect the
* vertical retrace at the earliest possible moment.. */
linecomp = target.timing.v_display;
linecomp=256; /*should display half the screen!*/
/*log the mode I am setting*/
LOG(2,("CRTC:\n\tHTOT:%x\n\tHDISPEND:%x\n\tHBLNKS:%x\n\tHBLNKE:%x\n\tHSYNCS:%x\n\tHSYNCE:%x\n\t",htotal,hdisp_e,hblnk_s,hblnk_e,hsync_s,hsync_e));
LOG(2,("VTOT:%x\n\tVDISPEND:%x\n\tVBLNKS:%x\n\tVBLNKE:%x\n\tVSYNCS:%x\n\tVSYNCE:%x\n",vtotal,vdisp_e,vblnk_s,vblnk_e,vsync_s,vsync_e));
@ -133,55 +118,79 @@ status_t gx00_crtc_set_timing(
/*actually program the card! Note linecomp is programmed to vblnk_s for VBI*/
/*horizontal - VGA regs*/
VGAW_I(CRTC,0,htotal&0xFF);
VGAW_I(CRTC,1,hdisp_e&0xFF);
VGAW_I(CRTC,2,hblnk_s&0xFF);
VGAW_I(CRTC,3,(hblnk_e&0x1F)|0x80);
VGAW_I(CRTC,4,hsync_s&0xFF);
VGAW_I(CRTC,5,(hsync_e&0x1F)|((hblnk_e&0x20)<<2));
VGAW_I(CRTC, 0x00, (htotal & 0x0ff));
VGAW_I(CRTC, 0x01, (hdisp_e & 0x0ff));
VGAW_I(CRTC, 0x02, (hblnk_s & 0x0ff));
/* b7 should be set for compatibility reasons */
VGAW_I(CRTC, 0x03, ((hblnk_e & 0x01f) | 0x80));
VGAW_I(CRTC, 0x04, (hsync_s & 0x0ff));
VGAW_I(CRTC, 0x05, (hsync_e & 0x01f) | ((hblnk_e & 0x020) << 2));
/*vertical - VGA regs*/
VGAW_I(CRTC,6,vtotal&0xFF);
VGAW_I(CRTC,7,
VGAW_I(CRTC, 0x06, (vtotal & 0x0ff));
VGAW_I(CRTC, 0x07,
(
((vtotal&0x100)>>(8-0)) |((vtotal&0x200)>>(9-5))|
((vdisp_e&0x100)>>(8-1))|((vdisp_e&0x200)>>(9-6))|
((vsync_s&0x100)>>(8-2))|((vsync_s&0x200)>>(9-7))|
((vblnk_s&0x100)>>(8-3))|((linecomp&0x100)>>(8-4))
((vtotal & 0x100) >> (8 - 0)) | ((vtotal & 0x200) >> (9 - 5)) |
((vdisp_e & 0x100) >> (8 - 1)) | ((vdisp_e & 0x200) >> (9 - 6)) |
((vsync_s & 0x100) >> (8 - 2)) | ((vsync_s & 0x200) >> (9 - 7)) |
((vblnk_s & 0x100) >> (8 - 3)) | ((linecomp & 0x100) >> (8 - 4))
));
VGAW_I(CRTC,0x8,0x00);
VGAW_I(CRTC,0x9,((vblnk_s&0x200)>>(9-5))|((linecomp&0x200)>>(9-6)));
VGAW_I(CRTC,0x10,vsync_s&0xFF);
VGAW_I(CRTC,0x11,((VGAR_I(CRTC,0x11))&0xF0)|(vsync_e&0xF));
VGAW_I(CRTC,0x12,vdisp_e&0xFF);
VGAW_I(CRTC,0x15,vblnk_s&0xFF);
VGAW_I(CRTC,0x16,vblnk_e&0xFF);
VGAW_I(CRTC,0x18,linecomp&0xFF);
VGAW_I(CRTC, 0x08, 0x00);
VGAW_I(CRTC, 0x09, ((vblnk_s & 0x200) >> (9 - 5)) | ((linecomp & 0x200) >> (9 - 6)));
VGAW_I(CRTC, 0x10, (vsync_s & 0x0ff));
VGAW_I(CRTC, 0x11, (((VGAR_I(CRTC, 0x11)) & 0xf0) | (vsync_e & 0x00f)));
VGAW_I(CRTC, 0x12, (vdisp_e & 0x0ff));
VGAW_I(CRTC, 0x15, (vblnk_s & 0x0ff));
VGAW_I(CRTC, 0x16, (vblnk_e & 0x0ff));
VGAW_I(CRTC, 0x18, (linecomp & 0x0ff));
/* horizontal - extended regs */
/* do not touch external sync reset inputs: used for TVout */
VGAW_I(CRTCEXT,1,
VGAW_I(CRTCEXT, 1,
(
((htotal&0x100)>>8)|
((hblnk_s&0x100)>>7)|
((hsync_s&0x100)>>6)|
(hblnk_e&0x40)|
(VGAR_I(CRTCEXT,1)&0xb8)
((htotal & 0x100) >> (8 - 0)) |
((hblnk_s & 0x100) >> (8 - 1)) |
((hsync_s & 0x100) >> (8 - 2)) |
((hblnk_e & 0x040) >> (6 - 6)) |
(VGAR_I(CRTCEXT, 1) & 0xb8)
));
/*vertical - extended regs*/
VGAW_I(CRTCEXT,2,
VGAW_I(CRTCEXT, 2,
(
((vtotal&0xC00)>>10)|
((vdisp_e&0x400)>>8)|
((vblnk_s&0xC00)>>7)|
((vsync_s&0xC00)>>5)|
((linecomp&0x400)>>3)
((vtotal & 0xc00) >> (10 - 0)) |
((vdisp_e & 0x400) >> (10 - 2)) |
((vblnk_s & 0xc00) >> (10 - 3)) |
((vsync_s & 0xc00) >> (10 - 5)) |
((linecomp & 0x400) >> (10 - 7))
));
/*set up HSYNC & VSYNC polarity*/
VGAW(MISCW,(VGAR(MISCR)&0x3F)|((!vsync_pos)<<7)|((!hsync_pos)<<6));
LOG(2,("HSYNC/VSYNC pol:%x %x MISC dump:%x\n",hsync_pos,vsync_pos,VGAR(MISCR)));
/* setup HSYNC & VSYNC polarity */
LOG(2,("CRTC: sync polarity: "));
temp = VGAR(MISCR);
if (target.timing.flags & B_POSITIVE_HSYNC)
{
LOG(2,("H:pos "));
temp &= ~0x40;
}
else
{
LOG(2,("H:neg "));
temp |= 0x40;
}
if (target.timing.flags & B_POSITIVE_VSYNC)
{
LOG(2,("V:pos "));
temp &= ~0x80;
}
else
{
LOG(2,("V:neg "));
temp |= 0x80;
}
VGAW(MISCW, temp);
LOG(2,(", MISC reg readback: $%02x\n", VGAR(MISCR)));
return B_OK;
}
@ -239,12 +248,41 @@ status_t gx00_crtc_depth(int mode)
return B_OK;
}
status_t gx00_crtc_dpms(uint8 display,uint8 h,uint8 v) // MIL2
status_t gx00_crtc_dpms(bool display, bool h, bool v) // MIL2
{
LOG(4,("gx00_crtc_dpms (%d,%d,%d)\n", display,h,v));
VGAW_I(SEQ,1,(!display)<<5);
VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)&0xCF)|((!v)<<5))|((!h)<<4);
LOG(4,("CRTC: setting DPMS: "));
if (display)
{
VGAW_I(SEQ,1, 0x00);
LOG(4,("display on, "));
}
else
{
VGAW_I(SEQ,1, 0x20);
LOG(4,("display off, "));
}
if (h)
{
VGAW_I(CRTCEXT, 1, (VGAR_I(CRTCEXT, 1) & 0xef));
LOG(4,("hsync enabled, "));
}
else
{
VGAW_I(CRTCEXT, 1, (VGAR_I(CRTCEXT, 1) | 0x10));
LOG(4,("hsync disabled, "));
}
if (v)
{
VGAW_I(CRTCEXT, 1, (VGAR_I(CRTCEXT, 1) & 0xdf));
LOG(4,("vsync enabled\n"));
}
else
{
VGAW_I(CRTCEXT, 1, (VGAR_I(CRTCEXT, 1) | 0x20));
LOG(4,("vsync disabled\n"));
}
/* set some required fixed values for proper MGA mode initialisation */
VGAW_I(CRTC,0x17,0xC3);
VGAW_I(CRTC,0x14,0x00);
@ -252,13 +290,20 @@ status_t gx00_crtc_dpms(uint8 display,uint8 h,uint8 v) // MIL2
return B_OK;
}
status_t gx00_crtc_dpms_fetch(uint8 * display,uint8 * h,uint8 * v) // MIL2
status_t gx00_crtc_dpms_fetch(bool *display, bool *h, bool *v) // MIL2
{
*display=!((VGAR_I(SEQ,1)&0x20)>>5);
*h=!((VGAR_I(CRTCEXT,1)&0x10)>>4);
*v=!((VGAR_I(CRTCEXT,1)&0x20)>>5);
*display=!(VGAR_I(SEQ, 1) & 0x20);
*h=!(VGAR_I(CRTCEXT, 1) & 0x10);
*v=!(VGAR_I(CRTCEXT, 1) & 0x20);
LOG(4,("CTRC: fetched DPMS state: "));
if (*display) LOG(4,("display on, "));
else LOG(4,("display off, "));
if (*h) LOG(4,("hsync enabled, "));
else LOG(4,("hsync disabled, "));
if (*v) LOG(4,("vsync enabled\n"));
else LOG(4,("vsync disabled\n"));
LOG(4,("gx00_crtc_dpms_fetch (%d,%d,%d)\n", *display,*h,*v));
return B_OK;
}

View File

@ -2,7 +2,7 @@
Authors:
Mark Watson 6/2000,
Rudolf Cornelissen 12/2002 - 4/2003
Rudolf Cornelissen 12/2002 - 12/2003
*/
#define MODULE_BIT 0x00020000
@ -157,39 +157,140 @@ status_t g400_crtc2_depth(int mode)
return B_OK;
}
status_t g400_crtc2_dpms(uint8 display,uint8 h,uint8 v)
status_t g400_crtc2_dpms(bool display, bool h, bool v)
{
if (display & h & v)
{
/* enable CRTC2 and don't touch the rest */
CR2W(CTL, ((CR2R(CTL) & 0xFFF0177E) | 0x01));
}
else
{
/* disable CRTC2 and don't touch the rest */
CR2W(CTL, (CR2R(CTL) & 0xFFF0177E));
}
LOG(4,("CRTC2: setting DPMS: "));
if (si->ps.card_type >= G450)
if (si->ps.card_type <= G400MAX)
{
//fixme:
/* setup monitor mode DPMS: G450 and later fully support this on CRTC2 */
//for now:
//enable 'straight-through' sync outputs on both analog output connectors...
DXIW(SYNCCTRL,0x00);
}
if (display && h && v)
{
/* enable CRTC2 and don't touch the rest */
CR2W(CTL, ((CR2R(CTL) & 0xFFF0177E) | 0x01));
LOG(4,("display on, hsync enabled, vsync enabled\n"));
}
else
{
/* disable CRTC2 and don't touch the rest */
CR2W(CTL, (CR2R(CTL) & 0xFFF0177E));
LOG(4,("display off, hsync disabled, vsync disabled\n"));
}
/* On <= G400MAX dualhead cards we always need to send a 'copy' to the MAVEN */
if (si->ps.secondary_head) gx00_maven_dpms(display, h, v);
/* On <= G400MAX dualhead cards we always need to send a 'copy' to the MAVEN */
if (si->ps.secondary_head) gx00_maven_dpms(display, h, v);
}
else /* G450/G550 */
{
/* set HD15 and DVI-A sync pol. to be fixed 'straight through' from the CRTCs,
* and preset enabled sync signals on both connectors.
* (polarities and primary DPMS are done via other registers.) */
uint8 temp = 0x00;
if (display)
{
/* enable CRTC2 and don't touch the rest */
CR2W(CTL, ((CR2R(CTL) & 0xFFF0177E) | 0x01));
LOG(4,("display on, "));
}
else
{
/* disable CRTC2 and don't touch the rest */
CR2W(CTL, (CR2R(CTL) & 0xFFF0177E));
LOG(4,("display off, "));
}
if (si->crossed_conns)
{
if (h)
{
/* enable DVI-A hsync */
temp &= ~0x01;
LOG(4,("hsync enabled, "));
}
else
{
/* disable DVI-A hsync */
temp |= 0x01;
LOG(4,("hsync disabled, "));
}
if (v)
{
/* enable DVI-A vsync */
temp &= ~0x02;
LOG(4,("vsync enabled\n"));
}
else
{
/* disable DVI-A vsync */
temp |= 0x02;
LOG(4,("vsync disabled\n"));
}
}
else
{
if (h)
{
/* enable HD15 hsync */
temp &= ~0x10;
LOG(4,("hsync enabled, "));
}
else
{
/* disable HD15 hsync */
temp |= 0x10;
LOG(4,("hsync disabled, "));
}
if (v)
{
/* enable HD15 vsync */
temp &= ~0x20;
LOG(4,("vsync enabled\n"));
}
else
{
/* disable HD15 vsync */
temp |= 0x20;
LOG(4,("vsync disabled\n"));
}
}
/* program new syncs */
DXIW(SYNCCTRL, temp);
}
return B_OK;
}
status_t g400_crtc2_dpms_fetch(uint8 * display,uint8 * h,uint8 * v)
status_t g400_crtc2_dpms_fetch(bool *display, bool *h, bool *v)
{
*display=CR2R(CTL)&1;
*display = (CR2R(CTL) & 0x00000001);
*h=*v=1; /*h/vsync always enabled on second CRTC, does not support other*/
if ((si->ps.card_type <= G400MAX))
{
/* no full DPMS support: display controls all signals */
*h = *v = *display;
}
else
{
/* G450 and G550 have full DPMS support on CRTC2 */
if (si->crossed_conns)
{
*h = !(DXIR(SYNCCTRL) & 0x01);
*v = !(DXIR(SYNCCTRL) & 0x02);
}
else
{
*h = !(DXIR(SYNCCTRL) & 0x10);
*v = !(DXIR(SYNCCTRL) & 0x20);
}
}
LOG(4,("CTRC2: fetched DPMS state: "));
if (*display) LOG(4,("display on, "));
else LOG(4,("display off, "));
if (*h) LOG(4,("hsync enabled, "));
else LOG(4,("hsync disabled, "));
if (*v) LOG(4,("vsync enabled\n"));
else LOG(4,("vsync disabled\n"));
return B_OK;
}

View File

@ -1,7 +1,7 @@
/* Authors:
Mark Watson 12/1999,
Apsed,
Rudolf Cornelissen 10/2002-4/2003
Rudolf Cornelissen 10/2002-12/2003
*/
#define MODULE_BIT 0x00008000
@ -56,7 +56,7 @@ status_t gx00_general_powerup()
status_t status;
uint32 card_class;
LOG(1,("POWERUP: Matrox (open)BeOS Accelerant 0.14 running.\n"));
LOG(1,("POWERUP: Matrox (open)BeOS Accelerant 0.15 running.\n"));
/* detect card type and power it up */
switch(CFGR(DEVID))
@ -292,7 +292,7 @@ status_t g100_general_powerup()
/*power up the PLLs,LUT,DAC*/
LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0);
gx00_crtc_dpms(false, false, false);
gx00_crtc_cursor_hide();
/* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
* (this would create electrical shortcuts,
@ -368,7 +368,7 @@ status_t g100_general_powerup()
VGAW_I(CRTC,0x11,0);
/*turn on display one*/
gx00_crtc_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
return B_OK;
}
@ -394,7 +394,7 @@ status_t g200_general_powerup()
/*power up the PLLs,LUT,DAC*/
LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0);
gx00_crtc_dpms(false, false, false);
gx00_crtc_cursor_hide();
/* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
* (this would create electrical shortcuts,
@ -468,7 +468,7 @@ status_t g200_general_powerup()
VGAW_I(CRTC,0x11,0);
/*turn on display one*/
gx00_crtc_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
return B_OK;
}
@ -491,11 +491,19 @@ status_t g400_general_powerup()
/* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
/* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */
if (si->ps.secondary_tvout)
{
ACCW(RST, 0x00000002);
snooze(1000);
ACCW(RST, 0x00000000);
}
/*power up the PLLs,LUT,DAC*/
LOG(4,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0);
g400_crtc2_dpms(0,0,0);
gx00_crtc_dpms(false, false, false);
g400_crtc2_dpms(false, false, false);
gx00_crtc_cursor_hide();
/* set voltage reference - not using DAC reference block */
@ -573,7 +581,7 @@ status_t g400_general_powerup()
}
/*turn on display one*/
gx00_crtc_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
return B_OK;
}
@ -605,8 +613,8 @@ status_t g450_general_powerup()
/* disable outputs */
DXIW(OUTPUTCONN,0x00);
/* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0);
g400_crtc2_dpms(0,0,0);
gx00_crtc_dpms(false, false, false);
g400_crtc2_dpms(false, false, false);
gx00_crtc_cursor_hide();
/* power up everything except DVI electronics (for now) */
@ -721,7 +729,7 @@ status_t g450_general_powerup()
gx50_general_output_select();
/*turn on display one*/
gx00_crtc_dpms(1,1,1);
gx00_crtc_dpms(true, true, true);
/* enable 'straight-through' sync outputs on both analog output connectors */
DXIW(SYNCCTRL,0x00);
@ -806,6 +814,8 @@ status_t gx00_general_dac_select(int dac)
/* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
DXIW(GENIODATA, 0x00);
/* signal CRTC2 DPMS which connector to program */
si->crossed_conns = false;
break;
//fixme: toggle PLL's below if possible:
// otherwise toggle PLL's for G400 2nd case?
@ -821,6 +831,8 @@ status_t gx00_general_dac_select(int dac)
/* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
DXIW(GENIODATA, 0x00);
/* signal CRTC2 DPMS which connector to program */
si->crossed_conns = true;
break;
default:
return B_ERROR;
@ -828,13 +840,6 @@ status_t gx00_general_dac_select(int dac)
return B_OK;
}
/*busy wait until retrace!*/
status_t gx00_general_wait_retrace()
{
while (!(ACCR(STATUS)&0x8));
return B_OK;
}
/* basic change of card state from VGA to powergraphics -> should work from BIOS init state*/
static
status_t gx00_general_bios_to_powergraphics()
@ -858,6 +863,13 @@ status_t gx00_general_bios_to_powergraphics()
{
case G400:
case G400MAX:
/* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */
if (si->ps.secondary_tvout)
{
ACCW(RST, 0x00000002);
snooze(1000);
ACCW(RST, 0x00000000);
}
/* makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr! */
DXIW(MAFCDEL,0x02);
break;
@ -901,7 +913,7 @@ status_t gx00_general_bios_to_powergraphics()
* Mode slopspace is reflected in fbc->bytes_per_row BTW. */
//fixme: seperate heads for real dualhead modes:
//CRTC1 and 2 constraints differ!
status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row)
status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode)
{
/* Note:
* This routine assumes that the CRTC memory pitch granularity is 'smaller than',
@ -1003,7 +1015,7 @@ status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per
/* check if we can setup this mode with acceleration:
* Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */
si->acc_mode = true;
*acc_mode = true;
/* check virtual_width */
switch (si->ps.card_type)
{
@ -1011,19 +1023,19 @@ status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per
case MIL2:
case G100:
/* acc constraint: */
if (target->virtual_width > 2048) si->acc_mode = false;
if (target->virtual_width > 2048) *acc_mode = false;
break;
default:
/* G200-G550 */
/* acc constraint: */
if (target->virtual_width > 4096) si->acc_mode = false;
if (target->virtual_width > 4096) *acc_mode = false;
/* for 32bit mode a lower CRTC1 restriction applies! */
if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask)))
si->acc_mode = false;
*acc_mode = false;
break;
}
/* virtual_height */
if (target->virtual_height > 2048) si->acc_mode = false;
if (target->virtual_height > 2048) *acc_mode = false;
/* now check virtual_size based on CRTC constraints,
* making sure virtual_width stays within the 'mask' constraint: which is only
@ -1064,7 +1076,7 @@ status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per
/* OK, now we know that virtual_width is valid, and it's needing no slopspace if
* it was confined above, so we can finally calculate safely if we need slopspace
* for this mode... */
if (si->acc_mode)
if (*acc_mode)
video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
else
video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);

View File

@ -2,7 +2,7 @@
/* Authors:
Mark Watson 6/2000,
Rudolf Cornelissen 1/2003-4/2003
Rudolf Cornelissen 1/2003-12/2003
Thanx to Petr Vandrovec for writing matroxfb.
*/
@ -14,12 +14,67 @@
status_t g450_g550_maven_set_vid_pll(display_mode target);
status_t g100_g400max_maven_set_vid_pll(display_mode target);
status_t gx00_maven_dpms(uint8 display,uint8 h,uint8 v)
/* This routine blanks the first 'line' below the screen used if there's memory left
* to place it in. This will prevent overscanning rubbish on the MAVEN DAC, but only
* if no screen using virtual height is setup.
* In the rare event the mode and overlay use up so much RAM there's not enough room
* left for one blank line, you will get overscanning rubbish from the overlay as it
* will overwrite the blank line placed here.
* This 'rectangle fill' is done in software because not all modes are supported by
* the acc engine.
* This function exists to partly overcome a G400 MAVEN hardware design fault, which
* influences output in both monitor and TVout modes. The fault is that the MAVEN
* keeps repeatedly displaying the last 8 pixels fetched from memory until fetching
* restarts after a vertical retrace.
* In order to let the maven fetch black pixels, an extra line has to be added to its
* CRTC timing. This line needs to be entirely filled black, so with zeros. This line
* will be displayed as last visible line, and the last 8 pixels of it will be
* repeated during vertical retrace.
* Note that the overscanning rubbish can be suppressed in TVout modes by extending
* the vertical sync pulse all the way 'to the end'. */
status_t gx00_maven_clrline()
{
uint32 x, screensize, pointer_reservation;
uint8* adr;
/* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK;
/* checkout space needed for hardcursor (if any) */
pointer_reservation = 0;
/* MIL 1/2 cards have a seperate buffer for the cursorbitmap inside the DAC */
if ((si->ps.card_type >= G100) && si->settings.hardcursor) pointer_reservation = 1024;
/* calculate actual screensize */
screensize = si->fbc.bytes_per_row * si->dm.virtual_height;
/* check if there's room left for a full blank line following the actual screen */
if ((screensize + si->fbc.bytes_per_row + pointer_reservation) <=
(si->ps.memory_size * 1024 * 1024))
{
LOG(4,("MAVEN: clearing line directly below screen\n"));
/* calculate first adress beyond actual screen */
adr = (uint8*)si->fbc.frame_buffer;
adr += screensize;
/* clear the line */
for (x = 0; x < si->fbc.bytes_per_row; x++)
{
*(adr + x) = 0x00;
}
}
else
LOG(4,("MAVEN: not clearing line directly below screen: no memory left\n"));
return B_OK;
}
status_t gx00_maven_dpms(bool display, bool h, bool v)
{
/* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK;
if (display & h & v)
if (display && h && v)
{
/* turn on screen */
if (!(si->dm.flags & TV_BITS))
@ -56,6 +111,8 @@ status_t gx00_maven_dpms(uint8 display,uint8 h,uint8 v)
/*set a mode line - inputs are in pixels/scanlines*/
status_t gx00_maven_set_timing(display_mode target)
{
uint8 temp, cnt, offset, loop;
/* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK;
@ -87,20 +144,66 @@ status_t gx00_maven_set_timing(display_mode target)
MAVWW(HVIDRSTL, (target.timing.h_total - si->crtc_delay));
MAVWW(VVIDRSTL, (target.timing.v_total - 2));
/* setup HSYNC & VSYNC polarity */
LOG(2,("MAVEN: sync polarity: "));
temp = MAVR(LUMA);
/* find out which offset from the 'reset position' we need */
switch (((target.timing.flags & B_POSITIVE_HSYNC) >> (29 - 0)) |
((target.timing.flags & B_POSITIVE_VSYNC) >> (30 - 1)))
{
case 0:
/* H neg, V neg */
LOG(2,("H:neg V:neg\n"));
offset = 2;
break;
case 1:
/* H pos, V neg */
LOG(2,("H:pos V:neg\n"));
offset = 3;
break;
case 2:
/* H neg, V pos */
LOG(2,("H:neg V:pos\n"));
offset = 1;
break;
case 3:
default:
/* H pos, V pos */
LOG(2,("H:pos V:pos\n"));
offset = 0;
break;
}
/* calculate the number of steps we need to make from the current 'position' */
cnt = 0;
if ((offset - ((int)si->maven_syncpol_offset)) < 0) cnt = 4;
cnt += offset - si->maven_syncpol_offset;
/* note the offset from 'reset position' we will have now */
si->maven_syncpol_offset = offset;
/* program the maven: */
/* make sure pulse bit is reset */
temp &= ~0x20;
MAVW(LUMA, temp);
snooze(5);
/* enable maven sync polarity programming */
temp |= 0x10;
MAVW(LUMA, temp);
snooze(5);
/* pulse sync programming bit until we have the polarities we want */
for (loop = 0; loop < cnt; loop++)
{
MAVW(LUMA, (temp | 0x20));
snooze(5);
MAVW(LUMA, (temp & ~0x20));
snooze(5);
}
/* disable maven sync polarity programming and reset pulse bit */
MAVW(LUMA, (temp & ~0x30));
return B_OK;
}
//not used:
/*
void gx00_maven_delay(int number)
{
// this function is nolonger needed on G450/G550 cards
if (si->ps.card_type > G400MAX) return;
MAVWW(HVIDRSTL,(si->dm.timing.h_total-number));
}
*/
/*set the mode, brightness is a value from 0->2 (where 1 is equivalent to direct)*/
status_t gx00_maven_mode(int mode,float brightness)
{
@ -109,11 +212,16 @@ status_t gx00_maven_mode(int mode,float brightness)
/* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK;
/*set luma to a suitable value for brightness*/
/*assuming 1A is a sensible value*/
luma = (uint8)(0x1a * brightness);
MAVW(LUMA,luma);
LOG(4,("MAVEN: LUMA setting - %x\n",luma));
/* set luma to a suitable value for brightness */
/* assuming 0x0a is a sensible value */
/* fixme:
* it looks like b6 and/or b7 determine the luma: just two values possible. */
/* NOTE: b4 and b5 have another function, don't set! (sync polarity programming) */
luma = (uint8)(0x0a * brightness);
if (luma > 0x0f) luma = 0x0f;
MAVW(LUMA, luma);
LOG(4,("MAVEN: LUMA setting - %x\n", luma));
return B_OK;
}

View File

@ -1,6 +1,6 @@
/* Authors:
Mark Watson 2000,
Rudolf Cornelissen 1/2003-3/2003
Rudolf Cornelissen 1/2003-12/2003
Thanx to Petr Vandrovec for writing matroxfb.
*/
@ -20,9 +20,6 @@ typedef struct {
float chroma_subcarrier;
} gx50_maven_timing;
//fixme: setup fixed CRTC2 modes for all modes and block other modes:
// - 640x480, 800x600, 1024x768 NTSC and PAL overscan compensated modes (desktop)
// - 640x480, 720x480 NTSC and 768x576, 720x576 non-overscan compensated modes (video)
//fixme: try to implement 'fast' and 'slow' settings for all modes,
// so buffer duplication or skipping won't be neccesary for realtime video.
//fixme: try to setup the CRTC2 in interlaced mode for the video modes on <= G400MAX cards.
@ -694,10 +691,190 @@ int maventv_init(display_mode target)
MAVW(LOCK, 0x01);
MAVW(OUTMODE, 0x08);
/* set high contrast/brightness range for TVout */
/* Note:
* b4-5 have contrast/brightness function during TVout, while these bits
* are used to set sync polarity in a serial fashion during monitor modes.
* Setting both these bits here will 'increase' the sync polarity offset
* by one! */
MAVW(LUMA, 0x78);
/* We just made a sync polarity programming step for monitor modes, so:
* note the offset from 'reset position' we will have now */
si->maven_syncpol_offset += 1;
if (si->maven_syncpol_offset > 3) si->maven_syncpol_offset = 0;
//unknown regs:
MAVW(STABLE, 0x02);
MAVW(MONEN, 0xB3);
/* modify mode to center and size correctly on TV */
{
int diff;
float uscan_fact;
bool tweak = false; /* needed for NTSC VCD mode */
if (!(tv_target.flags & TV_VIDEO)) /* Desktop modes */
{
LOG(4,("MAVENTV: setting underscanning ('downscaled') desktop mode\n"));
/* adapt mode to underscan correctly */
if ((tv_target.timing.h_display < 704) && ((tv_target.flags & TV_BITS) == TV_PAL))
{
/* can't be higher because of scaling limitations in MAVEN! */
uscan_fact = 0.77;
}
else
{
/* optimal setting for desktop modes.. */
uscan_fact = 0.80;
}
/* horizontal */
tv_target.timing.h_total = (tv_target.timing.h_display / uscan_fact);
/* adhere to CRTC constraints */
tv_target.timing.h_total &= ~0x0007;
/* vertical */
tv_target.timing.v_total = (tv_target.timing.v_display / uscan_fact);
/* now do vertical centering */
if ((tv_target.flags & TV_BITS) == TV_PAL)
{
diff = tv_target.timing.v_total - tv_target.timing.v_display;
tv_target.timing.v_sync_start = tv_target.timing.v_display + ((diff * 7) / 20);
/* sync all the way 'to the end' to prevent vertical overscanning
* rubbish on top of screen due to MAVEN hardware design fault */
tv_target.timing.v_sync_end = tv_target.timing.v_total;
}
else
{
diff = tv_target.timing.v_total - tv_target.timing.v_display;
tv_target.timing.v_sync_start = tv_target.timing.v_display + ((diff * 5) / 20);
/* sync all the way 'to the end' to prevent vertical overscanning
* rubbish on top of screen due to MAVEN hardware design fault */
tv_target.timing.v_sync_end = tv_target.timing.v_total;
}
}
else /* Video modes */
{
uint16 mode =
(((tv_target.flags & TV_BITS) << (14 - 9)) | tv_target.timing.h_display);
LOG(4,("MAVENTV: setting overscanning ('unscaled') video mode\n"));
/* adapt standard modes to be displayed 1:1 */
switch (mode)
{
case ((TV_NTSC << (14 - 9)) | 640): /* NTSC VCD mode */
/* horizontal: adhere to CRTC granularity (8) */
/* Note: h_total = 704 has no PLL match! */
tv_target.timing.h_total = 696;
/* because this 'low' horizontal resolution cannot be scaled up
* for overscanning use (MAVEN restriction) we need to do some
* tweaking to get a mode we can work with that still has the
* correct aspect ratio.
* This mode has just a little bit horizontal overscanning. */
tweak = true;
break;
case ((TV_NTSC << (14 - 9)) | 720): /* NTSC DVD mode */
/* horizontal: adhere to CRTC granularity (8) */
tv_target.timing.h_total = 784;
break;
case ((TV_PAL << (14 - 9)) | 768): /* PAL VCD mode */
/* horizontal: adhere to CRTC granularity (8) */
tv_target.timing.h_total = 832;
break;
case ((TV_PAL << (14 - 9)) | 720): /* PAL DVD mode */
/* horizontal: adhere to CRTC granularity (8) */
tv_target.timing.h_total = 784;
break;
default:
/* non-standard mode: just hope for he best. */
break;
}
/* now do vertical centering and clipping */
if ((tv_target.flags & TV_BITS) == TV_PAL)
{
/* defined by the PAL standard */
tv_target.timing.v_total = m_timing.v_total;
/* we need to center the image on TV vertically.
* note that 576 is the maximum supported resolution for the PAL standard,
* this is already overscanning by approx 8-10% */
diff = 576 - tv_target.timing.v_display;
/* if we cannot display the current vertical resolution fully, clip it */
if (diff < 0)
{
tv_target.timing.v_display = 576;
diff = 0;
}
/* now center the image on TV */
tv_target.timing.v_sync_start = tv_target.timing.v_display + (diff / 2);
/* sync all the way 'to the end' to prevent vertical overscanning
* rubbish on top of screen due to MAVEN hardware design fault */
/* note: probably invisible in these Video modes */
tv_target.timing.v_sync_end = tv_target.timing.v_total;
}
else
{
/* defined by the NTSC standard */
tv_target.timing.v_total = m_timing.v_total;
/* NTSC VCD mode needs to be scaled down vertically to get correct
* aspect ratio... */
if (tweak) tv_target.timing.v_total += 32;
/* we need to center the image on TV vertically.
* note that 480 is the maximum supported resolution for the NTSC standard,
* this is already overscanning by approx 8-10% */
diff = 480 - tv_target.timing.v_display;
/* if we cannot display the current vertical resolution fully, clip it */
if (diff < 0)
{
tv_target.timing.v_display = 480;
diff = 0;
}
/* now center the image on TV */
tv_target.timing.v_sync_start = tv_target.timing.v_display + (diff / 2);
/* ...NTSC VCD mode needs to be moved up to center the tweaked mode
* correcty... */
if (tweak) tv_target.timing.v_sync_start += 9;
/* sync all the way 'to the end' to prevent vertical overscanning
* rubbish on top of screen due to MAVEN hardware design fault */
/* note: might be visible in the NTSC VCD Video mode */
tv_target.timing.v_sync_end = tv_target.timing.v_total;
}
}
/* finally do horizontal centering */
if ((tv_target.flags & TV_BITS) == TV_PAL)
{
diff = tv_target.timing.h_total - tv_target.timing.h_display;
tv_target.timing.h_sync_start = tv_target.timing.h_display - 0 + (diff / 2);
/* keep adhering to CRTC constraints */
tv_target.timing.h_sync_start &= ~0x0007;
tv_target.timing.h_sync_end = tv_target.timing.h_sync_start + 16;
}
else
{
diff = tv_target.timing.h_total - tv_target.timing.h_display;
tv_target.timing.h_sync_start = tv_target.timing.h_display - 16 + (diff / 2);
/* ...and finally the NTSC VCD mode needs to be moved to the right to
* center the tweaked mode correctly. */
if (tweak) tv_target.timing.h_sync_start -= 16;
/* keep adhering to CRTC constraints */
tv_target.timing.h_sync_start &= ~0x0007;
tv_target.timing.h_sync_end = tv_target.timing.h_sync_start + 16;
}
}
/* tune crtc delay */
if ((tv_target.timing.h_display >= 1000) && (((tv_target.flags & TV_BITS) != TV_PAL)))
{
si->crtc_delay += 1;
}
else
{
si->crtc_delay -= 3;
}
/* setup video PLL */
g100_g400max_maventv_vid_pll_find(
tv_target, &ht_new, &ht_last_line, &m_result, &n_result, &p_result);
@ -767,13 +944,11 @@ int maventv_init(display_mode target)
int index;
/* calc hor scale-back factor from input to output picture (in 1.7 format)
* the MAVEN has 736 pixels fixed visible? outputline length for TVout */
//fixme: shouldn't this be 768 (= PAL 1:1 output 4:3 ratio format)?!?
* the MAVEN has 736 pixels fixed total outputline length for TVout */
h_scale_tv = (736 << 7) / tv_target.timing.h_total;//should be PLL corrected
LOG(4,("MAVENTV: horizontal scale-back factor is: %f\n", (h_scale_tv / 128.0)));
/* limit values to MAVEN capabilities (scale-back factor is 0.5-1.0) */
//fixme: how about lowres upscaling?
if (h_scale_tv > 0x80)
{
h_scale_tv = 0x80;
@ -912,9 +1087,19 @@ int maventv_init(display_mode target)
MAVW(GAMMA9, 0xC8); /* 200 */
/* set flickerfilter */
/* OFF: is dependant on MAVEN chip version(?): MGA_TVO_B = $40, else $00.
* ON : always set $a2. */
MAVW(FFILTER, 0xa2);
if (!(tv_target.flags & TV_VIDEO))
{
/* Desktop modes (those are scaled): filter on to prevent artifacts */
MAVW(FFILTER, 0xa2);
LOG(4,("MAVENTV: enabling flicker filter\n"));
}
else
{
/* Video modes (those are unscaled): filter off to increase sharpness */
//fixme? OFF is dependant on MAVEN version(?): MGA_TVO_B = $40, else $00.
MAVW(FFILTER, 0x00);
LOG(4,("MAVENTV: disabling flicker filter\n"));
}
/* 0x10 or anything ored with it */
//fixme? linux uses 0x14...

View File

@ -4,7 +4,7 @@ status_t mga_set_cas_latency();
status_t gx50_general_output_select();
status_t gx00_general_dac_select(int);
status_t gx00_general_wait_retrace();
status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row);
status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode);
//status_t gx00_general_bios_to_powergraphics();
/* apsed: logging macros */
@ -62,7 +62,8 @@ status_t mil2_dac_init(void);
status_t mil2_dac_set_pix_pll(float f_vco,int bpp);
/*MAVEN functions*/
status_t gx00_maven_dpms(uint8,uint8,uint8);
status_t gx00_maven_clrline();
status_t gx00_maven_dpms(bool display, bool h, bool v);
status_t gx00_maven_set_timing(display_mode target);
status_t gx00_maven_mode(int,float);
@ -83,17 +84,13 @@ status_t gx00_crtc_validate_timing(
uint16 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht,
uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt
);
status_t gx00_crtc_set_timing(
uint16 hd_e,uint16 hs_s,uint16 hs_e,uint16 ht,
uint16 vd_e,uint16 vs_s,uint16 vs_e,uint16 vt,
uint8 hsync_pos,uint8 vsync_pos
);
status_t gx00_crtc_set_timing(display_mode target);
status_t gx00_crtc_depth(int mode);
status_t gx00_crtc_set_display_start(uint32 startadd,uint8 bpp);
status_t gx00_crtc_set_display_pitch();
status_t gx00_crtc_dpms(uint8,uint8,uint8);
status_t gx00_crtc_dpms_fetch(uint8*,uint8*,uint8*);
status_t gx00_crtc_dpms(bool display,bool h,bool v);
status_t gx00_crtc_dpms_fetch(bool *display, bool *h, bool *v);
status_t gx00_crtc_mem_priority(uint8);
status_t gx00_crtc_cursor_init(); /*Yes, cursor follows CRTC1 - not the DAC!*/
@ -109,8 +106,8 @@ status_t g400_crtc2_depth(int mode);
status_t g400_crtc2_set_display_pitch();
status_t g400_crtc2_set_display_start(uint32 startadd,uint8 bpp);
status_t g400_crtc2_dpms(uint8 display,uint8 h,uint8 v);
status_t g400_crtc2_dpms_fetch(uint8 * display,uint8 * h,uint8 * v);
status_t g400_crtc2_dpms(bool display, bool h, bool v);
status_t g400_crtc2_dpms_fetch(bool *display, bool *h, bool *v);
/*acceleration functions*/
status_t check_acc_capability(uint32 feature);

View File

@ -1,5 +1,6 @@
/* Some commmon support functions */
/* Mark Watson 2/2000 */
/* Mark Watson 2/2000
* Rudolf Cornelissen 11/2003 */
#define MODULE_BIT 0x00000800
@ -17,12 +18,15 @@ void delay(bigtime_t i)
void mga_log(char *fmt, ...)
{
char buffer[1024];
char fname[64];
FILE *myhand;
va_list args;
myhand=fopen("/boot/home/" DRIVER_PREFIX ".accelerant.log","a+");
sprintf (fname, "/boot/home/" DRIVER_PREFIX ".accelerant.%d.log", accelerantIsClone);
myhand=fopen(fname,"a+");
if (myhand == NULL) return;
va_start(args,fmt);
vsprintf (buffer, fmt, args);
fprintf(myhand, "%s", buffer);

View File

@ -7,6 +7,16 @@ R5KernelAddon mga.driver : kernel drivers bin :
driver.c
;
Package openbeos-matrox-1.0 :
mga.driver :
boot home config add-ons kernel drivers bin ;
Package openbeos-matrox-1.0 :
<kernel!drivers!dev!graphics>mga.driver :
boot home config add-ons kernel drivers dev graphics ;
Package openbeos-matrox-1.0 :
mga.settings :
boot home config settings kernel drivers ;
# Link to kernel/drivers/dev/graphics
{
local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev graphics ] ;

View File

@ -4,7 +4,7 @@
Other authors:
Mark Watson;
Rudolf Cornelissen 3/2002.
Rudolf Cornelissen 3/2002-11/2003.
*/
/* standard kernel driver stuff */
@ -688,6 +688,9 @@ static status_t open_hook (const char* name, uint32 flags, void** cookie) {
(di->pcii.u.h0.interrupt_line == 0xff) || /* no IRQ assigned */
(di->pcii.u.h0.interrupt_line <= 0x02)) /* system IRQ assigned */
{
/* we are aborting! */
/* Note: the R4 graphics driver kit lacks this statement!! */
result = B_ERROR;
/* interrupt does not exist so exit without installing our handler */
goto delete_the_sem;
}

View File

@ -10,7 +10,7 @@
# mga.accelerant parameters
usebios false # if true rely on bios to coldstart the card instead of driver
#memory 2 # in MB, override builtin memory size detection
hardcursor false # if true use on-chip cursor capabilities
hardcursor true # if true use on-chip cursor capabilities
#logmask 0x00000000 # nothing logged, except errors, is default
#logmask 0x80000000 # log card physical features
#logmask 0x80000000 # log following mask