summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac5
-rw-r--r--src/radeon.h6
-rw-r--r--src/radeon_driver.c46
-rw-r--r--src/radeon_output.c13
4 files changed, 58 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac
index 1570e54c..cc4d490a 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 03db3604..801d616a 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 25b21191..9f9fd901 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 9850702c..64c0438d 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) {