Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a50f01a authored by Dave Airlie's avatar Dave Airlie
Browse files

drm/radeon/kms: vram sizing on certain r100 chips needs workaround.



If an rn50/r100/m6/m7 GPU has < 64MB RAM, i.e. 8/16/32, the
aperture used to calculate the MC_FB_LOCATION needs to be worked
out from the CONFIG_APER_SIZE register, and not the actual vram size.

TTM VRAM size was also being initialised wrong, use actual vram size
to initialise it.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 664f8659
Loading
Loading
Loading
Loading
+22 −12
Original line number Diff line number Diff line
@@ -173,8 +173,12 @@ void r100_mc_setup(struct radeon_device *rdev)
		DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
	}
	/* Write VRAM size in case we are limiting it */
	WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
	tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
	WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
	/* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM,
	 * if the aperture is 64MB but we have 32MB VRAM
	 * we report only 32MB VRAM but we have to set MC_FB_LOCATION
	 * to 64MB, otherwise the gpu accidentially dies */
	tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
	tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
	tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
	WREG32(RADEON_MC_FB_LOCATION, tmp);
@@ -1447,25 +1451,28 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
		uint32_t tom;
		/* read NB_TOM to get the amount of ram stolen for the GPU */
		tom = RREG32(RADEON_NB_TOM);
		rdev->mc.vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
		rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
		/* for IGPs we need to keep VRAM where it was put by the BIOS */
		rdev->mc.vram_location = (tom & 0xffff) << 16;
		WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
		WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
		rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
	} else {
		rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
		rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
		/* Some production boards of m6 will report 0
		 * if it's 8 MB
		 */
		if (rdev->mc.vram_size == 0) {
			rdev->mc.vram_size = 8192 * 1024;
			WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
		if (rdev->mc.real_vram_size == 0) {
			rdev->mc.real_vram_size = 8192 * 1024;
			WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
		}
		/* let driver place VRAM */
		rdev->mc.vram_location = 0xFFFFFFFFUL;
		 /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
		  * Novell bug 204882 + along with lots of ubuntu ones */
		if (config_aper_size > rdev->mc.vram_size)
			rdev->mc.vram_size = config_aper_size;
		if (config_aper_size > rdev->mc.real_vram_size)
			rdev->mc.mc_vram_size = config_aper_size;
		else
			rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
	}

	/* work out accessible VRAM */
@@ -1477,8 +1484,11 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
	if (accessible > rdev->mc.aper_size)
		accessible = rdev->mc.aper_size;

	if (rdev->mc.vram_size > rdev->mc.aper_size)
		rdev->mc.vram_size = rdev->mc.aper_size;
	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
		rdev->mc.mc_vram_size = rdev->mc.aper_size;

	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
		rdev->mc.real_vram_size = rdev->mc.aper_size;
}

void r100_vram_info(struct radeon_device *rdev)
+2 −2
Original line number Diff line number Diff line
@@ -95,8 +95,8 @@ int r520_mc_init(struct radeon_device *rdev)
		       "programming pipes. Bad things might happen.\n");
	}
	/* Write VRAM size in case we are limiting it */
	WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
	tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
	WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
	tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
	tmp = REG_SET(R520_MC_FB_TOP, tmp >> 16);
	tmp |= REG_SET(R520_MC_FB_START, rdev->mc.vram_location >> 16);
	WREG32_MC(R520_MC_FB_LOCATION, tmp);
+3 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ int r600_mc_init(struct radeon_device *rdev)
		       "programming pipes. Bad things might happen.\n");
	}

	tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
	tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
	tmp = REG_SET(R600_MC_FB_TOP, tmp >> 24);
	tmp |= REG_SET(R600_MC_FB_BASE, rdev->mc.vram_location >> 24);
	WREG32(R600_MC_VM_FB_LOCATION, tmp);
@@ -140,7 +140,8 @@ void r600_vram_get_type(struct radeon_device *rdev)
void r600_vram_info(struct radeon_device *rdev)
{
	r600_vram_get_type(rdev);
	rdev->mc.vram_size = RREG32(R600_CONFIG_MEMSIZE);
	rdev->mc.real_vram_size = RREG32(R600_CONFIG_MEMSIZE);
	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;

	/* Could aper size report 0 ? */
	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+4 −1
Original line number Diff line number Diff line
@@ -332,8 +332,11 @@ struct radeon_mc {
	unsigned		gtt_location;
	unsigned		gtt_size;
	unsigned		vram_location;
	unsigned		vram_size;
	/* for some chips with <= 32MB we need to lie
	 * about vram size near mc fb location */
	unsigned		mc_vram_size;
	unsigned		vram_width;
	unsigned		real_vram_size;
	int			vram_mtrr;
	bool			vram_is_ddr;
};
+11 −9
Original line number Diff line number Diff line
@@ -121,7 +121,7 @@ int radeon_mc_setup(struct radeon_device *rdev)
	if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
		/* vram location was already setup try to put gtt after
		 * if it fits */
		tmp = rdev->mc.vram_location + rdev->mc.vram_size;
		tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
			rdev->mc.gtt_location = tmp;
@@ -136,13 +136,13 @@ int radeon_mc_setup(struct radeon_device *rdev)
	} else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
		/* gtt location was already setup try to put vram before
		 * if it fits */
		if (rdev->mc.vram_size < rdev->mc.gtt_location) {
		if (rdev->mc.mc_vram_size < rdev->mc.gtt_location) {
			rdev->mc.vram_location = 0;
		} else {
			tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
			tmp += (rdev->mc.vram_size - 1);
			tmp &= ~(rdev->mc.vram_size - 1);
			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.vram_size) {
			tmp += (rdev->mc.mc_vram_size - 1);
			tmp &= ~(rdev->mc.mc_vram_size - 1);
			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.mc_vram_size) {
				rdev->mc.vram_location = tmp;
			} else {
				printk(KERN_ERR "[drm] vram too big to fit "
@@ -152,12 +152,14 @@ int radeon_mc_setup(struct radeon_device *rdev)
		}
	} else {
		rdev->mc.vram_location = 0;
		rdev->mc.gtt_location = rdev->mc.vram_size;
		rdev->mc.gtt_location = rdev->mc.mc_vram_size;
	}
	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.vram_size >> 20);
	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20);
	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
		 rdev->mc.vram_location,
		 rdev->mc.vram_location + rdev->mc.vram_size - 1);
		 rdev->mc.vram_location + rdev->mc.mc_vram_size - 1);
	if (rdev->mc.real_vram_size != rdev->mc.mc_vram_size)
		DRM_INFO("radeon: VRAM less than aperture workaround enabled\n");
	DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
		 rdev->mc.gtt_location,
@@ -573,7 +575,7 @@ int radeon_device_init(struct radeon_device *rdev,
	rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
				      MTRR_TYPE_WRCOMB, 1);
	DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n",
		 rdev->mc.vram_size >> 20,
		 rdev->mc.real_vram_size >> 20,
		 (unsigned)rdev->mc.aper_size >> 20);
	DRM_INFO("RAM width %dbits %cDR\n",
		 rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
Loading