summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_state.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-07-02 19:31:18 +1000
committerBen Skeggs <skeggsb@gmail.com>2007-07-09 16:16:44 +1000
commit163f8526123ffa38783fc911b5f7a19debce7f73 (patch)
tree361850d429808f9a3baf2228b2067160b6bc0fe1 /shared-core/nouveau_state.c
parentd57b7f02d2e525e5600e5d77370d7ad2b4c9b265 (diff)
nouveau: rewrite gpu object code
Allows multiple references to a single object, needed to support PCI(E)GART scatter-gather DMA objects which would quickly fill PRAMIN if each channel had its own. Handle per-channel private instmem areas. This is needed to support NV50, but might be something we want to do on earlier chipsets at some point? Everything that touches PRAMIN is a GPU object.
Diffstat (limited to 'shared-core/nouveau_state.c')
-rw-r--r--shared-core/nouveau_state.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index fa773d28..13bc930a 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -283,6 +283,20 @@ static int nouveau_card_init(drm_device_t *dev)
return 0;
}
+static void nouveau_card_takedown(drm_device_t *dev)
+{
+ drm_nouveau_private_t *dev_priv = dev->dev_private;
+ nouveau_engine_func_t *engine = &dev_priv->Engine;
+
+ engine->fifo.takedown(dev);
+ engine->graph.takedown(dev);
+ engine->fb.takedown(dev);
+ engine->timer.takedown(dev);
+ engine->mc.takedown(dev);
+ nouveau_gpuobj_takedown(dev);
+ nouveau_mem_close(dev);
+}
+
/* here a client dies, release the stuff that was allocated for its filp */
void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
{
@@ -314,11 +328,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
if (flags==NV_UNKNOWN)
return DRM_ERR(EINVAL);
- dev_priv = drm_alloc(sizeof(drm_nouveau_private_t), DRM_MEM_DRIVER);
+ dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
if (!dev_priv)
return DRM_ERR(ENOMEM);
- memset(dev_priv, 0, sizeof(drm_nouveau_private_t));
dev_priv->card_type=flags&NOUVEAU_FAMILY;
dev_priv->flags=flags&NOUVEAU_FLAGS;
@@ -338,6 +351,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
void nouveau_lastclose(struct drm_device *dev)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+ nouveau_card_takedown(dev);
+
if(dev_priv->fb_mtrr>0)
{
drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);