drm/radeon/kms: simplify memory controller setup V2
authorJerome Glisse <jglisse@redhat.com>
Wed, 17 Feb 2010 21:54:29 +0000 (21:54 +0000)
committerDave Airlie <airlied@redhat.com>
Thu, 18 Feb 2010 04:49:35 +0000 (14:49 +1000)
Get rid of _location and use _start/_end also simplify the
computation of vram_start|end & gtt_start|end. For R1XX-R2XX
we place VRAM at the same address of PCI aperture, those GPU
shouldn't have much memory and seems to behave better when
setup that way. For R3XX and newer we place VRAM at 0. For
R6XX-R7XX AGP we place VRAM before or after AGP aperture this
might limit to limit the VRAM size but it's very unlikely.
For IGP we don't change the VRAM placement.

Tested on (compiz,quake3,suspend/resume):
PCI/PCIE:RV280,R420,RV515,RV570,RV610,RV710
AGP:RV100,RV280,R420,RV350,RV620(RPB*),RV730
IGP:RS480(RPB*),RS690,RS780(RPB*),RS880

RPB: resume previously broken

V2 correct commit message to reflect more accurately the bug
and move VRAM placement to 0 for most of the GPU to avoid
limiting VRAM.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
18 files changed:
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c

index 3368920df5f40fa1fff969786a9cd4bd9aeab133..3f973d411d6159c77d33a480f14f708bc58c9e62 100644 (file)
@@ -439,7 +439,6 @@ int evergreen_mc_init(struct radeon_device *rdev)
        fixed20_12 a;
        u32 tmp;
        int chansize, numchan;
-       int r;
 
        /* Get VRAM informations */
        rdev->mc.vram_is_ddr = true;
@@ -475,48 +474,12 @@ int evergreen_mc_init(struct radeon_device *rdev)
        /* size in MB on evergreen */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       /* FIXME remove this once we support unmappable VRAM */
+       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;
-
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r)
-                       return r;
-               /* gtt_size is setup by radeon_agp_init */
-               rdev->mc.gtt_location = rdev->mc.agp_base;
-               tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-               /* Try to put vram before or after AGP because we
-                * we want SYSTEM_APERTURE to cover both VRAM and
-                * AGP so that GPU can catch out of VRAM/AGP access
-                */
-               if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-                       /* Enought place before */
-                       rdev->mc.vram_location = rdev->mc.gtt_location -
-                                                       rdev->mc.mc_vram_size;
-               } else if (tmp > rdev->mc.mc_vram_size) {
-                       /* Enought place after */
-                       rdev->mc.vram_location = rdev->mc.gtt_location +
-                                                       rdev->mc.gtt_size;
-               } else {
-                       /* Try to setup VRAM then AGP might not
-                        * not work on some card
-                        */
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               }
-       } else {
-               rdev->mc.vram_location = 0x00000000UL;
-               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        }
-       rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
+       r600_vram_gtt_location(rdev, &rdev->mc);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
@@ -525,6 +488,7 @@ int evergreen_mc_init(struct radeon_device *rdev)
        rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
        return 0;
 }
+
 int evergreen_gpu_reset(struct radeon_device *rdev)
 {
        /* FIXME: implement for evergreen */
@@ -726,6 +690,13 @@ int evergreen_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r)
+                       radeon_agp_disable(rdev);
+       }
+       /* initialize memory controller */
        r = evergreen_mc_init(rdev);
        if (r)
                return r;
index bc7d9e9211c8733a2f6791e9de72b2499489a0c5..1fdd793343b9846baf78e788283be3bf97dd2b26 100644 (file)
@@ -202,9 +202,8 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
        tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
        WREG32(RADEON_AIC_CNTL, tmp);
        /* set address range for PCI address translate */
-       WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
-       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-       WREG32(RADEON_AIC_HI_ADDR, tmp);
+       WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start);
+       WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end);
        /* set PCI GART page-table base address */
        WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
        tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
