xf86-video-ati: Branch 'master'

Adam Jackson ajax at kemper.freedesktop.org
Wed Dec 19 15:50:28 PST 2007


 configure.ac        |    5 +++++
 src/radeon.h        |    6 ++++++
 src/radeon_driver.c |   46 ++++++++++++++++++++++++++++++++++------------
 src/radeon_output.c |   13 +++++++++++++
 4 files changed, 58 insertions(+), 12 deletions(-)

New commits:
commit fb7a4e24f2da3561ef81371ca4013a4f13806e91
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Dec 19 19:15:19 2007 -0500

    Fix RN50 mode filtering.
    
    The old code would attempt to limit the maximum pixel size of the screen
    by limiting the maximum PLL frequency.  This ends up confusing the PLL
    computation code since sometimes your maximum freq can be lower than your
    minimum freq.  More to the point it's just wrong, maximum PLL frequency
    isn't the same thing as maximum pixel clock, and even that isn't the same
    thing as maximum scanout pixels per second.
    
    The correct thing to do is filter by the mode's effective memory bandwidth.

diff --git a/configure.ac b/configure.ac
index 1570e54..cc4d490 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,6 +204,11 @@ AC_CHECK_DECL(xf86XVFillKeyHelperDrawable,
 	      [],
 	      [#include <xf86xv.h>])
 
+AC_CHECK_DECL(xf86ModeBandwidth,
+	      [AC_DEFINE(HAVE_XF86MODEBANDWIDTH, 1, [Have xf86ModeBandwidth prototype])],
+	      [],
+	      [#include "xf86Modes.h"])
+
 AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
 	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
 	      [#include "xorg-server.h"])
diff --git a/src/radeon.h b/src/radeon.h
index 03db360..801d616 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -41,6 +41,7 @@
 #include <unistd.h>		/* For usleep() */
 #include <sys/time.h>		/* For gettimeofday() */
 
+#include "config.h"
 #include "xf86str.h"
 #include "compiler.h"
 #include "xf86fbman.h"
@@ -97,6 +98,11 @@
 #define MIN(a,b) ((a)>(b)?(b):(a))
 #endif
 
+#ifndef HAVE_XF86MODEBANDWIDTH
+extern unsigned int xf86ModeBandwidth(DisplayModePtr mode, int depth);
+#define MODE_BANDWIDTH MODE_BAD
+#endif
+
 typedef enum {
     OPTION_NOACCEL,
     OPTION_SW_CURSOR,
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 25b2119..9f9fd90 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1051,18 +1051,6 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
         info->mclk = 200.00;
     }
 
-    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
-        /* Avoid RN50 corruption due to memory bandwidth starvation.
-         * 18 is an empirical value based on the databook and Windows driver.
-         *
-	 * Empirical value changed to 24 to raise pixel clock limit and
-	 * allow higher resolution modes on capable monitors
-	 */
-        pll->max_pll_freq = min(pll->max_pll_freq,
-                               24 * info->mclk * 100 / pScrn->bitsPerPixel *
-                               info->RamWidth / 16);
-    }
-
     /* card limits for computing PLLs */
     pll->min_ref_div = 2;
     pll->max_ref_div = 0x3ff;
@@ -5380,10 +5368,44 @@ Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
 }
 #endif
 
+#ifndef HAVE_XF86MODEBANDWIDTH
+/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
+_X_HIDDEN unsigned int
+xf86ModeBandwidth(DisplayModePtr mode, int depth)
+{
+    float a_active, a_total, active_percent, pixels_per_second;
+    int bytes_per_pixel = (depth + 7) / 8;
+
+    if (!mode->HTotal || !mode->VTotal || !mode->Clock)
+	return 0;
+
+    a_active = mode->HDisplay * mode->VDisplay;
+    a_total = mode->HTotal * mode->VTotal;
+    active_percent = a_active / a_total;
+    pixels_per_second = active_percent * mode->Clock * 1000.0;
+
+    return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
+}
+#endif
+
 /* Used to disallow modes that are not supported by the hardware */
 ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
                                      Bool verbose, int flag)
 {
+    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    /*
+     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
+     * XXX should really do this for all chips by properly computing
+     * memory bandwidth and an overhead factor.
+     */
+    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
+	if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 300)
+	    return MODE_BANDWIDTH;
+    }
+
     /* There are problems with double scan mode at high clocks
      * They're likely related PLL and display buffer settings.
      * Disable these modes for now.
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 9850702..64c0438 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -789,6 +789,19 @@ static int
 radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    /*
+     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
+     * XXX should really do this for all chips by properly computing
+     * memory bandwidth and an overhead factor.
+     */
+    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
+	if (xf86ModeBandwidth(pMode, pScrn->bitsPerPixel) > 300)
+	    return MODE_BANDWIDTH;
+    }
 
     if (radeon_output->type == OUTPUT_STV ||
 	radeon_output->type == OUTPUT_CTV) {


More information about the xorg-commit mailing list