diff --git a/headers/private/graphics/nvidia/DriverInterface.h b/headers/private/graphics/nvidia/DriverInterface.h index d116ae15eb..ae4e7c0dd0 100644 --- a/headers/private/graphics/nvidia/DriverInterface.h +++ b/headers/private/graphics/nvidia/DriverInterface.h @@ -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 */ diff --git a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c index 271bdfba5d..c04ecb6efd 100644 --- a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c @@ -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")); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index 02a5abed3c..39b225db73 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -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. */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c index 70871502b9..eded54f993 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c @@ -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. */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 04c0eb179d..8e987e9080 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -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")); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c index b3cde60523..555432db17 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c @@ -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")); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c index 870451125e..1badc8859b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c @@ -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) { diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index f3c2a903d4..3da717269d 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -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"));