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

Commit 6d86951a authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nvc0: initial support for tiled buffer objects



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent ddbaf79a
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -120,9 +120,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
	align >>= PAGE_SHIFT;

	if (!nvbo->no_vm && dev_priv->chan_vm) {
		if (dev_priv->card_type == NV_C0)
			page_shift = 12;

		ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift,
				     NV_MEM_ACCESS_RW, &nvbo->vma);
		if (ret) {
+2 −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
+11 −7
Original line number Diff line number Diff line
@@ -115,15 +115,16 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
		OUT_RING(evo, 0);
		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
		if (dev_priv->chipset != 0x50)
			if (nv_crtc->fb.tile_flags == 0x7a00)
			if (nv_crtc->fb.tile_flags == 0x7a00 ||
			    nv_crtc->fb.tile_flags == 0xfe00)
				OUT_RING(evo, NvEvoFB32);
			else
			if (nv_crtc->fb.tile_flags == 0x7000)
				OUT_RING(evo, NvEvoFB16);
			else
				OUT_RING(evo, NvEvoVRAM);
				OUT_RING(evo, NvEvoVRAM_LP);
		else
			OUT_RING(evo, NvEvoVRAM);
			OUT_RING(evo, NvEvoVRAM_LP);
	}

	nv_crtc->fb.blanked = blanked;
@@ -555,13 +556,14 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
			return ret;

		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
		if (nv_crtc->fb.tile_flags == 0x7a00)
		if (nv_crtc->fb.tile_flags == 0x7a00 ||
		    nv_crtc->fb.tile_flags == 0xfe00)
			OUT_RING(evo, NvEvoFB32);
		else
		if (nv_crtc->fb.tile_flags == 0x7000)
			OUT_RING(evo, NvEvoFB16);
		else
			OUT_RING(evo, NvEvoVRAM);
			OUT_RING(evo, NvEvoVRAM_LP);
	}

	ret = RING_SPACE(evo, 12);
@@ -575,8 +577,10 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
	if (!nv_crtc->fb.tile_flags) {
		OUT_RING(evo, drm_fb->pitch | (1 << 20));
	} else {
		OUT_RING(evo, ((drm_fb->pitch / 4) << 4) |
				  fb->nvbo->tile_mode);
		u32 tile_mode = fb->nvbo->tile_mode;
		if (dev_priv->card_type >= NV_C0)
			tile_mode >>= 4;
		OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
	}
	if (dev_priv->chipset == 0x50)
		OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
+40 −13
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ nv50_evo_channel_del(struct nouveau_channel **pevo)

int
nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name,
		    u32 tile_flags, u32 magic_flags, u32 offset, u32 limit)
		    u32 tile_flags, u32 magic_flags, u32 offset, u32 limit,
		    u32 flags5)
{
	struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
	struct drm_device *dev = evo->dev;
@@ -70,10 +71,7 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name,
	nv_wo32(obj,  8, offset);
	nv_wo32(obj, 12, 0x00000000);
	nv_wo32(obj, 16, 0x00000000);
	if (dev_priv->card_type < NV_C0)
		nv_wo32(obj, 20, 0x00010000);
	else
		nv_wo32(obj, 20, 0x00020000);
	nv_wo32(obj, 20, flags5);
	dev_priv->engine.instmem.flush(dev);

	ret = nouveau_ramht_insert(evo, name, obj);
@@ -264,9 +262,31 @@ nv50_evo_create(struct drm_device *dev)
	}

	/* create some default objects for the scanout memtypes we support */
	if (dev_priv->card_type >= NV_C0) {
		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0xfe, 0x19,
					  0, 0xffffffff, 0x00000000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}

		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
					  0, dev_priv->vram_size, 0x00020000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}

		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
					  0, dev_priv->vram_size, 0x00000000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}
	} else
	if (dev_priv->chipset != 0x50) {
		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19,
					  0, 0xffffffff);
					  0, 0xffffffff, 0x00010000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
@@ -274,20 +294,27 @@ nv50_evo_create(struct drm_device *dev)


		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19,
					  0, 0xffffffff);
					  0, 0xffffffff, 0x00010000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}
	}

		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
				  0, dev_priv->vram_size);
					  0, dev_priv->vram_size, 0x00010000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}

		ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
					  0, dev_priv->vram_size, 0x00010000);
		if (ret) {
			nv50_evo_channel_del(&dev_priv->evo);
			return ret;
		}
	}

	return 0;
}

+9 −1
Original line number Diff line number Diff line
@@ -29,8 +29,16 @@
bool
nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
{
	if (likely(!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)))
	switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
	case 0x0000:
	case 0xfe00:
	case 0xdb00:
	case 0x1100:
		return true;
	default:
		break;
	}

	return false;
}