driver works nicely with virtualized head setup now!

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7296 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen 2004-04-22 14:41:39 +00:00
parent 0669fe20bd
commit 30f7642281
11 changed files with 147 additions and 92 deletions

View File

@ -278,7 +278,7 @@ typedef struct {
int_buf_info myBufInfo[MAXBUFFERS]; /* extra info on scaler input buffers */
overlay_token myToken; /* scaler is free/in use */
benaphore lock; /* for creating buffers and aquiring overlay unit routines */
uint8 crtc; /* location of overlay unit */
bool crtc; /* location of overlay unit */
} overlay;
} shared_info;

View File

@ -260,8 +260,8 @@ 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);
/* setup CRTC and DAC functions access */
setup_virtualized_heads(si->crtc_switch_mode);
/* bail out if the common initialization failed */
if (result != B_OK) goto error1;

View File

@ -1,4 +1,4 @@
/* Written by Rudolf Cornelissen 05/2002-2/2004 */
/* Written by Rudolf Cornelissen 05/2002-4/2004 */
/* Note on 'missing features' in BeOS 5.0.3 and DANO:
* BeOS needs to define more colorspaces! It would be nice if BeOS would support the FourCC 'definitions'
@ -604,12 +604,12 @@ status_t CONFIGURE_OVERLAY
case DUALHEAD_SWITCH:
if ((ow->h_start + (ow->width / 2)) <
(si->dm.h_display_start + si->dm.timing.h_display))
nv_bes_to_crtc(0);
nv_bes_to_crtc(si->crtc_switch_mode);
else
nv_bes_to_crtc(1);
nv_bes_to_crtc(!si->crtc_switch_mode);
break;
default:
nv_bes_to_crtc(0);
nv_bes_to_crtc(si->crtc_switch_mode);
break;
}
}

View File

@ -244,7 +244,7 @@ status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, con
/* Now find the nearest valid pixelclock we actually can setup for the target mode,
* this also makes sure we don't generate more pixel bandwidth than the device can handle */
/* calculate settings, but do not actually test anything (that costs too much time!) */
result = nv_dac_pix_pll_find(*target,&pix_clock_found,&m,&n,&p,0);
result = head1_pix_pll_find(*target,&pix_clock_found,&m,&n,&p,0);
/* update the target mode */
target->timing.pixel_clock = (pix_clock_found * 1000);

View File