@@ -1957,17 +1956,17 @@ static u32 r100_get_accessible_vram(struct radeon_device *rdev)
 void r100_vram_init_sizes(struct radeon_device *rdev)
 {
        u64 config_aper_size;
-       u32 accessible;
 
+       /* work out accessible VRAM */
+       rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
+       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
        config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
-
        if (rdev->flags & RADEON_IS_IGP) {
                uint32_t tom;
                /* read NB_TOM to get the amount of ram stolen for the GPU */
                tom = RREG32(RADEON_NB_TOM);
                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.real_vram_size);
                rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
        } else {
@@ -1979,30 +1978,19 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
                        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 */
+               /* 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.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 */
-       accessible = r100_get_accessible_vram(rdev);
-
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-
-       if (accessible > rdev->mc.aper_size)
-               accessible = rdev->mc.aper_size;
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       /* FIXME remove this once we support unmappable VRAM */
+       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_vga_set_state(struct radeon_device *rdev, bool state)
@@ -2019,11 +2007,18 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state)
        WREG32(RADEON_CONFIG_CNTL, temp);
 }
 
-void r100_vram_info(struct radeon_device *rdev)
+void r100_mc_init(struct radeon_device *rdev)
 {
-       r100_vram_get_type(rdev);
+       u64 base;
 
+       r100_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
+       base = rdev->mc.aper_base;
+       if (rdev->flags & RADEON_IS_IGP)
+               base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+       radeon_vram_location(rdev, &rdev->mc, base);
+       if (!(rdev->flags & RADEON_IS_AGP))
+               radeon_gtt_location(rdev, &rdev->mc);
 }
 
 
@@ -3294,10 +3289,9 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
 void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
 {
        /* Update base address for crtc */
-       WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location);
+       WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
        if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
-               WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR,
-                               rdev->mc.vram_location);
+               WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
        }
        /* Restore CRTC registers */
        WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
@@ -3458,32 +3452,6 @@ void r100_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
 }
 
-int r100_mc_init(struct radeon_device *rdev)
-{
-       int r;
-       u32 tmp;
-
-       /* Setup GPU memory space */
-       rdev->mc.vram_location = 0xFFFFFFFFUL;
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_IGP) {
-               tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
-               rdev->mc.vram_location = tmp << 16;
-       }
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       radeon_agp_disable(rdev);
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r)
-               return r;
-       return 0;
-}
-
 int r100_init(struct radeon_device *rdev)
 {
        int r;
@@ -3526,12 +3494,15 @@ int r100_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       r100_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r100_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
+       }
+       /* initialize VRAM */
+       r100_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index a4f395226b34b0a18d8e7ea9b2d30681f02ffb71..7e9f95653cbef1ebaf434d7e5a62a8dadb28f908 100644 (file)
@@ -121,15 +121,15 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
        /* discard memory request outside of configured range */
        tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
        WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
-       WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location);
-       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE;
+       WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_start);
+       tmp = rdev->mc.gtt_end & ~RADEON_GPU_PAGE_MASK;
        WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp);
        WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
        WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
        table_addr = rdev->gart.table_addr;
        WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr);
        /* FIXME: setup default page */
-       WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_location);
+       WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start);
        WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0);
        /* Clear error */
        WREG32_PCIE(0x18, 0);
@@ -459,13 +459,12 @@ int r300_gpu_reset(struct radeon_device *rdev)
 /*
  * r300,r350,rv350,rv380 VRAM info
  */
-void r300_vram_info(struct radeon_device *rdev)
+void r300_mc_init(struct radeon_device *rdev)
 {
        uint32_t tmp;
 
        /* DDR for all card after R300 & IGP */
        rdev->mc.vram_is_ddr = true;
-
        tmp = RREG32(RADEON_MEM_CNTL);
        tmp &= R300_MEM_NUM_CHANNELS_MASK;
        switch (tmp) {
@@ -474,8 +473,9 @@ void r300_vram_info(struct radeon_device *rdev)
        case 2: rdev->mc.vram_width = 256; break;
        default:  rdev->mc.vram_width = 128; break;
        }
-
        r100_vram_init_sizes(rdev);
+       if (!(rdev->flags & RADEON_IS_AGP))
+               radeon_gtt_location(rdev, &rdev->mc);
 }
 
 void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
