radeon: add support for memory map init

This commit is contained in:
Dave Airlie 2008-08-14 14:43:51 +10:00
parent eb8f9b9da4
commit 30ff279e42
3 changed files with 124 additions and 11 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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