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
@@ -5,7 +5,7 @@
Other authors: Other authors:
Mark Watson; Mark Watson;
Apsed; Apsed;
Rudolf Cornelissen 10/2002-4/2003. Rudolf Cornelissen 10/2002-12/2003.
*/ */
#ifndef DRIVERINTERFACE_H #ifndef DRIVERINTERFACE_H
@@ -51,6 +51,7 @@ typedef struct {
#define TV_PAL (1<<9) #define TV_PAL (1<<9)
#define TV_NTSC (2<<9) #define TV_NTSC (2<<9)
#define TV_CAPABLE (1<<11) #define TV_CAPABLE (1<<11)
#define TV_VIDEO (1<<12)
#define SKD_MOVE_CURSOR 0x00000001 #define SKD_MOVE_CURSOR 0x00000001
#define SKD_PROGRAM_CLUT 0x00000002 #define SKD_PROGRAM_CLUT 0x00000002
@@ -158,6 +159,9 @@ typedef struct {
uint32 count; /* last dwgsync slot used */ uint32 count; /* last dwgsync slot used */
uint32 last_idle; /* last dwgsync slot we *know* the engine was idle after */ uint32 last_idle; /* last dwgsync slot we *know* the engine was idle after */
benaphore lock; /* for serializing access to the acceleration engine */ 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; } engine;
/* card info - information gathered from PINS (and other sources) */ /* card info - information gathered from PINS (and other sources) */
@@ -221,13 +225,20 @@ typedef struct {
uint16 v5_mem_type; /* pins v5 memory type info */ uint16 v5_mem_type; /* pins v5 memory type info */
} ps; } 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]; 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; 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; settings settings;
struct struct
@@ -20,6 +20,8 @@ status_t GET_DISPLAY_MODE(display_mode *current_mode)
/* check for NULL pointer */ /* check for NULL pointer */
if (current_mode == NULL) return B_ERROR; if (current_mode == NULL) return B_ERROR;
LOG(4, ("GET_DISPLAY_MODE: returning current mode\n"));
*current_mode = si->dm; *current_mode = si->dm;
return B_OK; return B_OK;
} }
@@ -4,7 +4,7 @@
Other authors: Other authors:
Mark Watson, Mark Watson,
Rudolf Cornelissen 10/2002-3/2003. Rudolf Cornelissen 10/2002-12/2003.
*/ */
#define MODULE_BIT 0x00800000 #define MODULE_BIT 0x00800000
@@ -75,7 +75,7 @@ error0:
return result; 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) { static void uninit_common(void) {
/* release the memory mapped registers */ /* release the memory mapped registers */
delete_area(regs_area); delete_area(regs_area);
@@ -115,7 +115,10 @@ status_t INIT_ACCELERANT(int the_fd) {
/* bail out if the common initialization failed */ /* bail out if the common initialization failed */
if (result != B_OK) goto error0; if (result != B_OK) goto error0;
// LOG now available: !NULL si // 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 */ /* call the device specific init code */
result = gx00_general_powerup(); result = gx00_general_powerup();
@@ -235,11 +238,23 @@ status_t CLONE_ACCELERANT(void *data) {
char path[MAXPATHLEN]; char path[MAXPATHLEN];
/* the data is the device name */ /* 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); strcat(path, (const char *)data);
/* open the device, the permissions aren't important */ /* open the device, the permissions aren't important */
fd = open(path, B_READ_WRITE); fd = open(path, B_READ_WRITE);
if (fd < 0) { if (fd < 0)
{
/* 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; result = fd;
goto error0; goto error0;
} }
@@ -282,13 +297,18 @@ error0:
void UNINIT_ACCELERANT(void) void UNINIT_ACCELERANT(void)
{ {
if (accelerantIsClone) if (accelerantIsClone)
{
LOG(4,("UNINIT_ACCELERANT: shutting down clone accelerant.\n")); LOG(4,("UNINIT_ACCELERANT: shutting down clone accelerant.\n"));
}
else else
{
LOG(4,("UNINIT_ACCELERANT: shutting down primary accelerant.\n")); LOG(4,("UNINIT_ACCELERANT: shutting down primary accelerant.\n"));
/*delete benaphore*/ /* delete benaphores ONLY if we are the primary accelerant */
DELETE_BEN(si->engine.lock); DELETE_BEN(si->engine.lock);
DELETE_BEN(si->overlay.lock); DELETE_BEN(si->overlay.lock);
}
/* free our mode list area */ /* free our mode list area */
delete_area(my_mode_list_area); delete_area(my_mode_list_area);
/* paranoia */ /* paranoia */
+4
View File
@@ -21,6 +21,10 @@ Addon mga.accelerant : accelerants :
: false : libmatrox_engine.a : false : libmatrox_engine.a
; ;
Package openbeos-matrox-1.0 :
mga.accelerant :
boot home config add-ons accelerants ;
Depends mga.accelerant : mga.driver ; Depends mga.accelerant : mga.driver ;
SubInclude OBOS_TOP src add-ons accelerants matrox engine ; SubInclude OBOS_TOP src add-ons accelerants matrox engine ;
@@ -4,7 +4,7 @@
Other authors for MGA driver: Other authors for MGA driver:
Mark Watson, Mark Watson,
Rudolf Cornelissen 9/2002-4/2003 Rudolf Cornelissen 9/2002-12/2003
*/ */
#define MODULE_BIT 0x00400000 #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; status_t status = B_OK;
float pix_clock_found; float pix_clock_found;
uint8 m,n,p; uint8 m,n,p, bpp;
status_t result; status_t result;
uint32 max_vclk, row_bytes, pointer_reservation; uint32 max_vclk, row_bytes, pointer_reservation;
bool acc_mode;
double target_refresh = ((double)target->timing.pixel_clock * 1000.0) / double target_refresh = ((double)target->timing.pixel_clock * 1000.0) /
( (
(double)target->timing.h_total * (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; target->virtual_height = target->timing.v_display;
/* nail virtual size and 'subsequently' calculate rowbytes */ /* 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) if (result == B_ERROR)
{ {
LOG(4, ("PROPOSEMODE: could not validate virtual picture size, aborted.\n")); 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); * mode (fixed), and all modes support DPMS (fixed);
* We support scrolling and panning in every mode, so we 'send a signal' to * We support scrolling and panning in every mode, so we 'send a signal' to
* BWindowScreen.CanControlFrameBuffer() by setting B_SCROLL. */ * 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); 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 */ /* 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: case B_CMAP8:
max_vclk = si->ps.max_dac2_clock_8; max_vclk = si->ps.max_dac2_clock_8;
bpp = 1;
break; break;
case B_RGB15_LITTLE: case B_RGB15_LITTLE:
case B_RGB16_LITTLE: case B_RGB16_LITTLE:
max_vclk = si->ps.max_dac2_clock_16; max_vclk = si->ps.max_dac2_clock_16;
bpp = 2;
break; break;
case B_RGB24_LITTLE: case B_RGB24_LITTLE:
max_vclk = si->ps.max_dac2_clock_24; max_vclk = si->ps.max_dac2_clock_24;
bpp = 3;
break; break;
case B_RGB32_LITTLE: case B_RGB32_LITTLE:
max_vclk = si->ps.max_dac2_clock_32dh; max_vclk = si->ps.max_dac2_clock_32dh;
bpp = 4;
break; break;
default: default:
/* use fail-safe value */ /* use fail-safe value */
max_vclk = si->ps.max_dac2_clock_32dh; max_vclk = si->ps.max_dac2_clock_32dh;
bpp = 4;
break; break;
} }
/* set DUALHEAD_CAPABLE if suitable */ /* set DUALHEAD_CAPABLE if suitable */
//fixme: update for independant secondary head use! (reserve fixed memory then) //fixme: update for independant secondary head use! (reserve fixed memory then)
if (si->ps.secondary_head && 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->space == B_RGB16_LITTLE) || (target->space == B_RGB32_LITTLE)) &&
(target->timing.pixel_clock <= (max_vclk * 1000))) (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) */ /* set TV_CAPABLE if suitable: pixelclock is not important (defined by TVstandard) */
+144 -95
View File
@@ -5,7 +5,7 @@
Other authors: Other authors:
Mark Watson, Mark Watson,
Apsed, Apsed,
Rudolf Cornelissen 11/2002-4/2003 Rudolf Cornelissen 11/2002-12/2003
*/ */
#define MODULE_BIT 0x00200000 #define MODULE_BIT 0x00200000
@@ -50,10 +50,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
uint8 colour_depth1 = 32; uint8 colour_depth1 = 32;
status_t result; status_t result;
uint32 startadd,startadd_right; uint32 startadd,startadd_right;
// apsed TODO startadd is 19 bits if < g200 bool display, h, v;
uint8 display,h,v;
si->switched_crtcs = false;
/* Adjust mode to valid one and fail if invalid */ /* Adjust mode to valid one and fail if invalid */
target /*= bounds*/ = *mode_to_set; 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)); 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 */ /* disable interrupts using the kernel driver */
interrupt_enable(false); interrupt_enable(false);
/* find current DPMS state, then turn off screen(s) */ /* find current DPMS state, then turn off screen(s) */
gx00_crtc_dpms_fetch(&display,&h,&v); gx00_crtc_dpms_fetch(&display, &h, &v);
gx00_crtc_dpms(0,0,0); gx00_crtc_dpms(false, false, false);
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,0); if (si->ps.secondary_head) g400_crtc2_dpms(false, false, false);
/*where in framebuffer the screen is (should this be dependant on previous MOVEDISPLAY?)*/ /*where in framebuffer the screen is (should this be dependant on previous MOVEDISPLAY?)*/
startadd = si->fbc.frame_buffer - si->framebuffer; startadd = si->fbc.frame_buffer - si->framebuffer;
/* calculate and set new mode bytes_per_row */ /* 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!*/ /*Perform the very long mode switch!*/
if (target.flags & DUALHEAD_BITS) /*if some dualhead mode*/ 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 */ /* calculate needed MAVEN-CRTC delay: formula valid for straight-through CRTC's */
si->crtc_delay = 44 + 0 * (colour_depth2 == 16); 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 */ /* set the outputs */
switch (si->ps.card_type) switch (si->ps.card_type)
{ {
case G400: case G400:
case G400MAX: 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) switch (target.flags & DUALHEAD_BITS)
{ {
case DUALHEAD_ON: case DUALHEAD_ON:
@@ -203,17 +205,15 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
si->switched_crtcs = false; si->switched_crtcs = false;
/* re-calculate MAVEN-CRTC delay: formula valid for crossed CRTC's */ /* re-calculate MAVEN-CRTC delay: formula valid for crossed CRTC's */
si->crtc_delay = 17 + 4 * (colour_depth1 == 16); si->crtc_delay = 17 + 4 * (colour_depth1 == 16);
/* re-setup vertical timing adjust for crtc1 and crtc2 for crossed CRTC's */ /* re-setup vertical timing adjust for crtc connected to the MAVEN:
/* (extra "blanking" line for MAVEN) */ * cross connected. */
/* (extra "blanking" line for MAVEN hardware design fault) */
target.timing.v_display++; target.timing.v_display++;
target2.timing.v_display--; target2.timing.v_display--;
} }
break; break;
} }
break; break;
//fixme:
//setup crtc_delay and vertical timing adjust for G450(?)/G550,
//and remove the '+1' in crtc2 vertical timing(?)
case G450: case G450:
case G550: case G550:
if (!si->ps.primary_dvi) if (!si->ps.primary_dvi)
@@ -313,28 +313,12 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
} }
/* set the timing */ /* set the timing */
result = gx00_crtc_set_timing /*crtc1*/ gx00_crtc_set_timing(target);
(
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
);
/* we do not need to setup CRTC2 here for a head that's in TVout mode */ /* 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); if (!(target2.flags & TV_BITS)) result = g400_crtc2_set_timing(target2);
/* TVout support: setup CRTC2 and it's pixelclock */ /* TVout support: setup CRTC2 and it's pixelclock */
if (si->ps.secondary_tvout && (target2.flags & TV_BITS)) if (si->ps.secondary_tvout && (target2.flags & TV_BITS)) maventv_init(target2);
{
si->crtc_delay += 5;
maventv_init(target2);
}
} }
else /* single head mode */ else /* single head mode */
{ {
@@ -389,21 +373,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
default: default:
break; break;
} }
/* set the timing */ /* set the timing */
result = gx00_crtc_set_timing /*crtc1*/ gx00_crtc_set_timing(target);
(
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
);
//fixme: shut-off the videoPLL if it exists... //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; si->dm = target;
/* turn screen one on */ /* 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 */ /* 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 */ /* set up acceleration for this mode */
si->dm.virtual_height += 1;//for clipping!
gx00_acc_init(); gx00_acc_init();
si->dm.virtual_height -= 1;
/* clear line at bottom of screen (for maven) if dualhead mode */ /* clear line at bottom of screen if dualhead mode:
gx00_acc_rectangle(0,si->dm.virtual_width+1,si->dm.virtual_height,1,0); * 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)); 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); 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. */ /* Put the display into one of the Display Power Management modes. */
status_t SET_DPMS_MODE(uint32 dpms_flags) { status_t SET_DPMS_MODE(uint32 dpms_flags) {
interrupt_enable(false); interrupt_enable(false);
LOG(4,("SET_DPMS_MODE: 0x%08x\n", dpms_flags)); 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) switch(dpms_flags)
{ {
case B_DPMS_ON: /* H: on, V: on */ case B_DPMS_ON: /* H: on, V: on */
gx00_crtc_dpms(1,1,1); gx00_crtc_dpms(true, true, true);
if (si->ps.secondary_head) g400_crtc2_dpms(1,1,1); if (si->ps.secondary_head) g400_crtc2_dpms(true, true, true);
break; break;
case B_DPMS_STAND_BY: case B_DPMS_STAND_BY:
gx00_crtc_dpms(0,0,1); if (si->settings.greensync)
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,1); {
/* 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; break;
case B_DPMS_SUSPEND: case B_DPMS_SUSPEND:
gx00_crtc_dpms(0,1,0); if (si->settings.greensync)
if (si->ps.secondary_head) g400_crtc2_dpms(0,1,0); {
/* 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; break;
case B_DPMS_OFF: /* H: off, V: off, display off */ case B_DPMS_OFF: /* H: off, V: off, display off */
gx00_crtc_dpms(0,0,0); if (si->settings.greensync)
if (si->ps.secondary_head) g400_crtc2_dpms(0,0,0); {
/* 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; break;
default: default:
LOG(8,("SET: Invalid DPMS settings (DH) 0x%08x\n", dpms_flags)); 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; return B_ERROR;
} }
} }
else /*singlehead*/ else /* singlehead */
{ {
switch(dpms_flags) switch(dpms_flags)
{ {
case B_DPMS_ON: /* H: on, V: on */ case B_DPMS_ON: /* H: on, V: on */
gx00_crtc_dpms(1,1,1); gx00_crtc_dpms(true, true, true);
break; break;
case B_DPMS_STAND_BY: 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; break;
case B_DPMS_SUSPEND: 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; break;
case B_DPMS_OFF: /* H: off, V: off, display off */ 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; break;
default: 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); interrupt_enable(true);
return B_ERROR; return B_ERROR;
} }
@@ -641,29 +685,34 @@ status_t SET_DPMS_MODE(uint32 dpms_flags) {
return B_OK; return B_OK;
} }
/* /* Report device DPMS capabilities. */
Report device DPMS capabilities. uint32 DPMS_CAPABILITIES(void)
*/ {
uint32 DPMS_CAPABILITIES(void) { if (si->settings.greensync)
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND|B_DPMS_OFF; /* 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) { uint32 DPMS_MODE(void) {
uint8 display,h,v; bool display, h, v;
interrupt_enable(false); interrupt_enable(false);
gx00_crtc_dpms_fetch(&display,&h,&v); gx00_crtc_dpms_fetch(&display, &h, &v);
interrupt_enable(true); interrupt_enable(true);
if (display&h&v) if (display && h && v)
return B_DPMS_ON; return B_DPMS_ON;
else if(v) else if (si->settings.greensync)
return B_DPMS_OFF;
else if (v)
return B_DPMS_STAND_BY; return B_DPMS_STAND_BY;
else if(h) else if (h)
return B_DPMS_SUSPEND; return B_DPMS_SUSPEND;
else else
return B_DPMS_OFF; return B_DPMS_OFF;
+39 -41
View File
@@ -1,7 +1,7 @@
/* MGA Acceleration functions */ /* MGA Acceleration functions */
/* Authors: /* Authors:
Mark Watson 2/2000, Mark Watson 2/2000,
Rudolf Cornelissen 10/2002-4/2003. Rudolf Cornelissen 10/2002-11/2003.
*/ */
#define MODULE_BIT 0x00080000 #define MODULE_BIT 0x00080000
@@ -17,27 +17,23 @@ invert rectangle
blit 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 */ /* needed by MIL 1/2 because of adress linearisation constraints */
#define ACCW_YDSTLEN(dst, len) do { \ #define ACCW_YDSTLEN(dst, len) do { \
if (y_lin) { \ if (si->engine.y_lin) { \
ACCW(YDST,((dst)* (si->fbc.bytes_per_row / (depth >> 3))) >> 5); \ ACCW(YDST,((dst)* (si->fbc.bytes_per_row / (si->engine.depth >> 3))) >> 5); \
ACCW(LEN,len); \ ACCW(LEN,len); \
} else ACCW(YDSTLEN,((dst)<<16)|(len)); \ } else ACCW(YDSTLEN,((dst)<<16)|(len)); \
} while (0) } while (0)
status_t gx00_acc_wait_idle() status_t gx00_acc_wait_idle()
{ {
volatile int i; /* wait until engine completely idle */
while (ACCR(STATUS)&(1<<16)) 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; return B_OK;
} }
@@ -55,9 +51,9 @@ status_t gx00_acc_init()
} }
/* preset using hardware adress linearisation */ /* preset using hardware adress linearisation */
y_lin = 0x00; si->engine.y_lin = 0x00;
/* reset depth */ /* reset depth */
depth = 0; si->engine.depth = 0;
/* cleanup bitblt */ /* cleanup bitblt */
ACCW(OPMODE,0); ACCW(OPMODE,0);
@@ -70,15 +66,15 @@ status_t gx00_acc_init()
{ {
case B_CMAP8: case B_CMAP8:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x00)); ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x00));
depth = 8; si->engine.depth = 8;
break; break;
case B_RGB15_LITTLE:case B_RGB16_LITTLE: case B_RGB15_LITTLE:case B_RGB16_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x01)); ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x01));
depth = 16; si->engine.depth = 16;
break; break;
case B_RGB32_LITTLE:case B_RGBA32_LITTLE: case B_RGB32_LITTLE:case B_RGBA32_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x02)); ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x02));
depth = 32; si->engine.depth = 32;
break; break;
default: default:
LOG(8,("ACC: init, invalid bit depth\n")); LOG(8,("ACC: init, invalid bit depth\n"));
@@ -89,7 +85,7 @@ status_t gx00_acc_init()
switch (si->ps.card_type) switch (si->ps.card_type)
{ {
case MIL1: case MIL1:
switch (si->fbc.bytes_per_row / (depth >> 3)) switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{ {
case 640: case 640:
case 768: case 768:
@@ -105,14 +101,15 @@ status_t gx00_acc_init()
break; break;
default: default:
/* we are using software adress linearisation */ /* we are using software adress linearisation */
y_lin = 0x01; si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n")); LOG(8,("ACC: using software adress linearisation\n"));
break; 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; break;
case MIL2: case MIL2:
switch (si->fbc.bytes_per_row / (depth >> 3)) switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{ {
case 512: case 512:
case 640: case 640:
@@ -131,22 +128,23 @@ status_t gx00_acc_init()
break; break;
default: default:
/* we are using software adress linearisation */ /* we are using software adress linearisation */
y_lin = 0x01; si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n")); LOG(8,("ACC: using software adress linearisation\n"));
break; 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; break;
case G100: case G100:
/* always using hardware adress linearisation, because 2D/3D /* always using hardware adress linearisation, because 2D/3D
* engine works on every pitch multiple of 32 */ * 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; break;
default: default:
/* G200 and up are equal.. */ /* G200 and up are equal.. */
/* always using hardware adress linearisation, because 2D/3D /* always using hardware adress linearisation, because 2D/3D
* engine works on every pitch multiple of 32 */ * 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; break;
} }
@@ -163,8 +161,8 @@ status_t gx00_acc_init()
} }
/* init YDSTORG - apsed, if not inited, BitBlts may fails on <= G200 */ /* init YDSTORG - apsed, if not inited, BitBlts may fails on <= G200 */
src_dst = 0; si->engine.src_dst = 0;
ACCW(YDSTORG, src_dst); ACCW(YDSTORG, si->engine.src_dst);
/* <= G100 uses this register as SRCORG/DSTORG replacement, but /* <= G100 uses this register as SRCORG/DSTORG replacement, but
* MIL 1/2 does not need framebuffer space for the hardcursor! */ * MIL 1/2 does not need framebuffer space for the hardcursor! */
@@ -173,32 +171,32 @@ status_t gx00_acc_init()
switch (si->dm.space) switch (si->dm.space)
{ {
case B_CMAP8: case B_CMAP8:
src_dst = 1024 / 1; si->engine.src_dst = 1024 / 1;
break; break;
case B_RGB15_LITTLE: case B_RGB15_LITTLE:
case B_RGB16_LITTLE: case B_RGB16_LITTLE:
src_dst = 1024 / 2; si->engine.src_dst = 1024 / 2;
break; break;
case B_RGB32_LITTLE: case B_RGB32_LITTLE:
src_dst = 1024 / 4; si->engine.src_dst = 1024 / 4;
break; break;
default: default:
LOG(8,("ACC: G100 hardcursor not supported for current colorspace\n")); LOG(8,("ACC: G100 hardcursor not supported for current colorspace\n"));
return B_ERROR; return B_ERROR;
} }
} }
ACCW(YDSTORG,src_dst); ACCW(YDSTORG, si->engine.src_dst);
/* clipping */ /* clipping */
/* i.e. highest and lowest X pixel adresses */ /* 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 */ /* Y pixel addresses must be linear */
/* lowest adress */ /* lowest adress */
ACCW(YTOP, 0 + src_dst); ACCW(YTOP, 0 + si->engine.src_dst);
/* highest adress */ /* highest adress */
ACCW(YBOT,((si->dm.virtual_height - 1) * 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; 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; uint32 b_start,b_end;
/*find where the top,bottom and offset are*/ /*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; 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; b_end +=w;
/* sgnzero bit _must_ be '0' before accessing SGN! */ /* 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; return B_ERROR;
/*find where the top,bottom and offset are*/ /*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; 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; b_end +=w;
/* sgnzero bit _must_ be '0' before accessing SGN! */ /* sgnzero bit _must_ be '0' before accessing SGN! */
+165 -120
View File
@@ -2,7 +2,7 @@
/* Authors: /* Authors:
Mark Watson 2/2000, Mark Watson 2/2000,
Apsed, Apsed,
Rudolf Cornelissen 11/2002-4/2003 Rudolf Cornelissen 11/2002-12/2003
*/ */
#define MODULE_BIT 0x00040000 #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 uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt
) )
{ {
/*horizontal*/ /* horizontal */
/*make all parameters multiples of 8 and confine to required number of bits*/ /* make all parameters multiples of 8 */
*hd_e&=0x7F8; *hd_e &= 0x0ff8; /* 2048 is a valid value for this item! */
*hs_s&=0xFF8; *hs_s &= 0x0ff8;
*hs_e&=0xFF8; *hs_e &= 0x0ff8;
*ht &=0xFF8; *ht &= 0x0ff8;
/*confine to a reasonable width*/ /* confine to required number of bits, taking logic into account */
if (*hd_e<640) *hd_e=640; if (*hd_e > ((0x00ff + 1) << 3)) *hd_e = ((0x00ff + 1) << 3);
if (*hd_e>2048) *hd_e=2048; 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!*/ /* NOTE: keep horizontal timing at multiples of 8! */
if (*ht<(*hd_e+80)) *ht=*hd_e+80; /* 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 hor. total does not leave room for a sensible sync pulse, increase it! */
if (*hs_e>(*ht-0x8)) *hs_e=*ht-0x8; if (*ht < (*hd_e + 80)) *ht = (*hd_e + 80);
if (*hs_s<(*hd_e+0x8)) *hs_e=*hd_e+0x8;
/*correct sync pulse if it is too long*/ /* make sure sync pulse is not during display */
if (*hs_e>(*hs_s+0xF8)) *hs_e=*hs_s+0xF8; 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*/ /* correct sync pulse if it is too long:
if ( * there are only 5 bits available to save this in the card registers! */
*hd_e!=(*hd_e&0x7F8) || if (*hs_e > (*hs_s + 0xf8)) *hs_e = (*hs_s + 0xf8);
*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;
}
/*vertical*/ /*vertical*/
/*squish to required number of bits*/ /* confine to required number of bits, taking logic into account */
*vd_e&=0x7FF; if (*vd_e > 0x7ff ) *vd_e = 0x7ff ; /* linecomp max value = 0x7ff! */
*vs_s&=0xFFF; if (*vs_s > (0xfff - 1)) *vs_s = (0xfff - 1);
*vs_e&=0xFFF; if (*vs_e > 0xfff ) *vs_e = 0xfff ;
*vt &=0xFFF; if (*vt > (0xfff + 2)) *vt = (0xfff + 2);
/*confine to a reasonable height*/ /* confine to a reasonable height */
if (*vd_e<400) *vd_e=400; if (*vd_e < 480) *vd_e = 480;
if (*vd_e>2048) *vd_e=2048; if (*vd_e > 2047) *vd_e = 2047;
/*if vertical total does not leave room for a sync pulse, increase it!*/ /*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*/ /* make sure sync pulse is not during display */
if (*vs_e>(*vt-1)) *vs_e=*vt-1; if (*vs_e > (*vt - 1)) *vs_e = (*vt - 1);
if (*vs_s<(*vd_e+1)) *vs_s=*vd_e+1; if (*vs_s < (*vd_e + 1)) *vs_s = (*vd_e + 1);
/*correct sync pulse if it is too long*/ /* correct sync pulse if it is too long:
if (*vs_e>(*vs_s+0xF)) *vs_e=*vs_s+0xF; * 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; return B_OK;
} }
/*set a mode line - inputs are in pixels*/ /* set a mode line - inputs are in pixels */
status_t gx00_crtc_set_timing( status_t gx00_crtc_set_timing(display_mode target)
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
)
{ {
uint8 temp;
uint32 htotal; /*total horizontal total VCLKs*/ uint32 htotal; /*total horizontal total VCLKs*/
uint32 hdisp_e; /*end of horizontal display (begins at 0)*/ uint32 hdisp_e; /*end of horizontal display (begins at 0)*/
uint32 hsync_s; /*begin of horizontal sync pulse*/ uint32 hsync_s; /*begin of horizontal sync pulse*/
@@ -109,23 +92,25 @@ status_t gx00_crtc_set_timing(
LOG(4,("CRTC: setting timing\n")); LOG(4,("CRTC: setting timing\n"));
/* Modify parameters as required by the G400/G200 */ /* Modify parameters as required by standard VGA */
htotal = ((ht >> 3) - 5); htotal = ((target.timing.h_total >> 3) - 5);
hdisp_e = ((hd_e >> 3) -1); //so: timing - 8 hdisp_e = ((target.timing.h_display >> 3) - 1);
hblnk_s = hdisp_e; //so: timing - 8 hblnk_s = hdisp_e;
hblnk_e = (htotal + 4); //so: timing - 8 hblnk_e = (htotal + 4);
hsync_s = (hs_s >> 3); hsync_s = (target.timing.h_sync_start >> 3);
hsync_e = (hs_e >> 3); hsync_e = (target.timing.h_sync_end >> 3);
vtotal=vt-2; vtotal = target.timing.v_total - 2;
vdisp_e=vd_e-1; vdisp_e = target.timing.v_display - 1;
vsync_s=vs_s-1; vblnk_s = vdisp_e;
vsync_e=vs_e-1; vblnk_e = (vtotal + 1);
vblnk_s=vdisp_e; vsync_s = target.timing.v_sync_start - 1; /* Matrox */
vblnk_e=vtotal+1; 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 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,("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)); 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*/ /*actually program the card! Note linecomp is programmed to vblnk_s for VBI*/
/*horizontal - VGA regs*/ /*horizontal - VGA regs*/
VGAW_I(CRTC,0,htotal&0xFF); VGAW_I(CRTC, 0x00, (htotal & 0x0ff));
VGAW_I(CRTC,1,hdisp_e&0xFF); VGAW_I(CRTC, 0x01, (hdisp_e & 0x0ff));
VGAW_I(CRTC,2,hblnk_s&0xFF); VGAW_I(CRTC, 0x02, (hblnk_s & 0x0ff));
VGAW_I(CRTC,3,(hblnk_e&0x1F)|0x80); /* b7 should be set for compatibility reasons */
VGAW_I(CRTC,4,hsync_s&0xFF); VGAW_I(CRTC, 0x03, ((hblnk_e & 0x01f) | 0x80));
VGAW_I(CRTC,5,(hsync_e&0x1F)|((hblnk_e&0x20)<<2)); VGAW_I(CRTC, 0x04, (hsync_s & 0x0ff));
VGAW_I(CRTC, 0x05, (hsync_e & 0x01f) | ((hblnk_e & 0x020) << 2));
/*vertical - VGA regs*/ /*vertical - VGA regs*/
VGAW_I(CRTC,6,vtotal&0xFF); VGAW_I(CRTC, 0x06, (vtotal & 0x0ff));
VGAW_I(CRTC,7, VGAW_I(CRTC, 0x07,
( (
((vtotal&0x100)>>(8-0)) |((vtotal&0x200)>>(9-5))| ((vtotal & 0x100) >> (8 - 0)) | ((vtotal & 0x200) >> (9 - 5)) |
((vdisp_e&0x100)>>(8-1))|((vdisp_e&0x200)>>(9-6))| ((vdisp_e & 0x100) >> (8 - 1)) | ((vdisp_e & 0x200) >> (9 - 6)) |
((vsync_s&0x100)>>(8-2))|((vsync_s&0x200)>>(9-7))| ((vsync_s & 0x100) >> (8 - 2)) | ((vsync_s & 0x200) >> (9 - 7)) |
((vblnk_s&0x100)>>(8-3))|((linecomp&0x100)>>(8-4)) ((vblnk_s & 0x100) >> (8 - 3)) | ((linecomp & 0x100) >> (8 - 4))
)); ));
VGAW_I(CRTC,0x8,0x00); VGAW_I(CRTC, 0x08, 0x00);
VGAW_I(CRTC,0x9,((vblnk_s&0x200)>>(9-5))|((linecomp&0x200)>>(9-6))); VGAW_I(CRTC, 0x09, ((vblnk_s & 0x200) >> (9 - 5)) | ((linecomp & 0x200) >> (9 - 6)));
VGAW_I(CRTC,0x10,vsync_s&0xFF); VGAW_I(CRTC, 0x10, (vsync_s & 0x0ff));
VGAW_I(CRTC,0x11,((VGAR_I(CRTC,0x11))&0xF0)|(vsync_e&0xF)); VGAW_I(CRTC, 0x11, (((VGAR_I(CRTC, 0x11)) & 0xf0) | (vsync_e & 0x00f)));
VGAW_I(CRTC,0x12,vdisp_e&0xFF); VGAW_I(CRTC, 0x12, (vdisp_e & 0x0ff));
VGAW_I(CRTC,0x15,vblnk_s&0xFF); VGAW_I(CRTC, 0x15, (vblnk_s & 0x0ff));
VGAW_I(CRTC,0x16,vblnk_e&0xFF); VGAW_I(CRTC, 0x16, (vblnk_e & 0x0ff));
VGAW_I(CRTC,0x18,linecomp&0xFF); VGAW_I(CRTC, 0x18, (linecomp & 0x0ff));
/* horizontal - extended regs */ /* horizontal - extended regs */
/* do not touch external sync reset inputs: used for TVout */ /* do not touch external sync reset inputs: used for TVout */
VGAW_I(CRTCEXT,1, VGAW_I(CRTCEXT, 1,
( (
((htotal&0x100)>>8)| ((htotal & 0x100) >> (8 - 0)) |
((hblnk_s&0x100)>>7)| ((hblnk_s & 0x100) >> (8 - 1)) |
((hsync_s&0x100)>>6)| ((hsync_s & 0x100) >> (8 - 2)) |
(hblnk_e&0x40)| ((hblnk_e & 0x040) >> (6 - 6)) |
(VGAR_I(CRTCEXT,1)&0xb8) (VGAR_I(CRTCEXT, 1) & 0xb8)
)); ));
/*vertical - extended regs*/ /*vertical - extended regs*/
VGAW_I(CRTCEXT,2, VGAW_I(CRTCEXT, 2,
( (
((vtotal&0xC00)>>10)| ((vtotal & 0xc00) >> (10 - 0)) |
((vdisp_e&0x400)>>8)| ((vdisp_e & 0x400) >> (10 - 2)) |
((vblnk_s&0xC00)>>7)| ((vblnk_s & 0xc00) >> (10 - 3)) |
((vsync_s&0xC00)>>5)| ((vsync_s & 0xc00) >> (10 - 5)) |
((linecomp&0x400)>>3) ((linecomp & 0x400) >> (10 - 7))
)); ));
/*set up HSYNC & VSYNC polarity*/ /* setup HSYNC & VSYNC polarity */
VGAW(MISCW,(VGAR(MISCR)&0x3F)|((!vsync_pos)<<7)|((!hsync_pos)<<6)); LOG(2,("CRTC: sync polarity: "));
LOG(2,("HSYNC/VSYNC pol:%x %x MISC dump:%x\n",hsync_pos,vsync_pos,VGAR(MISCR))); 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; return B_OK;
} }
@@ -239,12 +248,41 @@ status_t gx00_crtc_depth(int mode)
return B_OK; 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)); LOG(4,("CRTC: setting DPMS: "));
VGAW_I(SEQ,1,(!display)<<5);
VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)&0xCF)|((!v)<<5))|((!h)<<4); 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 */ /* set some required fixed values for proper MGA mode initialisation */
VGAW_I(CRTC,0x17,0xC3); VGAW_I(CRTC,0x17,0xC3);
VGAW_I(CRTC,0x14,0x00); VGAW_I(CRTC,0x14,0x00);
@@ -252,13 +290,20 @@ status_t gx00_crtc_dpms(uint8 display,uint8 h,uint8 v) // MIL2
return B_OK; 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); *display=!(VGAR_I(SEQ, 1) & 0x20);
*h=!((VGAR_I(CRTCEXT,1)&0x10)>>4); *h=!(VGAR_I(CRTCEXT, 1) & 0x10);
*v=!((VGAR_I(CRTCEXT,1)&0x20)>>5); *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; return B_OK;
} }
+125 -24
View File
@@ -2,7 +2,7 @@
Authors: Authors:
Mark Watson 6/2000, Mark Watson 6/2000,
Rudolf Cornelissen 12/2002 - 4/2003 Rudolf Cornelissen 12/2002 - 12/2003
*/ */
#define MODULE_BIT 0x00020000 #define MODULE_BIT 0x00020000
@@ -157,39 +157,140 @@ status_t g400_crtc2_depth(int mode)
return B_OK; 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) LOG(4,("CRTC2: setting DPMS: "));
{
/* 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));
}
if (si->ps.card_type >= G450) if (si->ps.card_type <= G400MAX)
{ {
//fixme: if (display && h && v)
/* setup monitor mode DPMS: G450 and later fully support this on CRTC2 */ {
//for now: /* enable CRTC2 and don't touch the rest */
//enable 'straight-through' sync outputs on both analog output connectors... CR2W(CTL, ((CR2R(CTL) & 0xFFF0177E) | 0x01));
DXIW(SYNCCTRL,0x00); 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 */ /* 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); 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; 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; return B_OK;
} }
@@ -1,7 +1,7 @@
/* Authors: /* Authors:
Mark Watson 12/1999, Mark Watson 12/1999,
Apsed, Apsed,
Rudolf Cornelissen 10/2002-4/2003 Rudolf Cornelissen 10/2002-12/2003
*/ */
#define MODULE_BIT 0x00008000 #define MODULE_BIT 0x00008000
@@ -56,7 +56,7 @@ status_t gx00_general_powerup()
status_t status; status_t status;
uint32 card_class; 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 */ /* detect card type and power it up */
switch(CFGR(DEVID)) switch(CFGR(DEVID))
@@ -292,7 +292,7 @@ status_t g100_general_powerup()
/*power up the PLLs,LUT,DAC*/ /*power up the PLLs,LUT,DAC*/
LOG(2,("INIT: PLL/LUT/DAC powerup\n")); LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */ /* 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(); gx00_crtc_cursor_hide();
/* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! /* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
* (this would create electrical shortcuts, * (this would create electrical shortcuts,
@@ -368,7 +368,7 @@ status_t g100_general_powerup()
VGAW_I(CRTC,0x11,0); VGAW_I(CRTC,0x11,0);
/*turn on display one*/ /*turn on display one*/
gx00_crtc_dpms(1,1,1); gx00_crtc_dpms(true, true, true);
return B_OK; return B_OK;
} }
@@ -394,7 +394,7 @@ status_t g200_general_powerup()
/*power up the PLLs,LUT,DAC*/ /*power up the PLLs,LUT,DAC*/
LOG(2,("INIT: PLL/LUT/DAC powerup\n")); LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */ /* 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(); gx00_crtc_cursor_hide();
/* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! /* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
* (this would create electrical shortcuts, * (this would create electrical shortcuts,
@@ -468,7 +468,7 @@ status_t g200_general_powerup()
VGAW_I(CRTC,0x11,0); VGAW_I(CRTC,0x11,0);
/*turn on display one*/ /*turn on display one*/
gx00_crtc_dpms(1,1,1); gx00_crtc_dpms(true, true, true);
return B_OK; 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 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(); 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*/ /*power up the PLLs,LUT,DAC*/
LOG(4,("INIT: PLL/LUT/DAC powerup\n")); LOG(4,("INIT: PLL/LUT/DAC powerup\n"));
/* turn off both displays and the hardcursor (also disables transfers) */ /* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0); gx00_crtc_dpms(false, false, false);
g400_crtc2_dpms(0,0,0); g400_crtc2_dpms(false, false, false);
gx00_crtc_cursor_hide(); gx00_crtc_cursor_hide();
/* set voltage reference - not using DAC reference block */ /* set voltage reference - not using DAC reference block */
@@ -573,7 +581,7 @@ status_t g400_general_powerup()
} }
/*turn on display one*/ /*turn on display one*/
gx00_crtc_dpms(1,1,1); gx00_crtc_dpms(true, true, true);
return B_OK; return B_OK;
} }
@@ -605,8 +613,8 @@ status_t g450_general_powerup()
/* disable outputs */ /* disable outputs */
DXIW(OUTPUTCONN,0x00); DXIW(OUTPUTCONN,0x00);
/* turn off both displays and the hardcursor (also disables transfers) */ /* turn off both displays and the hardcursor (also disables transfers) */
gx00_crtc_dpms(0,0,0); gx00_crtc_dpms(false, false, false);
g400_crtc2_dpms(0,0,0); g400_crtc2_dpms(false, false, false);
gx00_crtc_cursor_hide(); gx00_crtc_cursor_hide();
/* power up everything except DVI electronics (for now) */ /* power up everything except DVI electronics (for now) */
@@ -721,7 +729,7 @@ status_t g450_general_powerup()
gx50_general_output_select(); gx50_general_output_select();
/*turn on display one*/ /*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 */ /* enable 'straight-through' sync outputs on both analog output connectors */
DXIW(SYNCCTRL,0x00); 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 */ /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40); DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
DXIW(GENIODATA, 0x00); DXIW(GENIODATA, 0x00);
/* signal CRTC2 DPMS which connector to program */
si->crossed_conns = false;
break; break;
//fixme: toggle PLL's below if possible: //fixme: toggle PLL's below if possible:
// otherwise toggle PLL's for G400 2nd case? // 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 */ /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40); DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
DXIW(GENIODATA, 0x00); DXIW(GENIODATA, 0x00);
/* signal CRTC2 DPMS which connector to program */
si->crossed_conns = true;
break; break;
default: default:
return B_ERROR; return B_ERROR;
@@ -828,13 +840,6 @@ status_t gx00_general_dac_select(int dac)
return B_OK; 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*/ /* basic change of card state from VGA to powergraphics -> should work from BIOS init state*/
static static
status_t gx00_general_bios_to_powergraphics() status_t gx00_general_bios_to_powergraphics()
@@ -858,6 +863,13 @@ status_t gx00_general_bios_to_powergraphics()
{ {
case G400: case G400:
case G400MAX: 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! */ /* makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr! */
DXIW(MAFCDEL,0x02); DXIW(MAFCDEL,0x02);
break; break;
@@ -901,7 +913,7 @@ status_t gx00_general_bios_to_powergraphics()
* Mode slopspace is reflected in fbc->bytes_per_row BTW. */ * Mode slopspace is reflected in fbc->bytes_per_row BTW. */
//fixme: seperate heads for real dualhead modes: //fixme: seperate heads for real dualhead modes:
//CRTC1 and 2 constraints differ! //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: /* Note:
* This routine assumes that the CRTC memory pitch granularity is 'smaller than', * 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: /* check if we can setup this mode with acceleration:
* Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */ * Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */
si->acc_mode = true; *acc_mode = true;
/* check virtual_width */ /* check virtual_width */
switch (si->ps.card_type) 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 MIL2:
case G100: case G100:
/* acc constraint: */ /* acc constraint: */
if (target->virtual_width > 2048) si->acc_mode = false; if (target->virtual_width > 2048) *acc_mode = false;
break; break;
default: default:
/* G200-G550 */ /* G200-G550 */
/* acc constraint: */ /* 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! */ /* for 32bit mode a lower CRTC1 restriction applies! */
if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask))) if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask)))
si->acc_mode = false; *acc_mode = false;
break; break;
} }
/* virtual_height */ /* 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, /* now check virtual_size based on CRTC constraints,
* making sure virtual_width stays within the 'mask' constraint: which is only * 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 /* 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 * it was confined above, so we can finally calculate safely if we need slopspace
* for this mode... */ * for this mode... */
if (si->acc_mode) if (*acc_mode)
video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
else else
video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
+127 -19
View File
@@ -2,7 +2,7 @@
/* Authors: /* Authors:
Mark Watson 6/2000, Mark Watson 6/2000,
Rudolf Cornelissen 1/2003-4/2003 Rudolf Cornelissen 1/2003-12/2003
Thanx to Petr Vandrovec for writing matroxfb. Thanx to Petr Vandrovec for writing matroxfb.
*/ */
@@ -14,12 +14,67 @@
status_t g450_g550_maven_set_vid_pll(display_mode target); status_t g450_g550_maven_set_vid_pll(display_mode target);
status_t g100_g400max_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 */ /* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK; if (si->ps.card_type > G400MAX) return B_OK;
if (display & h & v) if (display && h && v)
{ {
/* turn on screen */ /* turn on screen */
if (!(si->dm.flags & TV_BITS)) 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*/ /*set a mode line - inputs are in pixels/scanlines*/
status_t gx00_maven_set_timing(display_mode target) status_t gx00_maven_set_timing(display_mode target)
{ {
uint8 temp, cnt, offset, loop;
/* this function is nolonger needed on G450/G550 cards */ /* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK; 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(HVIDRSTL, (target.timing.h_total - si->crtc_delay));
MAVWW(VVIDRSTL, (target.timing.v_total - 2)); 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; 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)*/ /*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) 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 */ /* this function is nolonger needed on G450/G550 cards */
if (si->ps.card_type > G400MAX) return B_OK; if (si->ps.card_type > G400MAX) return B_OK;
/*set luma to a suitable value for brightness*/ /* set luma to a suitable value for brightness */
/*assuming 1A is a sensible value*/ /* assuming 0x0a is a sensible value */
luma = (uint8)(0x1a * brightness); /* fixme:
MAVW(LUMA,luma); * it looks like b6 and/or b7 determine the luma: just two values possible. */
LOG(4,("MAVEN: LUMA setting - %x\n",luma)); /* 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; return B_OK;
} }
@@ -1,6 +1,6 @@
/* Authors: /* Authors:
Mark Watson 2000, Mark Watson 2000,
Rudolf Cornelissen 1/2003-3/2003 Rudolf Cornelissen 1/2003-12/2003
Thanx to Petr Vandrovec for writing matroxfb. Thanx to Petr Vandrovec for writing matroxfb.
*/ */
@@ -20,9 +20,6 @@ typedef struct {
float chroma_subcarrier; float chroma_subcarrier;
} gx50_maven_timing; } 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, //fixme: try to implement 'fast' and 'slow' settings for all modes,
// so buffer duplication or skipping won't be neccesary for realtime video. // 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. //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(LOCK, 0x01);
MAVW(OUTMODE, 0x08); 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); 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(STABLE, 0x02);
MAVW(MONEN, 0xB3); 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 */ /* setup video PLL */
g100_g400max_maventv_vid_pll_find( g100_g400max_maventv_vid_pll_find(
tv_target, &ht_new, &ht_last_line, &m_result, &n_result, &p_result); 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; int index;
/* calc hor scale-back factor from input to output picture (in 1.7 format) /* 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 */ * the MAVEN has 736 pixels fixed total outputline length for TVout */
//fixme: shouldn't this be 768 (= PAL 1:1 output 4:3 ratio format)?!?
h_scale_tv = (736 << 7) / tv_target.timing.h_total;//should be PLL corrected 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))); 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) */ /* limit values to MAVEN capabilities (scale-back factor is 0.5-1.0) */
//fixme: how about lowres upscaling?
if (h_scale_tv > 0x80) if (h_scale_tv > 0x80)
{ {
h_scale_tv = 0x80; h_scale_tv = 0x80;
@@ -912,9 +1087,19 @@ int maventv_init(display_mode target)
MAVW(GAMMA9, 0xC8); /* 200 */ MAVW(GAMMA9, 0xC8); /* 200 */
/* set flickerfilter */ /* set flickerfilter */
/* OFF: is dependant on MAVEN chip version(?): MGA_TVO_B = $40, else $00. if (!(tv_target.flags & TV_VIDEO))
* ON : always set $a2. */ {
MAVW(FFILTER, 0xa2); /* 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 */ /* 0x10 or anything ored with it */
//fixme? linux uses 0x14... //fixme? linux uses 0x14...
@@ -4,7 +4,7 @@ status_t mga_set_cas_latency();
status_t gx50_general_output_select(); status_t gx50_general_output_select();
status_t gx00_general_dac_select(int); status_t gx00_general_dac_select(int);
status_t gx00_general_wait_retrace(); 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(); //status_t gx00_general_bios_to_powergraphics();
/* apsed: logging macros */ /* 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); status_t mil2_dac_set_pix_pll(float f_vco,int bpp);
/*MAVEN functions*/ /*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_set_timing(display_mode target);
status_t gx00_maven_mode(int,float); 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 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht,
uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt
); );
status_t gx00_crtc_set_timing( status_t gx00_crtc_set_timing(display_mode target);
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_depth(int mode); status_t gx00_crtc_depth(int mode);
status_t gx00_crtc_set_display_start(uint32 startadd,uint8 bpp); status_t gx00_crtc_set_display_start(uint32 startadd,uint8 bpp);
status_t gx00_crtc_set_display_pitch(); status_t gx00_crtc_set_display_pitch();
status_t gx00_crtc_dpms(uint8,uint8,uint8); status_t gx00_crtc_dpms(bool display,bool h,bool v);
status_t gx00_crtc_dpms_fetch(uint8*,uint8*,uint8*); status_t gx00_crtc_dpms_fetch(bool *display, bool *h, bool *v);
status_t gx00_crtc_mem_priority(uint8); status_t gx00_crtc_mem_priority(uint8);
status_t gx00_crtc_cursor_init(); /*Yes, cursor follows CRTC1 - not the DAC!*/ 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_pitch();
status_t g400_crtc2_set_display_start(uint32 startadd,uint8 bpp); 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(bool display, bool h, bool v);
status_t g400_crtc2_dpms_fetch(uint8 * display,uint8 * h,uint8 * v); status_t g400_crtc2_dpms_fetch(bool *display, bool *h, bool *v);
/*acceleration functions*/ /*acceleration functions*/
status_t check_acc_capability(uint32 feature); status_t check_acc_capability(uint32 feature);
@@ -1,5 +1,6 @@
/* Some commmon support functions */ /* Some commmon support functions */
/* Mark Watson 2/2000 */ /* Mark Watson 2/2000
* Rudolf Cornelissen 11/2003 */
#define MODULE_BIT 0x00000800 #define MODULE_BIT 0x00000800
@@ -17,12 +18,15 @@ void delay(bigtime_t i)
void mga_log(char *fmt, ...) void mga_log(char *fmt, ...)
{ {
char buffer[1024]; char buffer[1024];
char fname[64];
FILE *myhand; FILE *myhand;
va_list args; 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; if (myhand == NULL) return;
va_start(args,fmt); va_start(args,fmt);
vsprintf (buffer, fmt, args); vsprintf (buffer, fmt, args);
fprintf(myhand, "%s", buffer); fprintf(myhand, "%s", buffer);
@@ -7,6 +7,16 @@ R5KernelAddon mga.driver : kernel drivers bin :
driver.c 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 # Link to kernel/drivers/dev/graphics
{ {
local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev graphics ] ; local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev graphics ] ;
@@ -4,7 +4,7 @@
Other authors: Other authors:
Mark Watson; Mark Watson;
Rudolf Cornelissen 3/2002. Rudolf Cornelissen 3/2002-11/2003.
*/ */
/* standard kernel driver stuff */ /* 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 == 0xff) || /* no IRQ assigned */
(di->pcii.u.h0.interrupt_line <= 0x02)) /* system 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 */ /* interrupt does not exist so exit without installing our handler */
goto delete_the_sem; goto delete_the_sem;
} }
@@ -10,7 +10,7 @@
# mga.accelerant parameters # mga.accelerant parameters
usebios false # if true rely on bios to coldstart the card instead of driver usebios false # if true rely on bios to coldstart the card instead of driver
#memory 2 # in MB, override builtin memory size detection #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 0x00000000 # nothing logged, except errors, is default
#logmask 0x80000000 # log card physical features #logmask 0x80000000 # log card physical features
#logmask 0x80000000 # log following mask #logmask 0x80000000 # log following mask