@@ -1377,12 +1377,15 @@ int r300_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       r300_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r420_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
+       }
+       /* initialize memory controller */
+       r300_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index 12ebbdb83d1cf259f7ee1ab3aba2bae230349217..c7593b8f58eeaf61d41c8860fc0f74306071564e 100644 (file)
@@ -40,28 +40,6 @@ static void r420_set_reg_safe(struct radeon_device *rdev)
        rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);
 }
 
-int r420_mc_init(struct radeon_device *rdev)
-{
-       int r;
-
-       /* Setup GPU memory space */
-       rdev->mc.vram_location = 0xFFFFFFFFUL;
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       radeon_agp_disable(rdev);
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r) {
-               return r;
-       }
-       return 0;
-}
-
 void r420_pipes_init(struct radeon_device *rdev)
 {
        unsigned tmp;
@@ -349,13 +327,15 @@ int r420_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       r300_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r420_mc_init(rdev);
-       if (r) {
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
        }
+       /* initialize memory controller */
+       r300_mc_init(rdev);
        r420_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
index ddf5731eba0d8f294294a7a3bc4674ce2040a52e..2b8a5dd1351672bbacbf260d33441910514ff7a9 100644 (file)
@@ -119,13 +119,15 @@ static void r520_vram_get_type(struct radeon_device *rdev)
                rdev->mc.vram_width *= 2;
 }
 
-void r520_vram_info(struct radeon_device *rdev)
+void r520_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
 
        r520_vram_get_type(rdev);
-
        r100_vram_init_sizes(rdev);
+       radeon_vram_location(rdev, &rdev->mc, 0);
+       if (!(rdev->flags & RADEON_IS_AGP))
+               radeon_gtt_location(rdev, &rdev->mc);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
@@ -267,12 +269,15 @@ int r520_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       r520_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r420_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
+       }
+       /* initialize memory controller */
+       r520_mc_init(rdev);
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
index a865946d2d08bcc7063e8d42140960fec966148b..694a4c564f5262dfe1cb5f57a60a5b6e45a6029c 100644 (file)
@@ -611,6 +611,68 @@ static void r600_mc_program(struct radeon_device *rdev)
        rv515_vga_render_disable(rdev);
 }
 
+/**
+ * r600_vram_gtt_location - try to find VRAM & GTT location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ *
+ * Function will place try to place VRAM at same place as in CPU (PCI)
+ * address space as some GPU seems to have issue when we reprogram at
+ * different address space.
+ *
+ * If there is not enough space to fit the unvisible VRAM after the
+ * aperture then we limit the VRAM size to the aperture.
+ *
+ * If we are using AGP then place VRAM adjacent to AGP aperture are we need
+ * them to be in one from GPU point of view so that we can program GPU to
+ * catch access outside them (weird GPU policy see ??).
+ *
+ * This function will never fails, worst case are limiting VRAM or GTT.
+ *
+ * Note: GTT start, end, size should be initialized before calling this
+ * function on AGP platform.
+ */
+void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
+{
+       u64 size_bf, size_af;
+
+       if (mc->mc_vram_size > 0xE0000000) {
+               /* leave room for at least 512M GTT */
+               dev_warn(rdev->dev, "limiting VRAM\n");
+               mc->real_vram_size = 0xE0000000;
+               mc->mc_vram_size = 0xE0000000;
+       }
+       if (rdev->flags & RADEON_IS_AGP) {
+               size_bf = mc->gtt_start;
+               size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+               if (size_bf > size_af) {
+                       if (mc->mc_vram_size > size_bf) {
+                               dev_warn(rdev->dev, "limiting VRAM\n");
+                               mc->real_vram_size = size_bf;
+                               mc->mc_vram_size = size_bf;
+                       }
+                       mc->vram_start = mc->gtt_start - mc->mc_vram_size;
+               } else {
+                       if (mc->mc_vram_size > size_af) {
+                               dev_warn(rdev->dev, "limiting VRAM\n");
+                               mc->real_vram_size = size_af;
+                               mc->mc_vram_size = size_af;
+                       }
+                       mc->vram_start = mc->gtt_end;
+               }
+               mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+               dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+                               mc->mc_vram_size >> 20, mc->vram_start,
+                               mc->vram_end, mc->real_vram_size >> 20);
+       } else {
+               u64 base = 0;
+               if (rdev->flags & RADEON_IS_IGP)
+                       base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+               radeon_vram_location(rdev, &rdev->mc, base);
+               radeon_gtt_location(rdev, mc);
+       }
+}
+
 int r600_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
