diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c index 91abf0b..7c938ae 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c @@ -5,84 +5,77 @@ #include <engine/fifo.h> #include <core/ramht.h> -/* returns the size of fifo context */ -static int -nouveau_fifo_ctx_size(struct drm_device *dev) -{ - return 128 * 32; -} +#include "nv04.h" int nv40_instmem_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramht = NULL; - u32 offset, length, vs, rsvd; + struct nv04_instmem_priv *priv; + u32 vs, rsvd; int ret; - /* RAMIN always available */ - dev_priv->ramin_available = true; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + dev_priv->engine.instmem.priv = priv; - /* Reserve space at end of VRAM for PRAMIN */ - /* estimate grctx size, the magics come from nv40_grctx.c */ + /* PRAMIN aperture maps over the end of vram, reserve enough space + * to fit graphics contexts for every channel, the magics come + * from engine/graph/nv40.c + */ vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8); if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs; else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs; else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs; else rsvd = 0x4a40 * vs; rsvd += 16 * 1024; - rsvd *= 32; /* per-channel */ - - rsvd += 512 * 1024; /* pci(e)gart table */ - rsvd += 512 * 1024; /* object storage */ - + rsvd *= 32; /* per-channel */ + rsvd += 512 * 1024; /* pci(e)gart table */ + rsvd += 512 * 1024; /* object storage */ dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096); + dev_priv->ramin_available = true; - /* Setup shared RAMHT */ - ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096, - NVOBJ_FLAG_ZERO_ALLOC, &ramht); + ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_rsvd_vram); if (ret) return ret; - ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht); - nouveau_gpuobj_ref(NULL, &ramht); + /* 0x00000-0x10000: reserve for probable vbios image */ + ret = nouveau_gpuobj_new(dev, NULL, 0x10000, 0, 0, &priv->vbios); if (ret) return ret; - /* And RAMRO */ - ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512, - NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro); + /* 0x10000-0x18000: reserve for RAMHT */ + ret = nouveau_gpuobj_new(dev, NULL, 0x08000, 0, NVOBJ_FLAG_ZERO_ALLOC, + &priv->ramht); if (ret) return ret; - /* And RAMFC */ - length = nouveau_fifo_ctx_size(dev); - offset = 0x20000; - - ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length, - NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc); + /* 0x18000-0x18200: reserve for RAMRO + * 0x18200-0x20000: padding + */ + ret = nouveau_gpuobj_new(dev, NULL, 0x08000, 0, 0, &priv->ramro); if (ret) return ret; - /* Only allow space after RAMFC to be used for object allocation */ - offset += length; - - /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230 - * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0 - * ("new style" control) the upper 16-bits of 0x2220 points at this - * other mysterious table that's clobbering important things. + /* 0x20000-0x21000: reserve for RAMFC + * 0x21000-0x40000: padding + some unknown stuff (see below) + * + * It appears something is controlled by 0x2220/0x2230 on certain + * NV4x chipsets as well as RAMFC. When 0x2230 == 0 ("new style" + * control) the upper 16-bits of 0x2220 points at this other + * mysterious table that's clobbering important things. * * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting * smashed to pieces on us, so reserve 0x30000-0x40000 too.. */ - if (offset < 0x40000) - offset = 0x40000; + ret = nouveau_gpuobj_new(dev, NULL, 0x20000, 0, NVOBJ_FLAG_ZERO_ALLOC, + &priv->ramfc); + if (ret) + return ret; - ret = drm_mm_init(&dev_priv->ramin_heap, offset, - dev_priv->ramin_rsvd_vram - offset); - if (ret) { - NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret); + ret = nouveau_ramht_new(dev, priv->ramht, &dev_priv->ramht); + if (ret) return ret; - } return 0; } @@ -91,13 +84,18 @@ void nv40_instmem_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv04_instmem_priv *priv = dev_priv->engine.instmem.priv; nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); - nouveau_gpuobj_ref(NULL, &dev_priv->ramro); - nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); + nouveau_gpuobj_ref(NULL, &priv->ramfc); + nouveau_gpuobj_ref(NULL, &priv->ramro); + nouveau_gpuobj_ref(NULL, &priv->ramht); if (drm_mm_initialized(&dev_priv->ramin_heap)) drm_mm_takedown(&dev_priv->ramin_heap); + + kfree(priv); + dev_priv->engine.instmem.priv = NULL; } int |