added virtualized CRTC access with it's advantages
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7295 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3a4a20a09e
commit
0669fe20bd
@ -5,7 +5,7 @@
|
||||
Other authors:
|
||||
Mark Watson;
|
||||
Apsed;
|
||||
Rudolf Cornelissen 10/2002-3/2004.
|
||||
Rudolf Cornelissen 10/2002-4/2004.
|
||||
*/
|
||||
|
||||
#ifndef DRIVERINTERFACE_H
|
||||
@ -86,7 +86,7 @@ typedef struct settings { // apsed, see comments in nv.settings
|
||||
uint32 memory;
|
||||
bool usebios;
|
||||
bool hardcursor;
|
||||
bool greensync;
|
||||
bool switchhead;
|
||||
} settings;
|
||||
|
||||
/*shared info*/
|
||||
@ -147,6 +147,7 @@ typedef struct {
|
||||
display_mode dm2; /* current display mode configuration: head2 */
|
||||
bool acc_mode; /* signals (non)accelerated mode */
|
||||
bool interlaced_tv_mode;/* signals interlaced CRTC TV output mode */
|
||||
bool crtc_switch_mode; /* signals dualhead switch mode if panels are used */
|
||||
|
||||
/*frame buffer config - for BDirectScreen*/
|
||||
frame_buffer_config fbc; /* bytes_per_row and start of frame buffer: head1 */
|
||||
@ -232,6 +233,7 @@ typedef struct {
|
||||
uint16 panel2_width; /* native horizontal resolution for digital panels */
|
||||
uint16 panel2_height; /* navive vertical resolution for digital panels */
|
||||
float panel2_aspect; /* panel's aspect ratio */
|
||||
bool crtc2_prim; /* using CRTC2 as primary CRTC */
|
||||
uint32 tvout_chip_type; /* see tvchip_type enum above */
|
||||
status_t pins_status; /* B_OK if read correctly, B_ERROR if faked */
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Other authors:
|
||||
Mark Watson,
|
||||
Rudolf Cornelissen 4/2003-1/2004
|
||||
Rudolf Cornelissen 4/2003-4/2004
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x20000000
|
||||
@ -26,9 +26,9 @@ status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_crtc_cursor_define(andMask,xorMask);
|
||||
head1_cursor_define(andMask,xorMask);
|
||||
if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
|
||||
nv_crtc2_cursor_define(andMask,xorMask);
|
||||
head2_cursor_define(andMask,xorMask);
|
||||
|
||||
/* Update cursor variables appropriately. */
|
||||
si->cursor.width = width;
|
||||
@ -110,8 +110,8 @@ void MOVE_CURSOR(uint16 x, uint16 y)
|
||||
switch (si->dm.flags & DUALHEAD_BITS)
|
||||
{
|
||||
case DUALHEAD_CLONE:
|
||||
nv_crtc_cursor_position(x,y);
|
||||
nv_crtc2_cursor_position(x,y);
|
||||
head1_cursor_position(x,y);
|
||||
head2_cursor_position(x,y);
|
||||
break;
|
||||
case DUALHEAD_ON:
|
||||
case DUALHEAD_SWITCH:
|
||||
@ -120,26 +120,26 @@ void MOVE_CURSOR(uint16 x, uint16 y)
|
||||
if (si->cursor.dh_right)
|
||||
{
|
||||
LOG(4,("MOVE_CURSOR: now on left side\n"));
|
||||
nv_crtc2_cursor_hide();
|
||||
nv_crtc_cursor_show();
|
||||
head2_cursor_hide();
|
||||
head1_cursor_show();
|
||||
si->cursor.dh_right = false;
|
||||
}
|
||||
nv_crtc_cursor_position(x, y);
|
||||
head1_cursor_position(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!si->cursor.dh_right)
|
||||
{
|
||||
LOG(4,("MOVE_CURSOR: now on right side\n"));
|
||||
nv_crtc_cursor_hide();
|
||||
nv_crtc2_cursor_show();
|
||||
head1_cursor_hide();
|
||||
head2_cursor_show();
|
||||
si->cursor.dh_right = true;
|
||||
}
|
||||
nv_crtc2_cursor_position((x - si->dm.timing.h_display), y);
|
||||
head2_cursor_position((x - si->dm.timing.h_display), y);
|
||||
}
|
||||
break;
|
||||
default: /* singlehead mode */
|
||||
nv_crtc_cursor_position(x,y);
|
||||
head1_cursor_position(x,y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -154,13 +154,13 @@ void SHOW_CURSOR(bool is_visible)
|
||||
case DUALHEAD_CLONE:
|
||||
if (is_visible)
|
||||
{
|
||||
nv_crtc_cursor_show();
|
||||
nv_crtc2_cursor_show();
|
||||
head1_cursor_show();
|
||||
head2_cursor_show();
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_crtc_cursor_hide();
|
||||
nv_crtc2_cursor_hide();
|
||||
head1_cursor_hide();
|
||||
head2_cursor_hide();
|
||||
}
|
||||
break;
|
||||
case DUALHEAD_ON:
|
||||
@ -169,27 +169,27 @@ void SHOW_CURSOR(bool is_visible)
|
||||
{
|
||||
if (!si->cursor.dh_right)
|
||||
{
|
||||
nv_crtc_cursor_show();
|
||||
head1_cursor_show();
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_crtc2_cursor_show();
|
||||
head2_cursor_show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_crtc_cursor_hide();
|
||||
nv_crtc2_cursor_hide();
|
||||
head1_cursor_hide();
|
||||
head2_cursor_hide();
|
||||
}
|
||||
break;
|
||||
default: /* singlehead mode */
|
||||
if (is_visible)
|
||||
{
|
||||
nv_crtc_cursor_show();
|
||||
head1_cursor_show();
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_crtc_cursor_hide();
|
||||
head1_cursor_hide();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Other authors:
|
||||
Mark Watson,
|
||||
Rudolf Cornelissen 10/2002-1/2004.
|
||||
Rudolf Cornelissen 10/2002-4/2004.
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00800000
|
||||
@ -38,8 +38,8 @@ static status_t init_common(int the_fd) {
|
||||
goto error0;
|
||||
}
|
||||
// LOG is now available, si !NULL
|
||||
LOG(4,("init_common: logmask 0x%08x, memory %dMB, hardcursor %d, usebios %d, greensync %d\n",
|
||||
si->settings.logmask, si->settings.memory, si->settings.hardcursor, si->settings.usebios, si->settings.greensync));
|
||||
LOG(4,("init_common: logmask 0x%08x, memory %dMB, hardcursor %d, usebios %d, switchhead %d\n",
|
||||
si->settings.logmask, si->settings.memory, si->settings.hardcursor, si->settings.usebios, si->settings.switchhead));
|
||||
|
||||
/*Check for R4.5.0 and if it is running, use work around*/
|
||||
{
|
||||
@ -175,8 +175,8 @@ status_t INIT_ACCELERANT(int the_fd) {
|
||||
if (result != B_OK) goto error1;
|
||||
|
||||
/* initialise various cursor stuff*/
|
||||
nv_crtc_cursor_init();
|
||||
if (si->ps.secondary_head) nv_crtc2_cursor_init();
|
||||
head1_cursor_init();
|
||||
if (si->ps.secondary_head) head2_cursor_init();
|
||||
|
||||
/* ensure cursor state */
|
||||
SHOW_CURSOR(false);
|
||||
@ -260,6 +260,9 @@ status_t CLONE_ACCELERANT(void *data) {
|
||||
/* call the shared initialization code */
|
||||
result = init_common(fd);
|
||||
|
||||
/* setup CRTC functions access */
|
||||
setup_virtualized_crtcs(si->crtc_switch_mode);
|
||||
|
||||
/* bail out if the common initialization failed */
|
||||
if (result != B_OK) goto error1;
|
||||
|
||||
|
@ -157,7 +157,7 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
|
||||
#endif
|
||||
|
||||
/*find a nearby valid timing from that given*/
|
||||
result = nv_crtc_validate_timing
|
||||
result = head1_validate_timing
|
||||
(
|
||||
&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
|
||||
@ -387,11 +387,8 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
|
||||
LOG(1, ("PROPOSEMODE: validated status modeflags: $%08x\n", target->flags));
|
||||
|
||||
/* overrule timing command flags to be (fixed) blank_pedestal = 0.0IRE,
|
||||
* progressive scan (fixed), and setup sync_on_green flag according to
|
||||
* nv.settings options file */
|
||||
* progressive scan (fixed), and sync_on_green not avaible. */
|
||||
target->timing.flags &= ~(B_BLANK_PEDESTAL | B_TIMING_INTERLACED | B_SYNC_ON_GREEN);
|
||||
if (si->settings.greensync)
|
||||
target->timing.flags |= B_SYNC_ON_GREEN;
|
||||
/* The HSYNC and VSYNC command flags are actually executed by the driver. */
|
||||
|
||||
if (status == B_OK) LOG(4, ("PROPOSEMODE: completed successfully.\n"));
|
||||
|
@ -6,7 +6,7 @@
|
||||
Other authors:
|
||||
Mark Watson,
|
||||
Apsed,
|
||||
Rudolf Cornelissen 11/2002-1/2004
|
||||
Rudolf Cornelissen 11/2002-4/2004
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00200000
|
||||
@ -81,9 +81,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
interrupt_enable(false);
|
||||
|
||||
/* find current DPMS state, then turn off screen(s) */
|
||||
nv_crtc_dpms_fetch(&display, &h, &v);
|
||||
nv_crtc_dpms(false, false, false);
|
||||
if (si->ps.secondary_head) nv_crtc2_dpms(false, false, false);
|
||||
head1_dpms_fetch(&display, &h, &v);
|
||||
head1_dpms(false, false, false);
|
||||
if (si->ps.secondary_head) head2_dpms(false, false, false);
|
||||
|
||||
/*where in framebuffer the screen is (should this be dependant on previous MOVEDISPLAY?)*/
|
||||
startadd = (uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer;
|
||||
@ -128,22 +128,22 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
case B_CMAP8:
|
||||
colour_depth1 = 8;
|
||||
nv_dac_mode(BPP8, 1.0);
|
||||
nv_crtc_depth(BPP8);
|
||||
head1_depth(BPP8);
|
||||
break;
|
||||
case B_RGB15_LITTLE:
|
||||
colour_depth1 = 16;
|
||||
nv_dac_mode(BPP15, 1.0);
|
||||
nv_crtc_depth(BPP15);
|
||||
head1_depth(BPP15);
|
||||
break;
|
||||
case B_RGB16_LITTLE:
|
||||
colour_depth1 = 16;
|
||||
nv_dac_mode(BPP16, 1.0);
|
||||
nv_crtc_depth(BPP16);
|
||||
head1_depth(BPP16);
|
||||
break;
|
||||
case B_RGB32_LITTLE:
|
||||
colour_depth1 = 32;
|
||||
nv_dac_mode(BPP32, 1.0);
|
||||
nv_crtc_depth(BPP32);
|
||||
head1_depth(BPP32);
|
||||
break;
|
||||
}
|
||||
/*set the colour depth for CRTC2 and DAC2 */
|
||||
@ -152,22 +152,22 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
case B_CMAP8:
|
||||
colour_depth2 = 8;
|
||||
nv_dac2_mode(BPP8, 1.0);
|
||||
nv_crtc2_depth(BPP8);
|
||||
head2_depth(BPP8);
|
||||
break;
|
||||
case B_RGB15_LITTLE:
|
||||
colour_depth2 = 16;
|
||||
nv_dac2_mode(BPP15, 1.0);
|
||||
nv_crtc2_depth(BPP15);
|
||||
head2_depth(BPP15);
|
||||
break;
|
||||
case B_RGB16_LITTLE:
|
||||
colour_depth2 = 16;
|
||||
nv_dac2_mode(BPP16, 1.0);
|
||||
nv_crtc2_depth(BPP16);
|
||||
head2_depth(BPP16);
|
||||
break;
|
||||
case B_RGB32_LITTLE:
|
||||
colour_depth2 = 32;
|
||||
nv_dac2_mode(BPP32, 1.0);
|
||||
nv_crtc2_depth(BPP32);
|
||||
head2_depth(BPP32);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -177,10 +177,10 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
si->interlaced_tv_mode = true;
|
||||
*/
|
||||
/*set the display(s) pitches*/
|
||||
nv_crtc_set_display_pitch ();
|
||||
head1_set_display_pitch ();
|
||||
//fixme: seperate for real dualhead modes:
|
||||
//we need a secondary si->fbc!
|
||||
nv_crtc2_set_display_pitch ();
|
||||
head2_set_display_pitch ();
|
||||
|
||||
/*work out where the "right" screen starts*/
|
||||
startadd_right = startadd + (target.timing.h_display * (colour_depth1 >> 3));
|
||||
@ -215,19 +215,19 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
{
|
||||
case DUALHEAD_ON:
|
||||
case DUALHEAD_SWITCH:
|
||||
nv_crtc_set_display_start(startadd,colour_depth1);
|
||||
nv_crtc2_set_display_start(startadd_right,colour_depth2);
|
||||
head1_set_display_start(startadd,colour_depth1);
|
||||
head2_set_display_start(startadd_right,colour_depth2);
|
||||
break;
|
||||
case DUALHEAD_CLONE:
|
||||
nv_crtc_set_display_start(startadd,colour_depth1);
|
||||
nv_crtc2_set_display_start(startadd,colour_depth2);
|
||||
head1_set_display_start(startadd,colour_depth1);
|
||||
head2_set_display_start(startadd,colour_depth2);
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the timing */
|
||||
nv_crtc_set_timing(target);
|
||||
head1_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 = nv_crtc2_set_timing(target2);
|
||||
if (!(target2.flags & TV_BITS)) result = head2_set_timing(target2);
|
||||
|
||||
/* TVout support: setup CRTC2 and it's pixelclock */
|
||||
if (si->ps.tvout && (target2.flags & TV_BITS)) maventv_init(target2);
|
||||
@ -256,18 +256,18 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
|
||||
/* set the colour depth for CRTC1 and the DAC */
|
||||
/* first set the colordepth */
|
||||
nv_crtc_depth(colour_mode);
|
||||
head1_depth(colour_mode);
|
||||
/* then(!) program the PAL (<8bit colordepth does not support 8bit PAL) */
|
||||
nv_dac_mode(colour_mode,1.0);
|
||||
|
||||
/* set the display pitch */
|
||||
nv_crtc_set_display_pitch();
|
||||
head1_set_display_pitch();
|
||||
|
||||
/* tell the card what memory to display */
|
||||
nv_crtc_set_display_start(startadd,colour_depth1);
|
||||
head1_set_display_start(startadd,colour_depth1);
|
||||
|
||||
/* set the timing */
|
||||
nv_crtc_set_timing(target);
|
||||
head1_set_timing(target);
|
||||
|
||||
/* connect output */
|
||||
if (si->ps.secondary_head)
|
||||
@ -301,9 +301,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
si->dm = target;
|
||||
|
||||
/* turn screen one on */
|
||||
nv_crtc_dpms(display, h, v);
|
||||
head1_dpms(display, h, v);
|
||||
/* turn screen two on if a dualhead mode is active */
|
||||
if (target.flags & DUALHEAD_BITS) nv_crtc2_dpms(display,h,v);
|
||||
if (target.flags & DUALHEAD_BITS) head2_dpms(display,h,v);
|
||||
|
||||
/* set up acceleration for this mode */
|
||||
nv_acc_init();
|
||||
@ -316,7 +316,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
|
||||
interrupt_enable(true);
|
||||
|
||||
/* optimize memory-access if needed */
|
||||
// nv_crtc_mem_priority(colour_depth1);
|
||||
// head1_mem_priority(colour_depth1);
|
||||
|
||||
/* Tune RAM CAS-latency if needed. Must be done *here*! */
|
||||
nv_set_cas_latency();
|
||||
@ -391,15 +391,15 @@ status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) {
|
||||
{
|
||||
case DUALHEAD_ON:
|
||||
case DUALHEAD_SWITCH:
|
||||
nv_crtc_set_display_start(startadd,colour_depth);
|
||||
nv_crtc2_set_display_start(startadd_right,colour_depth);
|
||||
head1_set_display_start(startadd,colour_depth);
|
||||
head2_set_display_start(startadd_right,colour_depth);
|
||||
break;
|
||||
case DUALHEAD_OFF:
|
||||
nv_crtc_set_display_start(startadd,colour_depth);
|
||||
head1_set_display_start(startadd,colour_depth);
|
||||
break;
|
||||
case DUALHEAD_CLONE:
|
||||
nv_crtc_set_display_start(startadd,colour_depth);
|
||||
nv_crtc2_set_display_start(startadd,colour_depth);
|
||||
head1_set_display_start(startadd,colour_depth);
|
||||
head2_set_display_start(startadd,colour_depth);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -442,20 +442,20 @@ status_t SET_DPMS_MODE(uint32 dpms_flags) {
|
||||
switch(dpms_flags)
|
||||
{
|
||||
case B_DPMS_ON: /* H: on, V: on, display on */
|
||||
nv_crtc_dpms(true, true, true);
|
||||
if (si->ps.secondary_head) nv_crtc2_dpms(true, true, true);
|
||||
head1_dpms(true, true, true);
|
||||
if (si->ps.secondary_head) head2_dpms(true, true, true);
|
||||
break;
|
||||
case B_DPMS_STAND_BY:
|
||||
nv_crtc_dpms(false, false, true);
|
||||
if (si->ps.secondary_head) nv_crtc2_dpms(false, false, true);
|
||||
head1_dpms(false, false, true);
|
||||
if (si->ps.secondary_head) head2_dpms(false, false, true);
|
||||
break;
|
||||
case B_DPMS_SUSPEND:
|
||||
nv_crtc_dpms(false, true, false);
|
||||
if (si->ps.secondary_head) nv_crtc2_dpms(false, true, false);
|
||||
head1_dpms(false, true, false);
|
||||
if (si->ps.secondary_head) head2_dpms(false, true, false);
|
||||
break;
|
||||
case B_DPMS_OFF: /* H: off, V: off, display off */
|
||||
nv_crtc_dpms(false, false, false);
|
||||
if (si->ps.secondary_head) nv_crtc2_dpms(false, false, false);
|
||||
head1_dpms(false, false, false);
|
||||
if (si->ps.secondary_head) head2_dpms(false, false, false);
|
||||
break;
|
||||
default:
|
||||
LOG(8,("SET: Invalid DPMS settings (DH) 0x%08x\n", dpms_flags));
|
||||
@ -468,16 +468,16 @@ status_t SET_DPMS_MODE(uint32 dpms_flags) {
|
||||
switch(dpms_flags)
|
||||
{
|
||||
case B_DPMS_ON: /* H: on, V: on, display on */
|
||||
nv_crtc_dpms(true, true, true);
|
||||
head1_dpms(true, true, true);
|
||||
break;
|
||||
case B_DPMS_STAND_BY:
|
||||
nv_crtc_dpms(false, false, true);
|
||||
head1_dpms(false, false, true);
|
||||
break;
|
||||
case B_DPMS_SUSPEND:
|
||||
nv_crtc_dpms(false, true, false);
|
||||
head1_dpms(false, true, false);
|
||||
break;
|
||||
case B_DPMS_OFF: /* H: off, V: off, display off */
|
||||
nv_crtc_dpms(false, false, false);
|
||||
head1_dpms(false, false, false);
|
||||
break;
|
||||
default:
|
||||
LOG(8,("SET: Invalid DPMS settings (DH) 0x%08x\n", dpms_flags));
|
||||
@ -499,7 +499,7 @@ uint32 DPMS_MODE(void) {
|
||||
bool display, h, v;
|
||||
|
||||
interrupt_enable(false);
|
||||
nv_crtc_dpms_fetch(&display, &h, &v);
|
||||
head1_dpms_fetch(&display, &h, &v);
|
||||
interrupt_enable(true);
|
||||
|
||||
if (display && h && v)
|
||||
|
@ -1206,7 +1206,7 @@ int maventv_init(display_mode target)
|
||||
// }
|
||||
|
||||
/* setup CRTC2 timing */
|
||||
nv_crtc2_set_timing(tv_target);
|
||||
head2_set_timing(tv_target);
|
||||
|
||||
/* start whole thing if needed */
|
||||
// if (si->ps.card_type <= G400MAX) MAVW(RESYNC, 0x20);
|
||||
|
@ -80,7 +80,7 @@ status_t nv_general_powerup()
|
||||
{
|
||||
status_t status;
|
||||
|
||||
LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-12 running.\n"));
|
||||
LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-13 running.\n"));
|
||||
|
||||
/* preset no laptop */
|
||||
si->ps.laptop = false;
|
||||
@ -690,6 +690,66 @@ status_t nv_set_cas_latency()
|
||||
return result;
|
||||
}
|
||||
|
||||
void setup_virtualized_crtcs(bool cross)
|
||||
{
|
||||
if (cross)
|
||||
{
|
||||
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;
|
||||
head1_dpms = (crtc_dpms) nv_crtc2_dpms;
|
||||
head1_dpms_fetch = (crtc_dpms_fetch) nv_crtc2_dpms_fetch;
|
||||
head1_set_display_pitch = (crtc_set_display_pitch) nv_crtc2_set_display_pitch;
|
||||
head1_set_display_start = (crtc_set_display_start) nv_crtc2_set_display_start;
|
||||
head1_cursor_init = (crtc_cursor_init) nv_crtc2_cursor_init;
|
||||
head1_cursor_show = (crtc_cursor_show) nv_crtc2_cursor_show;
|
||||
head1_cursor_hide = (crtc_cursor_hide) nv_crtc2_cursor_hide;
|
||||
head1_cursor_define = (crtc_cursor_define) nv_crtc2_cursor_define;
|
||||
head1_cursor_position = (crtc_cursor_position) nv_crtc2_cursor_position;
|
||||
|
||||
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;
|
||||
head2_dpms = (crtc_dpms) nv_crtc_dpms;
|
||||
head2_dpms_fetch = (crtc_dpms_fetch) nv_crtc_dpms_fetch;
|
||||
head2_set_display_pitch = (crtc_set_display_pitch) nv_crtc_set_display_pitch;
|
||||
head2_set_display_start = (crtc_set_display_start) nv_crtc_set_display_start;
|
||||
head2_cursor_init = (crtc_cursor_init) nv_crtc_cursor_init;
|
||||
head2_cursor_show = (crtc_cursor_show) nv_crtc_cursor_show;
|
||||
head2_cursor_hide = (crtc_cursor_hide) nv_crtc_cursor_hide;
|
||||
head2_cursor_define = (crtc_cursor_define) nv_crtc_cursor_define;
|
||||
head2_cursor_position = (crtc_cursor_position) nv_crtc_cursor_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
head1_dpms = (crtc_dpms) nv_crtc_dpms;
|
||||
head1_dpms_fetch = (crtc_dpms_fetch) nv_crtc_dpms_fetch;
|
||||
head1_set_display_pitch = (crtc_set_display_pitch) nv_crtc_set_display_pitch;
|
||||
head1_set_display_start = (crtc_set_display_start) nv_crtc_set_display_start;
|
||||
head1_cursor_init = (crtc_cursor_init) nv_crtc_cursor_init;
|
||||
head1_cursor_show = (crtc_cursor_show) nv_crtc_cursor_show;
|
||||
head1_cursor_hide = (crtc_cursor_hide) nv_crtc_cursor_hide;
|
||||
head1_cursor_define = (crtc_cursor_define) nv_crtc_cursor_define;
|
||||
head1_cursor_position = (crtc_cursor_position) nv_crtc_cursor_position;
|
||||
|
||||
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;
|
||||
head2_dpms = (crtc_dpms) nv_crtc2_dpms;
|
||||
head2_dpms_fetch = (crtc_dpms_fetch) nv_crtc2_dpms_fetch;
|
||||
head2_set_display_pitch = (crtc_set_display_pitch) nv_crtc2_set_display_pitch;
|
||||
head2_set_display_start = (crtc_set_display_start) nv_crtc2_set_display_start;
|
||||
head2_cursor_init = (crtc_cursor_init) nv_crtc2_cursor_init;
|
||||
head2_cursor_show = (crtc_cursor_show) nv_crtc2_cursor_show;
|
||||
head2_cursor_hide = (crtc_cursor_hide) nv_crtc2_cursor_hide;
|
||||
head2_cursor_define = (crtc_cursor_define) nv_crtc2_cursor_define;
|
||||
head2_cursor_position = (crtc_cursor_position) nv_crtc2_cursor_position;
|
||||
}
|
||||
}
|
||||
|
||||
static status_t nvxx_general_powerup()
|
||||
{
|
||||
status_t result;
|
||||
@ -704,6 +764,9 @@ static status_t nvxx_general_powerup()
|
||||
/* log the PINS struct settings */
|
||||
dump_pins();
|
||||
|
||||
/* setup CRTC functions access: determined in parse_pins/fake_pins */
|
||||
setup_virtualized_crtcs(si->ps.crtc2_prim);
|
||||
|
||||
/* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
|
||||
//temp:
|
||||
return nv_general_bios_to_powergraphics();
|
||||
@ -712,8 +775,8 @@ return nv_general_bios_to_powergraphics();
|
||||
/*power up the PLLs,LUT,DAC*/
|
||||
LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
|
||||
/* turn off both displays and the hardcursor (also disables transfers) */
|
||||
nv_crtc_dpms(false, false, false);
|
||||
nv_crtc_cursor_hide();
|
||||
head1_dpms(false, false, false);
|
||||
head1_cursor_hide();
|
||||
/* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
|
||||
* (this would create electrical shortcuts,
|
||||
* resulting in extra chip heat and distortions visible on screen */
|
||||
@ -786,7 +849,7 @@ return nv_general_bios_to_powergraphics();
|
||||
// VGAW_I(CRTC,0x11,0);
|
||||
|
||||
/* turn on display one */
|
||||
nv_crtc_dpms(true , true, true);
|
||||
head1_dpms(true , true, true);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -796,8 +859,9 @@ status_t nv_general_output_select(bool cross)
|
||||
/* make sure this call is warranted */
|
||||
if (si->ps.secondary_head)
|
||||
{
|
||||
/* NV11 cards can't switch heads */
|
||||
if (si->ps.card_type != NV11)
|
||||
/* NV11 cards can't switch heads; we lack info to switch heads via outputs
|
||||
* if flatpanels are used */
|
||||
if ((si->ps.card_type != NV11) && !si->ps.tmds1_active && !si->ps.tmds2_active)
|
||||
{
|
||||
if (cross)
|
||||
{
|
||||
@ -823,7 +887,34 @@ status_t nv_general_output_select(bool cross)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(4,("INIT: NV11 outputs are hardwired to be straight-through\n"));
|
||||
/* make sure we have outputs wired straight through first */
|
||||
if (si->ps.card_type == NV11)
|
||||
{
|
||||
LOG(4,("INIT: NV11 outputs are hardwired to be straight-through\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(4,("INIT: switching outputs to be straight-through\n"));
|
||||
|
||||
/* enable head 1 on connector 1 */
|
||||
DACW(OUTPUT, 0x00000001);
|
||||
/* enable head 2 on connector 2 */
|
||||
DAC2W(OUTPUT, 0x00000101);
|
||||
}
|
||||
|
||||
/* now invert CRTC use to do switching */
|
||||
if (cross)
|
||||
{
|
||||
LOG(4,("INIT: switching CRTC use to be cross-connected\n"));
|
||||
si->crtc_switch_mode = !si->ps.crtc2_prim;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(4,("INIT: switching CRTC use to be straight-through\n"));
|
||||
si->crtc_switch_mode = si->ps.crtc2_prim;
|
||||
}
|
||||
/* update CRTC functions access */
|
||||
setup_virtualized_crtcs(si->crtc_switch_mode);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
@ -871,12 +962,12 @@ status_t nv_general_bios_to_powergraphics()
|
||||
}
|
||||
|
||||
/* turn off both displays and the hardcursors (also disables transfers) */
|
||||
nv_crtc_dpms(false, false, false);
|
||||
nv_crtc_cursor_hide();
|
||||
head1_dpms(false, false, false);
|
||||
head1_cursor_hide();
|
||||
if (si->ps.secondary_head)
|
||||
{
|
||||
nv_crtc2_dpms(false, false, false);
|
||||
nv_crtc2_cursor_hide();
|
||||
head2_dpms(false, false, false);
|
||||
head2_cursor_hide();
|
||||
}
|
||||
|
||||
if (si->ps.secondary_head)
|
||||
@ -970,7 +1061,7 @@ status_t nv_general_bios_to_powergraphics()
|
||||
if (si->ps.secondary_head) DAC2W(TSTCTRL, (DAC2R(TSTCTRL) & 0xfffeefff));
|
||||
|
||||
/* turn screen one on */
|
||||
nv_crtc_dpms(true, true, true);
|
||||
head1_dpms(true, true, true);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -8,3 +8,43 @@ extern area_id my_mode_list_area;
|
||||
extern int accelerantIsClone;
|
||||
|
||||
extern nv_get_set_pci nv_pci_access;
|
||||
|
||||
|
||||
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);
|
||||
typedef status_t (*crtc_dpms)(bool, bool, bool);
|
||||
typedef status_t (*crtc_dpms_fetch)(bool*, bool*, bool*);
|
||||
typedef status_t (*crtc_set_display_pitch)(void);
|
||||
typedef status_t (*crtc_set_display_start)(uint32, uint8);
|
||||
typedef status_t (*crtc_cursor_init)(void);
|
||||
typedef status_t (*crtc_cursor_show)(void);
|
||||
typedef status_t (*crtc_cursor_hide)(void);
|
||||
typedef status_t (*crtc_cursor_define)(uint8*, uint8*);
|
||||
typedef status_t (*crtc_cursor_position)(uint16, uint16);
|
||||
|
||||
crtc_validate_timing head1_validate_timing;
|
||||
crtc_set_timing head1_set_timing;
|
||||
crtc_depth head1_depth;
|
||||
crtc_dpms head1_dpms;
|
||||
crtc_dpms_fetch head1_dpms_fetch;
|
||||
crtc_set_display_pitch head1_set_display_pitch;
|
||||
crtc_set_display_start head1_set_display_start;
|
||||
crtc_cursor_init head1_cursor_init;
|
||||
crtc_cursor_show head1_cursor_show;
|
||||
crtc_cursor_hide head1_cursor_hide;
|
||||
crtc_cursor_define head1_cursor_define;
|
||||
crtc_cursor_position head1_cursor_position;
|
||||
|
||||
crtc_validate_timing head2_validate_timing;
|
||||
crtc_set_timing head2_set_timing;
|
||||
crtc_depth head2_depth;
|
||||
crtc_dpms head2_dpms;
|
||||
crtc_dpms_fetch head2_dpms_fetch;
|
||||
crtc_set_display_pitch head2_set_display_pitch;
|
||||
crtc_set_display_start head2_set_display_start;
|
||||
crtc_cursor_init head2_cursor_init;
|
||||
crtc_cursor_show head2_cursor_show;
|
||||
crtc_cursor_hide head2_cursor_hide;
|
||||
crtc_cursor_define head2_cursor_define;
|
||||
crtc_cursor_position head2_cursor_position;
|
||||
|
@ -245,6 +245,13 @@ void fake_pins(void)
|
||||
|
||||
/* find out the BIOS preprogrammed panel use status... */
|
||||
detect_panels();
|
||||
|
||||
/* select other CRTC for primary head use if specified by user in settings file */
|
||||
if (si->ps.secondary_head && si->settings.switchhead)
|
||||
{
|
||||
LOG(2,("INFO: switching CRTC's (specified in settings file)\n"));
|
||||
si->ps.crtc2_prim = !si->ps.crtc2_prim;
|
||||
}
|
||||
}
|
||||
|
||||
static void detect_panels()
|
||||
@ -252,11 +259,8 @@ static void detect_panels()
|
||||
/* detect if the BIOS enabled LCD's (internal panels or DVI) or TVout */
|
||||
|
||||
/* both external TMDS transmitters (used for LCD/DVI) and external TVencoders
|
||||
* can use the CRTC's in slaved mode. */
|
||||
* (can) use the CRTC's in slaved mode. */
|
||||
/* Note:
|
||||
* Apparantly a panel on CRTC1 uses the CRTC in slaved mode, while a panel
|
||||
* on CRTC2 uses the CRTC in master mode. */
|
||||
/* Note also:
|
||||
* DFP's are programmed with standard VESA modelines by the card's BIOS! */
|
||||
bool slaved_for_dev1 = false, slaved_for_dev2 = false;
|
||||
bool tvout1 = false, tvout2 = false;
|
||||
@ -319,6 +323,7 @@ static void detect_panels()
|
||||
si->ps.master_tmds2 = false;
|
||||
si->ps.tmds1_active = false;
|
||||
si->ps.tmds2_active = false;
|
||||
si->ps.crtc2_prim = false;
|
||||
/* determine the situation we are in... (regarding flatpanels) */
|
||||
/* fixme: add VESA DDC EDID stuff one day... */
|
||||
/* fixme: find out how to program those transmitters one day instead of
|
||||
@ -337,6 +342,10 @@ static void detect_panels()
|
||||
* BIOSes;
|
||||
* -> the programmed set of registers tells you where a TMDS (DVI) panel is
|
||||
* connected. */
|
||||
/* note also:
|
||||
* external TMDS encoders are only used for logic-level translation: it's
|
||||
* modeline registers are not used. Instead the GPU's internal modeline registers
|
||||
* are used. The external encoder is not connected to a I2C bus (confirmed NV34). */
|
||||
if (slaved_for_dev1 && !tvout1)
|
||||
{
|
||||
uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
|
||||
@ -425,6 +434,14 @@ static void detect_panels()
|
||||
if (si->ps.tmds2_active)
|
||||
si->ps.panel2_aspect = (si->ps.panel2_width / ((float)si->ps.panel2_height));
|
||||
|
||||
/* if one panel is detected, and it's on the secondary head on dualhead cards,
|
||||
* we use that head as primary head */
|
||||
if (si->ps.secondary_head && si->ps.tmds2_active && !si->ps.tmds1_active)
|
||||
{
|
||||
LOG(2,("INFO: CRTC2 has a panel only: defaulting to CRTC2 use\n"));
|
||||
si->ps.crtc2_prim = true;
|
||||
}
|
||||
|
||||
/* dump some panel configuration registers... */
|
||||
LOG(2,("INFO: Dumping flatpanel registers:\n"));
|
||||
LOG(2,("DAC1: FP_HDISPEND: %d\n", DACR(FP_HDISPEND)));
|
||||
|
@ -1,7 +1,8 @@
|
||||
/*general card functions*/
|
||||
status_t nv_general_powerup(void);
|
||||
status_t nv_set_cas_latency(void);
|
||||
status_t nv_general_output_select(bool cross);
|
||||
void setup_virtualized_crtcs(bool);
|
||||
status_t nv_general_output_select(bool);
|
||||
status_t nv_general_wait_retrace(void);
|
||||
status_t nv_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode);
|
||||
|
||||
|
@ -117,11 +117,19 @@ Dumprom is another 'tool' for bug-tracking purposes.
|
||||
<li><strong>true:</strong><br>
|
||||
<strong>dumprom true</strong> lets the driver dump a copy of your VGA BIOS in a file called <strong>nv.rom</strong> in your <strong>~ (home)</strong> folder.
|
||||
</ul>
|
||||
<li><strong>switchhead:</strong><br>
|
||||
With this option you can select which output on your card is the primary output (only for dualhead cards).
|
||||
<ul>
|
||||
<li><strong>false:</strong> (default setting)<br>
|
||||
Keep it set to <strong>switchhead false</strong>, unless you feel you want the card's other output to be used as primary one. Note that if a single digitally connected flatpanel is found, that panel will be the driver's primary output with this setting.
|
||||
<li><strong>true:</strong><br>
|
||||
<strong>switchhead true</strong> lets the driver 'invert' the output assignments for all modes.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<br>
|
||||
<a href="mailto:rag.cornelissen@inter.nl.net">Rudolf Cornelissen.</a>
|
||||
<p>(Page last updated on February 2, 2004)</p>
|
||||
<p>(Page last updated on April 22, 2004)</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,7 +4,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<p><h2>Changes done for each driverversion:</h2></p>
|
||||
<p><h1>head (0.10-12), (Rudolf)</h1></p>
|
||||
<p><h1>head (0.10-13), (Rudolf)</h1></p>
|
||||
<ul>
|
||||
<li>Implemented laptop internal flatpanel presence and native resolution detection;
|
||||
<li>Implemented external DVI flatpanel(s) presence and native resolution detection;
|
||||
@ -19,10 +19,11 @@
|
||||
<li>Updated panel detection code once more: pre NV18 DVI panels should be working again now;
|
||||
<li>Added flatpanel DPMS support for both heads via powerup/powerdown of LVDS and TMDS transmitters;
|
||||
<li>Added panel(s) native mode(s) to the modelist exported by the driver. You can now set it (them) by just selecting it from the Screenprefs app, <strong>except</strong> if you use the native R5 one. Use Dualhead setup instead (for example): the extra mode(s) will be at the bottom of the list;
|
||||
<li>Removed a bug in the panel detection code and added a bit more logging.
|
||||
<li>Removed a bug in the panel detection code and added a bit more logging;
|
||||
<li>Implemented virtualized CRTC1 and CRTC2 access: when one flatpanel is found on a card that panel is primary output now; dualhead switch mode is operational with flatpanels now; and the user has the option to select the primary output via nv.settings now (via the new 'switchhead' option).
|
||||
</ul>
|
||||
NOTE:<br>
|
||||
dualhead switch mode is not yet operational for flatpanels...
|
||||
WARNING:<br>
|
||||
Driver 0.10-13 has yet to be actually tested and updated to correct bugs!!
|
||||
<p><h1>nv_driver 0.09, (Rudolf)</h1></p>
|
||||
<ul>
|
||||
<li>Fixed NV11 trouble with repeating screen(s) on the right side of the monitor;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Other authors:
|
||||
Mark Watson;
|
||||
Rudolf Cornelissen 3/2002-3/2004.
|
||||
Rudolf Cornelissen 3/2002-4/2004.
|
||||
*/
|
||||
|
||||
/* standard kernel driver stuff */
|
||||
@ -263,7 +263,7 @@ static settings current_settings = { // see comments in nv.settings
|
||||
0, // memory
|
||||
false, // usebios
|
||||
false, // hardcursor
|
||||
false, // greensync
|
||||
false, // switchhead
|
||||
};
|
||||
|
||||
static void dumprom (void *rom, size_t size)
|
||||
@ -381,7 +381,7 @@ init_driver(void) {
|
||||
|
||||
current_settings.hardcursor = get_driver_boolean_parameter (settings_handle, "hardcursor", false, false);
|
||||
current_settings.usebios = get_driver_boolean_parameter (settings_handle, "usebios", false, false);
|
||||
current_settings.greensync = get_driver_boolean_parameter (settings_handle, "greensync", false, false);
|
||||
current_settings.switchhead = get_driver_boolean_parameter (settings_handle, "switchhead", false, false);
|
||||
|
||||
unload_driver_settings (settings_handle);
|
||||
}
|
||||
|
@ -17,6 +17,6 @@ hardcursor true # if true use on-chip cursor capabilities
|
||||
#logmask 0x08000604 # log overlay use in full
|
||||
#logmask 0xffffffff # log everything
|
||||
dumprom false # dump bios rom in ~/nv.rom: probably not functional yet
|
||||
greensync false # not functional, will be removed
|
||||
switchhead false # switch head assignment (dualhead cards only)
|
||||
|
||||
#--------- that's all.
|
Loading…
Reference in New Issue
Block a user