@@ -650,75 +712,20 @@ int r600_mc_init(struct radeon_device *rdev)
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       /* FIXME remove this once we support unmappable VRAM */
+       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;
-
-       if (rdev->flags & RADEON_IS_AGP) {
-               /* gtt_size is setup by radeon_agp_init */
-               rdev->mc.gtt_location = rdev->mc.agp_base;
-               tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-               /* Try to put vram before or after AGP because we
-                * we want SYSTEM_APERTURE to cover both VRAM and
-                * AGP so that GPU can catch out of VRAM/AGP access
-                */
-               if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-                       /* Enought place before */
-                       rdev->mc.vram_location = rdev->mc.gtt_location -
-                                                       rdev->mc.mc_vram_size;
-               } else if (tmp > rdev->mc.mc_vram_size) {
-                       /* Enought place after */
-                       rdev->mc.vram_location = rdev->mc.gtt_location +
-                                                       rdev->mc.gtt_size;
-               } else {
-                       /* Try to setup VRAM then AGP might not
-                        * not work on some card
-                        */
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               }
-       } else {
-               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-               rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
-                                                       0xFFFF) << 24;
-               tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
-               if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
-                       /* Enough place after vram */
-                       rdev->mc.gtt_location = tmp;
-               } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
-                       /* Enough place before vram */
-                       rdev->mc.gtt_location = 0;
-               } else {
-                       /* Not enough place after or before shrink
-                        * gart size
-                        */
-                       if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
-                               rdev->mc.gtt_location = 0;
-                               rdev->mc.gtt_size = rdev->mc.vram_location;
-                       } else {
-                               rdev->mc.gtt_location = tmp;
-                               rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
-                       }
-               }
-               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
        }
-       rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
+       r600_vram_gtt_location(rdev, &rdev->mc);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
        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 350ae71953e9ac907161d04df257827c3f4f53e4..0ca83ca911117249a926a2ea4c6ac264ab386a60 100644 (file)
@@ -282,6 +282,7 @@ union radeon_gart_table {
 };
 
 #define RADEON_GPU_PAGE_SIZE 4096
+#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
 
 struct radeon_gart {
        dma_addr_t                      table_addr;
@@ -316,21 +317,19 @@ struct radeon_mc {
        /* for some chips with <= 32MB we need to lie
         * about vram size near mc fb location */
        u64                     mc_vram_size;
-       u64                     gtt_location;
+       u64                     visible_vram_size;
        u64                     gtt_size;
        u64                     gtt_start;
        u64                     gtt_end;
-       u64                     vram_location;
        u64                     vram_start;
        u64                     vram_end;
        unsigned                vram_width;
        u64                     real_vram_size;
        int                     vram_mtrr;
        bool                    vram_is_ddr;
-       bool                    igp_sideport_enabled;
+       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);
 
@@ -1165,6 +1164,8 @@ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enabl
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
 extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
+extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
+extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
 struct r100_mc_save {
@@ -1219,7 +1220,7 @@ extern void r200_set_safe_registers(struct radeon_device *rdev);
 /* r300,r350,rv350,rv370,rv380 */
 extern void r300_set_reg_safe(struct radeon_device *rdev);
 extern void r300_mc_program(struct radeon_device *rdev);
-extern void r300_vram_info(struct radeon_device *rdev);
+extern void r300_mc_init(struct radeon_device *rdev);
 extern void r300_clock_startup(struct radeon_device *rdev);
 extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
 extern int rv370_pcie_gart_init(struct radeon_device *rdev);
@@ -1228,7 +1229,6 @@ extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
 extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
 
 /* r420,r423,rv410 */
-extern int r420_mc_init(struct radeon_device *rdev);
 extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
 extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
 extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
@@ -1270,6 +1270,7 @@ extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
                                        struct drm_display_mode *mode2);
 
 /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
+extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 extern bool r600_card_posted(struct radeon_device *rdev);
 extern void r600_cp_stop(struct radeon_device *rdev);
 extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size);
