From patchwork Wed Feb 17 21:54:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Glisse X-Patchwork-Id: 80089 Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1HLuA2H029820 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 17 Feb 2010 21:56:48 GMT Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1Nhrr1-0003Fr-35; Wed, 17 Feb 2010 21:54:43 +0000 Received: from sfi-mx-2.v28.ch3.sourceforge.com ([172.29.28.122] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1Nhrr0-0003Fc-0P for dri-devel@lists.sourceforge.net; Wed, 17 Feb 2010 21:54:42 +0000 Received-SPF: fail (sfi-mx-2.v28.ch3.sourceforge.com: domain of redhat.com does not designate 88.191.38.29 as permitted sender) client-ip=88.191.38.29; envelope-from=jglisse@redhat.com; helo=nox.protox.org; Received: from nox.protox.org ([88.191.38.29]) by sfi-mx-2.v28.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.69) id 1Nhrqy-0004b4-0h for dri-devel@lists.sourceforge.net; Wed, 17 Feb 2010 21:54:41 +0000 Received: from localhost.localdomain (lag77-1-82-238-106-69.fbx.proxad.net [82.238.106.69]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by nox.protox.org (Postfix) with ESMTPSA id 94EBE169E35; Wed, 17 Feb 2010 22:54:33 +0100 (CET) From: Jerome Glisse To: airlied@gmail.com Subject: [PATCH] drm/radeon/kms: simplify memory controller setup V2 Date: Wed, 17 Feb 2010 22:54:29 +0100 Message-Id: <1266443669-3247-1-git-send-email-jglisse@redhat.com> X-Mailer: git-send-email 1.6.6 X-Spam-Score: 5.0 (+++++) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 4.0 SPF_CHECK_FAIL SPF reports sender host as NOT permitted to send mails from 1.0 SPF_FAIL SPF: sender does not match SPF record (fail) X-Headers-End: 1Nhrqy-0004b4-0h Cc: Jerome Glisse , dri-devel@lists.sf.net X-BeenThere: dri-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.sourceforge.net X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 17 Feb 2010 21:56:49 +0000 (UTC) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 3368920..3f973d4 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -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; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bc7d9e9..1fdd793 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -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) diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 654aca1..7f8dd10 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -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); @@ -503,13 +503,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) { @@ -518,8 +517,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) @@ -1421,12 +1421,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) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 12ebbdb..c7593b8 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -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); diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index ddf5731..2b8a5dd 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -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); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 6434d6a..6869723 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -623,6 +623,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; @@ -662,75 +724,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; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9f35bee..c84c764 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -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); @@ -1160,6 +1159,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 { @@ -1214,7 +1215,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); @@ -1223,7 +1224,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); @@ -1265,6 +1265,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); diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index c0681a5..c445779 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -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) { diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index fb55faf..d459270 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -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. */ diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 105c678..c39ddda 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 83d4dbd..6432517 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 9f5e2f9..313c96b 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -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: diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index db820ae..1157e0f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -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); diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 1e4582e..626d518 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -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) diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 28c8690..d5aeb2a 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -45,23 +45,6 @@ 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); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 06e2771..8d37501 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -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); diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 0e1e6b8..bea747d 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -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); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 6f1f4ab..323fa6b 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -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)