Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 307559
b: refs/heads/master
c: d1b167e
h: refs/heads/master
i:
  307557: 1764bf7
  307555: e154238
  307551: 40d3b4d
v: v3
  • Loading branch information
Ben Skeggs committed May 24, 2012
1 parent 18c95d2 commit af2ea57
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 95 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 78df3a1c585c8c95fd9a472125f0cd406e8617ce
refs/heads/master: d1b167e168bdac0b6af11e7a8c601773639fc419
129 changes: 104 additions & 25 deletions trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "nouveau_mm.h"
#include "nouveau_vm.h"
#include "nouveau_fence.h"
#include "nouveau_ramht.h"

#include <linux/log2.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -510,6 +511,17 @@ nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
return ret;
}

static int
nvc0_bo_move_init(struct nouveau_channel *chan, u32 handle)
{
int ret = RING_SPACE(chan, 2);
if (ret == 0) {
BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
OUT_RING (chan, handle);
}
return ret;
}

static int
nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
Expand All @@ -528,17 +540,17 @@ nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NVC0(chan, NvSubM2MF, 0x0238, 2);
BEGIN_NVC0(chan, NvSubCopy, 0x0238, 2);
OUT_RING (chan, upper_32_bits(dst_offset));
OUT_RING (chan, lower_32_bits(dst_offset));
BEGIN_NVC0(chan, NvSubM2MF, 0x030c, 6);
BEGIN_NVC0(chan, NvSubCopy, 0x030c, 6);
OUT_RING (chan, upper_32_bits(src_offset));
OUT_RING (chan, lower_32_bits(src_offset));
OUT_RING (chan, PAGE_SIZE); /* src_pitch */
OUT_RING (chan, PAGE_SIZE); /* dst_pitch */
OUT_RING (chan, PAGE_SIZE); /* line_length */
OUT_RING (chan, line_count);
BEGIN_NVC0(chan, NvSubM2MF, 0x0300, 1);
BEGIN_NVC0(chan, NvSubCopy, 0x0300, 1);
OUT_RING (chan, 0x00100110);

page_count -= line_count;
Expand All @@ -549,6 +561,28 @@ nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
return 0;
}

static int
nv50_bo_move_init(struct nouveau_channel *chan, u32 handle)
{
int ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
&chan->m2mf_ntfy);
if (ret == 0) {
ret = RING_SPACE(chan, 6);
if (ret == 0) {
BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
OUT_RING (chan, handle);
BEGIN_NV04(chan, NvSubCopy, 0x0180, 3);
OUT_RING (chan, NvNotify0);
OUT_RING (chan, NvDmaFB);
OUT_RING (chan, NvDmaFB);
} else {
nouveau_ramht_remove(chan, NvNotify0);
}
}

return ret;
}

static int
nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
Expand All @@ -573,7 +607,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, 0x0200, 7);
BEGIN_NV04(chan, NvSubCopy, 0x0200, 7);
OUT_RING (chan, 0);
OUT_RING (chan, 0);
OUT_RING (chan, stride);
Expand All @@ -586,7 +620,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, 0x0200, 1);
BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
OUT_RING (chan, 1);
}
if (old_mem->mem_type == TTM_PL_VRAM &&
Expand All @@ -595,7 +629,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, 0x021c, 7);
BEGIN_NV04(chan, NvSubCopy, 0x021c, 7);
OUT_RING (chan, 0);
OUT_RING (chan, 0);
OUT_RING (chan, stride);
Expand All @@ -608,18 +642,18 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, 0x021c, 1);
BEGIN_NV04(chan, NvSubCopy, 0x021c, 1);
OUT_RING (chan, 1);
}

ret = RING_SPACE(chan, 14);
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, 0x0238, 2);
BEGIN_NV04(chan, NvSubCopy, 0x0238, 2);
OUT_RING (chan, upper_32_bits(src_offset));
OUT_RING (chan, upper_32_bits(dst_offset));
BEGIN_NV04(chan, NvSubM2MF, 0x030c, 8);
BEGIN_NV04(chan, NvSubCopy, 0x030c, 8);
OUT_RING (chan, lower_32_bits(src_offset));
OUT_RING (chan, lower_32_bits(dst_offset));
OUT_RING (chan, stride);
Expand All @@ -628,7 +662,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
OUT_RING (chan, height);
OUT_RING (chan, 0x00000101);
OUT_RING (chan, 0x00000000);
BEGIN_NV04(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
OUT_RING (chan, 0);

length -= amount;
Expand All @@ -639,6 +673,24 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
return 0;
}

static int
nv04_bo_move_init(struct nouveau_channel *chan, u32 handle)
{
int ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
&chan->m2mf_ntfy);
if (ret == 0) {
ret = RING_SPACE(chan, 4);
if (ret == 0) {
BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
OUT_RING (chan, handle);
BEGIN_NV04(chan, NvSubCopy, 0x0180, 1);
OUT_RING (chan, NvNotify0);
}
}

return ret;
}

static inline uint32_t
nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
struct nouveau_channel *chan, struct ttm_mem_reg *mem)
Expand All @@ -661,7 +713,7 @@ nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2);
BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2);
OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem));
OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem));

Expand All @@ -673,7 +725,7 @@ nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
if (ret)
return ret;