index c0681a5556dc96bc0bbbeec86774c3d23098ad35..c4457791dff1ae606004572d52b1d69eea1f7052 100644 (file)
@@ -237,6 +237,10 @@ int radeon_agp_init(struct radeon_device *rdev)
 
        rdev->mc.agp_base = rdev->ddev->agp->agp_info.aper_base;
        rdev->mc.gtt_size = rdev->ddev->agp->agp_info.aper_size << 20;
+       rdev->mc.gtt_start = rdev->mc.agp_base;
+       rdev->mc.gtt_end = rdev->mc.gtt_start + rdev->mc.gtt_size - 1;
+       dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+               rdev->mc.gtt_size >> 20, rdev->mc.gtt_start, rdev->mc.gtt_end);
 
        /* workaround some hw issues */
        if (rdev->family < CHIP_R200) {
index 7be3a69684639ff443fe994e01b0462511abae30..91a9b966238e39bdf9d3238d3a1c31a93f97b3ff 100644 (file)
@@ -100,80 +100,103 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
        }
 }
 
-/*
- * MC common functions
+/**
+ * radeon_vram_location - try to find VRAM location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ * @base: base address at which to put VRAM
+ *
+ * Function will place try to place VRAM at base address provided
+ * as parameter (which is so far either PCI aperture address or
+ * for IGP TOM base address).
+ *
+ * If there is not enough space to fit the unvisible VRAM in the 32bits
+ * address space then we limit the VRAM size to the aperture.
+ *
+ * If we are using AGP and if the AGP aperture doesn't allow us to have
+ * room for all the VRAM than we restrict the VRAM to the PCI aperture
+ * size and print a warning.
+ *
+ * This function will never fails, worst case are limiting VRAM.
+ *
+ * Note: GTT start, end, size should be initialized before calling this
+ * function on AGP platform.
+ *
+ * Note: We don't explictly enforce VRAM start to be aligned on VRAM size,
+ * this shouldn't be a problem as we are using the PCI aperture as a reference.
+ * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but
+ * not IGP.
+ *
+ * Note: we use mc_vram_size as on some board we need to program the mc to
+ * cover the whole aperture even if VRAM size is inferior to aperture size
+ * Novell bug 204882 + along with lots of ubuntu ones
+ *
+ * Note: when limiting vram it's safe to overwritte real_vram_size because
+ * we are not in case where real_vram_size is inferior to mc_vram_size (ie
+ * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu
+ * ones)
+ *
+ * Note: IGP TOM addr should be the same as the aperture addr, we don't
+ * explicitly check for that thought.
+ *
+ * FIXME: when reducing VRAM size align new size on power of 2.
  */
-int radeon_mc_setup(struct radeon_device *rdev)
+void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base)
+{
+       mc->vram_start = base;
+       if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) {
+               dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
+               mc->real_vram_size = mc->aper_size;
+               mc->mc_vram_size = mc->aper_size;
+       }
+       mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+       if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) {
+               dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
+               mc->real_vram_size = mc->aper_size;
+               mc->mc_vram_size = mc->aper_size;
+       }
+       mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+       dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+                       mc->mc_vram_size >> 20, mc->vram_start,
+                       mc->vram_end, mc->real_vram_size >> 20);
+}
+
+/**
+ * radeon_gtt_location - try to find GTT location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ *
+ * Function will place try to place GTT before or after VRAM.
+ *
+ * If GTT size is bigger than space left then we ajust GTT size.
+ * Thus function will never fails.
+ *
+ * FIXME: when reducing GTT size align new size on power of 2.
+ */
+void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
 {
-       uint32_t tmp;
+       u64 size_af, size_bf;
 
-       /* Some chips have an "issue" with the memory controller, the
-        * location must be aligned to the size. We just align it down,
-        * too bad if we walk over the top of system memory, we don't
-        * use DMA without a remapped anyway.
-        * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
-        */
-       /* FGLRX seems to setup like this, VRAM a 0, then GART.
-        */
-       /*
-        * Note: from R6xx the address space is 40bits but here we only
-        * use 32bits (still have to see a card which would exhaust 4G
-        * address space).
-        */
-       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.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;
-               } else {
-                       if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
-                               printk(KERN_ERR "[drm] GTT too big to fit "
-                                      "before or after vram location.\n");
-                               return -EINVAL;
-                       }
-                       rdev->mc.gtt_location = 0;
-               }
-       } else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
-               /* gtt location was already setup try to put vram before
-                * if it fits */
-               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.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 "
-                                      "before or after GTT location.\n");
-                               return -EINVAL;
-                       }
+       size_af = 0xFFFFFFFF - mc->vram_end;
+       size_bf = mc->vram_start;
+       if (size_bf > size_af) {
+               if (mc->gtt_size > size_bf) {
+                       dev_warn(rdev->dev, "limiting GTT\n");
+                       mc->gtt_size = size_bf;
                }
+               mc->gtt_start = mc->vram_start - mc->gtt_size;
        } else {
-               rdev->mc.vram_location = 0;
-               tmp = rdev->mc.mc_vram_size;
-               tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
-               rdev->mc.gtt_location = tmp;
-       }
-       rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-       DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20));
-       DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
-                (unsigned)rdev->mc.vram_location,
-                (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1));
-       DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20));
-       DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
-                (unsigned)rdev->mc.gtt_location,
-                (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1));
-       return 0;
+               if (mc->gtt_size > size_af) {
+                       dev_warn(rdev->dev, "limiting GTT\n");
+                       mc->gtt_size = size_af;
+               }
+               mc->gtt_start = mc->vram_end + 1;
+       }
+       mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
+       dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+                       mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
 }
 
