From 63e909772d0bc5a81586c9e118195b46e8238bf1 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Tue, 23 Jun 2009 20:52:30 +0000 Subject: [PATCH] added DDC/EDID widescreen detection for analog connected screens. Switched off the force widescreen option so autodetection is actually used. This should fix non-ws DVI connected screens displaying black screens or shutting off on non-native modes. Bumped version to 0.93. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31213 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/nvidia/ProposeDisplayMode.c | 111 +++++++++--------- .../accelerants/nvidia/engine/nv_general.c | 4 +- .../accelerants/nvidia/engine/nv_info.c | 52 ++++++-- .../drivers/graphics/nvidia/README.html | 12 +- .../drivers/graphics/nvidia/UPDATE.html | 11 +- .../kernel/drivers/graphics/nvidia/driver.c | 4 +- .../drivers/graphics/nvidia/nvidia.settings | 4 +- 7 files changed, 117 insertions(+), 81 deletions(-) diff --git a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c index c04ecb6efd..7bca886fbb 100644 --- a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c @@ -19,6 +19,7 @@ /* 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... */ +//fixme: if EDID monitor found create list via common EDID code... static const display_mode mode_list[] = { /* 4:3 modes; 307.2k pixels */ { { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */ @@ -85,8 +86,10 @@ static const display_mode mode_list[] = { /* 16:10 panel mode; 2.304M pixels */ { { 193160, 1920, 2048, 2256, 2592, 1200, 1201, 1204, 1242, T_POSITIVE_SYNC}, B_CMAP8, 1920, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1920X1200) */ //{ { 160000, 1920, 2010, 2060, 2110, 1200, 1202, 1208, 1235, T_POSITIVE_SYNC}, B_CMAP8, 1920, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1920X1200) */ -/* 16:9 panel mode; 1280x720 */ +/* 16:9 panel mode; 1280x720 (HDTV 1280x720p) */ { { 74520, 1280, 1368, 1424, 1656, 720, 724, 730, 750, T_POSITIVE_SYNC}, B_CMAP8, 1280, 720, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X720) */ +/* fixme, add: 16:9 panel mode; 1366x768 (HDTV '1280x720p') */ +/* fixme, add: 16:9 panel mode; 1920x1080 (HDTV 1920x1080p) */ }; @@ -140,86 +143,82 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa /* disable aspect checks for a requested TVout mode when mode is TVout capable */ if (!si->ps.tvout || !(BT_check_tvmode(*target) && (target->flags & TV_BITS))) { - /* check if all connected output devices can display the requested mode's aspect: */ + /* check if all connected output devices can display the requested mode's aspect. + * assuming 16:10 screens can display non-WS modes, but cannot (correctly) display 16:9 modes; + * assuming 16:9 screens can display non-WS modes, and can display 16:10 modes. */ /* calculate display mode aspect */ target_aspect = (target->timing.h_display / ((float)target->timing.v_display)); /* NOTE: * allow 0.10 difference so 5:4 aspect panels will be able to use 4:3 aspect modes! */ switch (si->ps.monitors) { - 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 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 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) */ + case 0: /* no monitor found at all */ + /* if forcing widescreen type was requested don't block mode */ if (target_aspect > 1.34 && !si->settings.force_ws) { LOG(4, ("PROPOSEMODE: not all output devices can display widescreen modes, aborted.\n")); return B_ERROR; } break; - } - - /* only export widescreen panel-TV modes when an exact resolution match exists, - * to prevent the modelist from becoming too crowded */ - if (target_aspect > 1.61 && !si->settings.force_ws) { - status_t panel_TV_stat = B_ERROR; - - 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.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; - } - if (panel_TV_stat != B_OK) { - LOG(4, ("PROPOSEMODE: WS panel_TV mode requested but no such TV here, aborted.\n")); - return B_ERROR; - } + case CRTC1_TMDS: /* digital panel on head 1, nothing on head 2 */ + case CRTC1_VGA: /* analog connected screen on head 1, nothing on head 2 */ + if (si->ps.crtc1_aspect < (target_aspect - 0.10)) { + LOG(4, ("PROPOSEMODE: screen at crtc1 is not widescreen type, aborted.\n")); + return B_ERROR; + } + break; + case CRTC2_TMDS: /* nothing on head 1, digital panel on head 2 */ + case CRTC2_VGA: /* analog connected screen on head 2, nothing on head 1 */ + if (si->ps.crtc2_aspect < (target_aspect - 0.10)) { + LOG(4, ("PROPOSEMODE: screen at crtc2 is not widescreen type, aborted.\n")); + return B_ERROR; + } + break; + case CRTC1_TMDS | CRTC2_TMDS: /* digital panels on both heads */ + case CRTC1_VGA | CRTC2_VGA: /* analog connected screens on both heads */ + case CRTC1_TMDS | CRTC2_VGA: /* digital panel on head 1, analog connected screen on head 2 */ + case CRTC1_VGA | CRTC2_TMDS: /* analog connected screen on head 1, digital panel on head 2 */ + default: /* more than two screens connected (illegal setup) */ + if ((si->ps.crtc1_aspect < (target_aspect - 0.10)) || + (si->ps.crtc2_aspect < (target_aspect - 0.10))) { + LOG(4, ("PROPOSEMODE: not all connected screens are widescreen type, aborted.\n")); + return B_ERROR; + } + break; } } - /* check if panel(s) can display the requested resolution (if connected) */ + /* check if screen(s) can display the requested resolution (if connected) */ 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")); + LOG(4, ("PROPOSEMODE: panel at crtc11 can't display requested resolution, aborted.\n")); return B_ERROR; } } 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")); + LOG(4, ("PROPOSEMODE: panel at crtc2 can't display requested resolution, aborted.\n")); return B_ERROR; } } +//still expand/update concerning edid, among others.. (setup accounting for cross-connected vga screens...): +/* + if (si->ps.monitors & CRTC1_VGA) { + if (target->timing.h_display > si->ps.xxx_timing.h_display + || target->timing.v_display > si->ps.xxx_timing.v_display) { + LOG(4, ("PROPOSEMODE: analog screen at crtc1 can't display requested resolution, aborted.\n")); + return B_ERROR; + } + } + if (si->ps.monitors & CRTC2_VGA) { + if (target->timing.h_display > si->ps.yyy_timing.h_display + || target->timing.v_display > si->ps.yyy_timing.v_display) { + LOG(4, ("PROPOSEMODE: analog screen at crtc2 can't display requested resolution, aborted.\n")); + return B_ERROR; + } + } +*/ +//end still update. /* validate display vs. virtual */ if (target->timing.h_display > target->virtual_width || want_same_width) diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index a836257870..28449b71a8 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -1,7 +1,7 @@ /* Authors: Mark Watson 12/1999, Apsed, - Rudolf Cornelissen 10/2002-5/2009 + Rudolf Cornelissen 10/2002-6/2009 tst.. */ @@ -92,7 +92,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: Haiku nVidia Accelerant 0.92 running.\n")); + LOG(1,("POWERUP: Haiku nVidia Accelerant 0.93 running.\n")); /* log VBLANK INT usability status */ if (si->ps.int_assigned) diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index fab630710d..3638120cc1 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -2191,7 +2191,7 @@ void fake_panel_start(void) /* 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: inverting head use (specified in settings file)\n")); + LOG(2,("INFO: inverting head use (specified in nvidia.settings file)\n")); si->ps.crtc2_prim = !si->ps.crtc2_prim; } } @@ -2584,18 +2584,34 @@ static void setup_output_matrix() if (!si->ps.con1_screen.digital) { si->ps.monitors |= CRTC1_VGA; si->ps.crtc1_aspect = si->ps.con1_screen.aspect; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; } } else { - if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA; + if (nv_dac_crt_connected()) { + si->ps.monitors |= CRTC1_VGA; + /* assume 4:3 monitor */ + si->ps.crtc1_aspect = 1.33; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; + } } /* secondary connector */ if (si->ps.con2_screen.have_edid) { if (!si->ps.con2_screen.digital) { si->ps.monitors |= CRTC2_VGA; si->ps.crtc2_aspect = si->ps.con2_screen.aspect; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc2_aspect = 1.60; } } else { - if (nv_dac2_crt_connected()) si->ps.monitors |= CRTC2_VGA; + if (nv_dac2_crt_connected()) { + si->ps.monitors |= CRTC2_VGA; + /* assume 4:3 monitor */ + si->ps.crtc2_aspect = 1.33; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc2_aspect = 1.60; + } } /* setup correct output and head use */ @@ -2713,9 +2729,20 @@ static void setup_output_matrix() /* (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 |= CRTC1_VGA; + if (!si->ps.con1_screen.digital) { + si->ps.monitors |= CRTC1_VGA; + si->ps.crtc1_aspect = si->ps.con1_screen.aspect; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; + } } else { - if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA; + if (nv_dac_crt_connected()) { + si->ps.monitors |= CRTC1_VGA; + /* assume 4:3 monitor */ + si->ps.crtc1_aspect = 1.33; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; + } } /* (sense analog monitor on secondary connector is impossible on NV11) */ @@ -2777,9 +2804,20 @@ static void setup_output_matrix() /* (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 |= CRTC1_VGA; + if (!si->ps.con1_screen.digital) { + si->ps.monitors |= CRTC1_VGA; + si->ps.crtc1_aspect = si->ps.con1_screen.aspect; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; + } } else { - if (nv_dac_crt_connected()) si->ps.monitors |= CRTC1_VGA; + if (nv_dac_crt_connected()) { + si->ps.monitors |= CRTC1_VGA; + /* assume 4:3 monitor */ + si->ps.crtc1_aspect = 1.33; + /* force widescreen type if requested */ + if (si->settings.force_ws) si->ps.crtc1_aspect = 1.60; + } } //fixme? add TVout (only, so no CRT connected) support... diff --git a/src/add-ons/kernel/drivers/graphics/nvidia/README.html b/src/add-ons/kernel/drivers/graphics/nvidia/README.html index 88d6d0dd97..60066dfaee 100644 --- a/src/add-ons/kernel/drivers/graphics/nvidia/README.html +++ b/src/add-ons/kernel/drivers/graphics/nvidia/README.html @@ -53,7 +53,7 @@ Geforce 8xxx and later series cards (NV50, G80, also known as GPGPU, general pur
  • If the driver still seems to create 'random' trouble make sure you have a fully functional VGA BIOS, or system BIOS for embedded cards (check for updates on the manufacturor's site). Make sure you mail me if you still have trouble but also if this version fixed that!
  • If on a laptop the internal panel doesn't work when you connect an external monitor, make sure you set 'output device selection' to 'internal' (instead of 'auto') in the system BIOS if it has such an option. If you have this symptom on a normal card, or on a laptop without that BIOS option then you are probably out of luck for dualhead support;
  • NV40 architecture cards: (GeForce 6xxx, but 6800 AGP seems to be OK)
    - Secondary analog monitor detection doesn't work and we can't control very well to which connector the card's output gets routed (lack of specs). This means you might have to experiment a bit with the way you connect your monitor to the card. A single analog or DVI screen should work OK, and two analog screens should be OK as well. + Secondary analog monitor load detection doesn't work and we can't control very well to which connector the card's output gets routed (lack of specs). This means you might have to experiment a bit with the way you connect your monitor to the card. A single analog or DVI screen should work OK, and two analog screens should be OK as well.

    @@ -229,11 +229,9 @@ If you select force_sync false the driver's 3D accelerant will
  • force_ws:
    This option (if enabled) overrules the aspect ratio detection for screens inside the driver. When set to true it forces all monitors to be treated as widescreen types.
  • primary: (set to disabled by default)
    Primary lets you force a certain card to be used as primary card in your system if you have multiple graphics cards installed: so it will display your desktop. To enable this (hack) feature uncomment this item and fill in the exact name of the card that is to be primary (as exported by the kerneldriver in /dev/graphics/). If you are going to select a card other than the one displaying your system's POST messages at bootup, make sure you also set 'usebios false' as otherwise the card(s) aren't coldstarted by the driver.
    @@ -255,6 +253,6 @@ The acceleration engine is disabled.

    Rudolf Cornelissen. -

    (Page last updated on May 1, 2009)

    +

    (Page last updated on June 23, 2009)

    diff --git a/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html b/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html index 4f4686e2f5..043c4ff00e 100644 --- a/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html +++ b/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html @@ -4,7 +4,7 @@

    Changes done for each driverversion:

    -

    head (SVN 0.91, Rudolf)

    +

    head (SVN 0.93, Rudolf)

    nv_driver 0.80 (Rudolf)