Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d99e5c5 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge remote branch 'nouveau/drm-nouveau-next' of /ssd/git/drm-nouveau-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()
parents 880981e4 183720b8
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -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
+68 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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)
@@ -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,
@@ -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;
@@ -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;

@@ -921,6 +983,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
		}

		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;
+16 −4
Original line number Diff line number Diff line
@@ -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;
}

+16 −6
Original line number Diff line number Diff line
@@ -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)
+8 −1
Original line number Diff line number Diff line
@@ -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
@@ -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)
{
Loading