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

Commit 8f7286f8 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50: support for compression



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 26c0c9e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ struct nouveau_mem {
	struct nouveau_vma tmp_vma;
	u8  page_shift;

	struct drm_mm_node *tag;
	struct list_head regions;
	dma_addr_t *pages;
	u32 memtype;
+1 −1
Original line number Diff line number Diff line
@@ -740,7 +740,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,

	ret = vram->get(dev, mem->num_pages << PAGE_SHIFT,
			mem->page_alignment << PAGE_SHIFT, size_nc,
			(nvbo->tile_flags >> 8) & 0xff, &node);
			(nvbo->tile_flags >> 8) & 0x3ff, &node);
	if (ret)
		return ret;

+4 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
	u32 max  = 1 << (vm->pgt_bits - bits);
	u32 end, len;

	delta = 0;
	list_for_each_entry(r, &node->regions, rl_entry) {
		u64 phys = (u64)r->offset << 12;
		u32 num  = r->length >> bits;
@@ -52,7 +53,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
				end = max;
			len = end - pte;

			vm->map(vma, pgt, node, pte, len, phys);
			vm->map(vma, pgt, node, pte, len, phys, delta);

			num -= len;
			pte += len;
@@ -60,6 +61,8 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
				pde++;
				pte = 0;
			}

			delta += (u64)len << vma->node->type;
		}
	}

+4 −3
Original line number Diff line number Diff line
@@ -67,7 +67,8 @@ struct nouveau_vm {
	void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde,
			struct nouveau_gpuobj *pgt[2]);
	void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *,
		    struct nouveau_mem *, u32 pte, u32 cnt, u64 phys);
		    struct nouveau_mem *, u32 pte, u32 cnt,
		    u64 phys, u64 delta);
	void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
		       struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
	void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
@@ -93,7 +94,7 @@ void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
		     struct nouveau_gpuobj *pgt[2]);
void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
		 struct nouveau_mem *, u32 pte, u32 cnt, u64 phys);
		 struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
@@ -104,7 +105,7 @@ void nv50_vm_flush_engine(struct drm_device *, int engine);
void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
		     struct nouveau_gpuobj *pgt[2]);
void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
		 struct nouveau_mem *, u32 pte, u32 cnt, u64 phys);
		 struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
+35 −16
Original line number Diff line number Diff line
@@ -8,31 +8,61 @@ struct nv50_fb_priv {
	dma_addr_t r100c08;
};

static void
nv50_fb_destroy(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
	struct nv50_fb_priv *priv = pfb->priv;

	if (drm_mm_initialized(&pfb->tag_heap))
		drm_mm_takedown(&pfb->tag_heap);

	if (priv->r100c08_page) {
		pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
			       PCI_DMA_BIDIRECTIONAL);
		__free_page(priv->r100c08_page);
	}

	kfree(priv);
	pfb->priv = NULL;
}

static int
nv50_fb_create(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
	struct nv50_fb_priv *priv;
	u32 tagmem;
	int ret;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	pfb->priv = priv;

	priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
	if (!priv->r100c08_page) {
		kfree(priv);
		nv50_fb_destroy(dev);
		return -ENOMEM;
	}

	priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0,
				     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
	if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) {
		__free_page(priv->r100c08_page);
		kfree(priv);
		nv50_fb_destroy(dev);
		return -EFAULT;
	}

	dev_priv->engine.fb.priv = priv;
	tagmem = nv_rd32(dev, 0x100320);
	NV_DEBUG(dev, "%d tags available\n", tagmem);
	ret = drm_mm_init(&pfb->tag_heap, 0, tagmem);
	if (ret) {
		nv50_fb_destroy(dev);
		return ret;
	}

	return 0;
}

@@ -81,18 +111,7 @@ nv50_fb_init(struct drm_device *dev)
void
nv50_fb_takedown(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nv50_fb_priv *priv;

	priv = dev_priv->engine.fb.priv;
	if (!priv)
		return;
	dev_priv->engine.fb.priv = NULL;

	pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
		       PCI_DMA_BIDIRECTIONAL);
	__free_page(priv->r100c08_page);
	kfree(priv);
	nv50_fb_destroy(dev);
}

void
Loading