From ecb04e265ac6a94035572ee8b6eab54d0cbd0a83 Mon Sep 17 00:00:00 2001 From: David Miller Date: Sat, 14 Feb 2009 01:51:07 -0800 Subject: [PATCH] --- yaml --- r: 138951 b: refs/heads/master c: 6abf6bb0ff90bb77f9429bd0d90fc841c358daf3 h: refs/heads/master i: 138949: 8a64ced8b4572dd456a342dfcbfb8eaf1ca616ee 138947: 4bbcd9db30eb1ad0542ac5569103686954efeeaa 138943: 8c7be629198e92407bc5e409d164df3d6a1dae51 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/radeon/radeon_cp.c | 58 ++++++++++++++++++++- trunk/drivers/gpu/drm/radeon/radeon_drv.h | 1 + trunk/drivers/gpu/drm/radeon/radeon_state.c | 1 + 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 74089283fb99..335e4afea244 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e8a894372b4ea05dc266ba7d7a7634315b6230e8 +refs/heads/master: 6abf6bb0ff90bb77f9429bd0d90fc841c358daf3 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cp.c b/trunk/drivers/gpu/drm/radeon/radeon_cp.c index 4a56e7d626a6..a18b3688a7f0 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cp.c @@ -919,6 +919,46 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } +static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) +{ + struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; + struct radeon_virt_surface *vp; + int i; + + for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { + if (!dev_priv->virt_surfaces[i].file_priv || + dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) + break; + } + if (i >= 2 * RADEON_MAX_SURFACES) + return -ENOMEM; + vp = &dev_priv->virt_surfaces[i]; + + for (i = 0; i < RADEON_MAX_SURFACES; i++) { + struct radeon_surface *sp = &dev_priv->surfaces[i]; + if (sp->refcount) + continue; + + vp->surface_index = i; + vp->lower = gart_info->bus_addr; + vp->upper = vp->lower + gart_info->table_size; + vp->flags = 0; + vp->file_priv = PCIGART_FILE_PRIV; + + sp->refcount = 1; + sp->lower = vp->lower; + sp->upper = vp->upper; + sp->flags = 0; + + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); + return 0; + } + + return -ENOMEM; +} + static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, struct drm_file *file_priv) { @@ -1212,6 +1252,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } else #endif { + u32 sctrl; + int ret; + dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset_set) { @@ -1253,12 +1296,25 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } } - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { + sctrl = RADEON_READ(RADEON_SURFACE_CNTL); + RADEON_WRITE(RADEON_SURFACE_CNTL, 0); + ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); + RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); + + if (!ret) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); return -ENOMEM; } + ret = radeon_setup_pcigart_surface(dev_priv); + if (ret) { + DRM_ERROR("failed to setup GART surface!\n"); + drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); + radeon_do_cleanup_cp(dev); + return ret; + } + /* Turn on PCI GART */ radeon_set_pcigart(dev_priv, 1); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.h b/trunk/drivers/gpu/drm/radeon/radeon_drv.h index 9b60a268dc7a..ecfd414bb99c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.h @@ -217,6 +217,7 @@ struct radeon_virt_surface { u32 upper; u32 flags; struct drm_file *file_priv; +#define PCIGART_FILE_PRIV ((void *) -1L) }; #define RADEON_FLUSH_EMITED (1 << 0) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_state.c b/trunk/drivers/gpu/drm/radeon/radeon_state.c index 03fea43dae75..043293ae6e48 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_state.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_state.c @@ -3155,6 +3155,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) void radeon_driver_lastclose(struct drm_device *dev) { + radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); radeon_do_release(dev); }