From 96545299d7405d4c0f44b727718e263653fc11aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:26:24 +1000 Subject: [PATCH] drm/nvc0: fix channel dma init paths Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 20 ++++++++++++++++---- drivers/gpu/drm/nouveau/nouveau_dma.c | 22 ++++++++++++++++------ drivers/gpu/drm/nouveau/nouveau_dma.h | 6 ++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 6f37995aee2..e37977d0246 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -38,9 +38,14 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) int ret; if (dev_priv->card_type >= NV_50) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - (1ULL << 40), NV_MEM_ACCESS_RO, - NV_MEM_TARGET_VM, &pushbuf); + if (dev_priv->card_type < NV_C0) { + ret = nouveau_gpuobj_dma_new(chan, + NV_CLASS_DMA_IN_MEMORY, 0, + (1ULL << 40), + NV_MEM_ACCESS_RO, + NV_MEM_TARGET_VM, + &pushbuf); + } chan->pushbuf_base = pb->bo.offset; } else if (pb->bo.mem.mem_type == TTM_PL_TT) { @@ -71,7 +76,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) nouveau_gpuobj_ref(pushbuf, &chan->pushbuf); nouveau_gpuobj_ref(NULL, &pushbuf); - return 0; + return ret; } static struct nouveau_bo * @@ -99,6 +104,13 @@ nouveau_channel_user_pushbuf_alloc(struct drm_device *dev) return NULL; } + ret = nouveau_bo_map(pushbuf); + if (ret) { + nouveau_bo_unpin(pushbuf); + nouveau_bo_ref(NULL, &pushbuf); + return NULL; + } + return pushbuf; } diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 6ff77cedc00..65699bfaaae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -36,7 +36,7 @@ nouveau_dma_pre_init(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nouveau_bo *pushbuf = chan->pushbuf_bo; - if (dev_priv->card_type == NV_50) { + if (dev_priv->card_type >= NV_50) { const int ib_size = pushbuf->bo.mem.size / 2; chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2; @@ -61,6 +61,21 @@ nouveau_dma_init(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; int ret, i; + if (dev_priv->card_type >= NV_C0) { + ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); + if (ret) + return ret; + + ret = RING_SPACE(chan, 2); + if (ret) + return ret; + + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1); + OUT_RING (chan, 0x00009039); + FIRE_RING (chan); + return 0; + } + /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ ret = nouveau_gpuobj_gr_new(chan, NvM2MF, dev_priv->card_type < NV_50 ? 0x0039 : 0x5039); @@ -72,11 +87,6 @@ nouveau_dma_init(struct nouveau_channel *chan) if (ret) return ret; - /* Map push buffer */ - ret = nouveau_bo_map(chan->pushbuf_bo); - if (ret) - return ret; - /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index d578c21d3c8..c118a331b5b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -124,6 +124,12 @@ OUT_RING(struct nouveau_channel *chan, int data) extern void OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords); +static inline void +BEGIN_NVC0(struct nouveau_channel *chan, int op, int subc, int mthd, int size) +{ + OUT_RING(chan, (op << 28) | (size << 16) | (subc << 13) | (mthd >> 2)); +} + static inline void BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) { -- 2.41.0