From: Dave Airlie <airl...@redhat.com>

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.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 drivers/gpu/drm/radeon/r100.c          |   34 ++++++++++++++++++++-----------
 drivers/gpu/drm/radeon/r520.c          |    4 +-
 drivers/gpu/drm/radeon/r600.c          |    5 ++-
 drivers/gpu/drm/radeon/radeon.h        |    5 +++-
 drivers/gpu/drm/radeon/radeon_device.c |   20 ++++++++++--------
 drivers/gpu/drm/radeon/radeon_gem.c    |    4 +-
 drivers/gpu/drm/radeon/radeon_ttm.c    |    2 +-
 drivers/gpu/drm/radeon/rs400.c         |    4 +-
 drivers/gpu/drm/radeon/rs600.c         |    2 +-
 drivers/gpu/drm/radeon/rs690.c         |    7 +++--
 drivers/gpu/drm/radeon/rv515.c         |    4 +-
 drivers/gpu/drm/radeon/rv770.c         |    2 +-
 12 files changed, 55 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 0aad4c0..ad799f2 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -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)
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index b6bd375..6a3cafd 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -94,8 +94,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);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c45559f..538cd90 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index af12a2f..85efcc9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -331,8 +331,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;
 };
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index f23083b..dbec8de 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -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,
@@ -568,7 +570,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');
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index 1254208..cded518 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -157,9 +157,9 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void 
*data,
        struct radeon_device *rdev = dev->dev_private;
        struct drm_radeon_gem_info *args = data;
 
-       args->vram_size = rdev->mc.vram_size;
+       args->vram_size = rdev->mc.real_vram_size;
        /* FIXME: report somethings that makes sense */
-       args->vram_visible = rdev->mc.vram_size - (4 * 1024 * 1024);
+       args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024);
        args->gart_size = rdev->mc.gtt_size;
        return 0;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 37e1cbc..852ab53 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -468,7 +468,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
                return r;
        }
        DRM_INFO("radeon: %uM of VRAM memory ready\n",
-                rdev->mc.vram_size / (1024 * 1024));
+                rdev->mc.real_vram_size / (1024 * 1024));
        r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
                           ((rdev->mc.gtt_size) >> PAGE_SHIFT));
        if (r) {
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index daf24e8..83c4681 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -232,7 +232,7 @@ int rs400_mc_init(struct radeon_device *rdev)
 
        rs400_gpu_init(rdev);
        rs400_gart_disable(rdev);
-       rdev->mc.gtt_location = rdev->mc.vram_size;
+       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
        rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
        rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
        r = radeon_mc_setup(rdev);
@@ -246,7 +246,7 @@ int rs400_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(RADEON_MC_FB_TOP, tmp >> 16);
        tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
        WREG32(RADEON_MC_FB_LOCATION, tmp);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index ab0c967..71f4c22 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -223,7 +223,7 @@ int rs600_mc_init(struct radeon_device *rdev)
                printk(KERN_WARNING "Failed to wait MC idle while "
                       "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(RS600_MC_FB_TOP, tmp >> 16);
        tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16);
        WREG32_MC(RS600_MC_FB_LOCATION, tmp);
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 79ba850..c7a3a2a 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -64,7 +64,7 @@ int rs690_mc_init(struct radeon_device *rdev)
        rs400_gart_disable(rdev);
 
        /* Setup GPU memory space */
-       rdev->mc.gtt_location = rdev->mc.vram_size;
+       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
        rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
        rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
        rdev->mc.vram_location = 0xFFFFFFFFUL;
@@ -79,7 +79,7 @@ int rs690_mc_init(struct radeon_device *rdev)
                printk(KERN_WARNING "Failed to wait MC idle while "
                       "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(RS690_MC_FB_TOP, tmp >> 16);
        tmp |= REG_SET(RS690_MC_FB_START, rdev->mc.vram_location >> 16);
        WREG32_MC(RS690_MCCFG_FB_LOCATION, tmp);
@@ -152,7 +152,8 @@ void rs690_vram_info(struct radeon_device *rdev)
        } else {
                rdev->mc.vram_width = 64;
        }
-       rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+       rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+       rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 
        rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
        rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 677929e..53846a6 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -99,10 +99,10 @@ int rv515_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);
+       WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
        tmp = REG_SET(RV515_MC_FB_START, rdev->mc.vram_location >> 16);
        WREG32(0x134, tmp);
-       tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
+       tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
        tmp = REG_SET(RV515_MC_FB_TOP, tmp >> 16);
        tmp |= REG_SET(RV515_MC_FB_START, rdev->mc.vram_location >> 16);
        WREG32_MC(RV515_MC_FB_LOCATION, tmp);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index da50cc5..21d8ffd 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -67,7 +67,7 @@ int rv770_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(R700_MC_FB_TOP, tmp >> 24);
        tmp |= REG_SET(R700_MC_FB_BASE, rdev->mc.vram_location >> 24);
        WREG32(R700_MC_VM_FB_LOCATION, tmp);
-- 
1.6.2.2


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to