Skip to content

Commit

Permalink
Merge remote branch 'nouveau/drm-nouveau-next' of /ssd/git/drm-nouvea…
Browse files Browse the repository at this point in the history
…u-next into drm-core-next

* 'nouveau/drm-nouveau-next' of /ssd/git/drm-nouveau-next:
  drm/nvc0: accelerate ttm buffer moves
  drm/nvc0: initial support for tiled buffer objects
  drm/nvc0: implement fbcon acceleration
  drm/nvc0: implement pgraph engine hooks
  drm/nvc0: implement pfifo engine hooks
  drm/nvc0: implement fencing
  drm/nvc0: fix channel dma init paths
  drm/nvc0: skip dma object creation for drm channel
  drm/nvc0: implement channel structure initialisation
  drm/nvc0: gpuobj_new need only check validity and init the relevant engine
  drm/nvc0: reject the notifier_alloc ioctl
  drm/nvc0: create shared channel vm
  drm/nvc0: initial vm implementation, use for bar1/bar3 management
  drm/nvc0: import initial vm backend
  drm/nouveau: modify vm to accomodate dual page tables for nvc0
  drm/nv50: add missing license header to nv50_fbcon.c
  drm/nv50: fix smatch warning in nv50_vram.c
  drm/nouveau: sizeof() vs ARRAY_SIZE()
  • Loading branch information
Dave Airlie committed Dec 21, 2010
2 parents 880981e + 183720b commit 1d99e5c
Show file tree
Hide file tree
Showing 30 changed files with 5,044 additions and 341 deletions.
10 changes: 6 additions & 4 deletions drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o nvc0_graph.o \
nv40_grctx.o nv50_grctx.o \
nv40_grctx.o nv50_grctx.o nvc0_grctx.o \
nv84_crypt.o \
nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \
nv50_cursor.o nv50_display.o nv50_fbcon.o \
nv50_cursor.o nv50_display.o \
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
nv04_crtc.o nv04_display.o nv04_cursor.o \
nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \
nv10_gpio.o nv50_gpio.o \
nv50_calc.o \
nv04_pm.o nv50_pm.o nva3_pm.o \
nv50_vram.o nv50_vm.o
nv50_vram.o nvc0_vram.o \
nv50_vm.o nvc0_vm.o

nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
Expand Down
73 changes: 68 additions & 5 deletions drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
man->default_caching = TTM_PL_FLAG_CACHED;
break;
case TTM_PL_VRAM:
if (dev_priv->card_type == NV_50) {
if (dev_priv->card_type >= NV_50) {
man->func = &nouveau_vram_manager;
man->io_reserve_fastpath = false;
man->use_io_reserve_lru = true;
Expand Down Expand Up @@ -514,6 +514,58 @@ nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
return chan->vram_handle;
}

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)
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
u64 src_offset = old_mem->start << PAGE_SHIFT;
u64 dst_offset = new_mem->start << PAGE_SHIFT;
u32 page_count = new_mem->num_pages;
int ret;

if (!nvbo->no_vm) {
if (old_mem->mem_type == TTM_PL_VRAM)
src_offset = nvbo->vma.offset;
else
src_offset += dev_priv->gart_info.aper_base;

if (new_mem->mem_type == TTM_PL_VRAM)
dst_offset = nvbo->vma.offset;
else
dst_offset += dev_priv->gart_info.aper_base;
}

page_count = new_mem->num_pages;
while (page_count) {
int line_count = (page_count > 2047) ? 2047 : page_count;

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

BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0238, 2);
OUT_RING (chan, upper_32_bits(dst_offset));
OUT_RING (chan, lower_32_bits(dst_offset));
BEGIN_NVC0(chan, 2, NvSubM2MF, 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, 2, NvSubM2MF, 0x0300, 1);
OUT_RING (chan, 0x00100110);

page_count -= line_count;
src_offset += (PAGE_SIZE * line_count);
dst_offset += (PAGE_SIZE * line_count);
}

return 0;
}

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 Down Expand Up @@ -690,7 +742,10 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
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
ret = nvc0_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
if (ret == 0) {
ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
no_wait_reserve,
Expand Down Expand Up @@ -901,6 +956,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
case TTM_PL_VRAM:
{
struct nouveau_vram *vram = mem->mm_node;
u8 page_shift;

if (!dev_priv->bar1_vm) {
mem->bus.offset = mem->start << PAGE_SHIFT;
Expand All @@ -909,8 +965,14 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
break;
}

ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, 12,
NV_MEM_ACCESS_RW, &vram->bar_vma);
if (dev_priv->card_type == NV_C0)
page_shift = vram->page_shift;
else
page_shift = 12;

ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size,
page_shift, NV_MEM_ACCESS_RW,
&vram->bar_vma);
if (ret)
return ret;

Expand All @@ -920,8 +982,9 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
return ret;
}

mem->bus.offset = vram->bar_vma.offset;
mem->bus.offset -= 0x0020000000ULL;
mem->bus.offset = vram->bar_vma.offset;
if (dev_priv->card_type == NV_50) /*XXX*/
mem->bus.offset -= 0x0020000000ULL;
mem->bus.base = pci_resource_start(dev->pdev, 1);
mem->bus.is_iomem = true;
}
Expand Down
20 changes: 16 additions & 4 deletions drivers/gpu/drm/nouveau/nouveau_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 *
Expand Down Expand Up @@ -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;
}