@ -52,7 +52,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
status_t result;
uint32 startadd,startadd_right;
bool display, h, v;
bool crt1, crt2, cross;
// bool crt1, crt2, cross;
/* Adjust mode to valid one and fail if invalid */
target /*= bounds*/ = *mode_to_set;
@ -109,16 +109,43 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
LOG(1,("SETMODE: blocking TVout: no TVout cable connected!\n"));
}
/* detect which connectors have a CRT connected */
//fixme: 'hot-plugging' for analog monitors removed: remove code as well;
//or make it work with digital panels connected as well.
// crt1 = nv_dac_crt_connected();
// crt2 = nv_dac2_crt_connected();
/* connect outputs 'straight-through' */
// if (crt1)
// {
/* connector1 is used as primary output */
// cross = false;
// }
// else
// {
// if (crt2)
/* connector2 is used as primary output */
// cross = true;
// else
/* no CRT detected: assume connector1 is used as primary output */
// cross = false;
// }
/* set output connectors assignment if possible */
if ((target.flags & DUALHEAD_BITS) == DUALHEAD_SWITCH)
/* invert output assignment in switch mode */
nv_general_output_select(true);
else
nv_general_output_select(false);
/* set the pixel clock PLL(s) */
LOG(8,("SETMODE: target clock %dkHz\n",target.timing.pixel_clock));
if (nv_dac_set_pix_pll(target) == B_ERROR)
if (head1_set_pix_pll(target) == B_ERROR)
LOG(8,("SETMODE: error setting pixel clock (internal DAC)\n"));
/* we do not need to set the pixelclock here for a head that's in TVout mode */
if (!(target2.flags & TV_BITS))
{
LOG(8,("SETMODE: target2 clock %dkHz\n",target2.timing.pixel_clock));
if (nv_dac2_set_pix_pll(target2) == B_ERROR)
if (head2_set_pix_pll(target2) == B_ERROR)
LOG(8,("SETMODE: error setting pixel clock (DAC2)\n"));
}
@ -127,22 +154,22 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
{
case B_CMAP8:
colour_depth1 = 8;
nv_dac_mode(BPP8, 1.0);
head1_mode(BPP8, 1.0);
head1_depth(BPP8);
break;
case B_RGB15_LITTLE:
colour_depth1 = 16;
nv_dac_mode(BPP15, 1.0);
head1_mode(BPP15, 1.0);
head1_depth(BPP15);
break;
case B_RGB16_LITTLE:
colour_depth1 = 16;
nv_dac_mode(BPP16, 1.0);
head1_mode(BPP16, 1.0);
head1_depth(BPP16);
break;
case B_RGB32_LITTLE:
colour_depth1 = 32;
nv_dac_mode(BPP32, 1.0);
head1_mode(BPP32, 1.0);
head1_depth(BPP32);
break;
}
@ -151,22 +178,22 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
{
case B_CMAP8:
colour_depth2 = 8;
nv_dac2_mode(BPP8, 1.0);
head2_mode(BPP8, 1.0);
head2_depth(BPP8);
break;
case B_RGB15_LITTLE:
colour_depth2 = 16;
nv_dac2_mode(BPP15, 1.0);
head2_mode(BPP15, 1.0);
head2_depth(BPP15);
break;
case B_RGB16_LITTLE:
colour_depth2 = 16;
nv_dac2_mode(BPP16, 1.0);
head2_mode(BPP16, 1.0);
head2_depth(BPP16);
break;
case B_RGB32_LITTLE:
colour_depth2 = 32;
nv_dac2_mode(BPP32, 1.0);
head2_mode(BPP32, 1.0);
head2_depth(BPP32);
break;
}
@ -185,31 +212,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/*work out where the "right" screen starts*/
startadd_right = startadd + (target.timing.h_display * (colour_depth1 >> 3));
/* detect which connectors have a CRT connected */
crt1 = nv_dac_crt_connected();
crt2 = nv_dac2_crt_connected();
/* connect outputs 'straight-through' */
if (crt1)
{
/* connector1 is used as primary output */
cross = false;
}
else
{
if (crt2)
/* connector2 is used as primary output */
cross = true;
else
/* no CRT detected: assume connector1 is used as primary output */
cross = false;
}
/* set output connectors assignment if possible */
if ((target.flags & DUALHEAD_BITS) == DUALHEAD_SWITCH)
/* invert output assignment in switch mode */
nv_general_output_select(!cross);
else
nv_general_output_select(cross);
/* Tell card what memory to display */
switch (target.flags & DUALHEAD_BITS)
{
@ -236,7 +238,34 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
{
status_t status;
int colour_mode = BPP32;
/* connect output */
if (si->ps.secondary_head)
{
/* detect which connectors have a CRT connected */
//fixme: 'hot-plugging' for analog monitors removed: remove code as well;
//or make it work with digital panels connected as well.
// crt1 = nv_dac_crt_connected();
// crt2 = nv_dac2_crt_connected();
/* connect outputs 'straight-through' */
// if (crt1)
// {
/* connector1 is used as primary output */
// cross = false;
// }
// else
// {
// if (crt2)
/* connector2 is used as primary output */
// cross = true;
// else
/* no CRT detected: assume connector1 is used as primary output */
// cross = false;
// }
/* set output connectors assignment if possible */
nv_general_output_select(false);
}
switch(target.space)
{
case B_CMAP8: colour_depth1 = 8; colour_mode = BPP8; break;
@ -249,7 +278,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
}
/* set the pixel clock PLL */
status = nv_dac_set_pix_pll(target);
status = head1_set_pix_pll(target);
if (status==B_ERROR)
LOG(8,("CRTC: error setting pixel clock (internal DAC)\n"));
@ -258,7 +287,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/* first set the colordepth */
head1_depth(colour_mode);
/* then(!) program the PAL (<8bit colordepth does not support 8bit PAL) */
nv_dac_mode(colour_mode,1.0);
head1_mode(colour_mode,1.0);
/* set the display pitch */
head1_set_display_pitch();
@ -269,31 +298,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/* set the timing */
head1_set_timing(target);
/* connect output */
if (si->ps.secondary_head)
{
/* detect which connectors have a CRT connected */
crt1 = nv_dac_crt_connected();
crt2 = nv_dac2_crt_connected();
/* connect outputs 'straight-through' */
if (crt1)
{
/* connector1 is used as primary output */
cross = false;
}
else
{
if (crt2)
/* connector2 is used as primary output */
cross = true;
else
/* no CRT detected: assume connector1 is used as primary output */
cross = false;
}
/* set output connectors assignment if possible */
nv_general_output_select(cross);
}
//fixme: shut-off the videoPLL if it exists...
}
@ -427,8 +431,8 @@ void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags
b[i]=*color_data++;
i++;
}
nv_dac_palette(r,g,b);
if (si->dm.flags & DUALHEAD_BITS) nv_dac2_palette(r,g,b);
head1_palette(r,g,b);
if (si->dm.flags & DUALHEAD_BITS) head2_palette(r,g,b);
}
/* Put the display into one of the Display Power Management modes. */

