0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "vmm.h"
0023
0024 #include <subdev/timer.h>
0025
0026 static void
0027 nv41_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
0028 u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr)
0029 {
0030 u32 data = (addr >> 7) | 0x00000001;
0031 while (ptes--) {
0032 VMM_WO032(pt, vmm, ptei++ * 4, data);
0033 data += 0x00000020;
0034 }
0035 }
0036
0037 static void
0038 nv41_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
0039 u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
0040 {
0041 VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, nv41_vmm_pgt_pte);
0042 }
0043
0044 static void
0045 nv41_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
0046 u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
0047 {
0048 #if PAGE_SHIFT == 12
0049 nvkm_kmap(pt->memory);
0050 while (ptes--) {
0051 const u32 data = (*map->dma++ >> 7) | 0x00000001;
0052 VMM_WO032(pt, vmm, ptei++ * 4, data);
0053 }
0054 nvkm_done(pt->memory);
0055 #else
0056 VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, nv41_vmm_pgt_pte);
0057 #endif
0058 }
0059
0060 static void
0061 nv41_vmm_pgt_unmap(struct nvkm_vmm *vmm,
0062 struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
0063 {
0064 VMM_FO032(pt, vmm, ptei * 4, 0, ptes);
0065 }
0066
0067 static const struct nvkm_vmm_desc_func
0068 nv41_vmm_desc_pgt = {
0069 .unmap = nv41_vmm_pgt_unmap,
0070 .dma = nv41_vmm_pgt_dma,
0071 .sgl = nv41_vmm_pgt_sgl,
0072 };
0073
0074 static const struct nvkm_vmm_desc
0075 nv41_vmm_desc_12[] = {
0076 { PGT, 17, 4, 0x1000, &nv41_vmm_desc_pgt },
0077 {}
0078 };
0079
0080 static void
0081 nv41_vmm_flush(struct nvkm_vmm *vmm, int level)
0082 {
0083 struct nvkm_device *device = vmm->mmu->subdev.device;
0084
0085 mutex_lock(&vmm->mmu->mutex);
0086 nvkm_wr32(device, 0x100810, 0x00000022);
0087 nvkm_msec(device, 2000,
0088 if (nvkm_rd32(device, 0x100810) & 0x00000020)
0089 break;
0090 );
0091 nvkm_wr32(device, 0x100810, 0x00000000);
0092 mutex_unlock(&vmm->mmu->mutex);
0093 }
0094
0095 static const struct nvkm_vmm_func
0096 nv41_vmm = {
0097 .valid = nv04_vmm_valid,
0098 .flush = nv41_vmm_flush,
0099 .page = {
0100 { 12, &nv41_vmm_desc_12[0], NVKM_VMM_PAGE_HOST },
0101 {}
0102 }
0103 };
0104
0105 int
0106 nv41_vmm_new(struct nvkm_mmu *mmu, bool managed, u64 addr, u64 size,
0107 void *argv, u32 argc, struct lock_class_key *key, const char *name,
0108 struct nvkm_vmm **pvmm)
0109 {
0110 return nv04_vmm_new_(&nv41_vmm, mmu, 0, managed, addr, size,
0111 argv, argc, key, name, pvmm);
0112 }