summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-08-14 14:43:51 +1000
committerDave Airlie <airlied@redhat.com>2008-08-14 14:43:51 +1000
commit30ff279e42b3b0608e8ff6620d2958c174449798 (patch)
treefb9e61e8ed1da64534c28a4d4579472217de446d
parenteb8f9b9da4d34b9bfa16dc3847e81976a12d2d0c (diff)
radeon: add support for memory map init
-rw-r--r--linux-core/radeon_gem.c86
-rw-r--r--shared-core/radeon_cp.c42
-rw-r--r--shared-core/radeon_drv.h7
3 files changed, 124 insertions, 11 deletions
diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c
index df4ed4ce..bf8fb2e9 100644
--- a/linux-core/radeon_gem.c
+++ b/linux-core/radeon_gem.c
@@ -615,6 +615,90 @@ int radeon_alloc_gart_objects(struct drm_device *dev)
}
+static void radeon_init_memory_map(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 mem_size, aper_size;
+
+ dev_priv->mc_fb_location = radeon_read_fb_location(dev_priv);
+ radeon_read_agp_location(dev_priv, &dev_priv->mc_agp_loc_lo, &dev_priv->mc_agp_loc_hi);
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ mem_size = RADEON_READ(R600_CONFIG_MEMSIZE);
+ aper_size = RADEON_READ(R600_CONFIG_APER_SIZE);
+ } else {
+ mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE);
+ aper_size = RADEON_READ(RADEON_CONFIG_APER_SIZE);
+ }
+
+ /* M6s report illegal memory size */
+ if (mem_size == 0)
+ mem_size = 8 * 1024 * 1024;
+
+ /* for RN50/M6/M7 - Novell bug 204882 */
+ if (aper_size > mem_size)
+ mem_size = aper_size;
+
+ if ((dev_priv->chip_family != CHIP_RS600) &&
+ (dev_priv->chip_family != CHIP_RS690) &&
+ (dev_priv->chip_family != CHIP_RS740)) {
+ if (dev_priv->flags & RADEON_IS_IGP)
+ dev_priv->mc_fb_location = RADEON_READ(RADEON_NB_TOM);
+ else {
+ uint32_t aper0_base;
+
+ if (dev_priv->chip_family >= CHIP_R600)
+ aper0_base = RADEON_READ(R600_CONFIG_F0_BASE);
+ else
+ aper0_base = RADEON_READ(RADEON_CONFIG_APER_0_BASE);
+
+
+ /* 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
+ */
+ if (dev_priv->chip_family == CHIP_RV280 ||
+ dev_priv->chip_family == CHIP_R300 ||
+ dev_priv->chip_family == CHIP_R350 ||
+ dev_priv->chip_family == CHIP_RV350 ||
+ dev_priv->chip_family == CHIP_RV380 ||
+ dev_priv->chip_family == CHIP_R420 ||
+ dev_priv->chip_family == CHIP_RV410)
+ aper0_base &= ~(mem_size - 1);
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ dev_priv->mc_fb_location = (aper0_base >> 24) |
+ (((aper0_base + mem_size - 1) & 0xff000000U) >> 8);
+ } else {
+ dev_priv->mc_fb_location = (aper0_base >> 16) |
+ ((aper0_base + mem_size - 1) & 0xffff0000U);
+ }
+ }
+ }
+
+ if (dev_priv->chip_family >= CHIP_R600)
+ dev_priv->fb_location = (dev_priv->mc_fb_location & 0xffff) << 24;
+ else
+ dev_priv->fb_location = (dev_priv->mc_fb_location & 0xffff) << 16;
+
+ if (radeon_is_avivo(dev_priv)) {
+ if (dev_priv->chip_family >= CHIP_R600)
+ RADEON_WRITE(R600_HDP_NONSURFACE_BASE, (dev_priv->mc_fb_location << 16) & 0xff0000);
+ else
+ RADEON_WRITE(AVIVO_HDP_FB_LOCATION, dev_priv->mc_fb_location);
+ }
+
+ radeon_write_fb_location(dev_priv, dev_priv->mc_fb_location);
+
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
+ dev_priv->fb_size =
+ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
+ - dev_priv->fb_location;
+
+}
+
/* init memory manager - start with all of VRAM and a 32MB GART aperture for now */
int radeon_gem_mm_init(struct drm_device *dev)
{
@@ -624,6 +708,8 @@ int radeon_gem_mm_init(struct drm_device *dev)
/* size the mappable VRAM memory for now */
radeon_vram_setup(dev);
+ radeon_init_memory_map(dev);
+
drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, /*dev_priv->mm.vram_offset >> PAGE_SHIFT,*/
(dev_priv->mm.vram_visible) >> PAGE_SHIFT,
0);
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 04f4b1f8..e30696fc 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -107,7 +107,33 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
return RADEON_READ(RADEON_MC_FB_LOCATION);
}
-static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
+void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi)
+{
+ if (dev_priv->chip_family == CHIP_RV770) {
+
+ } else if (dev_priv->chip_family == CHIP_R600) {
+ *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT);
+ *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP);
+ } else if (dev_priv->chip_family == CHIP_RV515) {
+ *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION);
+ *agp_hi = 0;
+ } else if (dev_priv->chip_family == CHIP_RS600) {
+ *agp_lo = 0;
+ *agp_hi = 0;
+ } else if (dev_priv->chip_family == CHIP_RS690 ||
+ dev_priv->chip_family == CHIP_RS740) {
+ *agp_lo = radeon_read_mc_reg(dev_priv, RS690_MC_AGP_LOCATION);
+ *agp_hi = 0;
+ } else if (dev_priv->chip_family >= CHIP_R520) {
+ *agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION);
+ *agp_hi = 0;
+ } else {
+ *agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION);
+ *agp_hi = 0;
+ }
+}
+
+void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
@@ -119,7 +145,7 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
}
-static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc, u32 agp_loc_hi)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
@@ -672,7 +698,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
- (dev_priv->gart_vm_start >> 16)));
+ (dev_priv->gart_vm_start >> 16)), 0);
ring_start = (dev_priv->cp_ring->offset
- dev->agp->base
@@ -873,7 +899,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
0xffff0000) | (dev_priv->gart_vm_start >> 16));
- radeon_write_agp_location(dev_priv, temp);
+ radeon_write_agp_location(dev_priv, temp, 0);
temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
@@ -921,7 +947,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
dev_priv->gart_vm_start +
dev_priv->gart_size - 1);
- radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0, 0); /* ?? */
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
RADEON_PCIE_TX_GART_EN);
@@ -965,7 +991,7 @@ void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
/* Turn off AGP aperture -- is this required for PCI GART?
*/
- radeon_write_agp_location(dev_priv, 0xffffffc0);
+ radeon_write_agp_location(dev_priv, 0xffffffc0, 0);
RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
} else {
RADEON_WRITE(RADEON_AIC_CNTL,
@@ -2482,10 +2508,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
- dev_priv->fb_size =
- ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
- - dev_priv->fb_location;
radeon_gem_mm_init(dev);
radeon_modeset_init(dev);
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index a40ff6dd..9edd3884 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -418,6 +418,10 @@ typedef struct drm_radeon_private {
bool is_ddr;
u32 ram_width;
+ uint32_t mc_fb_location;
+ uint32_t mc_agp_loc_lo;
+ uint32_t mc_agp_loc_hi;
+
enum radeon_pll_errata pll_errata;
int num_gb_pipes;
@@ -1655,7 +1659,8 @@ int radeon_modeset_init(struct drm_device *dev);
void radeon_modeset_cleanup(struct drm_device *dev);
extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr);
extern void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val);
-
+void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi);
+void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc);
extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on);
#define RADEONFB_CONN_LIMIT 4