View File

@ -1,5 +1,5 @@
/* Nvidia TNT and GeForce Back End Scaler functions */
/* Written by Rudolf Cornelissen 05/2002-2/2004 */
/* Written by Rudolf Cornelissen 05/2002-4/2004 */
#define MODULE_BIT 0x00000200
@ -8,7 +8,7 @@
//fixme: implement: (used for virtual screens!)
//void move_overlay(uint16 hdisp_start, uint16 vdisp_start);
status_t nv_bes_to_crtc(uint8 crtc)
status_t nv_bes_to_crtc(bool crtc)
{
if (si->ps.secondary_head)
{
@ -18,7 +18,7 @@ status_t nv_bes_to_crtc(uint8 crtc)
/* switch overlay engine to CRTC2 */
NV_REG32(NV32_FUNCSEL) &= ~0x00001000;
NV_REG32(NV32_2FUNCSEL) |= 0x00001000;
si->overlay.crtc = 1;
si->overlay.crtc = !si->crtc_switch_mode;
}
else
{
@ -26,7 +26,7 @@ status_t nv_bes_to_crtc(uint8 crtc)
/* switch overlay engine to CRTC1 */
NV_REG32(NV32_2FUNCSEL) &= ~0x00001000;
NV_REG32(NV32_FUNCSEL) |= 0x00001000;
si->overlay.crtc = 0;
si->overlay.crtc = si->crtc_switch_mode;
}
return B_OK;
}

View File

@ -80,7 +80,7 @@ status_t nv_general_powerup()
{
status_t status;
LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-13 running.\n"));
LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-14 running.\n"));
/* preset no laptop */
si->ps.laptop = false;
@ -690,7 +690,7 @@ status_t nv_set_cas_latency()
return result;
}
void setup_virtualized_crtcs(bool cross)
void setup_virtualized_heads(bool cross)
{
if (cross)
{
@ -707,6 +707,11 @@ void setup_virtualized_crtcs(bool cross)
head1_cursor_define = (crtc_cursor_define) nv_crtc2_cursor_define;
head1_cursor_position = (crtc_cursor_position) nv_crtc2_cursor_position;
head1_mode = (dac_mode) nv_dac2_mode;
head1_palette = (dac_palette) nv_dac2_palette;
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_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;
@ -719,6 +724,11 @@ void setup_virtualized_crtcs(bool cross)
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;
head2_mode = (dac_mode) nv_dac_mode;
head2_palette = (dac_palette) nv_dac_palette;
head2_set_pix_pll = (dac_set_pix_pll) nv_dac_set_pix_pll;
head2_pix_pll_find = (dac_pix_pll_find) nv_dac_pix_pll_find;
}
else
{
@ -735,6 +745,11 @@ void setup_virtualized_crtcs(bool cross)
head1_cursor_define = (crtc_cursor_define) nv_crtc_cursor_define;
head1_cursor_position = (crtc_cursor_position) nv_crtc_cursor_position;
head1_mode = (dac_mode) nv_dac_mode;
head1_palette = (dac_palette) nv_dac_palette;
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_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;
@ -747,6 +762,11 @@ void setup_virtualized_crtcs(bool cross)
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;
head2_mode = (dac_mode) nv_dac2_mode;
head2_palette = (dac_palette) nv_dac2_palette;
head2_set_pix_pll = (dac_set_pix_pll) nv_dac2_set_pix_pll;
head2_pix_pll_find = (dac_pix_pll_find) nv_dac2_pix_pll_find;
}
}
@ -764,8 +784,8 @@ 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);
/* setup CRTC and DAC functions access: determined in parse_pins/fake_pins */
setup_virtualized_heads(si->ps.crtc2_prim);
/* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
//temp:
@ -861,7 +881,8 @@ status_t nv_general_output_select(bool cross)
{
/* 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)
//fixme: nolonger used: will be removed later on.
if (0)//(si->ps.card_type != NV11) && !si->ps.tmds1_active && !si->ps.tmds2_active)
{
if (cross)
{
@ -913,8 +934,8 @@ status_t nv_general_output_select(bool cross)
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);
/* update CRTC and DAC functions access */
setup_virtualized_heads(si->crtc_switch_mode);
}
return B_OK;
}
@ -979,7 +1000,7 @@ status_t nv_general_bios_to_powergraphics()
NV_REG32(NV32_2FUNCSEL) &= ~0x00001000;
NV_REG32(NV32_FUNCSEL) |= 0x00001000;
}
si->overlay.crtc = 0;
si->overlay.crtc = false;
/* enable 'enhanced' mode on primary head: */
/* enable access to primary head */

