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

drm/nvc0: enable per-client address spaces

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

+55 -40
+46 -28
drivers/gpu/drm/nouveau/nouveau_object.c
··· 690 690 return 0; 691 691 } 692 692 693 + static int 694 + nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm) 695 + { 696 + struct drm_device *dev = chan->dev; 697 + struct nouveau_gpuobj *pgd = NULL; 698 + struct nouveau_vm_pgd *vpgd; 699 + int ret, i; 700 + 701 + ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin); 702 + if (ret) 703 + return ret; 704 + 705 + /* create page directory for this vm if none currently exists, 706 + * will be destroyed automagically when last reference to the 707 + * vm is removed 708 + */ 709 + if (list_empty(&vm->pgd_list)) { 710 + ret = nouveau_gpuobj_new(dev, NULL, 65536, 0x1000, 0, &pgd); 711 + if (ret) 712 + return ret; 713 + } 714 + nouveau_vm_ref(vm, &chan->vm, pgd); 715 + nouveau_gpuobj_ref(NULL, &pgd); 716 + 717 + /* point channel at vm's page directory */ 718 + vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head); 719 + nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst)); 720 + nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst)); 721 + nv_wo32(chan->ramin, 0x0208, 0xffffffff); 722 + nv_wo32(chan->ramin, 0x020c, 0x000000ff); 723 + 724 + /* map display semaphore buffers into channel's vm */ 725 + for (i = 0; i < 2; i++) { 726 + struct nv50_display_crtc *dispc = &nv50_display(dev)->crtc[i]; 727 + 728 + ret = nouveau_bo_vma_add(dispc->sem.bo, chan->vm, 729 + &chan->dispc_vma[i]); 730 + if (ret) 731 + return ret; 732 + } 733 + 734 + return 0; 735 + } 736 + 693 737 int 694 738 nouveau_gpuobj_channel_init(struct nouveau_channel *chan, 695 739 uint32_t vram_h, uint32_t tt_h) ··· 746 702 int ret, i; 747 703 748 704 NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); 749 - if (dev_priv->card_type == NV_C0) { 750 - struct nouveau_vm_pgd *vpgd; 751 - 752 - ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, 753 - &chan->ramin); 754 - if (ret) 755 - return ret; 756 - 757 - nouveau_vm_ref(vm, &chan->vm, NULL); 758 - 759 - vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head); 760 - nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst)); 761 - nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst)); 762 - nv_wo32(chan->ramin, 0x0208, 0xffffffff); 763 - nv_wo32(chan->ramin, 0x020c, 0x000000ff); 764 - 765 - for (i = 0; i < 2; i++) { 766 - struct nv50_display_crtc *dispc = 767 - &nv50_display(dev)->crtc[i]; 768 - 769 - ret = nouveau_bo_vma_add(dispc->sem.bo, chan->vm, 770 - &chan->dispc_vma[i]); 771 - if (ret) 772 - return ret; 773 - } 774 - 775 - return 0; 776 - } 705 + if (dev_priv->card_type == NV_C0) 706 + return nvc0_gpuobj_channel_init(chan, vm); 777 707 778 708 /* Allocate a chunk of memory for per-channel object storage */ 779 709 ret = nouveau_gpuobj_channel_init_pramin(chan);
+6 -1
drivers/gpu/drm/nouveau/nouveau_state.c
··· 787 787 } 788 788 } else 789 789 if (dev_priv->card_type >= NV_C0) { 790 - nouveau_vm_ref(dev_priv->chan_vm, &fpriv->vm, NULL); 790 + ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, 791 + &fpriv->vm); 792 + if (ret) { 793 + kfree(fpriv); 794 + return ret; 795 + } 791 796 } 792 797 793 798 file_priv->driver_priv = fpriv;
+3 -11
drivers/gpu/drm/nouveau/nvc0_instmem.c
··· 32 32 struct nouveau_channel *bar1; 33 33 struct nouveau_gpuobj *bar3_pgd; 34 34 struct nouveau_channel *bar3; 35 - struct nouveau_gpuobj *chan_pgd; 36 35 }; 37 36 38 37 int ··· 180 181 goto error; 181 182 182 183 /* channel vm */ 183 - ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, &vm); 184 + ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, 185 + &dev_priv->chan_vm); 184 186 if (ret) 185 187 goto error; 186 - 187 - ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, 0, &priv->chan_pgd); 188 - if (ret) 189 - goto error; 190 - 191 - nouveau_vm_ref(vm, &dev_priv->chan_vm, priv->chan_pgd); 192 - nouveau_vm_ref(NULL, &vm, NULL); 193 188 194 189 nvc0_instmem_resume(dev); 195 190 return 0; ··· 204 211 nv_wr32(dev, 0x1704, 0x00000000); 205 212 nv_wr32(dev, 0x1714, 0x00000000); 206 213 207 - nouveau_vm_ref(NULL, &dev_priv->chan_vm, priv->chan_pgd); 208 - nouveau_gpuobj_ref(NULL, &priv->chan_pgd); 214 + nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL); 209 215 210 216 nvc0_channel_del(&priv->bar1); 211 217 nouveau_vm_ref(NULL, &dev_priv->bar1_vm, priv->bar1_pgd);