rewrote kerneldriver and accelerant's retrace INT handling. This fixes the 'driver hanging' bug exhibiting sometimes when CRTC2 is being used as primary CRTC (driver internal feature). INT handling now exists for both CRTC1 and CRTC2: enabling only the INTs for the head currently being used as primary. (limitation can be removed once we use a driver instance 'per head' instead of 'per card'.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16281 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen 2006-02-07 14:58:28 +00:00
parent a932a97b52
commit 155a2ad0a5
6 changed files with 86 additions and 30 deletions

View File

@ -13,25 +13,6 @@
#include "acc_std.h"
/*
Enable/Disable interrupts. Just a wrapper around the
ioctl() to the kernel driver.
*/
static void interrupt_enable(bool flag)
{
status_t result = B_OK;
nv_set_bool_state sbs;
if (si->ps.int_assigned)
{
/* set the magic number so the driver knows we're for real */
sbs.magic = NV_PRIVATE_DATA_MAGIC;
sbs.do_it = flag;
/* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, NV_RUN_INTERRUPTS, &sbs, sizeof(sbs));
}
}
/* First validate the mode, then call lots of bit banging stuff to set the mode(s)! */
status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
{
@ -78,7 +59,8 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
si->engine.threeD.clones = 0x00000000;
/* disable interrupts using the kernel driver */
interrupt_enable(false);
head1_interrupt_enable(false);
if (si->ps.secondary_head) head2_interrupt_enable(false);
/* disable TVout if supported */
if (si->ps.tvout) BT_stop_tvout();
@ -339,7 +321,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
SET_DPMS_MODE(si->dpms_flags);
/* enable interrupts using the kernel driver */
interrupt_enable(true);
//fixme:
//add head2 once we use one driver instance 'per head' (instead of 'per card')
head1_interrupt_enable(true);
/* make sure a possible 3D add-on will re-initialize itself by signalling ready */
si->engine.threeD.mode_changing = false;
@ -416,7 +400,9 @@ status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) {
startadd += (uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer;
startadd_right = startadd + si->dm.timing.h_display * (colour_depth >> 3);
interrupt_enable(false);
/* disable interrupts using the kernel driver */
head1_interrupt_enable(false);
if (si->ps.secondary_head) head2_interrupt_enable(false);
switch (si->dm.flags & DUALHEAD_BITS)
{
@ -434,7 +420,10 @@ status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) {
break;
}
interrupt_enable(true);
//fixme:
//add head2 once we use one driver instance 'per head' (instead of 'per card')
head1_interrupt_enable(true);
return B_OK;
}
@ -467,7 +456,9 @@ status_t SET_DPMS_MODE(uint32 dpms_flags)
{
bool display, h1h, h1v, h2h, h2v, do_p1, do_p2;
interrupt_enable(false);
/* disable interrupts using the kernel driver */
head1_interrupt_enable(false);
if (si->ps.secondary_head) head2_interrupt_enable(false);
LOG(4,("SET_DPMS_MODE: $%08x\n", dpms_flags));
@ -494,7 +485,10 @@ status_t SET_DPMS_MODE(uint32 dpms_flags)
break;
default:
LOG(8,("SET: Invalid DPMS settings $%08x\n", dpms_flags));
interrupt_enable(true);
//fixme:
//add head2 once we use one driver instance 'per head' (instead of 'per card')
head1_interrupt_enable(true);
return B_ERROR;
}
@ -593,7 +587,10 @@ status_t SET_DPMS_MODE(uint32 dpms_flags)
if (si->dm.flags & TV_BITS)
BT_dpms(display);
interrupt_enable(true);
//fixme:
//add head2 once we use one driver instance 'per head' (instead of 'per card')
head1_interrupt_enable(true);
return B_OK;
}

View File

@ -1,12 +1,34 @@
/* CTRC functionality */
/* Author:
Rudolf Cornelissen 11/2002-1/2006
Rudolf Cornelissen 11/2002-2/2006
*/
#define MODULE_BIT 0x00040000
#include "nv_std.h"
/*
Enable/Disable interrupts. Just a wrapper around the
ioctl() to the kernel driver.
*/
status_t nv_crtc_interrupt_enable(bool flag)
{
status_t result = B_OK;
nv_set_vblank_int svi;
if (si->ps.int_assigned)
{
/* set the magic number so the driver knows we're for real */
svi.magic = NV_PRIVATE_DATA_MAGIC;
svi.crtc = 0;
svi.do_it = flag;
/* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, NV_RUN_INTERRUPTS, &svi, sizeof(svi));
}
return result;
}
/* doing general fail-safe default setup here */
//fixme: this is a _very_ basic setup, and it's preliminary...
status_t nv_crtc_update_fifo()

View File

@ -1,12 +1,34 @@
/* second CTRC functionality for GeForce cards */
/* Author:
Rudolf Cornelissen 11/2002-1/2006
Rudolf Cornelissen 11/2002-2/2006
*/
#define MODULE_BIT 0x00020000
#include "nv_std.h"
/*
Enable/Disable interrupts. Just a wrapper around the
ioctl() to the kernel driver.
*/
status_t nv_crtc2_interrupt_enable(bool flag)
{
status_t result = B_OK;
nv_set_vblank_int svi;
if (si->ps.int_assigned)
{
/* set the magic number so the driver knows we're for real */
svi.magic = NV_PRIVATE_DATA_MAGIC;
svi.crtc = 1;
svi.do_it = flag;
/* contact driver and get a pointer to the registers and shared data */
result = ioctl(fd, NV_RUN_INTERRUPTS, &svi, sizeof(svi));
}
return result;
}
/* doing general fail-safe default setup here */
//fixme: this is a _very_ basic setup, and it's preliminary...
status_t nv_crtc2_update_fifo()

View File

@ -91,7 +91,7 @@ status_t nv_general_powerup()
{
status_t status;
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.71 running.\n"));
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.72 running.\n"));
/* log VBLANK INT usability status */
if (si->ps.int_assigned)
@ -1142,6 +1142,8 @@ void setup_virtualized_heads(bool cross)
{
if (cross)
{
head1_interrupt_enable = (crtc_interrupt_enable) nv_crtc2_interrupt_enable;
head1_update_fifo = (crtc_update_fifo) nv_crtc2_update_fifo;
head1_validate_timing = (crtc_validate_timing) nv_crtc2_validate_timing;
head1_set_timing = (crtc_set_timing) nv_crtc2_set_timing;
head1_depth = (crtc_depth) nv_crtc2_depth;
@ -1161,6 +1163,8 @@ void setup_virtualized_heads(bool cross)
head1_set_pix_pll = (dac_set_pix_pll) nv_dac2_set_pix_pll;
head1_pix_pll_find = (dac_pix_pll_find) nv_dac2_pix_pll_find;
head2_interrupt_enable = (crtc_interrupt_enable) nv_crtc_interrupt_enable;
head2_update_fifo = (crtc_update_fifo) nv_crtc_update_fifo;
head2_validate_timing = (crtc_validate_timing) nv_crtc_validate_timing;
head2_set_timing = (crtc_set_timing) nv_crtc_set_timing;
head2_depth = (crtc_depth) nv_crtc_depth;
@ -1182,6 +1186,8 @@ void setup_virtualized_heads(bool cross)
}
else
{
head1_interrupt_enable = (crtc_interrupt_enable) nv_crtc_interrupt_enable;
head1_update_fifo = (crtc_update_fifo) nv_crtc_update_fifo;
head1_validate_timing = (crtc_validate_timing) nv_crtc_validate_timing;
head1_set_timing = (crtc_set_timing) nv_crtc_set_timing;
head1_depth = (crtc_depth) nv_crtc_depth;
@ -1201,6 +1207,8 @@ void setup_virtualized_heads(bool cross)
head1_set_pix_pll = (dac_set_pix_pll) nv_dac_set_pix_pll;
head1_pix_pll_find = (dac_pix_pll_find) nv_dac_pix_pll_find;
head2_interrupt_enable = (crtc_interrupt_enable) nv_crtc2_interrupt_enable;
head2_update_fifo = (crtc_update_fifo) nv_crtc2_update_fifo;
head2_validate_timing = (crtc_validate_timing) nv_crtc2_validate_timing;
head2_set_timing = (crtc_set_timing) nv_crtc2_set_timing;
head2_depth = (crtc_depth) nv_crtc2_depth;

View File

@ -11,7 +11,8 @@ extern int accelerantIsClone;
extern nv_get_set_pci nv_pci_access;
extern nv_in_out_isa nv_isa_access;
typedef status_t (*crtc_interrupt_enable)(bool);
typedef status_t (*crtc_update_fifo)(void);
typedef status_t (*crtc_validate_timing)(uint16*, uint16*, uint16*, uint16*, uint16*, uint16*, uint16*, uint16*);
typedef status_t (*crtc_set_timing)(display_mode);
typedef status_t (*crtc_depth)(int);
@ -31,6 +32,8 @@ typedef status_t (*dac_palette)(uint8[256], uint8[256], uint8[256]);
typedef status_t (*dac_set_pix_pll)(display_mode);
typedef status_t (*dac_pix_pll_find)(display_mode, float*, uint8*, uint8*, uint8*, uint8);
crtc_interrupt_enable head1_interrupt_enable;
crtc_update_fifo head1_update_fifo;
crtc_validate_timing head1_validate_timing;
crtc_set_timing head1_set_timing;
crtc_depth head1_depth;
@ -45,6 +48,8 @@ crtc_cursor_position head1_cursor_position;
crtc_stop_tvout head1_stop_tvout;
crtc_start_tvout head1_start_tvout;
crtc_interrupt_enable head2_interrupt_enable;
crtc_update_fifo head2_update_fifo;
crtc_validate_timing head2_validate_timing;
crtc_set_timing head2_set_timing;
crtc_depth head2_depth;

View File

@ -65,6 +65,7 @@ status_t BT_stop_tvout(void);
status_t BT_setmode(display_mode target);
/* CRTC1 functions */
status_t nv_crtc_interrupt_enable(bool);
status_t nv_crtc_update_fifo(void);
status_t nv_crtc_validate_timing(
uint16 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht,
@ -84,6 +85,7 @@ status_t nv_crtc_stop_tvout(void);
status_t nv_crtc_start_tvout(void);
/* CRTC2 functions */
status_t nv_crtc2_interrupt_enable(bool);
status_t nv_crtc2_update_fifo(void);
status_t nv_crtc2_validate_timing(
uint16 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht,