drm/radeon/kms: detect sideport memory on IGP chips
authorAlex Deucher <alexdeucher@gmail.com>
Tue, 5 Jan 2010 16:27:29 +0000 (11:27 -0500)
committerDave Airlie <airlied@redhat.com>
Fri, 8 Jan 2010 03:08:56 +0000 (13:08 +1000)
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>
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c

index 5c6058c6dddef7a07619a2a28cf21b9ba184f8eb..921926f3d1f3b6c8f9faf596c1dc92fb549aeda0 100644 (file)
@@ -726,6 +726,10 @@ int r600_mc_init(struct radeon_device *rdev)
        a.full = rfixed_const(100);
        rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
        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;
 }
 
index 53b55608102b0df5a97fd099fca0d8063d5e13b7..a7e349dc4b9783ab5635bc55833709a2eb9310cb 100644 (file)
@@ -319,10 +319,12 @@ struct radeon_mc {
        u64                     real_vram_size;
        int                     vram_mtrr;
        bool                    vram_is_ddr;
+       bool                    igp_sideport_enabled;
 };
 
 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
index 1834035401132452ee6f631a1beb98603cae15c9..fa82ca74324e45be7fece1a947ea1ead50a5a77d 100644 (file)
@@ -938,6 +938,43 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
        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,
                                   struct radeon_encoder_int_tmds *tmds)
 {
index 58f342659cc741870660172971224654e6a4bb07..7914455c96ca9024814d152fee0c37439b1129ee 100644 (file)
@@ -595,6 +595,20 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
        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] = {
        0x00000808,             /* r100  */
        0x00000808,             /* rv100 */
index d9ffe1f56e8fc2aca4acc845b1e470ceb9642203..4e636de877b237b2ca5c53eb15b62d4008a939f6 100644 (file)
@@ -221,8 +221,9 @@ int radeon_bo_unpin(struct radeon_bo *bo)
 int radeon_bo_evict_vram(struct radeon_device *rdev)
 {
        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);
 }
index 368415df5f3abe954494e58f239708c1c5a1557b..bf7b3cf80ed70746ee8a2d1333c7a301e1ba4bd3 100644 (file)
@@ -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.gtt_location = 0xFFFFFFFFUL;
        r = radeon_mc_setup(rdev);
+       rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
        if (r)
                return r;
        return 0;
index 4245218e954fd908859f8ac39bd87349c9bb3e20..19258943a3706c2e5a18556e0a0f9eabbf1aedc9 100644 (file)
@@ -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.gtt_location = 0xffffffffUL;
        r = radeon_mc_setup(rdev);
+       rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        if (r)
                return r;
        return 0;
index 1e22f52d6039ff67c369b3317a997d0881ac094d..42f27205a5978bd11d7c737b74d1d136d6b0962a 100644 (file)
@@ -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.gtt_location = 0xFFFFFFFFUL;
        r = radeon_mc_setup(rdev);
+       rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        if (r)
                return r;
        return 0;