Expand Down
22 changes: 16 additions & 6 deletions drivers/gpu/drm/nouveau/nouveau_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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)
Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ enum {
/* G80+ display objects */
NvEvoVRAM = 0x01000000,
NvEvoFB16 = 0x01000001,
NvEvoFB32 = 0x01000002
NvEvoFB32 = 0x01000002,
NvEvoVRAM_LP = 0x01000003
};

#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039
Expand Down Expand Up @@ -124,6 +125,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)
{
Expand Down
12 changes: 7 additions & 5 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct nouveau_vram {
struct drm_device *dev;

struct nouveau_vma bar_vma;
u8 page_shift;

struct list_head regions;
u32 memtype;
Expand Down Expand Up @@ -239,6 +240,7 @@ struct nouveau_channel {
/* PFIFO context */
struct nouveau_gpuobj *ramfc;
struct nouveau_gpuobj *cache;
void *fifo_priv;

/* PGRAPH context */
/* XXX may be merge 2 pointers as private data ??? */
Expand Down Expand Up @@ -336,6 +338,7 @@ struct nouveau_fb_engine {
};

struct nouveau_fifo_engine {
void *priv;
int channels;

struct nouveau_gpuobj *playlist[2];
Expand All @@ -362,6 +365,7 @@ struct nouveau_pgraph_engine {
bool accel_blocked;
bool registered;
int grctx_size;
void *priv;

/* NV2x/NV3x context table (0x400780) */
struct nouveau_gpuobj *ctx_table;
Expand Down Expand Up @@ -841,6 +845,9 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev,
struct nouveau_fence *fence);
extern const struct ttm_mem_type_manager_func nouveau_vram_manager;

/* nvc0_vram.c */
extern const struct ttm_mem_type_manager_func nvc0_vram_manager;

/* nouveau_notifier.c */
extern int nouveau_notifier_init_channel(struct nouveau_channel *);
extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
Expand Down Expand Up @@ -1228,11 +1235,6 @@ extern int nvc0_instmem_init(struct drm_device *);
extern void nvc0_instmem_takedown(struct drm_device *);
extern int nvc0_instmem_suspend(struct drm_device *);
extern void nvc0_instmem_resume(struct drm_device *);
extern int nvc0_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align);
extern void nvc0_instmem_put(struct nouveau_gpuobj *);
extern int nvc0_instmem_map(struct nouveau_gpuobj *);
extern void nvc0_instmem_unmap(struct nouveau_gpuobj *);
extern void nvc0_instmem_flush(struct drm_device *);

/* nv04_mc.c */
extern int nv04_mc_init(struct drm_device *);
Expand Down
24 changes: 20 additions & 4 deletions drivers/gpu/drm/nouveau/nouveau_fbcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
else
if (dev_priv->card_type < NV_C0)
ret = nv50_fbcon_fillrect(info, rect);
else
ret = nvc0_fbcon_fillrect(info, rect);
mutex_unlock(&dev_priv->channel->mutex);
}

Expand Down Expand Up @@ -98,6 +100,8 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
else
if (dev_priv->card_type < NV_C0)
ret = nv50_fbcon_copyarea(info, image);
else
ret = nvc0_fbcon_copyarea(info, image);
mutex_unlock(&dev_priv->channel->mutex);
}

Expand Down Expand Up @@ -128,6 +132,8 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
else
if (dev_priv->card_type < NV_C0)
ret = nv50_fbcon_imageblit(info, image);
else
ret = nvc0_fbcon_imageblit(info, image);
mutex_unlock(&dev_priv->channel->mutex);
}

Expand Down Expand Up @@ -163,10 +169,18 @@ nouveau_fbcon_sync(struct fb_info *info)
return 0;
}

BEGIN_RING(chan, 0, 0x0104, 1);
OUT_RING(chan, 0);
BEGIN_RING(chan, 0, 0x0100, 1);
OUT_RING(chan, 0);
if (dev_priv->card_type >= NV_C0) {
BEGIN_NVC0(chan, 2, NvSub2D, 0x010c, 1);
OUT_RING (chan, 0);
BEGIN_NVC0(chan, 2, NvSub2D, 0x0100, 1);
OUT_RING (chan, 0);
} else {
BEGIN_RING(chan, 0, 0x0104, 1);
OUT_RING (chan, 0);
BEGIN_RING(chan, 0, 0x0100, 1);
OUT_RING (chan, 0);
}

nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff);
FIRE_RING(chan);
mutex_unlock(&chan->mutex);
Expand Down Expand Up @@ -370,6 +384,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
else
if (dev_priv->card_type < NV_C0)
ret = nv50_fbcon_accel_init(info);
else
ret = nvc0_fbcon_accel_init(info);

if (ret == 0)
info->fbops = &nouveau_fbcon_ops;
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_fbcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,17 @@ int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv04_fbcon_accel_init(struct fb_info *info);

int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv50_fbcon_accel_init(struct fb_info *info);

int nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nvc0_fbcon_accel_init(struct fb_info *info);

void nouveau_fbcon_gpu_lockup(struct fb_info *info);

int nouveau_fbcon_init(struct drm_device *dev);
Expand Down
Loading

0 comments on commit 1d99e5c

Please sign in to comment.