doing preparations for using analog widescreen detection. if all is right the driver's behaviour hasn't changed yet.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31183 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -41,6 +41,12 @@ typedef struct {
|
||||
|
||||
#define NV_PRIVATE_DATA_MAGIC 0x0009 /* a private driver rev, of sorts */
|
||||
|
||||
/* monitor setup */
|
||||
#define CRTC1_TMDS 0x01
|
||||
#define CRTC2_TMDS 0x10
|
||||
#define CRTC1_VGA 0x02
|
||||
#define CRTC2_VGA 0x20
|
||||
|
||||
/* dualhead extensions to flags */
|
||||
#define DUALHEAD_OFF (0<<6)
|
||||
#define DUALHEAD_CLONE (1<<6)
|
||||
@@ -344,12 +350,10 @@ typedef struct {
|
||||
bool slaved_tmds2; /* external TMDS encoder active on CRTC2 */
|
||||
bool master_tmds1; /* on die TMDS encoder active on CRTC1 */
|
||||
bool master_tmds2; /* on die TMDS encoder active on CRTC2 */
|
||||
bool tmds1_active; /* found panel on CRTC1 that is active */
|
||||
bool tmds2_active; /* found panel on CRTC2 that is active */
|
||||
display_timing p1_timing; /* 'modeline' fetched for panel 1 */
|
||||
display_timing p2_timing; /* 'modeline' fetched for panel 2 */
|
||||
float panel1_aspect; /* panel's aspect ratio */
|
||||
float panel2_aspect; /* panel's aspect ratio */
|
||||
float crtc1_aspect; /* screen's aspect ratio */
|
||||
float crtc2_aspect; /* screen's aspect ratio */
|
||||
edid_specs con1_screen; /* EDID properties of the screen connected to connector 1 */
|
||||
edid_specs con2_screen; /* EDID properties of the screen connected to connector 2 */
|
||||
bool crtc2_prim; /* using CRTC2 as primary CRTC */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Other authors for NV driver:
|
||||
Mark Watson,
|
||||
Rudolf Cornelissen 9/2002-4/2006
|
||||
Rudolf Cornelissen 9/2002-6/2009
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00400000
|
||||
@@ -16,9 +16,6 @@
|
||||
#define MODE_FLAGS 0
|
||||
#define MODE_COUNT (sizeof (mode_list) / sizeof (display_mode))
|
||||
|
||||
/*some monitors only handle a fixed set of modes*/
|
||||
#include "valid_mode_list"
|
||||
|
||||
/* Standard VESA modes,
|
||||
* plus panel specific resolution modes which are internally modified during run-time depending on the requirements of the actual
|
||||
* panel connected. The modes as listed here, should timing-wise be as compatible with analog (CRT) monitors as can be... */
|
||||
@@ -129,55 +126,6 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
LOG(1, ("PROPOSEMODE: (ENTER) requested virtual_width %d, virtual_height %d\n",
|
||||
target->virtual_width, target->virtual_height));
|
||||
|
||||
/*check valid list:
|
||||
if (VALID_REQUIRED is set)
|
||||
{
|
||||
if (find modes with same size)
|
||||
{
|
||||
pick one with nearest pixel clock
|
||||
}
|
||||
else
|
||||
{
|
||||
pick next largest with nearest pixel clock and modify visible portion as far as possible
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef VALID_MODE_REQUIRED
|
||||
{
|
||||
int i;
|
||||
int closest_mode_ptr;
|
||||
uint32 closest_mode_clock;
|
||||
|
||||
LOG(1, ("PROPOSEMODE: valid mode required!\n"));
|
||||
|
||||
closest_mode_ptr = 0xbad;
|
||||
closest_mode_clock = 0;
|
||||
for (i = 0; i < VALID_MODES; i++) {
|
||||
/*check size is ok and clock is better than any found before*/
|
||||
if (target->timing.h_display == valid_mode_list[i].h_display
|
||||
&& target->timing.v_display == valid_mode_list[i].v_display) {
|
||||
if (abs(valid_mode_list[i].pixel_clock-target->timing.pixel_clock)
|
||||
< abs(closest_mode_clock-target->timing.pixel_clock)) {
|
||||
closest_mode_clock = valid_mode_list[i].pixel_clock;
|
||||
closest_mode_ptr = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closest_mode_ptr == 0xbad) {
|
||||
/* if no modes of correct size */
|
||||
LOG(4, ("PROPOSEMODE: no valid mode found, aborted.\n"));
|
||||
return B_ERROR;
|
||||
} else {
|
||||
target->timing = valid_mode_list[closest_mode_ptr];
|
||||
/* I require this refresh */
|
||||
target_refresh = ((double)target->timing.pixel_clock * 1000.0)
|
||||
/ ((double)target->timing.h_total * (double)target->timing.v_total);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*find a nearby valid timing from that given*/
|
||||
result = head1_validate_timing(&target->timing.h_display,
|
||||
&target->timing.h_sync_start, &target->timing.h_sync_end,
|
||||
@@ -198,25 +146,33 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
/* NOTE:
|
||||
* allow 0.10 difference so 5:4 aspect panels will be able to use 4:3 aspect modes! */
|
||||
switch (si->ps.monitors) {
|
||||
case 0x01: /* digital panel on head 1, nothing on head 2 */
|
||||
if (si->ps.panel1_aspect < (target_aspect - 0.10)) {
|
||||
case CRTC1_TMDS: /* digital panel on head 1, nothing on head 2 */
|
||||
if (si->ps.crtc1_aspect < (target_aspect - 0.10)) {
|
||||
LOG(4, ("PROPOSEMODE: connected panel1 is not widescreen type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
case 0x10: /* nothing on head 1, digital panel on head 2 */
|
||||
if (si->ps.panel2_aspect < (target_aspect - 0.10)) {
|
||||
case CRTC2_TMDS: /* nothing on head 1, digital panel on head 2 */
|
||||
if (si->ps.crtc2_aspect < (target_aspect - 0.10)) {
|
||||
LOG(4, ("PROPOSEMODE: connected panel2 is not widescreen type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
case 0x11: /* digital panels on both heads */
|
||||
if ((si->ps.panel1_aspect < (target_aspect - 0.10))
|
||||
|| (si->ps.panel2_aspect < (target_aspect - 0.10))) {
|
||||
case CRTC1_TMDS | CRTC2_TMDS: /* digital panels on both heads */
|
||||
if ((si->ps.crtc1_aspect < (target_aspect - 0.10))
|
||||
|| (si->ps.crtc2_aspect < (target_aspect - 0.10))) {
|
||||
LOG(4, ("PROPOSEMODE: not all connected panels are widescreen type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
//
|
||||
// case CRTC1_VGA: /* analog connected screen on head 1, nothing on head 2 */
|
||||
// if (si->ps.panel1_aspect < (target_aspect - 0.10)) {
|
||||
// LOG(4, ("PROPOSEMODE: connected panel1 is not widescreen type, aborted.\n"));
|
||||
// return B_ERROR;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
default:
|
||||
/* at least one analog monitor is connected, or nothing detected at all */
|
||||
/* (if forcing widescreen type was requested don't block mode) */
|
||||
@@ -232,12 +188,12 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
if (target_aspect > 1.61 && !si->settings.force_ws) {
|
||||
status_t panel_TV_stat = B_ERROR;
|
||||
|
||||
if (si->ps.tmds1_active) {
|
||||
if (si->ps.monitors & CRTC1_TMDS) {
|
||||
if (target->timing.h_display == si->ps.p1_timing.h_display
|
||||
&& target->timing.v_display == si->ps.p1_timing.v_display)
|
||||
panel_TV_stat = B_OK;
|
||||
}
|
||||
if (si->ps.tmds2_active) {
|
||||
if (si->ps.monitors & CRTC2_TMDS) {
|
||||
if (target->timing.h_display == si->ps.p2_timing.h_display
|
||||
&& target->timing.v_display == si->ps.p2_timing.v_display)
|
||||
panel_TV_stat = B_OK;
|
||||
@@ -250,14 +206,14 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
}
|
||||
|
||||
/* check if panel(s) can display the requested resolution (if connected) */
|
||||
if (si->ps.tmds1_active) {
|
||||
if (si->ps.monitors & CRTC1_TMDS) {
|
||||
if (target->timing.h_display > si->ps.p1_timing.h_display
|
||||
|| target->timing.v_display > si->ps.p1_timing.v_display) {
|
||||
LOG(4, ("PROPOSEMODE: panel1 can't display requested resolution, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
if (si->ps.tmds2_active) {
|
||||
if (si->ps.monitors & CRTC2_TMDS) {
|
||||
if (target->timing.h_display > si->ps.p2_timing.h_display
|
||||
|| target->timing.v_display > si->ps.p2_timing.v_display) {
|
||||
LOG(4, ("PROPOSEMODE: panel2 can't display requested resolution, aborted.\n"));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* CTRC functionality */
|
||||
/* Author:
|
||||
Rudolf Cornelissen 11/2002-2/2006
|
||||
Rudolf Cornelissen 11/2002-6/2009
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00040000
|
||||
@@ -217,7 +217,7 @@ status_t nv_crtc_set_timing(display_mode target)
|
||||
* wide horizontal stripes. This can be observed earliest on fullscreen overlay,
|
||||
* and if it gets worse, also normal desktop output will suffer. The stripes
|
||||
* are mainly visible at the left of the screen, over the entire screen height. */
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
LOG(2,("CRTC: DFP active: tuning modeline\n"));
|
||||
|
||||
@@ -410,10 +410,10 @@ status_t nv_crtc_set_timing(display_mode target)
|
||||
|
||||
/* disable CRTC slaved mode unless a panel is in use */
|
||||
// fixme: this kills TVout when it was in use...
|
||||
if (!si->ps.tmds1_active) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x7f));
|
||||
if (!(si->ps.monitors & CRTC1_TMDS)) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x7f));
|
||||
|
||||
/* setup flatpanel if connected and active */
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
uint32 iscale_x, iscale_y;
|
||||
|
||||
@@ -485,7 +485,7 @@ status_t nv_crtc_set_timing(display_mode target)
|
||||
* 1400 x 1050 (1.33). */
|
||||
/* NOTE:
|
||||
* allow 0.10 difference so 1280x1024 panels will be used fullscreen! */
|
||||
if ((iscale_x != (1 << 12)) && (si->ps.panel1_aspect > (dm_aspect + 0.10)))
|
||||
if ((iscale_x != (1 << 12)) && (si->ps.crtc1_aspect > (dm_aspect + 0.10)))
|
||||
{
|
||||
uint16 diff;
|
||||
|
||||
@@ -505,7 +505,7 @@ status_t nv_crtc_set_timing(display_mode target)
|
||||
/* correct for portrait panels... */
|
||||
/* NOTE:
|
||||
* allow 0.10 difference so 1280x1024 panels will be used fullscreen! */
|
||||
if ((iscale_y != (1 << 12)) && (si->ps.panel1_aspect < (dm_aspect - 0.10)))
|
||||
if ((iscale_y != (1 << 12)) && (si->ps.crtc1_aspect < (dm_aspect - 0.10)))
|
||||
{
|
||||
LOG(2,("CRTC: (relative) portrait panel: should tune vertical scaling\n"));
|
||||
/* fixme: implement if this kind of portrait panels exist on nVidia... */
|
||||
@@ -592,7 +592,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
/* end synchronous reset because display should be enabled */
|
||||
SEQW(RESET, 0x03);
|
||||
|
||||
if (do_panel && si->ps.tmds1_active)
|
||||
if (do_panel && (si->ps.monitors & CRTC1_TMDS))
|
||||
{
|
||||
if (!si->ps.laptop)
|
||||
{
|
||||
@@ -622,7 +622,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
{
|
||||
//fixme? linux only does this on dualhead cards...
|
||||
//fixme: see if LVDS head can be determined with two panels there...
|
||||
if (!si->ps.tmds2_active && (si->ps.card_type != NV11))
|
||||
if (!(si->ps.monitors & CRTC2_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* b2 = 0 = enable laptop panel backlight */
|
||||
/* note: this seems to be a write-only register. */
|
||||
@@ -640,7 +640,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
/* turn screen off */
|
||||
SEQW(CLKMODE, (temp | 0x20));
|
||||
|
||||
if (do_panel && si->ps.tmds1_active)
|
||||
if (do_panel && (si->ps.monitors & CRTC1_TMDS))
|
||||
{
|
||||
if (!si->ps.laptop)
|
||||
{
|
||||
@@ -665,7 +665,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
{
|
||||
//fixme? linux only does this on dualhead cards...
|
||||
//fixme: see if LVDS head can be determined with two panels there...
|
||||
if (!si->ps.tmds2_active && (si->ps.card_type != NV11))
|
||||
if (!(si->ps.monitors & CRTC2_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* b2 = 1 = disable laptop panel backlight */
|
||||
/* note: this seems to be a write-only register. */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* second CTRC functionality for GeForce cards */
|
||||
/* Author:
|
||||
Rudolf Cornelissen 11/2002-2/2006
|
||||
Rudolf Cornelissen 11/2002-6/2009
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00020000
|
||||
@@ -203,7 +203,7 @@ status_t nv_crtc2_set_timing(display_mode target)
|
||||
* wide horizontal stripes. This can be observed earliest on fullscreen overlay,
|
||||
* and if it gets worse, also normal desktop output will suffer. The stripes
|
||||
* are mainly visible at the left of the screen, over the entire screen height. */
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
LOG(2,("CRTC2: DFP active: tuning modeline\n"));
|
||||
|
||||
@@ -393,10 +393,10 @@ status_t nv_crtc2_set_timing(display_mode target)
|
||||
|
||||
/* disable CRTC slaved mode unless a panel is in use */
|
||||
// fixme: this kills TVout when it was in use...
|
||||
if (!si->ps.tmds2_active) CRTC2W(PIXEL, (CRTC2R(PIXEL) & 0x7f));
|
||||
if (!(si->ps.monitors & CRTC2_TMDS)) CRTC2W(PIXEL, (CRTC2R(PIXEL) & 0x7f));
|
||||
|
||||
/* setup flatpanel if connected and active */
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
uint32 iscale_x, iscale_y;
|
||||
|
||||
@@ -468,7 +468,7 @@ status_t nv_crtc2_set_timing(display_mode target)
|
||||
* 1400 x 1050 (1.33). */
|
||||
/* NOTE:
|
||||
* allow 0.10 difference so 1280x1024 panels will be used fullscreen! */
|
||||
if ((iscale_x != (1 << 12)) && (si->ps.panel2_aspect > (dm_aspect + 0.10)))
|
||||
if ((iscale_x != (1 << 12)) && (si->ps.crtc2_aspect > (dm_aspect + 0.10)))
|
||||
{
|
||||
uint16 diff;
|
||||
|
||||
@@ -488,7 +488,7 @@ status_t nv_crtc2_set_timing(display_mode target)
|
||||
/* correct for portrait panels... */
|
||||
/* NOTE:
|
||||
* allow 0.10 difference so 1280x1024 panels will be used fullscreen! */
|
||||
if ((iscale_y != (1 << 12)) && (si->ps.panel2_aspect < (dm_aspect - 0.10)))
|
||||
if ((iscale_y != (1 << 12)) && (si->ps.crtc2_aspect < (dm_aspect - 0.10)))
|
||||
{
|
||||
LOG(2,("CRTC2: (relative) portrait panel: should tune vertical scaling\n"));
|
||||
/* fixme: implement if this kind of portrait panels exist on nVidia... */
|
||||
@@ -575,7 +575,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
/* end synchronous reset because display should be enabled */
|
||||
SEQW(RESET, 0x03);
|
||||
|
||||
if (do_panel && si->ps.tmds2_active)
|
||||
if (do_panel && (si->ps.monitors & CRTC2_TMDS))
|
||||
{
|
||||
if (!si->ps.laptop)
|
||||
{
|
||||
@@ -604,7 +604,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
else
|
||||
{
|
||||
//fixme: see if LVDS head can be determined with two panels there...
|
||||
if (!si->ps.tmds1_active && (si->ps.card_type != NV11))
|
||||
if (!(si->ps.monitors & CRTC1_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* b2 = 0 = enable laptop panel backlight */
|
||||
/* note: this seems to be a write-only register. */
|
||||
@@ -622,7 +622,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
/* turn screen off */
|
||||
SEQW(CLKMODE, (temp | 0x20));
|
||||
|
||||
if (do_panel && si->ps.tmds2_active)
|
||||
if (do_panel && (si->ps.monitors & CRTC2_TMDS))
|
||||
{
|
||||
if (!si->ps.laptop)
|
||||
{
|
||||
@@ -646,7 +646,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
|
||||
else
|
||||
{
|
||||
//fixme: see if LVDS head can be determined with two panels there...
|
||||
if (!si->ps.tmds1_active && (si->ps.card_type != NV11))
|
||||
if (!(si->ps.monitors & CRTC1_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* b2 = 1 = disable laptop panel backlight */
|
||||
/* note: this seems to be a write-only register. */
|
||||
|
||||
@@ -158,7 +158,7 @@ status_t nv_dac_set_pix_pll(display_mode target)
|
||||
* note:
|
||||
* this assumes the cards BIOS correctly programmed the panel (is likely) */
|
||||
//fixme: when VESA DDC EDID stuff is implemented, this option can be deleted...
|
||||
if (si->ps.tmds1_active && !si->settings.pgm_panel)
|
||||
if ((si->ps.monitors & CRTC1_TMDS) && !si->settings.pgm_panel)
|
||||
{
|
||||
LOG(4,("DAC: Not programming DFP refresh (specified in nvidia.settings)\n"));
|
||||
|
||||
@@ -171,7 +171,7 @@ status_t nv_dac_set_pix_pll(display_mode target)
|
||||
/* fix a DVI or laptop flatpanel to 60Hz refresh! */
|
||||
/* Note:
|
||||
* The pixelclock drives the flatpanel modeline, not the CRTC modeline. */
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
LOG(4,("DAC: Fixing DFP refresh to 60Hz!\n"));
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ status_t nv_dac2_set_pix_pll(display_mode target)
|
||||
* note:
|
||||
* this assumes the cards BIOS correctly programmed the panel (is likely) */
|
||||
//fixme: when VESA DDC EDID stuff is implemented, this option can be deleted...
|
||||
if (si->ps.tmds2_active && !si->settings.pgm_panel)
|
||||
if ((si->ps.monitors & CRTC2_TMDS) && !si->settings.pgm_panel)
|
||||
{
|
||||
LOG(4,("DAC2: Not programming DFP refresh (specified in nvidia.settings)\n"));
|
||||
|
||||
@@ -174,7 +174,7 @@ status_t nv_dac2_set_pix_pll(display_mode target)
|
||||
/* fix a DVI or laptop flatpanel to 60Hz refresh! */
|
||||
/* Note:
|
||||
* The pixelclock drives the flatpanel modeline, not the CRTC modeline. */
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
LOG(4,("DAC2: Fixing DFP refresh to 60Hz!\n"));
|
||||
|
||||
|
||||
@@ -690,6 +690,8 @@ void i2c_DetectScreens(void)
|
||||
|
||||
si->ps.con1_screen.have_edid = false;
|
||||
si->ps.con2_screen.have_edid = false;
|
||||
si->ps.con1_screen.aspect = 0;
|
||||
si->ps.con2_screen.aspect = 0;
|
||||
|
||||
/* check existance of bus 0 */
|
||||
if (si->ps.i2c_bus0) {
|
||||
|
||||
@@ -2280,16 +2280,15 @@ static void detect_panels()
|
||||
/* do some presets */
|
||||
si->ps.p1_timing.h_display = 0;
|
||||
si->ps.p1_timing.v_display = 0;
|
||||
si->ps.panel1_aspect = 0;
|
||||
si->ps.crtc1_aspect = 0;
|
||||
si->ps.p2_timing.h_display = 0;
|
||||
si->ps.p2_timing.v_display = 0;
|
||||
si->ps.panel2_aspect = 0;
|
||||
si->ps.crtc2_aspect = 0;
|
||||
si->ps.slaved_tmds1 = false;
|
||||
si->ps.slaved_tmds2 = false;
|
||||
si->ps.master_tmds1 = false;
|
||||
si->ps.master_tmds2 = false;
|
||||
si->ps.tmds1_active = false;
|
||||
si->ps.tmds2_active = false;
|
||||
si->ps.monitors = 0x00;
|
||||
/* 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
|
||||
@@ -2322,7 +2321,7 @@ static void detect_panels()
|
||||
if ((width >= 640) && (height >= 480))
|
||||
{
|
||||
si->ps.slaved_tmds1 = true;
|
||||
si->ps.tmds1_active = true;
|
||||
si->ps.monitors |= CRTC1_TMDS;
|
||||
si->ps.p1_timing.h_display = width;
|
||||
si->ps.p1_timing.v_display = height;
|
||||
}
|
||||
@@ -2335,7 +2334,7 @@ static void detect_panels()
|
||||
if ((width >= 640) && (height >= 480))
|
||||
{
|
||||
si->ps.slaved_tmds2 = true;
|
||||
si->ps.tmds2_active = true;
|
||||
si->ps.monitors |= CRTC2_TMDS;
|
||||
si->ps.p2_timing.h_display = width;
|
||||
si->ps.p2_timing.v_display = height;
|
||||
}
|
||||
@@ -2349,7 +2348,7 @@ static void detect_panels()
|
||||
if ((width >= 640) && (height >= 480))
|
||||
{
|
||||
si->ps.master_tmds1 = true;
|
||||
si->ps.tmds1_active = true;
|
||||
si->ps.monitors |= CRTC1_TMDS;
|
||||
si->ps.p1_timing.h_display = width;
|
||||
si->ps.p1_timing.v_display = height;
|
||||
}
|
||||
@@ -2363,7 +2362,7 @@ static void detect_panels()
|
||||
if ((width >= 640) && (height >= 480))
|
||||
{
|
||||
si->ps.master_tmds2 = true;
|
||||
si->ps.tmds2_active = true;
|
||||
si->ps.monitors |= CRTC2_TMDS;
|
||||
si->ps.p2_timing.h_display = width;
|
||||
si->ps.p2_timing.v_display = height;
|
||||
}
|
||||
@@ -2372,7 +2371,8 @@ static void detect_panels()
|
||||
//fixme...:
|
||||
//we are assuming that no DVI is used as external monitor on laptops;
|
||||
//otherwise we probably get into trouble here if the checked specs match.
|
||||
if (si->ps.laptop && si->ps.tmds1_active && si->ps.tmds2_active &&
|
||||
if (si->ps.laptop &&
|
||||
((si->ps.monitors & (CRTC1_TMDS | CRTC2_TMDS)) == (CRTC1_TMDS | CRTC2_TMDS)) &&
|
||||
((DACR(FP_TG_CTRL) & 0x80000000) == (DAC2R(FP_TG_CTRL) & 0x80000000)) &&
|
||||
(si->ps.p1_timing.h_display == si->ps.p2_timing.h_display) &&
|
||||
(si->ps.p1_timing.v_display == si->ps.p2_timing.v_display))
|
||||
@@ -2384,7 +2384,7 @@ static void detect_panels()
|
||||
/* LVDS panel is _always_ on CRTC2, so clear false primary detection */
|
||||
si->ps.slaved_tmds1 = false;
|
||||
si->ps.master_tmds1 = false;
|
||||
si->ps.tmds1_active = false;
|
||||
si->ps.monitors &= ~CRTC1_TMDS;
|
||||
si->ps.p1_timing.h_display = 0;
|
||||
si->ps.p1_timing.v_display = 0;
|
||||
}
|
||||
@@ -2395,7 +2395,7 @@ static void detect_panels()
|
||||
/* LVDS panel is on CRTC2, so clear false primary detection */
|
||||
si->ps.slaved_tmds1 = false;
|
||||
si->ps.master_tmds1 = false;
|
||||
si->ps.tmds1_active = false;
|
||||
si->ps.monitors &= ~CRTC1_TMDS;
|
||||
si->ps.p1_timing.h_display = 0;
|
||||
si->ps.p1_timing.v_display = 0;
|
||||
}
|
||||
@@ -2404,7 +2404,7 @@ static void detect_panels()
|
||||
/* LVDS panel is on CRTC1, so clear false secondary detection */
|
||||
si->ps.slaved_tmds2 = false;
|
||||
si->ps.master_tmds2 = false;
|
||||
si->ps.tmds2_active = false;
|
||||
si->ps.monitors &= ~CRTC2_TMDS;
|
||||
si->ps.p2_timing.h_display = 0;
|
||||
si->ps.p2_timing.v_display = 0;
|
||||
}
|
||||
@@ -2412,13 +2412,13 @@ static void detect_panels()
|
||||
}
|
||||
|
||||
/* fetch panel(s) modeline(s) */
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
/* determine panel aspect ratio */
|
||||
si->ps.panel1_aspect =
|
||||
si->ps.crtc1_aspect =
|
||||
(si->ps.p1_timing.h_display / ((float)si->ps.p1_timing.v_display));
|
||||
/* force widescreen type if requested */
|
||||
if (si->settings.force_ws) si->ps.panel1_aspect = 1.60;
|
||||
if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60;
|
||||
/* horizontal timing */
|
||||
si->ps.p1_timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1;
|
||||
si->ps.p1_timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1;
|
||||
@@ -2438,13 +2438,13 @@ static void detect_panels()
|
||||
si->ps.p1_timing.pixel_clock =
|
||||
(si->ps.p1_timing.h_total * si->ps.p1_timing.v_total * 60) / 1000;
|
||||
}
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
/* determine panel aspect ratio */
|
||||
si->ps.panel2_aspect =
|
||||
si->ps.crtc2_aspect =
|
||||
(si->ps.p2_timing.h_display / ((float)si->ps.p2_timing.v_display));
|
||||
/* force widescreen type if requested */
|
||||
if (si->settings.force_ws) si->ps.panel2_aspect = 1.60;
|
||||
if (si->settings.force_ws) si->ps.crtc2_aspect = 1.60;
|
||||
/* horizontal timing */
|
||||
si->ps.p2_timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1;
|
||||
si->ps.p2_timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1;
|
||||
@@ -2533,7 +2533,7 @@ static void detect_panels()
|
||||
* but only after a failed VESA modeswitch by the HAIKU kernel
|
||||
* at boot time caused by a BIOS fault inside the gfx card: it says
|
||||
* it can do VESA 1280x1024x32 on CRTC1/DAC1 but it fails: no signal. */
|
||||
if (si->ps.tmds1_active && (si->ps.card_type != NV11))
|
||||
if ((si->ps.monitors & CRTC1_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* Read a indexed register to see if it indicates LVDS or TMDS panel presence.
|
||||
* b0-7 = adress, b16 = 1 = write_enable */
|
||||
@@ -2544,7 +2544,7 @@ static void detect_panels()
|
||||
else
|
||||
LOG(2,("INFO: Flatpanel on head 1 is TMDS type\n"));
|
||||
}
|
||||
if (si->ps.tmds2_active && (si->ps.card_type != NV11))
|
||||
if ((si->ps.monitors & CRTC2_TMDS) && (si->ps.card_type != NV11))
|
||||
{
|
||||
/* Read a indexed register to see if it indicates LVDS or TMDS panel presence.
|
||||
* b0-7 = adress, b16 = 1 = write_enable */
|
||||
@@ -2562,8 +2562,6 @@ static void detect_panels()
|
||||
static void setup_output_matrix()
|
||||
{
|
||||
/* setup defaults: */
|
||||
/* no monitors (output devices) detected */
|
||||
si->ps.monitors = 0x00;
|
||||
/* head 1 will be the primary head */
|
||||
si->ps.crtc2_prim = false;
|
||||
|
||||
@@ -2576,22 +2574,28 @@ static void setup_output_matrix()
|
||||
/* connect analog outputs straight through */
|
||||
nv_general_output_select(false);
|
||||
|
||||
/* presetup by the card's BIOS, we can't change this (lack of info) */
|
||||
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
|
||||
if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
|
||||
/* panels are pre-connected to a CRTC (1 or 2) by the card's BIOS,
|
||||
* we can't change this (lack of info) */
|
||||
|
||||
/* detect analog monitors. First try EDID, else use load sensing. */
|
||||
/* (load sensing is confirmed working OK on NV18, NV28 and NV34.) */
|
||||
/* primary connector: */
|
||||
if (si->ps.con1_screen.have_edid) {
|
||||
if (!si->ps.con1_screen.digital) si->ps.monitors |= 0x02;
|
||||
if (!si->ps.con1_screen.digital) {
|
||||
si->ps.monitors |= CRTC1_VGA;
|
||||
si->ps.crtc1_aspect = si->ps.con1_screen.aspect;
|
||||
}
|
||||
} else {
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA;
|
||||
}
|
||||
/* secondary connector */
|
||||
if (si->ps.con2_screen.have_edid) {
|
||||
if (!si->ps.con2_screen.digital) si->ps.monitors |= 0x20;
|
||||
if (!si->ps.con2_screen.digital) {
|
||||
si->ps.monitors |= CRTC2_VGA;
|
||||
si->ps.crtc2_aspect = si->ps.con2_screen.aspect;
|
||||
}
|
||||
} else {
|
||||
if (nv_dac2_crt_connected()) si->ps.monitors |= 0x20;
|
||||
if (nv_dac2_crt_connected()) si->ps.monitors |= CRTC2_VGA;
|
||||
}
|
||||
|
||||
/* setup correct output and head use */
|
||||
@@ -2619,6 +2623,9 @@ static void setup_output_matrix()
|
||||
LOG(2,("INFO: correcting...\n"));
|
||||
/* cross connect analog outputs so analog panel or CRT gets head 2 */
|
||||
nv_general_output_select(true);
|
||||
si->ps.monitors = 0x21;
|
||||
si->ps.crtc1_aspect = si->ps.con2_screen.aspect;
|
||||
si->ps.crtc2_aspect = si->ps.con1_screen.aspect;
|
||||
LOG(2,("INFO: head 1 has a digital panel;\n"));
|
||||
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
|
||||
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
|
||||
@@ -2641,6 +2648,9 @@ static void setup_output_matrix()
|
||||
LOG(2,("INFO: correcting...\n"));
|
||||
/* cross connect analog outputs so analog panel or CRT gets head 1 */
|
||||
nv_general_output_select(true);
|
||||
si->ps.monitors = 0x12;
|
||||
si->ps.crtc1_aspect = si->ps.con2_screen.aspect;
|
||||
si->ps.crtc2_aspect = si->ps.con1_screen.aspect;
|
||||
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
|
||||
LOG(2,("INFO: head 2 has a digital panel:\n"));
|
||||
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
|
||||
@@ -2696,16 +2706,16 @@ static void setup_output_matrix()
|
||||
/* confirmed no analog output switch-options for NV11 */
|
||||
LOG(2,("INFO: NV11 outputs are hardwired to be straight-through\n"));
|
||||
|
||||
/* presetup by the card's BIOS, we can't change this (lack of info) */
|
||||
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
|
||||
if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
|
||||
/* panels are pre-connected to a CRTC (1 or 2) by the card's BIOS,
|
||||
* we can't change this (lack of info) */
|
||||
|
||||
/* detect analog monitors. First try EDID, else use load sensing. */
|
||||
/* (load sensing is confirmed working OK on NV11.) */
|
||||
/* primary connector: */
|
||||
if (si->ps.con1_screen.have_edid) {
|
||||
if (!si->ps.con1_screen.digital) si->ps.monitors |= 0x02;
|
||||
if (!si->ps.con1_screen.digital) si->ps.monitors |= CRTC1_VGA;
|
||||
} else {
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA;
|
||||
}
|
||||
/* (sense analog monitor on secondary connector is impossible on NV11) */
|
||||
|
||||
@@ -2760,15 +2770,16 @@ static void setup_output_matrix()
|
||||
}
|
||||
else /* singlehead cards */
|
||||
{
|
||||
/* presetup by the card's BIOS, we can't change this (lack of info) */
|
||||
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
|
||||
/* panels are pre-setup by the card's BIOS,
|
||||
* we can't change this (lack of info) */
|
||||
|
||||
/* detect analog monitors. First try EDID, else use load sensing. */
|
||||
/* (load sensing is confirmed working OK on all cards.) */
|
||||
/* primary connector: */
|
||||
if (si->ps.con1_screen.have_edid) {
|
||||
if (!si->ps.con1_screen.digital) si->ps.monitors |= 0x02;
|
||||
if (!si->ps.con1_screen.digital) si->ps.monitors |= CRTC1_VGA;
|
||||
} else {
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
|
||||
if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA;
|
||||
}
|
||||
|
||||
//fixme? add TVout (only, so no CRT connected) support...
|
||||
@@ -2777,7 +2788,7 @@ static void setup_output_matrix()
|
||||
|
||||
void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
|
||||
{
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors |= CRTC1_TMDS)
|
||||
{
|
||||
/* timing ('modeline') */
|
||||
p1->timing = si->ps.p1_timing;
|
||||
@@ -2793,7 +2804,7 @@ void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
|
||||
else
|
||||
*pan1 = false;
|
||||
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors |= CRTC2_TMDS)
|
||||
{
|
||||
/* timing ('modeline') */
|
||||
p2->timing = si->ps.p2_timing;
|
||||
@@ -3300,19 +3311,19 @@ void dump_pins(void)
|
||||
LOG(2,("card memory_size: %3.3fMb\n", (si->ps.memory_size / (1024.0 * 1024.0))));
|
||||
LOG(2,("laptop: "));
|
||||
if (si->ps.laptop) LOG(2,("yes\n")); else LOG(2,("no\n"));
|
||||
if (si->ps.tmds1_active)
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
LOG(2,("found DFP (digital flatpanel) on CRTC1; CRTC1 is %s\n",
|
||||
si->ps.slaved_tmds1 ? "slaved" : "master"));
|
||||
LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
|
||||
si->ps.p1_timing.h_display, si->ps.p1_timing.v_display, si->ps.panel1_aspect));
|
||||
si->ps.p1_timing.h_display, si->ps.p1_timing.v_display, si->ps.crtc1_aspect));
|
||||
}
|
||||
if (si->ps.tmds2_active)
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
LOG(2,("found DFP (digital flatpanel) on CRTC2; CRTC2 is %s\n",
|
||||
si->ps.slaved_tmds2 ? "slaved" : "master"));
|
||||
LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
|
||||
si->ps.p2_timing.h_display, si->ps.p2_timing.v_display, si->ps.panel2_aspect));
|
||||
si->ps.p2_timing.h_display, si->ps.p2_timing.v_display, si->ps.crtc2_aspect));
|
||||
}
|
||||
LOG(2,("monitor (output devices) setup matrix: $%02x\n", si->ps.monitors));
|
||||
LOG(2,("INFO: end pinsdump.\n"));
|
||||
|
||||
Reference in New Issue
Block a user