0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "nouveau_mem.h"
0023 #include "nouveau_drv.h"
0024 #include "nouveau_bo.h"
0025
0026 #include <drm/ttm/ttm_bo_driver.h>
0027
0028 #include <nvif/class.h>
0029 #include <nvif/if000a.h>
0030 #include <nvif/if500b.h>
0031 #include <nvif/if500d.h>
0032 #include <nvif/if900b.h>
0033 #include <nvif/if900d.h>
0034
0035 int
0036 nouveau_mem_map(struct nouveau_mem *mem,
0037 struct nvif_vmm *vmm, struct nvif_vma *vma)
0038 {
0039 union {
0040 struct nv50_vmm_map_v0 nv50;
0041 struct gf100_vmm_map_v0 gf100;
0042 } args;
0043 u32 argc = 0;
0044
0045 switch (vmm->object.oclass) {
0046 case NVIF_CLASS_VMM_NV04:
0047 break;
0048 case NVIF_CLASS_VMM_NV50:
0049 args.nv50.version = 0;
0050 args.nv50.ro = 0;
0051 args.nv50.priv = 0;
0052 args.nv50.kind = mem->kind;
0053 args.nv50.comp = mem->comp;
0054 argc = sizeof(args.nv50);
0055 break;
0056 case NVIF_CLASS_VMM_GF100:
0057 case NVIF_CLASS_VMM_GM200:
0058 case NVIF_CLASS_VMM_GP100:
0059 args.gf100.version = 0;
0060 if (mem->mem.type & NVIF_MEM_VRAM)
0061 args.gf100.vol = 0;
0062 else
0063 args.gf100.vol = 1;
0064 args.gf100.ro = 0;
0065 args.gf100.priv = 0;
0066 args.gf100.kind = mem->kind;
0067 argc = sizeof(args.gf100);
0068 break;
0069 default:
0070 WARN_ON(1);
0071 return -ENOSYS;
0072 }
0073
0074 return nvif_vmm_map(vmm, vma->addr, mem->mem.size, &args, argc, &mem->mem, 0);
0075 }
0076
0077 void
0078 nouveau_mem_fini(struct nouveau_mem *mem)
0079 {
0080 nvif_vmm_put(&mem->cli->drm->client.vmm.vmm, &mem->vma[1]);
0081 nvif_vmm_put(&mem->cli->drm->client.vmm.vmm, &mem->vma[0]);
0082 mutex_lock(&mem->cli->drm->master.lock);
0083 nvif_mem_dtor(&mem->mem);
0084 mutex_unlock(&mem->cli->drm->master.lock);
0085 }
0086
0087 int
0088 nouveau_mem_host(struct ttm_resource *reg, struct ttm_tt *tt)
0089 {
0090 struct nouveau_mem *mem = nouveau_mem(reg);
0091 struct nouveau_cli *cli = mem->cli;
0092 struct nouveau_drm *drm = cli->drm;
0093 struct nvif_mmu *mmu = &cli->mmu;
0094 struct nvif_mem_ram_v0 args = {};
0095 u8 type;
0096 int ret;
0097
0098 if (!nouveau_drm_use_coherent_gpu_mapping(drm))
0099 type = drm->ttm.type_ncoh[!!mem->kind];
0100 else
0101 type = drm->ttm.type_host[0];
0102
0103 if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND))
0104 mem->comp = mem->kind = 0;
0105 if (mem->comp && !(mmu->type[type].type & NVIF_MEM_COMP)) {
0106 if (mmu->object.oclass >= NVIF_CLASS_MMU_GF100)
0107 mem->kind = mmu->kind[mem->kind];
0108 mem->comp = 0;
0109 }
0110
0111 if (tt->sg)
0112 args.sgl = tt->sg->sgl;
0113 else
0114 args.dma = tt->dma_address;
0115
0116 mutex_lock(&drm->master.lock);
0117 ret = nvif_mem_ctor_type(mmu, "ttmHostMem", cli->mem->oclass, type, PAGE_SHIFT,
0118 reg->num_pages << PAGE_SHIFT,
0119 &args, sizeof(args), &mem->mem);
0120 mutex_unlock(&drm->master.lock);
0121 return ret;
0122 }
0123
0124 int
0125 nouveau_mem_vram(struct ttm_resource *reg, bool contig, u8 page)
0126 {
0127 struct nouveau_mem *mem = nouveau_mem(reg);
0128 struct nouveau_cli *cli = mem->cli;
0129 struct nouveau_drm *drm = cli->drm;
0130 struct nvif_mmu *mmu = &cli->mmu;
0131 u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
0132 int ret;
0133
0134 mutex_lock(&drm->master.lock);
0135 switch (cli->mem->oclass) {
0136 case NVIF_CLASS_MEM_GF100:
0137 ret = nvif_mem_ctor_type(mmu, "ttmVram", cli->mem->oclass,
0138 drm->ttm.type_vram, page, size,
0139 &(struct gf100_mem_v0) {
0140 .contig = contig,
0141 }, sizeof(struct gf100_mem_v0),
0142 &mem->mem);
0143 break;
0144 case NVIF_CLASS_MEM_NV50:
0145 ret = nvif_mem_ctor_type(mmu, "ttmVram", cli->mem->oclass,
0146 drm->ttm.type_vram, page, size,
0147 &(struct nv50_mem_v0) {
0148 .bankswz = mmu->kind[mem->kind] == 2,
0149 .contig = contig,
0150 }, sizeof(struct nv50_mem_v0),
0151 &mem->mem);
0152 break;
0153 default:
0154 ret = -ENOSYS;
0155 WARN_ON(1);
0156 break;
0157 }
0158 mutex_unlock(&drm->master.lock);
0159
0160 reg->start = mem->mem.addr >> PAGE_SHIFT;
0161 return ret;
0162 }
0163
0164 void
0165 nouveau_mem_del(struct ttm_resource_manager *man, struct ttm_resource *reg)
0166 {
0167 struct nouveau_mem *mem = nouveau_mem(reg);
0168
0169 nouveau_mem_fini(mem);
0170 ttm_resource_fini(man, reg);
0171 kfree(mem);
0172 }
0173
0174 int
0175 nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp,
0176 struct ttm_resource **res)
0177 {
0178 struct nouveau_mem *mem;
0179
0180 if (!(mem = kzalloc(sizeof(*mem), GFP_KERNEL)))
0181 return -ENOMEM;
0182
0183 mem->cli = cli;
0184 mem->kind = kind;
0185 mem->comp = comp;
0186
0187 *res = &mem->base;
0188 return 0;
0189 }