BEGIN_NV04(chan, NvSubM2MF,
BEGIN_NV04(chan, NvSubCopy,
NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
OUT_RING (chan, src_offset);
OUT_RING (chan, dst_offset);
Expand All @@ -683,7 +735,7 @@ nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
OUT_RING (chan, line_count);
OUT_RING (chan, 0x00000101);
OUT_RING (chan, 0x00000000);
BEGIN_NV04(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
OUT_RING (chan, 0);

page_count -= line_count;
Expand Down Expand Up @@ -743,16 +795,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
goto out;
}

if (dev_priv->card_type < NV_50)
ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
else
if (dev_priv->card_type < NV_C0)
ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
else
if (dev_priv->card_type < NV_E0)
ret = nvc0_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
else
ret = nve0_bo_move_copy(chan, bo, &bo->mem, new_mem);
ret = dev_priv->ttm.move(chan, bo, &bo->mem, new_mem);
if (ret == 0) {
ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
no_wait_reserve,
Expand All @@ -764,6 +807,42 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
return ret;
}

void
nouveau_bo_move_init(struct nouveau_channel *chan)
{
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
static const struct {
const char *name;
u32 oclass;
int (*exec)(struct nouveau_channel *,
struct ttm_buffer_object *,
struct ttm_mem_reg *, struct ttm_mem_reg *);
int (*init)(struct nouveau_channel *, u32 handle);
} _methods[] = {
{ "COPY", 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "M2MF", 0x9039, nvc0_bo_move_m2mf, nvc0_bo_move_init },
{ "M2MF", 0x5039, nv50_bo_move_m2mf, nv50_bo_move_init },
{ "M2MF", 0x0039, nv04_bo_move_m2mf, nv04_bo_move_init },
{}
}, *mthd = _methods;
const char *name = "CPU";
int ret;

do {
ret = nouveau_gpuobj_gr_new(chan, mthd->oclass, mthd->oclass);
if (ret == 0) {
ret = mthd->init(chan, mthd->oclass);
if (ret == 0) {
dev_priv->ttm.move = mthd->exec;
name = mthd->name;
break;
}
}
} while ((++mthd)->exec);

NV_INFO(chan->dev, "MM: using %s for buffer copies\n", name);
}

static int
nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
bool no_wait_reserve, bool no_wait_gpu,
Expand Down Expand Up @@ -920,8 +999,8 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
goto out;
}

/* Software copy if the card isn't up and running yet. */
if (!dev_priv->channel) {
/* CPU copy if we have no accelerated method available */
if (!dev_priv->ttm.move) {
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
goto out;
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ nouveau_channel_ref(struct nouveau_channel *chan,
*pchan = chan;
}

void
int
nouveau_channel_idle(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
Expand All @@ -370,6 +370,7 @@ nouveau_channel_idle(struct nouveau_channel *chan)

if (ret)
NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id);
return ret;
}

/* cleans up all the fifos from file_priv */
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/gpu/drm/nouveau/nouveau_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,12 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,

/* Hardcoded object assignments to subchannels (subchannel id). */
enum {
NvSubM2MF = 0,
NvSubCtxSurf2D = 0,
NvSubSw = 1,
NvSubCtxSurf2D = 2,
NvSubImageBlit = 2,
NvSub2D = 3,
NvSubGdiRect = 3,
NvSubCopy = 4,
NvSubImageBlit = 4
};

/* Object handles. */
Expand All @@ -74,6 +73,7 @@ enum {
NvSema = 0x8000000f,
NvEvoSema0 = 0x80000010,
NvEvoSema1 = 0x80000011,
NvNotify1 = 0x80000012,

/* G80+ display objects */
NvEvoVRAM = 0x01000000,
Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,9 @@ struct drm_nouveau_private {
struct ttm_bo_global_ref bo_global_ref;
struct ttm_bo_device bdev;
atomic_t validate_sequence;
int (*move)(struct nouveau_channel *,
struct ttm_buffer_object *,
struct ttm_mem_reg *, struct ttm_mem_reg *);
} ttm;

struct {
Expand Down Expand Up @@ -930,7 +933,7 @@ extern void nouveau_channel_put_unlocked(struct nouveau_channel **);
extern void nouveau_channel_put(struct nouveau_channel **);
extern void nouveau_channel_ref(struct nouveau_channel *chan,
struct nouveau_channel **pchan);
extern void nouveau_channel_idle(struct nouveau_channel *chan);
extern int nouveau_channel_idle(struct nouveau_channel *chan);

/* nouveau_object.c */
#define NVOBJ_ENGINE_ADD(d, e, p) do { \
Expand Down Expand Up @@ -1322,6 +1325,7 @@ extern int nv04_crtc_create(struct drm_device *, int index);

/* nouveau_bo.c */
extern struct ttm_bo_driver nouveau_bo_driver;
extern void nouveau_bo_move_init(struct nouveau_channel *);
extern int nouveau_bo_new(struct drm_device *, int size, int align,
uint32_t flags, uint32_t tile_mode,
uint32_t tile_flags,
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
return eng->object_new(chan, oc->engine, handle, class);
}

NV_ERROR(dev, "illegal object class: 0x%x\n", class);
return -EINVAL;
}

Expand Down
Loading

0 comments on commit af2ea57

Please sign in to comment.