diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index d2ae0f12de..3de4ae8d3d 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -241,22 +241,59 @@ status_t nv_crtc_set_timing(display_mode target) /* (interlace is supported on upto and including NV10, NV15, and NV30 and up) */ CRTCW(INTERLACE, 0xff); - /* setup flatpanel scaling if needed */ - //fixme: unlock registers and/or setup chksum?!? doesn't work yet :-/ + /* setup flatpanel if connected and active */ if (si->ps.tmds1_active) { uint32 iscale_x, iscale_y; //fixme: checkout upscaling and aspect!!! - iscale_x = ((4096 * target.timing.h_display) / si->ps.panel1_width); - iscale_y = ((4096 * target.timing.v_display) / si->ps.panel1_height); - DACW(FP_DEBUG3, (iscale_x & 0x00001fff) | ((iscale_y & 0x00001fff) << 16)); + /* calculate needed inverse scaling factors in 20.12 format */ + iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.panel1_width); + iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.panel1_height); - /* limit last fetched line if vertical scaling is done */ - if (iscale_y != 4096) - DACW(FP_DEBUG2, ((1 << 28) | ((target.timing.v_display - 1) << 16))); - else + /* unblock flatpanel timing programming (or something like that..) */ + CRTCW(FP_HTIMING, 0); + CRTCW(FP_VTIMING, 0); + + /* nVidia cards only support upscaling: NV11 can't scale at all */ + if ((si->ps.card_arch == NV11) || + (iscale_x > (1 << 12)) || (iscale_y > (1 << 12))) + { + LOG(2,("CRTC: DFP needs to do scaling\n")); + + /* disable last fetched line limiting */ DACW(FP_DEBUG2, 0x00000000); + /* inform panel to scale */ + DACW(FP_TG_CTRL, (DACR(FP_TG_CTRL) | 0x00000100)); + } + else + { + LOG(2,("CRTC: GPU scales if needed\n")); + + /* GPU scaling is automatically setup by hardware */ +//fixme: checkout non 4:3 aspect scaling. +// DACW(FP_DEBUG3, (iscale_x & 0x00001fff) | ((iscale_y & 0x00001fff) << 16)); +// temp = (((iscale_x >> 1) & 0x00000fff) | (((iscale_y >> 1) & 0x00000fff) << 16)); +// DACW(FP_DEBUG1, (temp | (1 << 12) | (1 << 28))); + + /* limit last fetched line if vertical scaling is done */ + if (iscale_y != (1 << 12)) + DACW(FP_DEBUG2, ((1 << 28) | ((target.timing.v_display - 1) << 16))); +//not needed apparantly: +// ((1 << 12) | ((target.timing.h_display - 1) << 0))); + else + DACW(FP_DEBUG2, 0x00000000); + + /* inform panel not to scale */ + DACW(FP_TG_CTRL, (DACR(FP_TG_CTRL) & 0xfffffeff)); + } + + /* do some logging.. */ + LOG(2,("CRTC: FP_DEBUG0 reg readback: $%08x\n", DACR(FP_DEBUG0))); + LOG(2,("CRTC: FP_DEBUG1 reg readback: $%08x\n", DACR(FP_DEBUG1))); + LOG(2,("CRTC: FP_DEBUG2 reg readback: $%08x\n", DACR(FP_DEBUG2))); + LOG(2,("CRTC: FP_DEBUG3 reg readback: $%08x\n", DACR(FP_DEBUG3))); + LOG(2,("CRTC: FP_TG_CTRL reg readback: $%08x\n", DACR(FP_TG_CTRL))); } return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c index 7ece4c6016..53915e006e 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c @@ -223,22 +223,59 @@ status_t nv_crtc2_set_timing(display_mode target) /* (interlace is supported on upto and including NV10, NV15, and NV30 and up) */ CRTC2W(INTERLACE, 0xff); - /* setup flatpanel scaling if needed */ - //fixme: unlock registers and/or setup chksum?!? doesn't work yet :-/ + /* setup flatpanel if connected and active */ if (si->ps.tmds2_active) { uint32 iscale_x, iscale_y; //fixme: checkout upscaling and aspect!!! - iscale_x = ((4096 * target.timing.h_display) / si->ps.panel2_width); - iscale_y = ((4096 * target.timing.v_display) / si->ps.panel2_height); - DAC2W(FP_DEBUG3, (iscale_x & 0x00001fff) | ((iscale_y & 0x00001fff) << 16)); + /* calculate needed inverse scaling factors in 20.12 format */ + iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.panel2_width); + iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.panel2_height); - /* limit last fetched line if vertical scaling is done */ - if (iscale_y != 4096) - DAC2W(FP_DEBUG2, ((1 << 28) | ((target.timing.v_display - 1) << 16))); - else + /* unblock flatpanel timing programming (or something like that..) */ + CRTC2W(FP_HTIMING, 0); + CRTC2W(FP_VTIMING, 0); + + /* nVidia cards only support upscaling: NV11 can't scale at all */ + if ((si->ps.card_arch == NV11) || + (iscale_x > (1 << 12)) || (iscale_y > (1 << 12))) + { + LOG(2,("CRTC2: DFP needs to do scaling\n")); + + /* disable last fetched line limiting */ DAC2W(FP_DEBUG2, 0x00000000); + /* inform panel to scale */ + DAC2W(FP_TG_CTRL, (DAC2R(FP_TG_CTRL) | 0x00000100)); + } + else + { + LOG(2,("CRTC2: GPU scales if needed\n")); + + /* GPU scaling is automatically setup by hardware */ +//fixme: checkout non 4:3 aspect scaling. +// DAC2W(FP_DEBUG3, (iscale_x & 0x00001fff) | ((iscale_y & 0x00001fff) << 16)); +// temp = (((iscale_x >> 1) & 0x00000fff) | (((iscale_y >> 1) & 0x00000fff) << 16)); +// DAC2W(FP_DEBUG1, (temp | (1 << 12) | (1 << 28))); + + /* limit last fetched line if vertical scaling is done */ + if (iscale_y != (1 << 12)) + DAC2W(FP_DEBUG2, ((1 << 28) | ((target.timing.v_display - 1) << 16))); +//not needed apparantly: +// ((1 << 12) | ((target.timing.h_display - 1) << 0))); + else + DAC2W(FP_DEBUG2, 0x00000000); + + /* inform panel not to scale */ + DAC2W(FP_TG_CTRL, (DAC2R(FP_TG_CTRL) & 0xfffffeff)); + } + + /* do some logging.. */ + LOG(2,("CRTC2: FP_DEBUG0 reg readback: $%08x\n", DAC2R(FP_DEBUG0))); + LOG(2,("CRTC2: FP_DEBUG1 reg readback: $%08x\n", DAC2R(FP_DEBUG1))); + LOG(2,("CRTC2: FP_DEBUG2 reg readback: $%08x\n", DAC2R(FP_DEBUG2))); + LOG(2,("CRTC2: FP_DEBUG3 reg readback: $%08x\n", DAC2R(FP_DEBUG3))); + LOG(2,("CRTC2: FP_TG_CTRL reg readback: $%08x\n", DAC2R(FP_TG_CTRL))); } return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index 1932c0a248..72452fb7d0 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -310,6 +310,8 @@ static void detect_panels() * relying on the cards BIOS to do it. This adds TVout options where panels * are used! * Currently we'd loose the panel setup while not being able to restore it. */ + /* Note: + * NV11 cards can't distinquish between head 1 and head 2. */ if (slaved_for_dev1 && !tvout1) { uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1); @@ -322,7 +324,8 @@ static void detect_panels() si->ps.panel1_height = height; } } - if (si->ps.secondary_head && slaved_for_dev2 && !tvout2) + if ((si->ps.card_arch != NV11) && + si->ps.secondary_head && slaved_for_dev2 && !tvout2) { uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1); uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1); @@ -346,7 +349,8 @@ static void detect_panels() si->ps.panel1_height = height; } } - if (si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2) + if ((si->ps.card_arch != NV11) && + si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2) { uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1); uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);