summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-08-06 22:05:31 +1000
committerBen Skeggs <skeggsb@gmail.com>2007-08-06 22:05:31 +1000
commitcf04641bc61c8bc18101713a8d95ef98e6afae7f (patch)
treebd05e99d8404347729654c9bfe2d815eceaf9a3d /shared-core
parent51f24be578025e3f1eae859288adf5232afc898d (diff)
nouveau: Give DRM its own gpu channel
If your card doesn't have working context switching, it is now broken.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/nouveau_drv.h26
-rw-r--r--shared-core/nouveau_fifo.c14
-rw-r--r--shared-core/nouveau_state.c9
-rw-r--r--shared-core/nv04_instmem.c1
4 files changed, 42 insertions, 8 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 0b173b76..10f9149e 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -134,6 +134,22 @@ struct nouveau_channel
struct list_head ramht_refs; /* Objects referenced by RAMHT */
};
+struct nouveau_drm_channel {
+ struct nouveau_channel *chan;
+
+ /* DMA state */
+ int max, put, cur, free;
+ int push_free;
+ volatile uint32_t *pushbuf;
+
+ /* Notifiers */
+ uint32_t notify0_offset;
+
+ /* Buffer moves */
+ uint32_t m2mf_dma_source;
+ uint32_t m2mf_dma_destin;
+};
+
struct nouveau_config {
struct {
int location;
@@ -222,6 +238,7 @@ struct drm_nouveau_private {
struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER];
struct nouveau_engine Engine;
+ struct nouveau_drm_channel channel;
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
struct nouveau_gpuobj *ramht;
@@ -345,6 +362,10 @@ extern int nouveau_fifo_ctx_size(struct drm_device *);
extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *);
extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *,
int channel);
+extern int nouveau_fifo_alloc(struct drm_device *dev,
+ struct nouveau_channel **chan,
+ struct drm_file *file_priv,
+ uint32_t fb_ctxdma, uint32_t tt_ctxdma);
extern void nouveau_fifo_free(struct nouveau_channel *);
/* nouveau_object.c */
@@ -400,6 +421,11 @@ extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
+/* nouveau_dma.c */
+extern int nouveau_dma_channel_init(struct drm_device *);
+extern void nouveau_dma_channel_takedown(struct drm_device *);
+extern int nouveau_dma_wait(struct drm_device *, int size);
+
/* nv04_fb.c */
extern int nv04_fb_init(struct drm_device *);
extern void nv04_fb_takedown(struct drm_device *);
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 152b669a..823801f9 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -261,9 +261,10 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan)
}
/* allocates and initializes a fifo for user space consumption */
-int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
- struct drm_file *file_priv,
- uint32_t vram_handle, uint32_t tt_handle)
+int
+nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
+ struct drm_file *file_priv,
+ uint32_t vram_handle, uint32_t tt_handle)
{
int ret;
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -288,7 +289,6 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
/* no more fifos. you lost. */
if (channel==nouveau_fifo_number(dev))
return -EINVAL;
- (*chan_ret) = channel;
dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel),
DRM_MEM_DRIVER);
@@ -394,6 +394,7 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
NV_WRITE(NV03_PFIFO_CACHES, 1);
DRM_INFO("%s: initialised FIFO %d\n", __func__, channel);
+ *chan_ret = chan;
return 0;
}
@@ -482,13 +483,12 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
return -EINVAL;
- res = nouveau_fifo_alloc(dev, &init->channel, file_priv,
+ res = nouveau_fifo_alloc(dev, &chan, file_priv,
init->fb_ctxdma_handle,
init->tt_ctxdma_handle);
if (res)
return res;
- chan = dev_priv->fifos[init->channel];
-
+ init->channel = chan->id;
init->put_base = chan->pushbuf_base;
/* make the fifo available to user space */
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index 4fb53291..9dab34cc 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -274,6 +274,8 @@ nouveau_card_init(struct drm_device *dev)
struct nouveau_engine *engine;
int ret;
+ DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
+
if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
return 0;
@@ -335,6 +337,9 @@ nouveau_card_init(struct drm_device *dev)
/* what about PVIDEO/PCRTC/PRAMDAC etc? */
+ ret = nouveau_dma_channel_init(dev);
+ if (ret) return ret;
+
dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
return 0;
}
@@ -344,7 +349,11 @@ static void nouveau_card_takedown(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->Engine;
+ DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
+
if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
+ nouveau_dma_channel_takedown(dev);
+
engine->fifo.takedown(dev);
engine->graph.takedown(dev);
engine->fb.takedown(dev);
diff --git a/shared-core/nv04_instmem.c b/shared-core/nv04_instmem.c
index 36aa6200..5e0f6f4e 100644
--- a/shared-core/nv04_instmem.c
+++ b/shared-core/nv04_instmem.c
@@ -129,7 +129,6 @@ nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
if (gpuobj && gpuobj->im_backing) {
if (gpuobj->im_bound)
dev_priv->Engine.instmem.unbind(dev, gpuobj);
- nouveau_mem_free(dev, gpuobj->im_backing);
gpuobj->im_backing = NULL;
}
}