View File

@ -23,6 +23,11 @@ typedef status_t (*crtc_cursor_hide)(void);
typedef status_t (*crtc_cursor_define)(uint8*, uint8*);
typedef status_t (*crtc_cursor_position)(uint16, uint16);
typedef status_t (*dac_mode)(int, float);
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_validate_timing head1_validate_timing;
crtc_set_timing head1_set_timing;
crtc_depth head1_depth;
@ -48,3 +53,13 @@ crtc_cursor_show head2_cursor_show;
crtc_cursor_hide head2_cursor_hide;
crtc_cursor_define head2_cursor_define;
crtc_cursor_position head2_cursor_position;
dac_mode head1_mode;
dac_palette head1_palette;
dac_set_pix_pll head1_set_pix_pll;
dac_pix_pll_find head1_pix_pll_find;
dac_mode head2_mode;
dac_palette head2_palette;
dac_set_pix_pll head2_set_pix_pll;
dac_pix_pll_find head2_pix_pll_find;

View File

@ -246,6 +246,17 @@ void fake_pins(void)
/* find out the BIOS preprogrammed panel use status... */
detect_panels();
/* if no panel, but one analog monitor 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.tmds1_active && !si->ps.tmds2_active)
{
if (nv_dac2_crt_connected() && !nv_dac_crt_connected())
{
LOG(2,("INFO: CRTC2 has a monitor only: defaulting to CRTC2 use\n"));
si->ps.crtc2_prim = true;
}
}
/* select other CRTC for primary head use if specified by user in settings file */
if (si->ps.secondary_head && si->settings.switchhead)
{

View File

@ -1,7 +1,7 @@
/*general card functions*/
status_t nv_general_powerup(void);
status_t nv_set_cas_latency(void);
void setup_virtualized_crtcs(bool);
void setup_virtualized_heads(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);
@ -109,7 +109,7 @@ status_t nv_acc_wait_idle(void);
/*backend scaler functions*/
status_t check_overlay_capability(uint32 feature);
status_t nv_bes_to_crtc(uint8 crtc);
status_t nv_bes_to_crtc(bool crtc);
status_t nv_bes_init(void);
status_t nv_configure_bes
(const overlay_buffer *ob, const overlay_window *ow,const overlay_view *ov, int offset);

View File

@ -4,7 +4,7 @@
</head>
<body>
<p><h2>Changes done for each driverversion:</h2></p>
<p><h1>head (0.10-13), (Rudolf)</h1></p>
<p><h1>head (0.10-14), (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;
@ -20,10 +20,14 @@
<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>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).
<li>Implemented virtualized CRTC1/DAC1 and CRTC2/DAC2 access: when one flatpanel is found on a card that panel is always primary output now;
<li>Dualhead switch mode is operational with flatpanels now (via the virtualized setup);
<li>The user has the option to select the primary output via nv.settings now (via the new 'switchhead' option);
<li>Modified analog type monitor detection to work the same as for digital panels (detect on bootup only);
<li>Added dualhead switch mode for NV11 (works via virtualized head access implemented now);
<li>Modified dualhead switch mode for all other cards to work via the virtualized head access also;
<li>Modified overlay to work correctly with the virtualized setup.
</ul>
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;