Browse Source

drm/radeon/kms: detect sideport memory on IGP chips

This detects if the sideport memory is enabled and
if it is VRAM is evicted on suspend/resume.

This should fix s/r issues on some IGPs.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Alex Deucher 15 years ago
parent
commit
06b6476d6b

+ 4 - 0
drivers/gpu/drm/radeon/r600.c

@@ -726,6 +726,10 @@ int r600_mc_init(struct radeon_device *rdev)
 	a.full = rfixed_const(100);
 	a.full = rfixed_const(100);
 	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
 	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
 	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
 	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+
+	if (rdev->flags & RADEON_IS_IGP)
+		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 3 - 1
drivers/gpu/drm/radeon/radeon.h

@@ -319,10 +319,12 @@ struct radeon_mc {
 	u64			real_vram_size;
 	u64			real_vram_size;
 	int			vram_mtrr;
 	int			vram_mtrr;
 	bool			vram_is_ddr;
 	bool			vram_is_ddr;
+	bool                    igp_sideport_enabled;
 };
 };
 
 
 int radeon_mc_setup(struct radeon_device *rdev);
 int radeon_mc_setup(struct radeon_device *rdev);
-
+bool radeon_combios_sideport_present(struct radeon_device *rdev);
+bool radeon_atombios_sideport_present(struct radeon_device *rdev);
 
 
 /*
 /*
  * GPU scratch registers structures, functions & helpers
  * GPU scratch registers structures, functions & helpers

+ 37 - 0
drivers/gpu/drm/radeon/radeon_atombios.c

@@ -938,6 +938,43 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
 	return false;
 	return false;
 }
 }
 
 
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+};
+
+bool radeon_atombios_sideport_present(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
+	union igp_info *igp_info;
+	u8 frev, crev;
+	u16 data_offset;
+
+	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
+			       &crev, &data_offset);
+
+	igp_info = (union igp_info *)(mode_info->atom_context->bios +
+				      data_offset);
+
+	if (igp_info) {
+		switch (crev) {
+		case 1:
+			if (igp_info->info.ucMemoryType & 0xf0)
+				return true;
+			break;
+		case 2:
+			if (igp_info->info_2.ucMemoryType & 0x0f)
+				return true;
+			break;
+		default:
+			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
+			break;
+		}
+	}
+	return false;
+}
+
 bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
 bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
 				   struct radeon_encoder_int_tmds *tmds)
 				   struct radeon_encoder_int_tmds *tmds)
 {
 {

+ 14 - 0
drivers/gpu/drm/radeon/radeon_combios.c

@@ -595,6 +595,20 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
 	return false;
 	return false;
 }
 }
 
 
+bool radeon_combios_sideport_present(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	u16 igp_info;
+
+	igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
+
+	if (igp_info) {
+		if (RBIOS16(igp_info + 0x4))
+			return true;
+	}
+	return false;
+}
+
 static const uint32_t default_primarydac_adj[CHIP_LAST] = {
 static const uint32_t default_primarydac_adj[CHIP_LAST] = {
 	0x00000808,		/* r100  */
 	0x00000808,		/* r100  */
 	0x00000808,		/* rv100 */
 	0x00000808,		/* rv100 */

+ 3 - 2
drivers/gpu/drm/radeon/radeon_object.c

@@ -221,8 +221,9 @@ int radeon_bo_unpin(struct radeon_bo *bo)
 int radeon_bo_evict_vram(struct radeon_device *rdev)
 int radeon_bo_evict_vram(struct radeon_device *rdev)
 {
 {
 	if (rdev->flags & RADEON_IS_IGP) {
 	if (rdev->flags & RADEON_IS_IGP) {
-		/* Useless to evict on IGP chips */
-		return 0;
+		if (rdev->mc.igp_sideport_enabled == false)
+			/* Useless to evict on IGP chips */
+			return 0;
 	}
 	}
 	return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 	return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 }
 }

+ 1 - 0
drivers/gpu/drm/radeon/rs400.c

@@ -356,6 +356,7 @@ static int rs400_mc_init(struct radeon_device *rdev)
 	rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
 	rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	r = radeon_mc_setup(rdev);
 	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
 	if (r)
 	if (r)
 		return r;
 		return r;
 	return 0;
 	return 0;

+ 1 - 0
drivers/gpu/drm/radeon/rs600.c

@@ -56,6 +56,7 @@ int rs600_mc_init(struct radeon_device *rdev)
 	rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
 	rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
 	rdev->mc.gtt_location = 0xffffffffUL;
 	rdev->mc.gtt_location = 0xffffffffUL;
 	r = radeon_mc_setup(rdev);
 	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
 	if (r)
 	if (r)
 		return r;
 		return r;
 	return 0;
 	return 0;

+ 1 - 0
drivers/gpu/drm/radeon/rs690.c

@@ -172,6 +172,7 @@ static int rs690_mc_init(struct radeon_device *rdev)
 	rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
 	rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	r = radeon_mc_setup(rdev);
 	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
 	if (r)
 	if (r)
 		return r;
 		return r;
 	return 0;
 	return 0;