-
 /*
  * GPU helpers function.
  */
index 105c678fa73a51986aa0a36586e6e4f41bbf8c55..c39ddda138403e430770467c1ece97f134720ebd 100644 (file)
@@ -252,7 +252,7 @@ int radeonfb_create(struct drm_device *dev,
        info->flags = FBINFO_DEFAULT;
        info->fbops = &radeonfb_ops;
 
-       tmp = fb_gpuaddr - rdev->mc.vram_location;
+       tmp = fb_gpuaddr - rdev->mc.vram_start;
        info->fix.smem_start = rdev->mc.aper_base + tmp;
        info->fix.smem_len = size;
        info->screen_base = fbptr;
index 83d4dbd6d067fe0cb16bb495a60d29aadcc7f728..643251719f1c5948c313458a3dc0c0398526c34b 100644 (file)
@@ -403,7 +403,7 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 
        /* if scanout was in GTT this really wouldn't work */
        /* crtc offset is from display base addr not FB location */
-       radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
+       radeon_crtc->legacy_display_base_addr = rdev->mc.vram_start;
 
        base -= radeon_crtc->legacy_display_base_addr;
 
index 9f5e2f929da98e92cd8c418d010587ad7045d451..313c96bc09da1dcfcb0703ed3aa82a2038af0731 100644 (file)
@@ -186,7 +186,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                radeon_bo_kunmap(gtt_obj[i]);
 
                DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
-                        gtt_addr - rdev->mc.gtt_location);
+                        gtt_addr - rdev->mc.gtt_start);
        }
 
 out_cleanup:
index db820ae9a034432043ca1cefe708b1e4d489bc45..1157e0f758fa17588953ec6aeaabfa0a577af063 100644 (file)
@@ -150,7 +150,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
                man->default_caching = TTM_PL_FLAG_CACHED;
                break;
        case TTM_PL_TT:
-               man->gpu_offset = rdev->mc.gtt_location;
+               man->gpu_offset = rdev->mc.gtt_start;
                man->available_caching = TTM_PL_MASK_CACHING;
                man->default_caching = TTM_PL_FLAG_CACHED;
                man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -180,7 +180,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
                break;
        case TTM_PL_VRAM:
                /* "On-card" video ram */
-               man->gpu_offset = rdev->mc.vram_location;
+               man->gpu_offset = rdev->mc.vram_start;
                man->flags = TTM_MEMTYPE_FLAG_FIXED |
                             TTM_MEMTYPE_FLAG_NEEDS_IOREMAP |
                             TTM_MEMTYPE_FLAG_MAPPABLE;
