From 19e5e222eeff7245ac15ebd7b733dfe0c2137457 Mon Sep 17 00:00:00 2001
From: Rudolf Cornelissen
Date: Wed, 16 Sep 2009 08:24:30 +0000
Subject: [PATCH] improved modeline scaling for digitally connected screens.
This fixes shifted output on screen mostly happening on 640x480 resolution,
due to missing CRTC SYNC pulses (ticket #4442). Bumped version to 1.04.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33150 a95241bf-73f2-0310-859d-f6bbb57e9c96
---
.../accelerants/nvidia/engine/nv_crtc.c | 30 ++++++++++++++++++-
.../accelerants/nvidia/engine/nv_crtc2.c | 30 ++++++++++++++++++-
.../accelerants/nvidia/engine/nv_general.c | 2 +-
.../drivers/graphics/nvidia/UPDATE.html | 6 ++--
4 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c
index 3d724960ad..b291a77517 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-6/2009
+ Rudolf Cornelissen 11/2002-9/2009
*/
#define MODULE_BIT 0x00040000
@@ -246,10 +246,24 @@ status_t nv_crtc_set_timing(display_mode target)
target.timing.h_total -= 32;
}
+ /* assure sync pulse is at the correct timing position */
if (target.timing.h_sync_start == target.timing.h_display)
target.timing.h_sync_start += 8;
if (target.timing.h_sync_end == target.timing.h_total)
target.timing.h_sync_end -= 8;
+ /* assure we (still) have a sync pulse */
+ if (target.timing.h_sync_start == target.timing.h_sync_end) {
+ if (target.timing.h_sync_end < (target.timing.h_total - 8)) {
+ target.timing.h_sync_end += 8;
+ } else {
+ if (target.timing.h_sync_start > (target.timing.h_display + 8)) {
+ target.timing.h_sync_start -= 8;
+ } else {
+ LOG(2,("CRTC: tuning modeline, not enough room for Hsync pulse, forcing it anyway..\n"));
+ target.timing.h_sync_start -= 8;
+ }
+ }
+ }
/* vertical timing */
target.timing.v_sync_start =
@@ -264,10 +278,24 @@ status_t nv_crtc_set_timing(display_mode target)
((uint16)((si->ps.p1_timing.v_total / ((float)si->ps.p1_timing.v_display)) *
target.timing.v_display)) - 1;
+ /* assure sync pulse is at the correct timing position */
if (target.timing.v_sync_start == target.timing.v_display)
target.timing.v_sync_start += 1;
if (target.timing.v_sync_end == target.timing.v_total)
target.timing.v_sync_end -= 1;
+ /* assure we (still) have a sync pulse */
+ if (target.timing.v_sync_start == target.timing.v_sync_end) {
+ if (target.timing.v_sync_end < (target.timing.v_total - 1)) {
+ target.timing.v_sync_end += 1;
+ } else {
+ if (target.timing.v_sync_start > (target.timing.v_display + 1)) {
+ target.timing.v_sync_start -= 1;
+ } else {
+ LOG(2,("CRTC: tuning modeline, not enough room for Vsync pulse, forcing it anyway..\n"));
+ target.timing.v_sync_start -= 1;
+ }
+ }
+ }
/* disable GPU scaling testmode so automatic scaling will be done */
DACW(FP_DEBUG1, 0);
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c
index 223ab70f76..9f74784f37 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-6/2009
+ Rudolf Cornelissen 11/2002-9/2009
*/
#define MODULE_BIT 0x00020000
@@ -232,10 +232,24 @@ status_t nv_crtc2_set_timing(display_mode target)
target.timing.h_total -= 32;
}
+ /* assure sync pulse is at the correct timing position */
if (target.timing.h_sync_start == target.timing.h_display)
target.timing.h_sync_start += 8;
if (target.timing.h_sync_end == target.timing.h_total)
target.timing.h_sync_end -= 8;
+ /* assure we (still) have a sync pulse */
+ if (target.timing.h_sync_start == target.timing.h_sync_end) {
+ if (target.timing.h_sync_end < (target.timing.h_total - 8)) {
+ target.timing.h_sync_end += 8;
+ } else {
+ if (target.timing.h_sync_start > (target.timing.h_display + 8)) {
+ target.timing.h_sync_start -= 8;
+ } else {
+ LOG(2,("CRTC2: tuning modeline, not enough room for Hsync pulse, forcing it anyway..\n"));
+ target.timing.h_sync_start -= 8;
+ }
+ }
+ }
/* vertical timing */
target.timing.v_sync_start =
@@ -250,10 +264,24 @@ status_t nv_crtc2_set_timing(display_mode target)
((uint16)((si->ps.p2_timing.v_total / ((float)si->ps.p2_timing.v_display)) *
target.timing.v_display)) - 1;
+ /* assure sync pulse is at the correct timing position */
if (target.timing.v_sync_start == target.timing.v_display)
target.timing.v_sync_start += 1;
if (target.timing.v_sync_end == target.timing.v_total)
target.timing.v_sync_end -= 1;
+ /* assure we (still) have a sync pulse */
+ if (target.timing.v_sync_start == target.timing.v_sync_end) {
+ if (target.timing.v_sync_end < (target.timing.v_total - 1)) {
+ target.timing.v_sync_end += 1;
+ } else {
+ if (target.timing.v_sync_start > (target.timing.v_display + 1)) {
+ target.timing.v_sync_start -= 1;
+ } else {
+ LOG(2,("CRTC2: tuning modeline, not enough room for Vsync pulse, forcing it anyway..\n"));
+ target.timing.v_sync_start -= 1;
+ }
+ }
+ }
/* disable GPU scaling testmode so automatic scaling will be done */
DAC2W(FP_DEBUG1, 0);
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c
index f95bc29d5f..039b467e80 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_general.c
+++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c
@@ -92,7 +92,7 @@ status_t nv_general_powerup()
{
status_t status;
- LOG(1,("POWERUP: Haiku nVidia Accelerant 1.03 running.\n"));
+ LOG(1,("POWERUP: Haiku nVidia Accelerant 1.04 running.\n"));
/* log VBLANK INT usability status */
if (si->ps.int_assigned)
diff --git a/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html b/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html
index 1ee09a159b..f3e24b3d6f 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 1.03, Rudolf)
+head (SVN 1.04, Rudolf)
- Fixed driver assuming enabling AGP mode succeeded on some occasions if it did not block it itself. Blocking AGP mode completely via the AGP busmanager (option 'block_agp') resulted in a crashing acceleration engine because it was setup for AGP transfers instead of using PCI transfers. Error was solved with help from user kraton.
- Fixed shared_info struct problem occuring when 3D 'accelerant' is used (tested Alpha 4.1): the TVencoder type definition list apparantly gets some memory assigned these days when done inside the definition of shared_info. Moved encoder list outside the shared_info definition.
@@ -27,7 +27,9 @@
- Added support for Haiku specific driverhook GET_PREFERRED_DISPLAY_MODE. Laptops should now also startup in native mode automatically at first system boot;
- Rewrote framebuffer memory detection. Accelerant now only uses the amount of RAM mapped by the kerneldriver as maximum. This fixes black screen at app_server startup on a number of GF6xxx and GF7xxx cards;
- Finally(!) fixed PLL selection trouble on NV40 architecture (Geforce 6xxx and 7xxx) cards. Now dualhead should (almost) always work OK, and now low-res bootscreens should nolonger result in 'frequency out of range' messages on DVI connected screens;
-
- Fixed shivering display on some systems (confirmed a Geforce 5200 laptop): Pixelclocks should never be setup for spread spectrum on analog connections.
+
- Fixed shivering display on some systems (confirmed a Geforce 5200 laptop): Pixelclocks should never be setup for spread spectrum on analog connections;
+
- Added full HDTV mode (1920x1080p) to exported modelist: Haiku's Screen preflet allows you to set this mode now if your screen supports it;
+
- Improved modeline scaling for digitally connected screens: this fixes missing SYNC pulses on some setups. The screen nolonger shows shifted pictures (this happened mostly on 640x480 resolution).
nv_driver 0.80 (Rudolf)