summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-09-01 09:24:35 +0400
committerBen Skeggs <bskeggs@redhat.com>2010-09-24 10:23:22 +0400
commite05c5a317efb03854950a3fcc5c9501bfefc7d68 (patch)
tree188a3d497848cd383e69734a17e4d76f7939056f /drivers
parentfbd2895e45aebdb3d3ea73a3a796cf3bb9c912da (diff)
downloadlinux-e05c5a317efb03854950a3fcc5c9501bfefc7d68.tar.xz
drm/nouveau: tidy ram{ht,fc,ro} a bit
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ramht.c23
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ramht.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fifo.c11
-rw-r--r--drivers/gpu/drm/nouveau/nv04_instmem.c87
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fifo.c13
-rw-r--r--drivers/gpu/drm/nouveau/nv40_fifo.c11
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fifo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_instmem.c4
11 files changed, 69 insertions, 101 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 3ba7a649fe51..71e27087951b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -545,15 +545,11 @@ struct drm_nouveau_private {
spinlock_t context_switch_lock;
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
- struct nouveau_ramht *ramht;
+ struct nouveau_ramht *ramht;
+ struct nouveau_gpuobj *ramfc;
+ struct nouveau_gpuobj *ramro;
+
uint32_t ramin_rsvd_vram;
- uint32_t ramht_offset;
- uint32_t ramht_size;
- uint32_t ramht_bits;
- uint32_t ramfc_offset;
- uint32_t ramfc_size;
- uint32_t ramro_offset;
- uint32_t ramro_size;
struct {
enum {
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index b68922f2fe54..198c2514f893 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -192,8 +192,6 @@ nouveau_gpuobj_takedown(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
NV_DEBUG(dev, "\n");
-
- nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
}
void
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c
index 5f9d52f06305..ccbc8d69ea68 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ramht.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c
@@ -28,21 +28,23 @@
#include "nouveau_ramht.h"
static uint32_t
-nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
+nouveau_ramht_hash_handle(struct nouveau_channel *chan, uint32_t handle)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_ramht *ramht = chan->ramht;
uint32_t hash = 0;
int i;
- NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle);
+ NV_DEBUG(dev, "ch%d handle=0x%08x\n", chan->id, handle);
- for (i = 32; i > 0; i -= dev_priv->ramht_bits) {
- hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
- handle >>= dev_priv->ramht_bits;
+ for (i = 32; i > 0; i -= ramht->bits) {
+ hash ^= (handle & ((1 << ramht->bits) - 1));
+ handle >>= ramht->bits;
}
if (dev_priv->card_type < NV_50)
- hash ^= channel << (dev_priv->ramht_bits - 4);
+ hash ^= chan->id << (ramht->bits - 4);
hash <<= 3;
NV_DEBUG(dev, "hash=0x%08x\n", hash);
@@ -103,7 +105,7 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
}
}
- co = ho = nouveau_ramht_hash_handle(dev, chan->id, handle);
+ co = ho = nouveau_ramht_hash_handle(chan, handle);
do {
if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
NV_DEBUG(dev,
@@ -119,7 +121,7 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
chan->id, co, nv_ro32(ramht, co));
co += 8;
- if (co >= dev_priv->ramht_size)
+ if (co >= ramht->size)
co = 0;
} while (co != ho);
@@ -149,7 +151,7 @@ nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
break;
}
- co = ho = nouveau_ramht_hash_handle(dev, chan->id, handle);
+ co = ho = nouveau_ramht_hash_handle(chan, handle);
do {
if (nouveau_ramht_entry_valid(dev, ramht, co) &&
(handle == nv_ro32(ramht, co))) {
@@ -163,7 +165,7 @@ nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
}
co += 8;
- if (co >= dev_priv->ramht_size)
+ if (co >= ramht->size)
co = 0;
} while (co != ho);
@@ -196,6 +198,7 @@ nouveau_ramht_new(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
ramht->dev = dev;
ramht->refcount = 1;
+ ramht->bits = drm_order(gpuobj->size / 8);
INIT_LIST_HEAD(&ramht->entries);
nouveau_gpuobj_ref(gpuobj, &ramht->gpuobj);
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.h b/drivers/gpu/drm/nouveau/nouveau_ramht.h
index 7076ae4c07a5..f37737a93642 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ramht.h
+++ b/drivers/gpu/drm/nouveau/nouveau_ramht.h
@@ -37,6 +37,7 @@ struct nouveau_ramht {
int refcount;
struct nouveau_gpuobj *gpuobj;
struct list_head entries;
+ int bits;
};
extern int nouveau_ramht_new(struct drm_device *, struct nouveau_gpuobj *,
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
index b7ecafb78d77..64dc0e215eeb 100644
--- a/drivers/gpu/drm/nouveau/nv04_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv04_fifo.c
@@ -27,8 +27,9 @@
#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"
+#include "nouveau_ramht.h"
-#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE))
+#define NV04_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV04_RAMFC__SIZE))
#define NV04_RAMFC__SIZE 32
#define NV04_RAMFC_DMA_PUT 0x00
#define NV04_RAMFC_DMA_GET 0x04
@@ -262,10 +263,10 @@ nv04_fifo_init_ramxx(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht_bits - 9) << 16) |
- (dev_priv->ramht_offset >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
- nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+ ((dev_priv->ramht->bits - 9) << 16) |
+ (dev_priv->ramht->gpuobj->pinst >> 8));
+ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
+ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8);
}
static void
diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
index 15cd468f4c29..88316100389b 100644
--- a/drivers/gpu/drm/nouveau/nv04_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
@@ -18,65 +18,15 @@ nouveau_fifo_ctx_size(struct drm_device *dev)
return 32;
}
-static void
-nv04_instmem_configure_fixed_tables(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine *engine = &dev_priv->engine;
-
- /* FIFO hash table (RAMHT)
- * use 4k hash table at RAMIN+0x10000
- * TODO: extend the hash table
- */
- dev_priv->ramht_offset = 0x10000;
- dev_priv->ramht_bits = 9;
- dev_priv->ramht_size = (1 << dev_priv->ramht_bits); /* nr entries */
- dev_priv->ramht_size *= 8; /* 2 32-bit values per entry in RAMHT */
- NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset,
- dev_priv->ramht_size);
-
- /* FIFO runout table (RAMRO) - 512k at 0x11200 */
- dev_priv->ramro_offset = 0x11200;
- dev_priv->ramro_size = 512;
- NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset,
- dev_priv->ramro_size);
-
- /* FIFO context table (RAMFC)
- * NV40 : Not sure exactly how to position RAMFC on some cards,
- * 0x30002 seems to position it at RAMIN+0x20000 on these
- * cards. RAMFC is 4kb (32 fifos, 128byte entries).
- * Others: Position RAMFC at RAMIN+0x11400
- */
- dev_priv->ramfc_size = engine->fifo.channels *
- nouveau_fifo_ctx_size(dev);
- switch (dev_priv->card_type) {
- case NV_40:
- dev_priv->ramfc_offset = 0x20000;
- break;
- case NV_30:
- case NV_20:
- case NV_10:
- case NV_04:
- default:
- dev_priv->ramfc_offset = 0x11400;
- break;
- }
- NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
- dev_priv->ramfc_size);
-}
-
int nv04_instmem_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *ramht = NULL;
- uint32_t offset;
+ u32 offset, length;
int ret;
- nv04_instmem_configure_fixed_tables(dev);
-
/* Setup shared RAMHT */
- ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset, ~0,
- dev_priv->ramht_size,
+ ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
NVOBJ_FLAG_ZERO_ALLOC, &ramht);
if (ret)
return ret;
@@ -86,10 +36,30 @@ int nv04_instmem_init(struct drm_device *dev)
if (ret)
return ret;
- /* Create a heap to manage RAMIN allocations, we don't allocate
- * the space that was reserved for RAMHT/FC/RO.
- */
- offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+ /* And RAMRO */
+ ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512,
+ NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro);
+ if (ret)
+ return ret;
+
+ /* And RAMFC */
+ length = dev_priv->engine.fifo.channels * nouveau_fifo_ctx_size(dev);
+ switch (dev_priv->card_type) {
+ case NV_40:
+ offset = 0x20000;
+ break;
+ default:
+ offset = 0x11400;
+ break;
+ }
+
+ ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
+ NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
+ 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
@@ -118,6 +88,11 @@ int nv04_instmem_init(struct drm_device *dev)
void
nv04_instmem_takedown(struct drm_device *dev)
{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
+ nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
+ nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
}
int
diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c
index ccb07fb701ca..f1b03ad58fd5 100644
--- a/drivers/gpu/drm/nouveau/nv10_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv10_fifo.c
@@ -27,8 +27,9 @@
#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"
+#include "nouveau_ramht.h"
-#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE))
+#define NV10_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV10_RAMFC__SIZE))
#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32)
int
@@ -202,14 +203,14 @@ nv10_fifo_init_ramxx(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht_bits - 9) << 16) |
- (dev_priv->ramht_offset >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+ ((dev_priv->ramht->bits - 9) << 16) |
+ (dev_priv->ramht->gpuobj->pinst >> 8));
+ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
if (dev_priv->chipset < 0x17) {
- nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8);
} else {
- nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) |
+ nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc->pinst >> 8) |
(1 << 16) /* 64 Bytes entry*/);
/* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */
}
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
index 03f4dc13725b..d337b8b28cdd 100644
--- a/drivers/gpu/drm/nouveau/nv40_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv40_fifo.c
@@ -27,8 +27,9 @@
#include "drmP.h"
#include "nouveau_drv.h"
#include "nouveau_drm.h"
+#include "nouveau_ramht.h"
-#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV40_RAMFC__SIZE))
+#define NV40_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV40_RAMFC__SIZE))
#define NV40_RAMFC__SIZE 128
int
@@ -240,9 +241,9 @@ nv40_fifo_init_ramxx(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht_bits - 9) << 16) |
- (dev_priv->ramht_offset >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+ ((dev_priv->ramht->bits - 9) << 16) |
+ (dev_priv->ramht->gpuobj->pinst >> 8));
+ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
switch (dev_priv->chipset) {
case 0x47:
@@ -270,7 +271,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev)
nv_wr32(dev, 0x2230, 0);
nv_wr32(dev, NV40_PFIFO_RAMFC,
((dev_priv->vram_size - 512 * 1024 +
- dev_priv->ramfc_offset) >> 16) | (3 << 16));
+ dev_priv->ramfc->pinst) >> 16) | (3 << 16));
break;
}
}
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
index 4fc8b59cc41e..a46a961102f3 100644
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -259,7 +259,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
nv_wo32(ramfc, 0x48, chan->pushbuf->cinst >> 4);
- nv_wo32(ramfc, 0x80, (0 << 27) /* 4KiB */ |
+ nv_wo32(ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->gpuobj->cinst >> 4));
nv_wo32(ramfc, 0x44, 0x2101ffff);
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index d932594449c1..2e0aaf971b2f 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -230,10 +230,6 @@ nv50_instmem_init(struct drm_device *dev)
for (i = 0; i < 8; i++)
nv_wr32(dev, 0x1900 + (i*4), 0);
- /*XXX: incorrect, but needed to make hash func "work" */
- dev_priv->ramht_offset = 0x10000;
- dev_priv->ramht_bits = 9;
- dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c
index 0ffdcf6c7f5d..595540975637 100644
--- a/drivers/gpu/drm/nouveau/nvc0_instmem.c
+++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c
@@ -220,10 +220,6 @@ nvc0_instmem_init(struct drm_device *dev)
return -ENOMEM;
}
- /*XXX: incorrect, but needed to make hash func "work" */
- dev_priv->ramht_offset = 0x10000;
- dev_priv->ramht_bits = 9;
- dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
return 0;
}