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

Commit 4c136142 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50: implement global channel address space on new VM code



As of this commit, it's guaranteed that if an object is in VRAM that its
GPU virtual address will be constant.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f869ef88
Loading
Loading
Loading
Loading
+25 −16
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
		DRM_ERROR("bo %p still attached to GEM object\n", bo);

	nv10_mem_put_tile_region(dev, nvbo->tile, NULL);
	nouveau_vm_put(&nvbo->vma);
	kfree(nvbo);
}

@@ -113,6 +114,15 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
			       &align, &size);
	align >>= PAGE_SHIFT;

	if (!nvbo->no_vm && dev_priv->chan_vm) {
		ret = nouveau_vm_get(dev_priv->chan_vm, size, 16,
				     NV_MEM_ACCESS_RW, &nvbo->vma);
		if (ret) {
			kfree(nvbo);
			return ret;
		}
	}

	nouveau_bo_placement_set(nvbo, flags, 0);

	nvbo->channel = chan;
@@ -125,6 +135,11 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
	}
	nvbo->channel = NULL;

	if (nvbo->vma.node) {
		if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
			nvbo->bo.offset = nvbo->vma.offset;
	}

	*pnvbo = nvbo;
	return 0;
}
@@ -294,6 +309,11 @@ nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
	if (ret)
		return ret;

	if (nvbo->vma.node) {
		if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
			nvbo->bo.offset = nvbo->vma.offset;
	}

	return 0;
}

@@ -400,9 +420,6 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
		man->available_caching = TTM_PL_FLAG_UNCACHED |
					 TTM_PL_FLAG_WC;
		man->default_caching = TTM_PL_FLAG_WC;
		if (dev_priv->card_type == NV_50)
			man->gpu_offset = 0x40000000;
		else
		man->gpu_offset = 0;
		break;
	case TTM_PL_TT:
@@ -507,12 +524,12 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
	dst_offset = new_mem->start << PAGE_SHIFT;
	if (!nvbo->no_vm) {
		if (old_mem->mem_type == TTM_PL_VRAM)
			src_offset += dev_priv->vm_vram_base;
			src_offset  = nvbo->vma.offset;
		else
			src_offset += dev_priv->vm_gart_base;

		if (new_mem->mem_type == TTM_PL_VRAM)
			dst_offset += dev_priv->vm_vram_base;
			dst_offset  = nvbo->vma.offset;
		else
			dst_offset += dev_priv->vm_gart_base;
	}
@@ -756,7 +773,6 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
	struct drm_device *dev = dev_priv->dev;
	struct nouveau_bo *nvbo = nouveau_bo(bo);
	uint64_t offset;
	int ret;

	if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) {
		/* Nothing to do. */
@@ -766,15 +782,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,

	offset = new_mem->start << PAGE_SHIFT;

	if (dev_priv->card_type == NV_50) {
		ret = nv50_mem_vm_bind_linear(dev,
					      offset + dev_priv->vm_vram_base,
					      new_mem->size,
					      nouveau_bo_tile_layout(nvbo),
					      offset);
		if (ret)
			return ret;

	if (dev_priv->chan_vm) {
		nouveau_vm_map(&nvbo->vma, new_mem->mm_node);
	} else if (dev_priv->card_type >= NV_10) {
		*new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size,
						nvbo->tile_mode,
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)

	if (dev_priv->card_type >= NV_50) {
		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
					     dev_priv->vm_end, NV_MEM_ACCESS_RO,
					     (1ULL << 40), NV_MEM_ACCESS_RO,
					     NV_MEM_TARGET_VM, &pushbuf);
		chan->pushbuf_base = pb->bo.offset;
	} else
+3 −5
Original line number Diff line number Diff line
@@ -339,11 +339,9 @@ nouveau_pci_resume(struct pci_dev *pdev)

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
		u32 offset = nv_crtc->cursor.nvbo->bo.mem.start << PAGE_SHIFT;

		nv_crtc->cursor.set_offset(nv_crtc,
					nv_crtc->cursor.nvbo->bo.offset -
					dev_priv->vm_vram_base);

		nv_crtc->cursor.set_offset(nv_crtc, offset);
		nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
						 nv_crtc->cursor_saved_y);
	}
+2 −15
Original line number Diff line number Diff line
@@ -65,10 +65,6 @@ struct nouveau_vram;
#define NOUVEAU_MAX_CHANNEL_NR 128
#define NOUVEAU_MAX_TILE_NR 15

#define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL)
#define NV50_VM_BLOCK    (512*1024*1024ULL)
#define NV50_VM_VRAM_NR  (NV50_VM_MAX_VRAM / NV50_VM_BLOCK)

struct nouveau_vram {
	struct drm_device *dev;

@@ -106,6 +102,7 @@ struct nouveau_bo {

	struct nouveau_channel *channel;

	struct nouveau_vma vma;
	bool mappable;
	bool no_vm;

@@ -252,7 +249,6 @@ struct nouveau_channel {
	struct nouveau_vm     *vm;
	struct nouveau_gpuobj *vm_pd;
	struct nouveau_gpuobj *vm_gart_pt;
	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];

	/* Objects */
	struct nouveau_gpuobj *ramin; /* Private instmem */
@@ -712,13 +708,9 @@ struct drm_nouveau_private {
	struct nouveau_vm *bar3_vm;

	/* G8x/G9x virtual address space */
	struct nouveau_vm *chan_vm;
	uint64_t vm_gart_base;
	uint64_t vm_gart_size;
	uint64_t vm_vram_base;
	uint64_t vm_vram_size;
	uint64_t vm_end;
	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
	int vm_vram_pt_nr;

	struct nvbios vbios;

@@ -836,11 +828,6 @@ extern struct nouveau_tile_reg *nv10_mem_set_tiling(
extern void nv10_mem_put_tile_region(struct drm_device *dev,
				     struct nouveau_tile_reg *tile,
				     struct nouveau_fence *fence);
extern int  nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt,
				    uint32_t size, uint32_t flags,
				    uint64_t phys);
extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt,
			       uint32_t size);
extern const struct ttm_mem_type_manager_func nouveau_vram_manager;

/* nouveau_notifier.c */
+2 −2
Original line number Diff line number Diff line
@@ -338,8 +338,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
			      FBINFO_HWACCEL_IMAGEBLIT;
	info->flags |= FBINFO_CAN_FORCE_OUTPUT;
	info->fbops = &nouveau_fbcon_sw_ops;
	info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset -
			       dev_priv->vm_vram_base;
	info->fix.smem_start = dev->mode_config.fb_base +
			       (nvbo->bo.mem.start << PAGE_SHIFT);
	info->fix.smem_len = size;

	info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
Loading