diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 368c173873..f2b836055b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -1,6 +1,6 @@ /* program the DAC */ /* Author: - Rudolf Cornelissen 12/2003-3/2004 + Rudolf Cornelissen 12/2003-4/2004 */ #define MODULE_BIT 0x00010000 @@ -18,7 +18,6 @@ bool nv_dac_crt_connected(void) uint32 output, dac; bool present; -//fixme? checkout NV11... /* save output connector setting */ output = DACR(OUTPUT); /* save DAC state */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c index 50413fd701..09b5a48456 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c @@ -1,6 +1,6 @@ /* program the secondary DAC */ /* Author: - Rudolf Cornelissen 12/2003-3/2004 + Rudolf Cornelissen 12/2003-4/2004 */ #define MODULE_BIT 0x00001000 @@ -16,7 +16,9 @@ bool nv_dac2_crt_connected() uint32 output, dac; bool present; -//fixme? checkout NV11... + /* NOTE: + * NV11 can't do this: It will report DAC1 status instead. */ + /* save output connector setting */ output = DAC2R(OUTPUT); /* save DAC state */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index 66b9a86ed2..372adb86d7 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -80,7 +80,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-14 running.\n")); + LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-15 running.\n")); /* preset no laptop */ si->ps.laptop = false; @@ -882,8 +882,7 @@ status_t nv_general_output_select(bool cross) /* make sure this call is warranted */ if (si->ps.secondary_head) { - /* NV11 cards can't switch heads; we lack info to switch heads via outputs - * if flatpanels are used */ + /* NV11 cards can't switch heads (confirmed) */ if (si->ps.card_type != NV11) { if (cross) @@ -892,7 +891,7 @@ status_t nv_general_output_select(bool cross) /* enable head 2 on connector 1 */ /* (b8 = select CRTC (head) for output, - * b4 = enable DVI???, + * b4 = ??? (confirmed not to be a FP switch), * b0 = enable CRT) */ DACW(OUTPUT, 0x00000101); /* enable head 1 on connector 2 */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index d9960ec398..18386fae94 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -9,6 +9,7 @@ #include "nv_std.h" static void detect_panels(void); +static void setup_output_matrix(void); static void pinsnv4_fake(void); static void pinsnv5_nv5m64_fake(void); static void pinsnv6_fake(void); @@ -246,71 +247,13 @@ void fake_pins(void) /* find out the BIOS preprogrammed panel use status... */ detect_panels(); -//in progress! - if (si->ps.secondary_head) - { - if (si->ps.card_type != NV11) - { - uint8 monitors = 0x00; - - /* presetup by the card's BIOS, we can't change this (lack of info) */ - if (si->ps.tmds1_active) monitors |= 0x01; - if (si->ps.tmds2_active) monitors |= 0x02; -//fixme: checkout NV25, NV18, NV11... NV34 must use DAC _and_ DAC2 for det. - /* connect analog outputs straight through */ - nv_general_output_select(false); - /* sense analog monitor on primary connector */ - if (nv_dac_crt_connected()) monitors |= 0x04; - /* cross connect analog outputs */ - nv_general_output_select(true); - /* sense analog monitor on secondary connector */ - if (nv_dac_crt_connected()) monitors |= 0x08; - /* re-connect analog outputs straight through */ - nv_general_output_select(false); - -//fixme! two monitors on one DAC _can_ happen!!! (switch analog outputs then!) - switch (monitors) - { - case 0x01: /* digital panel on DAC1, nothing on DAC2 */ - case 0x04: /* analog panel or CRT on DAC1, nothing on DAC2 */ - case 0x05: /* both types on DAC1, nothing on DAC2 (shouldn't happen) */ - LOG(2,("INFO: head 1 has a monitor only: defaulting to head 1 use\n")); - break; - case 0x02: /* digital panel on DAC2, nothing on DAC1 */ - case 0x08: /* analog panel or CRT on DAC2, nothing on DAC1 */ - case 0x0a: /* both types on DAC2, nothing on DAC1 (shouldn't happen) */ - LOG(2,("INFO: head 2 has a monitor only: defaulting to head 2 use\n")); - si->ps.crtc2_prim = true; - break; - default: /* monitors found on both DACs, or nothing found at all */ - LOG(2,("INFO: head 2 has a monitor only: defaulting to head 2 use\n")); - break; - } - } - else - { - LOG(4,("INFO: NV11 outputs are hardwired to be straight-through\n")); - } - } -// - -//fixme: remove.. - /* 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; - } - } -*/ + /* determine and setup output devices and heads */ + setup_output_matrix(); /* select other CRTC for primary head use if specified by user in settings file */ if (si->ps.secondary_head && si->settings.switchhead) { - LOG(2,("INFO: switching CRTC's (specified in settings file)\n")); + LOG(2,("INFO: inverting head use (specified in settings file)\n")); si->ps.crtc2_prim = !si->ps.crtc2_prim; } } @@ -384,7 +327,6 @@ static void detect_panels() si->ps.master_tmds2 = false; si->ps.tmds1_active = false; si->ps.tmds2_active = false; - si->ps.crtc2_prim = false; /* determine the situation we are in... (regarding flatpanels) */ /* fixme: add VESA DDC EDID stuff one day... */ /* fixme: find out how to program those transmitters one day instead of @@ -495,14 +437,6 @@ static void detect_panels() if (si->ps.tmds2_active) si->ps.panel2_aspect = (si->ps.panel2_width / ((float)si->ps.panel2_height)); - /* if one panel is detected, and it's on the secondary head on dualhead cards, - * we use that head as primary head */ - if (si->ps.secondary_head && si->ps.tmds2_active && !si->ps.tmds1_active) - { - LOG(2,("INFO: CRTC2 has a panel only: defaulting to CRTC2 for primary use\n")); - si->ps.crtc2_prim = true; - } - /* dump some panel configuration registers... */ LOG(2,("INFO: Dumping flatpanel registers:\n")); LOG(2,("DAC1: FP_HDISPEND: %d\n", DACR(FP_HDISPEND))); @@ -562,6 +496,145 @@ static void detect_panels() LOG(2,("INFO: End flatpanel registers dump.\n")); } +//fixme: in progress!! +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; + + /* setup output devices and heads */ + if (si->ps.secondary_head) + { + if (si->ps.card_type != NV11) + { + /* setup defaults: */ + /* 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; + /* detect analog monitors (confirmed working OK on NV18, NV28 and NV34): */ + /* sense analog monitor on primary connector */ + if (nv_dac_crt_connected()) si->ps.monitors |= 0x02; + /* sense analog monitor on secondary connector */ + if (nv_dac2_crt_connected()) si->ps.monitors |= 0x20; + + /* setup correct output and head use */ + //fixme? add TVout (only, so no CRT(s) connected) support... + switch (si->ps.monitors) + { + case 0x00: /* no monitor found at all */ + LOG(2,("INFO: head 1 has nothing connected;\n")); + LOG(2,("INFO: head 2 has nothing connected:\n")); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + case 0x01: /* digital panel on head 1, nothing on head 2 */ + LOG(2,("INFO: head 1 has a digital panel;\n")); + LOG(2,("INFO: head 2 has nothing connected:\n")); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */ + LOG(2,("INFO: head 1 has an analog panel or CRT;\n")); + LOG(2,("INFO: head 2 has nothing connected:\n")); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + case 0x03: /* both types on head 1, nothing on head 2 */ + LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n")); + LOG(2,("INFO: head 2 has nothing connected:\n")); + LOG(2,("INFO: correcting...\n")); + /* cross connect analog outputs so analog panel or CRT gets head 2 */ + nv_general_output_select(true); + 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")); + break; + case 0x10: /* nothing on head 1, digital panel on head 2 */ + LOG(2,("INFO: head 1 has nothing connected;\n")); + LOG(2,("INFO: head 2 has a digital panel:\n")); + LOG(2,("INFO: defaulting to head 2 for primary use.\n")); + si->ps.crtc2_prim = true; + break; + case 0x20: /* nothing on head 1, analog panel or CRT on head 2 */ + LOG(2,("INFO: head 1 has nothing connected;\n")); + LOG(2,("INFO: head 2 has an analog panel or CRT:\n")); + LOG(2,("INFO: defaulting to head 2 for primary use.\n")); + si->ps.crtc2_prim = true; + break; + case 0x30: /* nothing on head 1, both types on head 2 */ + LOG(2,("INFO: head 1 has nothing connected;\n")); + LOG(2,("INFO: head 2 has a digital panel AND an analog panel or CRT:\n")); + LOG(2,("INFO: correcting...\n")); + /* cross connect analog outputs so analog panel or CRT gets head 1 */ + nv_general_output_select(true); + 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")); + si->ps.crtc2_prim = true; + break; + case 0x11: /* digital panels on both heads */ + LOG(2,("INFO: head 1 has a digital panel;\n")); + LOG(2,("INFO: head 2 has a digital panel:\n")); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */ + 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")); + si->ps.crtc2_prim = true; + break; + case 0x21: /* digital panel on head 1, analog panel or CRT on head 2 */ + 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")); + break; + case 0x22: /* analog panel(s) or CRT(s) on both heads */ + LOG(2,("INFO: head 1 has an analog panel or CRT;\n")); + LOG(2,("INFO: head 2 has an analog panel or CRT:\n")); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + default: /* more than two monitors connected to just two outputs: illegal! */ + LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors)); + LOG(2,("INFO: defaulting to head 1 for primary use.\n")); + break; + } + } + else /* dualhead NV11 cards */ + { + /* 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; + /* detect analog monitor (confirmed working OK on NV11): */ + /* sense analog monitor on primary connector */ + if (nv_dac_crt_connected()) si->ps.monitors |= 0x02; + /* (sense analog monitor on secondary connector is impossible on NV11) */ + + /* setup correct output and head use */ + //fixme? add TVout (only, so no CRT(s) connected) support... + switch (si->ps.monitors) + { + //fixme: add/setup NV11 matrix use!!! + } + } + } + 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; + /* detect analog monitor (confirmed working OK on all cards): */ + /* sense analog monitor on primary connector */ + if (nv_dac_crt_connected()) si->ps.monitors |= 0x02; + + //fixme? add TVout (only, so no CRT connected) support... + } +} + void get_panel_modelines(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2) { if (si->ps.tmds1_active) @@ -1080,5 +1153,6 @@ void dump_pins(void) LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n", si->ps.panel2_width, si->ps.panel2_height, si->ps.panel2_aspect)); } + LOG(2,("monitor (output devices) setup matrix: $%02x\n", si->ps.monitors)); LOG(2,("INFO: end pinsdump.\n")); }