@@ -262,10 +262,10 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
 
        switch (old_mem->mem_type) {
        case TTM_PL_VRAM:
-               old_start += rdev->mc.vram_location;
+               old_start += rdev->mc.vram_start;
                break;
        case TTM_PL_TT:
-               old_start += rdev->mc.gtt_location;
+               old_start += rdev->mc.gtt_start;
                break;
        default:
                DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
@@ -273,10 +273,10 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
        }
        switch (new_mem->mem_type) {
        case TTM_PL_VRAM:
-               new_start += rdev->mc.vram_location;
+               new_start += rdev->mc.vram_start;
                break;
        case TTM_PL_TT:
-               new_start += rdev->mc.gtt_location;
+               new_start += rdev->mc.gtt_start;
                break;
        default:
                DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
index 1e4582e27c143d5ece3588fc875d96460f69be80..626d51891ee968613efeffc6612698387b46f1d4 100644 (file)
@@ -151,9 +151,8 @@ int rs400_gart_enable(struct radeon_device *rdev)
                WREG32(RADEON_AGP_BASE, 0xFFFFFFFF);
                WREG32(RS480_AGP_BASE_2, 0);
        }
-       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-       tmp = REG_SET(RS690_MC_AGP_TOP, tmp >> 16);
-       tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_location >> 16);
+       tmp = REG_SET(RS690_MC_AGP_TOP, rdev->mc.gtt_end >> 16);
+       tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_start >> 16);
        if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {
                WREG32_MC(RS690_MCCFG_AGP_LOCATION, tmp);
                tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
@@ -252,14 +251,19 @@ void rs400_gpu_init(struct radeon_device *rdev)
        }
 }
 
-void rs400_vram_info(struct radeon_device *rdev)
+void rs400_mc_init(struct radeon_device *rdev)
 {
+       u64 base;
+
        rs400_gart_adjust_size(rdev);
+       rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
        /* DDR for all card after R300 & IGP */
        rdev->mc.vram_is_ddr = true;
        rdev->mc.vram_width = 128;
-
        r100_vram_init_sizes(rdev);
+       base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+       radeon_vram_location(rdev, &rdev->mc, base);
+       radeon_gtt_location(rdev, &rdev->mc);
 }
 
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -363,22 +367,6 @@ static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 #endif
 }
 
-static int rs400_mc_init(struct radeon_device *rdev)
-{
-       int r;
-       u32 tmp;
-
-       /* Setup GPU memory space */
-       tmp = RREG32(R_00015C_NB_TOM);
-       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;
-}
-
 void rs400_mc_program(struct radeon_device *rdev)
 {
        struct r100_mc_save save;
@@ -517,12 +505,8 @@ int rs400_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       rs400_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = rs400_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize memory controller */
+       rs400_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index 28c8690c7a35711aeb06ce221aef75b101866371..d5aeb2a31d59f42ad06e632111d4f742b5073699 100644 (file)
 void rs600_gpu_init(struct radeon_device *rdev);
 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
-int rs600_mc_init(struct radeon_device *rdev)
-{
-       /* read back the MC value from the hw */
-       int r;
-       u32 tmp;
-
-       /* Setup GPU memory space */
-       tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
-       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;
-}
-
 /* hpd for digital panel detect/disconnect */
 bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
 {
@@ -475,22 +458,21 @@ void rs600_gpu_init(struct radeon_device *rdev)
                dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
 }
 
-void rs600_vram_info(struct radeon_device *rdev)
+void rs600_mc_init(struct radeon_device *rdev)
 {
+       u64 base;
+
        rdev->mc.vram_is_ddr = true;
        rdev->mc.vram_width = 128;
-
        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);
-
-       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;
+       rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+       base = RREG32_MC(R_000004_MC_FB_LOCATION);
+       base = G_000004_MC_FB_START(base) << 16;
+       radeon_vram_location(rdev, &rdev->mc, base);
+       radeon_gtt_location(rdev, &rdev->mc);
 }
 
 void rs600_bandwidth_update(struct radeon_device *rdev)
@@ -666,12 +648,8 @@ int rs600_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       rs600_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = rs600_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize memory controller */
+       rs600_mc_init(rdev);
        rs600_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
