/* * Copyright 2017 Red Hat Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE.
*/ #include"vmm.h"
staticbool
nv50_vmm_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgt, u64 *pdata)
{ struct nvkm_mmu_pt *pt;
u64 data = 0xdeadcafe00000000ULL; if (pgt && (pt = pgt->pt[0])) { switch (pgt->page) { case 16: data = 0x00000001; break; case 12: data = 0x00000003; switch (nvkm_memory_size(pt->memory)) { case 0x100000: data |= 0x00000000; break; case 0x040000: data |= 0x00000020; break; case 0x020000: data |= 0x00000040; break; case 0x010000: data |= 0x00000060; break; default:
WARN_ON(1); returnfalse;
} break; default:
WARN_ON(1); returnfalse;
}
switch (nvkm_memory_target(pt->memory)) { case NVKM_MEM_TARGET_VRAM: data |= 0x00000000; break; case NVKM_MEM_TARGET_HOST: data |= 0x00000008; break; case NVKM_MEM_TARGET_NCOH: data |= 0x0000000c; break; default:
WARN_ON(1); returnfalse;
}
void
nv50_vmm_flush(struct nvkm_vmm *vmm, int level)
{ struct nvkm_subdev *subdev = &vmm->mmu->subdev; struct nvkm_device *device = subdev->device; int i, id;
mutex_lock(&vmm->mmu->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { if (!atomic_read(&vmm->engref[i])) continue;
/* unfortunate hw bug workaround... */ if (i == NVKM_ENGINE_GR && device->gr) { int ret = nvkm_gr_tlb_flush(device->gr); if (ret != -ENODEV) continue;
}
switch (i) { case NVKM_ENGINE_GR : id = 0x00; break; case NVKM_ENGINE_VP : case NVKM_ENGINE_MSPDEC: id = 0x01; break; case NVKM_SUBDEV_BAR : id = 0x06; break; case NVKM_ENGINE_MSPPP : case NVKM_ENGINE_MPEG : id = 0x08; break; case NVKM_ENGINE_BSP : case NVKM_ENGINE_MSVLD : id = 0x09; break; case NVKM_ENGINE_CIPHER: case NVKM_ENGINE_SEC : id = 0x0a; break; case NVKM_ENGINE_CE : id = 0x0d; break; default: continue;
}
nvkm_wr32(device, 0x100c80, (id << 16) | 1); if (nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) break;
) < 0)
nvkm_error(subdev, "%s mmu invalidate timeout\n", nvkm_subdev_type[i]);
}
mutex_unlock(&vmm->mmu->mutex);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.