Skip to contentSkip to conversation

DRM: Fix radeon mapping of AGP

PATCH New Benjamin Herrenschmidt 1 participant 1 message May 18, 2005 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 DRM: Fix radeon mapping of AGP

Hi David!

Here's my latest version of the patch for radeon_cp that fixes the possible overlap mapping we talked about. I went the paranoid way this time, by checking both CONFIG_MEMSIZE and MC_FB_LOCATION "top", in order to put the AGP aperture always above any of those. This should avoid bad surprises in the future and fix the problem with existing ppc r300's who have CONFIG_APER_SIZE < CONFIG_MEM_SIZE.

The X.org side is still bogus, but at least, with this DRM fix, this won't break it all, X will just use only half of VRAM I suppose. I'll work on fixing X later.

Let me know if that patch is ok, others on the list, I would appreciate if you could give it a try and make sure it doesn't cause any regression. It applies against current Linus git tree.

drivers/char/drm/radeon_drv.h +1 -0
Index: linux-work/drivers/char/drm/radeon_drv.h
===================================================================
@@ -346,6 +346,7 @@
 #define RADEON_CLOCK_CNTL_DATA		0x000c
 #	define RADEON_PLL_WR_EN			(1 << 7)
 #define RADEON_CLOCK_CNTL_INDEX		0x0008
+#define RADEON_CONFIG_MEMSIZE		0x00f8
 #define RADEON_CONFIG_APER_SIZE		0x0108
 #define RADEON_CRTC_OFFSET		0x0224
 #define RADEON_CRTC_OFFSET_CNTL		0x0228
drivers/char/drm/radeon_cp.c +28 -3
Index: linux-work/drivers/char/drm/radeon_cp.c
===================================================================
@@ -1267,7 +1267,8 @@
 
 static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 {
-	drm_radeon_private_t *dev_priv = dev->dev_private;;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u32 gart_loc, mem_size, mem_top;
 	DRM_DEBUG( "\n" );
 
 	dev_priv->is_pci = init->is_pci;
@@ -1476,8 +1477,32 @@
 
 
 	dev_priv->gart_size = init->gart_size;
-	dev_priv->gart_vm_start = dev_priv->fb_location
-				+ RADEON_READ( RADEON_CONFIG_APER_SIZE );
+	mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE);
+	mem_top = RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000;
+
+	/* assume mem_size of 0 means one of those buggy M6 and thus
+	 * is 8Mb
+	 */
+	if (mem_size == 0)
+		mem_size = 0x00800000;
+	
+	/* if MC_FB_LOCATION was set for a bigger aperture, then adapt,
+	 * we really want to make sure there is no overlap between the
+	 * region defined by MC_FB_LOCATION and the AGP aperture
+	 */
+	if (((mem_top + 1) - dev_priv->fb_location) > mem_size)
+		mem_size = (mem_top + 1) - dev_priv->fb_location;
+	/* try to put the gart after the framebuffer */
+	gart_loc = dev_priv->fb_location + mem_size;
+	/* if it overflows, warn and try to put it _before_ the framebuffer */
+	if ((gart_loc + dev_priv->gart_size) < dev_priv->fb_location) {
+		DRM_INFO("Warning ! Gart does not fit above framebuffer in "
+			 "card space, moving it below. Risks collision with "
+			 " main memory ! ");
+		gart_loc = dev_priv->fb_location - dev_priv->gart_size;
+	}
+	
+	dev_priv->gart_vm_start = gart_loc;
 
 #if __OS_HAS_AGP
 	if ( !dev_priv->is_pci )