index 06e2771aee5a8443b94e44e80da3c3b7928590b5..8d37501da7df167219ad7874b8110a146d211d9f 100644 (file)
@@ -129,27 +129,20 @@ void rs690_pm_info(struct radeon_device *rdev)
        rdev->pm.sideport_bandwidth.full = rfixed_div(rdev->pm.sideport_bandwidth, tmp);
 }
 
-void rs690_vram_info(struct radeon_device *rdev)
+void rs690_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
+       u64 base;
 
        rs400_gart_adjust_size(rdev);
-
        rdev->mc.vram_is_ddr = true;
        rdev->mc.vram_width = 128;
-
        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);
-
-       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;
-
+       base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
+       base = G_000100_MC_FB_START(base) << 16;
        rs690_pm_info(rdev);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
@@ -160,22 +153,9 @@ void rs690_vram_info(struct radeon_device *rdev)
        a.full = rfixed_const(16);
        /* core_bandwidth = sclk(Mhz) * 16 */
        rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
-}
-
-static int rs690_mc_init(struct radeon_device *rdev)
-{
-       int r;
-       u32 tmp;
-
-       /* Setup GPU memory space */
-       tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
-       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;
+       radeon_vram_location(rdev, &rdev->mc, base);
+       radeon_gtt_location(rdev, &rdev->mc);
 }
 
 void rs690_line_buffer_adjust(struct radeon_device *rdev,
@@ -728,12 +708,8 @@ int rs690_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       rs690_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = rs690_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize memory controller */
+       rs690_mc_init(rdev);
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
index 0e1e6b8632b86c0e1b6d9665f831f684c11c1dcc..bea747da123ffef833df17c8d71e9ee1b0c02121 100644 (file)
@@ -277,13 +277,15 @@ static void rv515_vram_get_type(struct radeon_device *rdev)
        }
 }
 
-void rv515_vram_info(struct radeon_device *rdev)
+void rv515_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
 
        rv515_vram_get_type(rdev);
-
        r100_vram_init_sizes(rdev);
+       radeon_vram_location(rdev, &rdev->mc, 0);
+       if (!(rdev->flags & RADEON_IS_AGP))
+               radeon_gtt_location(rdev, &rdev->mc);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
@@ -587,12 +589,15 @@ int rv515_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       rv515_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r420_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
+       }
+       /* initialize memory controller */
+       rv515_mc_init(rdev);
        rv515_debugfs(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
index 6f1f4abbe88c567f5568607e5dff719bde5a8f68..323fa6be508230561d6dbdc922a58412cf61c872 100644 (file)
@@ -820,45 +820,12 @@ int rv770_mc_init(struct radeon_device *rdev)
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       /* FIXME remove this once we support unmappable VRAM */
+       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;
-
-       if (rdev->flags & RADEON_IS_AGP) {
-               /* gtt_size is setup by radeon_agp_init */
-               rdev->mc.gtt_location = rdev->mc.agp_base;
-               tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-               /* Try to put vram before or after AGP because we
-                * we want SYSTEM_APERTURE to cover both VRAM and
-                * AGP so that GPU can catch out of VRAM/AGP access
-                */
-               if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-                       /* Enought place before */
-                       rdev->mc.vram_location = rdev->mc.gtt_location -
-                                                       rdev->mc.mc_vram_size;
-               } else if (tmp > rdev->mc.mc_vram_size) {
-                       /* Enought place after */
-                       rdev->mc.vram_location = rdev->mc.gtt_location +
-                                                       rdev->mc.gtt_size;
-               } else {
-                       /* Try to setup VRAM then AGP might not
-                        * not work on some card
-                        */
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               }
-       } else {
-               rdev->mc.vram_location = 0x00000000UL;
-               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        }
-       rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
+       r600_vram_gtt_location(rdev, &rdev->mc);
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
@@ -867,6 +834,7 @@ int rv770_mc_init(struct radeon_device *rdev)
        rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
        return 0;
 }
+
 int rv770_gpu_reset(struct radeon_device *rdev)
 {
        /* FIXME: implement any rv770 specific bits */
@@ -1042,6 +1010,7 @@ int rv770_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
+       /* initialize AGP */
        if (rdev->flags & RADEON_IS_AGP) {
                r = radeon_agp_init(rdev);
                if (r)