Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/nv50: support for compression

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

+79 -27
+1
drivers/gpu/drm/nouveau/nouveau_drv.h
··· 72 72 struct nouveau_vma tmp_vma; 73 73 u8 page_shift; 74 74 75 + struct drm_mm_node *tag; 75 76 struct list_head regions; 76 77 dma_addr_t *pages; 77 78 u32 memtype;
+1 -1
drivers/gpu/drm/nouveau/nouveau_mem.c
··· 740 740 741 741 ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, 742 742 mem->page_alignment << PAGE_SHIFT, size_nc, 743 - (nvbo->tile_flags >> 8) & 0xff, &node); 743 + (nvbo->tile_flags >> 8) & 0x3ff, &node); 744 744 if (ret) 745 745 return ret; 746 746
+4 -1
drivers/gpu/drm/nouveau/nouveau_vm.c
··· 40 40 u32 max = 1 << (vm->pgt_bits - bits); 41 41 u32 end, len; 42 42 43 + delta = 0; 43 44 list_for_each_entry(r, &node->regions, rl_entry) { 44 45 u64 phys = (u64)r->offset << 12; 45 46 u32 num = r->length >> bits; ··· 53 52 end = max; 54 53 len = end - pte; 55 54 56 - vm->map(vma, pgt, node, pte, len, phys); 55 + vm->map(vma, pgt, node, pte, len, phys, delta); 57 56 58 57 num -= len; 59 58 pte += len; ··· 61 60 pde++; 62 61 pte = 0; 63 62 } 63 + 64 + delta += (u64)len << vma->node->type; 64 65 } 65 66 } 66 67
+4 -3
drivers/gpu/drm/nouveau/nouveau_vm.h
··· 67 67 void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde, 68 68 struct nouveau_gpuobj *pgt[2]); 69 69 void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, 70 - struct nouveau_mem *, u32 pte, u32 cnt, u64 phys); 70 + struct nouveau_mem *, u32 pte, u32 cnt, 71 + u64 phys, u64 delta); 71 72 void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, 72 73 struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); 73 74 void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt); ··· 94 93 void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, 95 94 struct nouveau_gpuobj *pgt[2]); 96 95 void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, 97 - struct nouveau_mem *, u32 pte, u32 cnt, u64 phys); 96 + struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); 98 97 void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, 99 98 struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); 100 99 void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); ··· 105 104 void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, 106 105 struct nouveau_gpuobj *pgt[2]); 107 106 void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, 108 - struct nouveau_mem *, u32 pte, u32 cnt, u64 phys); 107 + struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); 109 108 void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, 110 109 struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); 111 110 void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
+35 -16
drivers/gpu/drm/nouveau/nv50_fb.c
··· 8 8 dma_addr_t r100c08; 9 9 }; 10 10 11 + static void 12 + nv50_fb_destroy(struct drm_device *dev) 13 + { 14 + struct drm_nouveau_private *dev_priv = dev->dev_private; 15 + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 16 + struct nv50_fb_priv *priv = pfb->priv; 17 + 18 + if (drm_mm_initialized(&pfb->tag_heap)) 19 + drm_mm_takedown(&pfb->tag_heap); 20 + 21 + if (priv->r100c08_page) { 22 + pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, 23 + PCI_DMA_BIDIRECTIONAL); 24 + __free_page(priv->r100c08_page); 25 + } 26 + 27 + kfree(priv); 28 + pfb->priv = NULL; 29 + } 30 + 11 31 static int 12 32 nv50_fb_create(struct drm_device *dev) 13 33 { 14 34 struct drm_nouveau_private *dev_priv = dev->dev_private; 35 + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 15 36 struct nv50_fb_priv *priv; 37 + u32 tagmem; 38 + int ret; 16 39 17 40 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 18 41 if (!priv) 19 42 return -ENOMEM; 43 + pfb->priv = priv; 20 44 21 45 priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 22 46 if (!priv->r100c08_page) { 23 - kfree(priv); 47 + nv50_fb_destroy(dev); 24 48 return -ENOMEM; 25 49 } 26 50 27 51 priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, 28 52 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 29 53 if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { 30 - __free_page(priv->r100c08_page); 31 - kfree(priv); 54 + nv50_fb_destroy(dev); 32 55 return -EFAULT; 33 56 } 34 57 35 - dev_priv->engine.fb.priv = priv; 58 + tagmem = nv_rd32(dev, 0x100320); 59 + NV_DEBUG(dev, "%d tags available\n", tagmem); 60 + ret = drm_mm_init(&pfb->tag_heap, 0, tagmem); 61 + if (ret) { 62 + nv50_fb_destroy(dev); 63 + return ret; 64 + } 65 + 36 66 return 0; 37 67 } 38 68 ··· 111 81 void 112 82 nv50_fb_takedown(struct drm_device *dev) 113 83 { 114 - struct drm_nouveau_private *dev_priv = dev->dev_private; 115 - struct nv50_fb_priv *priv; 116 - 117 - priv = dev_priv->engine.fb.priv; 118 - if (!priv) 119 - return; 120 - dev_priv->engine.fb.priv = NULL; 121 - 122 - pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, 123 - PCI_DMA_BIDIRECTIONAL); 124 - __free_page(priv->r100c08_page); 125 - kfree(priv); 84 + nv50_fb_destroy(dev); 126 85 } 127 86 128 87 void
+7 -1
drivers/gpu/drm/nouveau/nv50_vm.c
··· 83 83 84 84 void 85 85 nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 86 - struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys) 86 + struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) 87 87 { 88 + u32 comp = (mem->memtype & 0x180) >> 7; 88 89 u32 block; 89 90 int i; 90 91 ··· 106 105 107 106 phys += block << (vma->node->type - 3); 108 107 cnt -= block; 108 + if (comp) { 109 + u32 tag = mem->tag->start + ((delta >> 16) * comp); 110 + offset_h |= (tag << 17); 111 + delta += block << (vma->node->type - 3); 112 + } 109 113 110 114 while (block) { 111 115 nv_wo32(pgt, pte + 0, offset_l);
+24 -3
drivers/gpu/drm/nouveau/nv50_vram.c
··· 69 69 list_del(&this->rl_entry); 70 70 nouveau_mm_put(mm, this); 71 71 } 72 + 73 + if (mem->tag) { 74 + drm_mm_put_block(mem->tag); 75 + mem->tag = NULL; 76 + } 72 77 mutex_unlock(&mm->mutex); 73 78 74 79 kfree(mem); ··· 81 76 82 77 int 83 78 nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc, 84 - u32 type, struct nouveau_mem **pmem) 79 + u32 memtype, struct nouveau_mem **pmem) 85 80 { 86 81 struct drm_nouveau_private *dev_priv = dev->dev_private; 87 82 struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; ··· 89 84 struct nouveau_mm *mm = man->priv; 90 85 struct nouveau_mm_node *r; 91 86 struct nouveau_mem *mem; 87 + int comp = (memtype & 0x300) >> 8; 88 + int type = (memtype & 0x07f); 92 89 int ret; 93 90 94 91 if (!types[type]) ··· 103 96 if (!mem) 104 97 return -ENOMEM; 105 98 99 + mutex_lock(&mm->mutex); 100 + if (comp) { 101 + if (align == 16) { 102 + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 103 + int n = (size >> 4) * comp; 104 + 105 + mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0); 106 + if (mem->tag) 107 + mem->tag = drm_mm_get_block(mem->tag, n, 0); 108 + } 109 + 110 + if (unlikely(!mem->tag)) 111 + comp = 0; 112 + } 113 + 106 114 INIT_LIST_HEAD(&mem->regions); 107 115 mem->dev = dev_priv->dev; 108 - mem->memtype = type; 116 + mem->memtype = (comp << 7) | type; 109 117 mem->size = size; 110 118 111 - mutex_lock(&mm->mutex); 112 119 do { 113 120 ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r); 114 121 if (ret) {
+1 -1
drivers/gpu/drm/nouveau/nvc0_vm.c
··· 59 59 60 60 void 61 61 nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 62 - struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys) 62 + struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) 63 63 { 64 64 u32 next = 1 << (vma->node->type - 8); 65 65
+1 -1
drivers/gpu/drm/nouveau/nvc0_vram.c
··· 78 78 79 79 INIT_LIST_HEAD(&mem->regions); 80 80 mem->dev = dev_priv->dev; 81 - mem->memtype = type; 81 + mem->memtype = (type & 0xff); 82 82 mem->size = size; 83 83 84 84 mutex_lock(&mm->mutex);
+1
include/drm/nouveau_drm.h
··· 94 94 #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) 95 95 #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) 96 96 97 + #define NOUVEAU_GEM_TILE_COMP 0x00030000 /* nv50-only */ 97 98 #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00 98 99 #define NOUVEAU_GEM_TILE_16BPP 0x00000001 99 100 #define NOUVEAU_GEM_TILE_32BPP 0x00000002