18e39abffSBen Skeggs /*
28e39abffSBen Skeggs * Copyright 2017 Red Hat Inc.
38e39abffSBen Skeggs *
48e39abffSBen Skeggs * Permission is hereby granted, free of charge, to any person obtaining a
58e39abffSBen Skeggs * copy of this software and associated documentation files (the "Software"),
68e39abffSBen Skeggs * to deal in the Software without restriction, including without limitation
78e39abffSBen Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88e39abffSBen Skeggs * and/or sell copies of the Software, and to permit persons to whom the
98e39abffSBen Skeggs * Software is furnished to do so, subject to the following conditions:
108e39abffSBen Skeggs *
118e39abffSBen Skeggs * The above copyright notice and this permission notice shall be included in
128e39abffSBen Skeggs * all copies or substantial portions of the Software.
138e39abffSBen Skeggs *
148e39abffSBen Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158e39abffSBen Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168e39abffSBen Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
178e39abffSBen Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
188e39abffSBen Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
198e39abffSBen Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
208e39abffSBen Skeggs * OTHER DEALINGS IN THE SOFTWARE.
218e39abffSBen Skeggs */
228e39abffSBen Skeggs #include "vmm.h"
238e39abffSBen Skeggs
2471871aa6SBen Skeggs #include <core/client.h>
25f9400afbSBen Skeggs #include <subdev/fb.h>
26f9400afbSBen Skeggs #include <subdev/ltc.h>
2771871aa6SBen Skeggs #include <subdev/timer.h>
2871871aa6SBen Skeggs #include <engine/gr.h>
29f9400afbSBen Skeggs
30f9400afbSBen Skeggs #include <nvif/ifc00d.h>
31f9400afbSBen Skeggs #include <nvif/unpack.h>
32f9400afbSBen Skeggs
33a5ff307fSBen Skeggs static void
gp100_vmm_pfn_unmap(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)34a5ff307fSBen Skeggs gp100_vmm_pfn_unmap(struct nvkm_vmm *vmm,
35a5ff307fSBen Skeggs struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
36a5ff307fSBen Skeggs {
37a5ff307fSBen Skeggs struct device *dev = vmm->mmu->subdev.device->dev;
38a5ff307fSBen Skeggs dma_addr_t addr;
39a5ff307fSBen Skeggs
40a5ff307fSBen Skeggs nvkm_kmap(pt->memory);
41a5ff307fSBen Skeggs while (ptes--) {
42a5ff307fSBen Skeggs u32 datalo = nvkm_ro32(pt->memory, pt->base + ptei * 8 + 0);
43a5ff307fSBen Skeggs u32 datahi = nvkm_ro32(pt->memory, pt->base + ptei * 8 + 4);
44a5ff307fSBen Skeggs u64 data = (u64)datahi << 32 | datalo;
45a5ff307fSBen Skeggs if ((data & (3ULL << 1)) != 0) {
46a5ff307fSBen Skeggs addr = (data >> 8) << 12;
47a5ff307fSBen Skeggs dma_unmap_page(dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
48a5ff307fSBen Skeggs }
49a5ff307fSBen Skeggs ptei++;
50a5ff307fSBen Skeggs }
51a5ff307fSBen Skeggs nvkm_done(pt->memory);
52a5ff307fSBen Skeggs }
53a5ff307fSBen Skeggs
54a5ff307fSBen Skeggs static bool
gp100_vmm_pfn_clear(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)55a5ff307fSBen Skeggs gp100_vmm_pfn_clear(struct nvkm_vmm *vmm,
56a5ff307fSBen Skeggs struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
57a5ff307fSBen Skeggs {
58a5ff307fSBen Skeggs bool dma = false;
59a5ff307fSBen Skeggs nvkm_kmap(pt->memory);
60a5ff307fSBen Skeggs while (ptes--) {
61a5ff307fSBen Skeggs u32 datalo = nvkm_ro32(pt->memory, pt->base + ptei * 8 + 0);
62a5ff307fSBen Skeggs u32 datahi = nvkm_ro32(pt->memory, pt->base + ptei * 8 + 4);
63a5ff307fSBen Skeggs u64 data = (u64)datahi << 32 | datalo;
64a5ff307fSBen Skeggs if ((data & BIT_ULL(0)) && (data & (3ULL << 1)) != 0) {
65a5ff307fSBen Skeggs VMM_WO064(pt, vmm, ptei * 8, data & ~BIT_ULL(0));
66a5ff307fSBen Skeggs dma = true;
67a5ff307fSBen Skeggs }
68a5ff307fSBen Skeggs ptei++;
69a5ff307fSBen Skeggs }
70a5ff307fSBen Skeggs nvkm_done(pt->memory);
71a5ff307fSBen Skeggs return dma;
72a5ff307fSBen Skeggs }
73a5ff307fSBen Skeggs
74a5ff307fSBen Skeggs static void
gp100_vmm_pgt_pfn(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)75a5ff307fSBen Skeggs gp100_vmm_pgt_pfn(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
76a5ff307fSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
77a5ff307fSBen Skeggs {
78a5ff307fSBen Skeggs struct device *dev = vmm->mmu->subdev.device->dev;
79a5ff307fSBen Skeggs dma_addr_t addr;
80a5ff307fSBen Skeggs
81a5ff307fSBen Skeggs nvkm_kmap(pt->memory);
821a77decdSRalph Campbell for (; ptes; ptes--, map->pfn++) {
83a5ff307fSBen Skeggs u64 data = 0;
841a77decdSRalph Campbell
851a77decdSRalph Campbell if (!(*map->pfn & NVKM_VMM_PFN_V))
861a77decdSRalph Campbell continue;
871a77decdSRalph Campbell
88a5ff307fSBen Skeggs if (!(*map->pfn & NVKM_VMM_PFN_W))
89a5ff307fSBen Skeggs data |= BIT_ULL(6); /* RO. */
90a5ff307fSBen Skeggs
918f187163SAlistair Popple if (!(*map->pfn & NVKM_VMM_PFN_A))
928f187163SAlistair Popple data |= BIT_ULL(7); /* Atomic disable. */
938f187163SAlistair Popple
94a5ff307fSBen Skeggs if (!(*map->pfn & NVKM_VMM_PFN_VRAM)) {
95a5ff307fSBen Skeggs addr = *map->pfn >> NVKM_VMM_PFN_ADDR_SHIFT;
96a5ff307fSBen Skeggs addr = dma_map_page(dev, pfn_to_page(addr), 0,
97a5ff307fSBen Skeggs PAGE_SIZE, DMA_BIDIRECTIONAL);
98a5ff307fSBen Skeggs if (!WARN_ON(dma_mapping_error(dev, addr))) {
99a5ff307fSBen Skeggs data |= addr >> 4;
100a5ff307fSBen Skeggs data |= 2ULL << 1; /* SYSTEM_COHERENT_MEMORY. */
101a5ff307fSBen Skeggs data |= BIT_ULL(3); /* VOL. */
102a5ff307fSBen Skeggs data |= BIT_ULL(0); /* VALID. */
103a5ff307fSBen Skeggs }
104a5ff307fSBen Skeggs } else {
105a5ff307fSBen Skeggs data |= (*map->pfn & NVKM_VMM_PFN_ADDR) >> 4;
106a5ff307fSBen Skeggs data |= BIT_ULL(0); /* VALID. */
107a5ff307fSBen Skeggs }
108a5ff307fSBen Skeggs
109a5ff307fSBen Skeggs VMM_WO064(pt, vmm, ptei++ * 8, data);
110a5ff307fSBen Skeggs }
111a5ff307fSBen Skeggs nvkm_done(pt->memory);
112a5ff307fSBen Skeggs }
113a5ff307fSBen Skeggs
114f9400afbSBen Skeggs static inline void
gp100_vmm_pgt_pte(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map,u64 addr)115f9400afbSBen Skeggs gp100_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
116f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr)
117f9400afbSBen Skeggs {
118f9400afbSBen Skeggs u64 data = (addr >> 4) | map->type;
119f9400afbSBen Skeggs
120f9400afbSBen Skeggs map->type += ptes * map->ctag;
121f9400afbSBen Skeggs
122f9400afbSBen Skeggs while (ptes--) {
123f9400afbSBen Skeggs VMM_WO064(pt, vmm, ptei++ * 8, data);
124f9400afbSBen Skeggs data += map->next;
125f9400afbSBen Skeggs }
126f9400afbSBen Skeggs }
127f9400afbSBen Skeggs
128f9400afbSBen Skeggs static void
gp100_vmm_pgt_sgl(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)129f9400afbSBen Skeggs gp100_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
130f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
131f9400afbSBen Skeggs {
132f9400afbSBen Skeggs VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte);
133f9400afbSBen Skeggs }
134f9400afbSBen Skeggs
135f9400afbSBen Skeggs static void
gp100_vmm_pgt_dma(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)136f9400afbSBen Skeggs gp100_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
137f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
138f9400afbSBen Skeggs {
139f9400afbSBen Skeggs if (map->page->shift == PAGE_SHIFT) {
140f9400afbSBen Skeggs VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes);
141f9400afbSBen Skeggs nvkm_kmap(pt->memory);
142f9400afbSBen Skeggs while (ptes--) {
143f9400afbSBen Skeggs const u64 data = (*map->dma++ >> 4) | map->type;
144f9400afbSBen Skeggs VMM_WO064(pt, vmm, ptei++ * 8, data);
145f9400afbSBen Skeggs map->type += map->ctag;
146f9400afbSBen Skeggs }
147f9400afbSBen Skeggs nvkm_done(pt->memory);
148f9400afbSBen Skeggs return;
149f9400afbSBen Skeggs }
150f9400afbSBen Skeggs
151f9400afbSBen Skeggs VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte);
152f9400afbSBen Skeggs }
153f9400afbSBen Skeggs
154f9400afbSBen Skeggs static void
gp100_vmm_pgt_mem(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)155f9400afbSBen Skeggs gp100_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
156f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
157f9400afbSBen Skeggs {
158f9400afbSBen Skeggs VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte);
159f9400afbSBen Skeggs }
160f9400afbSBen Skeggs
161f9400afbSBen Skeggs static void
gp100_vmm_pgt_sparse(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)162f9400afbSBen Skeggs gp100_vmm_pgt_sparse(struct nvkm_vmm *vmm,
163f9400afbSBen Skeggs struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
164f9400afbSBen Skeggs {
165f9400afbSBen Skeggs /* VALID_FALSE + VOL tells the MMU to treat the PTE as sparse. */
166f9400afbSBen Skeggs VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(3) /* VOL. */, ptes);
167f9400afbSBen Skeggs }
168f9400afbSBen Skeggs
1698e39abffSBen Skeggs static const struct nvkm_vmm_desc_func
1708e39abffSBen Skeggs gp100_vmm_desc_spt = {
171f9400afbSBen Skeggs .unmap = gf100_vmm_pgt_unmap,
172f9400afbSBen Skeggs .sparse = gp100_vmm_pgt_sparse,
173f9400afbSBen Skeggs .mem = gp100_vmm_pgt_mem,
174f9400afbSBen Skeggs .dma = gp100_vmm_pgt_dma,
175f9400afbSBen Skeggs .sgl = gp100_vmm_pgt_sgl,
176a5ff307fSBen Skeggs .pfn = gp100_vmm_pgt_pfn,
177a5ff307fSBen Skeggs .pfn_clear = gp100_vmm_pfn_clear,
178a5ff307fSBen Skeggs .pfn_unmap = gp100_vmm_pfn_unmap,
1798e39abffSBen Skeggs };
1808e39abffSBen Skeggs
181f9400afbSBen Skeggs static void
gp100_vmm_lpt_invalid(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)182f9400afbSBen Skeggs gp100_vmm_lpt_invalid(struct nvkm_vmm *vmm,
183f9400afbSBen Skeggs struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
184f9400afbSBen Skeggs {
185f9400afbSBen Skeggs /* VALID_FALSE + PRIV tells the MMU to ignore corresponding SPTEs. */
186f9400afbSBen Skeggs VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(5) /* PRIV. */, ptes);
187f9400afbSBen Skeggs }
188f9400afbSBen Skeggs
1898e39abffSBen Skeggs static const struct nvkm_vmm_desc_func
1908e39abffSBen Skeggs gp100_vmm_desc_lpt = {
191f9400afbSBen Skeggs .invalid = gp100_vmm_lpt_invalid,
192f9400afbSBen Skeggs .unmap = gf100_vmm_pgt_unmap,
193f9400afbSBen Skeggs .sparse = gp100_vmm_pgt_sparse,
194f9400afbSBen Skeggs .mem = gp100_vmm_pgt_mem,
1958e39abffSBen Skeggs };
1968e39abffSBen Skeggs
197f9400afbSBen Skeggs static inline void
gp100_vmm_pd0_pte(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map,u64 addr)198f9400afbSBen Skeggs gp100_vmm_pd0_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
199f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr)
200f9400afbSBen Skeggs {
201f9400afbSBen Skeggs u64 data = (addr >> 4) | map->type;
202f9400afbSBen Skeggs
203f9400afbSBen Skeggs map->type += ptes * map->ctag;
204f9400afbSBen Skeggs
205f9400afbSBen Skeggs while (ptes--) {
206f9400afbSBen Skeggs VMM_WO128(pt, vmm, ptei++ * 0x10, data, 0ULL);
207f9400afbSBen Skeggs data += map->next;
208f9400afbSBen Skeggs }
209f9400afbSBen Skeggs }
210f9400afbSBen Skeggs
211f9400afbSBen Skeggs static void
gp100_vmm_pd0_mem(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)212f9400afbSBen Skeggs gp100_vmm_pd0_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
213f9400afbSBen Skeggs u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
214f9400afbSBen Skeggs {
215f9400afbSBen Skeggs VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gp100_vmm_pd0_pte);
216f9400afbSBen Skeggs }
217f9400afbSBen Skeggs
218f9400afbSBen Skeggs static inline bool
gp100_vmm_pde(struct nvkm_mmu_pt * pt,u64 * data)219f9400afbSBen Skeggs gp100_vmm_pde(struct nvkm_mmu_pt *pt, u64 *data)
220f9400afbSBen Skeggs {
221f9400afbSBen Skeggs switch (nvkm_memory_target(pt->memory)) {
222f9400afbSBen Skeggs case NVKM_MEM_TARGET_VRAM: *data |= 1ULL << 1; break;
223f9400afbSBen Skeggs case NVKM_MEM_TARGET_HOST: *data |= 2ULL << 1;
224f9400afbSBen Skeggs *data |= BIT_ULL(3); /* VOL. */
225f9400afbSBen Skeggs break;
226f9400afbSBen Skeggs case NVKM_MEM_TARGET_NCOH: *data |= 3ULL << 1; break;
227f9400afbSBen Skeggs default:
228f9400afbSBen Skeggs WARN_ON(1);
229f9400afbSBen Skeggs return false;
230f9400afbSBen Skeggs }
231f9400afbSBen Skeggs *data |= pt->addr >> 4;
232f9400afbSBen Skeggs return true;
233f9400afbSBen Skeggs }
234f9400afbSBen Skeggs
235f9400afbSBen Skeggs static void
gp100_vmm_pd0_pde(struct nvkm_vmm * vmm,struct nvkm_vmm_pt * pgd,u32 pdei)236f9400afbSBen Skeggs gp100_vmm_pd0_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei)
237f9400afbSBen Skeggs {
238f9400afbSBen Skeggs struct nvkm_vmm_pt *pgt = pgd->pde[pdei];
239f9400afbSBen Skeggs struct nvkm_mmu_pt *pd = pgd->pt[0];
240f9400afbSBen Skeggs u64 data[2] = {};
241f9400afbSBen Skeggs
242f9400afbSBen Skeggs if (pgt->pt[0] && !gp100_vmm_pde(pgt->pt[0], &data[0]))
243f9400afbSBen Skeggs return;
244f9400afbSBen Skeggs if (pgt->pt[1] && !gp100_vmm_pde(pgt->pt[1], &data[1]))
245f9400afbSBen Skeggs return;
246f9400afbSBen Skeggs
247f9400afbSBen Skeggs nvkm_kmap(pd->memory);
248f9400afbSBen Skeggs VMM_WO128(pd, vmm, pdei * 0x10, data[0], data[1]);
249f9400afbSBen Skeggs nvkm_done(pd->memory);
250f9400afbSBen Skeggs }
251f9400afbSBen Skeggs
252f9400afbSBen Skeggs static void
gp100_vmm_pd0_sparse(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 pdei,u32 pdes)253f9400afbSBen Skeggs gp100_vmm_pd0_sparse(struct nvkm_vmm *vmm,
254f9400afbSBen Skeggs struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes)
255f9400afbSBen Skeggs {
256f9400afbSBen Skeggs /* VALID_FALSE + VOL_BIG tells the MMU to treat the PDE as sparse. */
257f9400afbSBen Skeggs VMM_FO128(pt, vmm, pdei * 0x10, BIT_ULL(3) /* VOL_BIG. */, 0ULL, pdes);
258f9400afbSBen Skeggs }
259f9400afbSBen Skeggs
260f9400afbSBen Skeggs static void
gp100_vmm_pd0_unmap(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 pdei,u32 pdes)261f9400afbSBen Skeggs gp100_vmm_pd0_unmap(struct nvkm_vmm *vmm,
262f9400afbSBen Skeggs struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes)
263f9400afbSBen Skeggs {
264f9400afbSBen Skeggs VMM_FO128(pt, vmm, pdei * 0x10, 0ULL, 0ULL, pdes);
265f9400afbSBen Skeggs }
266f9400afbSBen Skeggs
2674725c6b8SRalph Campbell static void
gp100_vmm_pd0_pfn_unmap(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)2684725c6b8SRalph Campbell gp100_vmm_pd0_pfn_unmap(struct nvkm_vmm *vmm,
2694725c6b8SRalph Campbell struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
2704725c6b8SRalph Campbell {
2714725c6b8SRalph Campbell struct device *dev = vmm->mmu->subdev.device->dev;
2724725c6b8SRalph Campbell dma_addr_t addr;
2734725c6b8SRalph Campbell
2744725c6b8SRalph Campbell nvkm_kmap(pt->memory);
2754725c6b8SRalph Campbell while (ptes--) {
2764725c6b8SRalph Campbell u32 datalo = nvkm_ro32(pt->memory, pt->base + ptei * 16 + 0);
2774725c6b8SRalph Campbell u32 datahi = nvkm_ro32(pt->memory, pt->base + ptei * 16 + 4);
2784725c6b8SRalph Campbell u64 data = (u64)datahi << 32 | datalo;
2794725c6b8SRalph Campbell
2804725c6b8SRalph Campbell if ((data & (3ULL << 1)) != 0) {
2814725c6b8SRalph Campbell addr = (data >> 8) << 12;
2824725c6b8SRalph Campbell dma_unmap_page(dev, addr, 1UL << 21, DMA_BIDIRECTIONAL);
2834725c6b8SRalph Campbell }
2844725c6b8SRalph Campbell ptei++;
2854725c6b8SRalph Campbell }
2864725c6b8SRalph Campbell nvkm_done(pt->memory);
2874725c6b8SRalph Campbell }
2884725c6b8SRalph Campbell
2894725c6b8SRalph Campbell static bool
gp100_vmm_pd0_pfn_clear(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes)2904725c6b8SRalph Campbell gp100_vmm_pd0_pfn_clear(struct nvkm_vmm *vmm,
2914725c6b8SRalph Campbell struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes)
2924725c6b8SRalph Campbell {
2934725c6b8SRalph Campbell bool dma = false;
2944725c6b8SRalph Campbell
2954725c6b8SRalph Campbell nvkm_kmap(pt->memory);
2964725c6b8SRalph Campbell while (ptes--) {
2974725c6b8SRalph Campbell u32 datalo = nvkm_ro32(pt->memory, pt->base + ptei * 16 + 0);
2984725c6b8SRalph Campbell u32 datahi = nvkm_ro32(pt->memory, pt->base + ptei * 16 + 4);
2994725c6b8SRalph Campbell u64 data = (u64)datahi << 32 | datalo;
3004725c6b8SRalph Campbell
3014725c6b8SRalph Campbell if ((data & BIT_ULL(0)) && (data & (3ULL << 1)) != 0) {
3024725c6b8SRalph Campbell VMM_WO064(pt, vmm, ptei * 16, data & ~BIT_ULL(0));
3034725c6b8SRalph Campbell dma = true;
3044725c6b8SRalph Campbell }
3054725c6b8SRalph Campbell ptei++;
3064725c6b8SRalph Campbell }
3074725c6b8SRalph Campbell nvkm_done(pt->memory);
3084725c6b8SRalph Campbell return dma;
3094725c6b8SRalph Campbell }
3104725c6b8SRalph Campbell
3114725c6b8SRalph Campbell static void
gp100_vmm_pd0_pfn(struct nvkm_vmm * vmm,struct nvkm_mmu_pt * pt,u32 ptei,u32 ptes,struct nvkm_vmm_map * map)3124725c6b8SRalph Campbell gp100_vmm_pd0_pfn(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt,
3134725c6b8SRalph Campbell u32 ptei, u32 ptes, struct nvkm_vmm_map *map)
3144725c6b8SRalph Campbell {
3154725c6b8SRalph Campbell struct device *dev = vmm->mmu->subdev.device->dev;
3164725c6b8SRalph Campbell dma_addr_t addr;
3174725c6b8SRalph Campbell
3184725c6b8SRalph Campbell nvkm_kmap(pt->memory);
3191a77decdSRalph Campbell for (; ptes; ptes--, map->pfn++) {
3204725c6b8SRalph Campbell u64 data = 0;
3214725c6b8SRalph Campbell
3221a77decdSRalph Campbell if (!(*map->pfn & NVKM_VMM_PFN_V))
3231a77decdSRalph Campbell continue;
3241a77decdSRalph Campbell
3254725c6b8SRalph Campbell if (!(*map->pfn & NVKM_VMM_PFN_W))
3264725c6b8SRalph Campbell data |= BIT_ULL(6); /* RO. */
3274725c6b8SRalph Campbell
3288f187163SAlistair Popple if (!(*map->pfn & NVKM_VMM_PFN_A))
3298f187163SAlistair Popple data |= BIT_ULL(7); /* Atomic disable. */
3308f187163SAlistair Popple
3314725c6b8SRalph Campbell if (!(*map->pfn & NVKM_VMM_PFN_VRAM)) {
3324725c6b8SRalph Campbell addr = *map->pfn >> NVKM_VMM_PFN_ADDR_SHIFT;
3334725c6b8SRalph Campbell addr = dma_map_page(dev, pfn_to_page(addr), 0,
3344725c6b8SRalph Campbell 1UL << 21, DMA_BIDIRECTIONAL);
3354725c6b8SRalph Campbell if (!WARN_ON(dma_mapping_error(dev, addr))) {
3364725c6b8SRalph Campbell data |= addr >> 4;
3374725c6b8SRalph Campbell data |= 2ULL << 1; /* SYSTEM_COHERENT_MEMORY. */
3384725c6b8SRalph Campbell data |= BIT_ULL(3); /* VOL. */
3394725c6b8SRalph Campbell data |= BIT_ULL(0); /* VALID. */
3404725c6b8SRalph Campbell }
3414725c6b8SRalph Campbell } else {
3424725c6b8SRalph Campbell data |= (*map->pfn & NVKM_VMM_PFN_ADDR) >> 4;
3434725c6b8SRalph Campbell data |= BIT_ULL(0); /* VALID. */
3444725c6b8SRalph Campbell }
3454725c6b8SRalph Campbell
3464725c6b8SRalph Campbell VMM_WO064(pt, vmm, ptei++ * 16, data);
3474725c6b8SRalph Campbell }
3484725c6b8SRalph Campbell nvkm_done(pt->memory);
3494725c6b8SRalph Campbell }
3504725c6b8SRalph Campbell
3518e39abffSBen Skeggs static const struct nvkm_vmm_desc_func
3528e39abffSBen Skeggs gp100_vmm_desc_pd0 = {
353f9400afbSBen Skeggs .unmap = gp100_vmm_pd0_unmap,
354f9400afbSBen Skeggs .sparse = gp100_vmm_pd0_sparse,
355f9400afbSBen Skeggs .pde = gp100_vmm_pd0_pde,
356f9400afbSBen Skeggs .mem = gp100_vmm_pd0_mem,
3574725c6b8SRalph Campbell .pfn = gp100_vmm_pd0_pfn,
3584725c6b8SRalph Campbell .pfn_clear = gp100_vmm_pd0_pfn_clear,
3594725c6b8SRalph Campbell .pfn_unmap = gp100_vmm_pd0_pfn_unmap,
3608e39abffSBen Skeggs };
3618e39abffSBen Skeggs
362f9400afbSBen Skeggs static void
gp100_vmm_pd1_pde(struct nvkm_vmm * vmm,struct nvkm_vmm_pt * pgd,u32 pdei)363f9400afbSBen Skeggs gp100_vmm_pd1_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei)
364f9400afbSBen Skeggs {
365f9400afbSBen Skeggs struct nvkm_vmm_pt *pgt = pgd->pde[pdei];
366f9400afbSBen Skeggs struct nvkm_mmu_pt *pd = pgd->pt[0];
367f9400afbSBen Skeggs u64 data = 0;
368f9400afbSBen Skeggs
369f9400afbSBen Skeggs if (!gp100_vmm_pde(pgt->pt[0], &data))
370f9400afbSBen Skeggs return;
371f9400afbSBen Skeggs
372f9400afbSBen Skeggs nvkm_kmap(pd->memory);
373f9400afbSBen Skeggs VMM_WO064(pd, vmm, pdei * 8, data);
374f9400afbSBen Skeggs nvkm_done(pd->memory);
375f9400afbSBen Skeggs }
376f9400afbSBen Skeggs
3778e39abffSBen Skeggs static const struct nvkm_vmm_desc_func
3788e39abffSBen Skeggs gp100_vmm_desc_pd1 = {
379f9400afbSBen Skeggs .unmap = gf100_vmm_pgt_unmap,
380f9400afbSBen Skeggs .sparse = gp100_vmm_pgt_sparse,
381f9400afbSBen Skeggs .pde = gp100_vmm_pd1_pde,
3828e39abffSBen Skeggs };
3838e39abffSBen Skeggs
3848e39abffSBen Skeggs const struct nvkm_vmm_desc
3858e39abffSBen Skeggs gp100_vmm_desc_16[] = {
3868e39abffSBen Skeggs { LPT, 5, 8, 0x0100, &gp100_vmm_desc_lpt },
3878e39abffSBen Skeggs { PGD, 8, 16, 0x1000, &gp100_vmm_desc_pd0 },
3888e39abffSBen Skeggs { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 },
3898e39abffSBen Skeggs { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 },
3908e39abffSBen Skeggs { PGD, 2, 8, 0x1000, &gp100_vmm_desc_pd1 },
3918e39abffSBen Skeggs {}
3928e39abffSBen Skeggs };
3938e39abffSBen Skeggs
3948e39abffSBen Skeggs const struct nvkm_vmm_desc
3958e39abffSBen Skeggs gp100_vmm_desc_12[] = {
3968e39abffSBen Skeggs { SPT, 9, 8, 0x1000, &gp100_vmm_desc_spt },
3978e39abffSBen Skeggs { PGD, 8, 16, 0x1000, &gp100_vmm_desc_pd0 },
3988e39abffSBen Skeggs { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 },
3998e39abffSBen Skeggs { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 },
4008e39abffSBen Skeggs { PGD, 2, 8, 0x1000, &gp100_vmm_desc_pd1 },
4018e39abffSBen Skeggs {}
4028e39abffSBen Skeggs };
4038e39abffSBen Skeggs
4048e39abffSBen Skeggs int
gp100_vmm_valid(struct nvkm_vmm * vmm,void * argv,u32 argc,struct nvkm_vmm_map * map)405f9400afbSBen Skeggs gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
406f9400afbSBen Skeggs struct nvkm_vmm_map *map)
407f9400afbSBen Skeggs {
408f9400afbSBen Skeggs const enum nvkm_memory_target target = nvkm_memory_target(map->memory);
409f9400afbSBen Skeggs const struct nvkm_vmm_page *page = map->page;
410f9400afbSBen Skeggs union {
411f9400afbSBen Skeggs struct gp100_vmm_map_vn vn;
412f9400afbSBen Skeggs struct gp100_vmm_map_v0 v0;
413f9400afbSBen Skeggs } *args = argv;
414f9400afbSBen Skeggs struct nvkm_device *device = vmm->mmu->subdev.device;
415f9400afbSBen Skeggs struct nvkm_memory *memory = map->memory;
416176ada03SJames Jones u8 kind, kind_inv, priv, ro, vol;
417f9400afbSBen Skeggs int kindn, aper, ret = -ENOSYS;
418f9400afbSBen Skeggs const u8 *kindm;
419f9400afbSBen Skeggs
420f9400afbSBen Skeggs map->next = (1ULL << page->shift) >> 4;
421f9400afbSBen Skeggs map->type = 0;
422f9400afbSBen Skeggs
423f9400afbSBen Skeggs if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
424f9400afbSBen Skeggs vol = !!args->v0.vol;
425f9400afbSBen Skeggs ro = !!args->v0.ro;
426f9400afbSBen Skeggs priv = !!args->v0.priv;
427f9400afbSBen Skeggs kind = args->v0.kind;
428f9400afbSBen Skeggs } else
429f9400afbSBen Skeggs if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
430f9400afbSBen Skeggs vol = target == NVKM_MEM_TARGET_HOST;
431f9400afbSBen Skeggs ro = 0;
432f9400afbSBen Skeggs priv = 0;
433f9400afbSBen Skeggs kind = 0x00;
434f9400afbSBen Skeggs } else {
435f9400afbSBen Skeggs VMM_DEBUG(vmm, "args");
436f9400afbSBen Skeggs return ret;
437f9400afbSBen Skeggs }
438f9400afbSBen Skeggs
439f9400afbSBen Skeggs aper = vmm->func->aper(target);
440f9400afbSBen Skeggs if (WARN_ON(aper < 0))
441f9400afbSBen Skeggs return aper;
442f9400afbSBen Skeggs
443176ada03SJames Jones kindm = vmm->mmu->func->kind(vmm->mmu, &kindn, &kind_inv);
444176ada03SJames Jones if (kind >= kindn || kindm[kind] == kind_inv) {
445f9400afbSBen Skeggs VMM_DEBUG(vmm, "kind %02x", kind);
446f9400afbSBen Skeggs return -EINVAL;
447f9400afbSBen Skeggs }
448f9400afbSBen Skeggs
449f9400afbSBen Skeggs if (kindm[kind] != kind) {
450f9400afbSBen Skeggs u64 tags = nvkm_memory_size(memory) >> 16;
451f9400afbSBen Skeggs if (aper != 0 || !(page->type & NVKM_VMM_PAGE_COMP)) {
452f9400afbSBen Skeggs VMM_DEBUG(vmm, "comp %d %02x", aper, page->type);
453f9400afbSBen Skeggs return -EINVAL;
454f9400afbSBen Skeggs }
455f9400afbSBen Skeggs
456*6b252cf4SDanilo Krummrich if (!map->no_comp) {
457f9400afbSBen Skeggs ret = nvkm_memory_tags_get(memory, device, tags,
458f9400afbSBen Skeggs nvkm_ltc_tags_clear,
459f9400afbSBen Skeggs &map->tags);
460f9400afbSBen Skeggs if (ret) {
461f9400afbSBen Skeggs VMM_DEBUG(vmm, "comp %d", ret);
462f9400afbSBen Skeggs return ret;
463f9400afbSBen Skeggs }
464*6b252cf4SDanilo Krummrich }
465f9400afbSBen Skeggs
466*6b252cf4SDanilo Krummrich if (!map->no_comp && map->tags->mn) {
467f9400afbSBen Skeggs tags = map->tags->mn->offset + (map->offset >> 16);
468f9400afbSBen Skeggs map->ctag |= ((1ULL << page->shift) >> 16) << 36;
469f9400afbSBen Skeggs map->type |= tags << 36;
470f9400afbSBen Skeggs map->next |= map->ctag;
471f9400afbSBen Skeggs } else {
472f9400afbSBen Skeggs kind = kindm[kind];
473f9400afbSBen Skeggs }
474f9400afbSBen Skeggs }
475f9400afbSBen Skeggs
476f9400afbSBen Skeggs map->type |= BIT(0);
477f9400afbSBen Skeggs map->type |= (u64)aper << 1;
478f9400afbSBen Skeggs map->type |= (u64) vol << 3;
479f9400afbSBen Skeggs map->type |= (u64)priv << 5;
480f9400afbSBen Skeggs map->type |= (u64) ro << 6;
481f9400afbSBen Skeggs map->type |= (u64)kind << 56;
482f9400afbSBen Skeggs return 0;
483f9400afbSBen Skeggs }
484f9400afbSBen Skeggs
48571871aa6SBen Skeggs static int
gp100_vmm_fault_cancel(struct nvkm_vmm * vmm,void * argv,u32 argc)48671871aa6SBen Skeggs gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, u32 argc)
48771871aa6SBen Skeggs {
48871871aa6SBen Skeggs struct nvkm_device *device = vmm->mmu->subdev.device;
48971871aa6SBen Skeggs union {
49071871aa6SBen Skeggs struct gp100_vmm_fault_cancel_v0 v0;
49171871aa6SBen Skeggs } *args = argv;
49271871aa6SBen Skeggs int ret = -ENOSYS;
493381ba6a6SKarol Herbst u32 aper;
49471871aa6SBen Skeggs
49571871aa6SBen Skeggs if ((ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false)))
49671871aa6SBen Skeggs return ret;
49771871aa6SBen Skeggs
49871871aa6SBen Skeggs /* Translate MaxwellFaultBufferA instance pointer to the same
49971871aa6SBen Skeggs * format as the NV_GR_FECS_CURRENT_CTX register.
50071871aa6SBen Skeggs */
50171871aa6SBen Skeggs aper = (args->v0.inst >> 8) & 3;
50271871aa6SBen Skeggs args->v0.inst >>= 12;
50371871aa6SBen Skeggs args->v0.inst |= aper << 28;
50471871aa6SBen Skeggs args->v0.inst |= 0x80000000;
50571871aa6SBen Skeggs
50671871aa6SBen Skeggs if (!WARN_ON(nvkm_gr_ctxsw_pause(device))) {
507404046cfSLuo penghao if (nvkm_gr_ctxsw_inst(device) == args->v0.inst) {
50871871aa6SBen Skeggs gf100_vmm_invalidate(vmm, 0x0000001b
50971871aa6SBen Skeggs /* CANCEL_TARGETED. */ |
51071871aa6SBen Skeggs (args->v0.hub << 20) |
51171871aa6SBen Skeggs (args->v0.gpc << 15) |
51271871aa6SBen Skeggs (args->v0.client << 9));
51371871aa6SBen Skeggs }
51471871aa6SBen Skeggs WARN_ON(nvkm_gr_ctxsw_resume(device));
51571871aa6SBen Skeggs }
51671871aa6SBen Skeggs
51771871aa6SBen Skeggs return 0;
51871871aa6SBen Skeggs }
51971871aa6SBen Skeggs
52071871aa6SBen Skeggs static int
gp100_vmm_fault_replay(struct nvkm_vmm * vmm,void * argv,u32 argc)52171871aa6SBen Skeggs gp100_vmm_fault_replay(struct nvkm_vmm *vmm, void *argv, u32 argc)
52271871aa6SBen Skeggs {
52371871aa6SBen Skeggs union {
52471871aa6SBen Skeggs struct gp100_vmm_fault_replay_vn vn;
52571871aa6SBen Skeggs } *args = argv;
52671871aa6SBen Skeggs int ret = -ENOSYS;
52771871aa6SBen Skeggs
52871871aa6SBen Skeggs if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
52971871aa6SBen Skeggs gf100_vmm_invalidate(vmm, 0x0000000b); /* REPLAY_GLOBAL. */
53071871aa6SBen Skeggs }
53171871aa6SBen Skeggs
53271871aa6SBen Skeggs return ret;
53371871aa6SBen Skeggs }
53471871aa6SBen Skeggs
53571871aa6SBen Skeggs int
gp100_vmm_mthd(struct nvkm_vmm * vmm,struct nvkm_client * client,u32 mthd,void * argv,u32 argc)53671871aa6SBen Skeggs gp100_vmm_mthd(struct nvkm_vmm *vmm,
53771871aa6SBen Skeggs struct nvkm_client *client, u32 mthd, void *argv, u32 argc)
53871871aa6SBen Skeggs {
53971871aa6SBen Skeggs switch (mthd) {
54071871aa6SBen Skeggs case GP100_VMM_VN_FAULT_REPLAY:
54171871aa6SBen Skeggs return gp100_vmm_fault_replay(vmm, argv, argc);
54271871aa6SBen Skeggs case GP100_VMM_VN_FAULT_CANCEL:
54371871aa6SBen Skeggs return gp100_vmm_fault_cancel(vmm, argv, argc);
54471871aa6SBen Skeggs default:
54571871aa6SBen Skeggs break;
54671871aa6SBen Skeggs }
54771871aa6SBen Skeggs return -EINVAL;
54871871aa6SBen Skeggs }
54971871aa6SBen Skeggs
550f9400afbSBen Skeggs void
gp100_vmm_invalidate_pdb(struct nvkm_vmm * vmm,u64 addr)551d389fd4fSBen Skeggs gp100_vmm_invalidate_pdb(struct nvkm_vmm *vmm, u64 addr)
552d389fd4fSBen Skeggs {
553d389fd4fSBen Skeggs struct nvkm_device *device = vmm->mmu->subdev.device;
554d389fd4fSBen Skeggs nvkm_wr32(device, 0x100cb8, lower_32_bits(addr));
555d389fd4fSBen Skeggs nvkm_wr32(device, 0x100cec, upper_32_bits(addr));
556d389fd4fSBen Skeggs }
557d389fd4fSBen Skeggs
558d389fd4fSBen Skeggs void
gp100_vmm_flush(struct nvkm_vmm * vmm,int depth)559f9400afbSBen Skeggs gp100_vmm_flush(struct nvkm_vmm *vmm, int depth)
560f9400afbSBen Skeggs {
561874c1b56SBen Skeggs u32 type = (5 /* CACHE_LEVEL_UP_TO_PDE3 */ - depth) << 24;
562874c1b56SBen Skeggs if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR]))
563874c1b56SBen Skeggs type |= 0x00000004; /* HUB_ONLY */
564874c1b56SBen Skeggs type |= 0x00000001; /* PAGE_ALL */
565874c1b56SBen Skeggs gf100_vmm_invalidate(vmm, type);
566f9400afbSBen Skeggs }
567f9400afbSBen Skeggs
568f9400afbSBen Skeggs int
gp100_vmm_join(struct nvkm_vmm * vmm,struct nvkm_memory * inst)5698e39abffSBen Skeggs gp100_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst)
5708e39abffSBen Skeggs {
571ab2ee9ffSBen Skeggs u64 base = BIT_ULL(10) /* VER2 */ | BIT_ULL(11) /* 64KiB */;
572ab2ee9ffSBen Skeggs if (vmm->replay) {
573ab2ee9ffSBen Skeggs base |= BIT_ULL(4); /* FAULT_REPLAY_TEX */
574ab2ee9ffSBen Skeggs base |= BIT_ULL(5); /* FAULT_REPLAY_GCC */
575ab2ee9ffSBen Skeggs }
5768e39abffSBen Skeggs return gf100_vmm_join_(vmm, inst, base);
5778e39abffSBen Skeggs }
5788e39abffSBen Skeggs
5798e39abffSBen Skeggs static const struct nvkm_vmm_func
5808e39abffSBen Skeggs gp100_vmm = {
5818e39abffSBen Skeggs .join = gp100_vmm_join,
5828e39abffSBen Skeggs .part = gf100_vmm_part,
583f9400afbSBen Skeggs .aper = gf100_vmm_aper,
584f9400afbSBen Skeggs .valid = gp100_vmm_valid,
585f9400afbSBen Skeggs .flush = gp100_vmm_flush,
58671871aa6SBen Skeggs .mthd = gp100_vmm_mthd,
587d389fd4fSBen Skeggs .invalidate_pdb = gp100_vmm_invalidate_pdb,
5888e39abffSBen Skeggs .page = {
5898e39abffSBen Skeggs { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
5908e39abffSBen Skeggs { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx },
5918e39abffSBen Skeggs { 29, &gp100_vmm_desc_16[2], NVKM_VMM_PAGE_Sxxx },
5928e39abffSBen Skeggs { 21, &gp100_vmm_desc_16[1], NVKM_VMM_PAGE_SVxC },
5938e39abffSBen Skeggs { 16, &gp100_vmm_desc_16[0], NVKM_VMM_PAGE_SVxC },
5948e39abffSBen Skeggs { 12, &gp100_vmm_desc_12[0], NVKM_VMM_PAGE_SVHx },
5958e39abffSBen Skeggs {}
5968e39abffSBen Skeggs }
5978e39abffSBen Skeggs };
5988e39abffSBen Skeggs
5998e39abffSBen Skeggs int
gp100_vmm_new_(const struct nvkm_vmm_func * func,struct nvkm_mmu * mmu,bool managed,u64 addr,u64 size,void * argv,u32 argc,struct lock_class_key * key,const char * name,struct nvkm_vmm ** pvmm)600ab2ee9ffSBen Skeggs gp100_vmm_new_(const struct nvkm_vmm_func *func,
601ab2ee9ffSBen Skeggs struct nvkm_mmu *mmu, bool managed, u64 addr, u64 size,
602ab2ee9ffSBen Skeggs void *argv, u32 argc, struct lock_class_key *key,
603ab2ee9ffSBen Skeggs const char *name, struct nvkm_vmm **pvmm)
604ab2ee9ffSBen Skeggs {
605ab2ee9ffSBen Skeggs union {
606ab2ee9ffSBen Skeggs struct gp100_vmm_vn vn;
607ab2ee9ffSBen Skeggs struct gp100_vmm_v0 v0;
608ab2ee9ffSBen Skeggs } *args = argv;
609ab2ee9ffSBen Skeggs int ret = -ENOSYS;
610ab2ee9ffSBen Skeggs bool replay;
611ab2ee9ffSBen Skeggs
612ab2ee9ffSBen Skeggs if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
613ab2ee9ffSBen Skeggs replay = args->v0.fault_replay != 0;
614ab2ee9ffSBen Skeggs } else
615ab2ee9ffSBen Skeggs if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
616ab2ee9ffSBen Skeggs replay = false;
617ab2ee9ffSBen Skeggs } else
618ab2ee9ffSBen Skeggs return ret;
619ab2ee9ffSBen Skeggs
620ab2ee9ffSBen Skeggs ret = nvkm_vmm_new_(func, mmu, 0, managed, addr, size, key, name, pvmm);
621ab2ee9ffSBen Skeggs if (ret)
622ab2ee9ffSBen Skeggs return ret;
623ab2ee9ffSBen Skeggs
624ab2ee9ffSBen Skeggs (*pvmm)->replay = replay;
625ab2ee9ffSBen Skeggs return 0;
626ab2ee9ffSBen Skeggs }
627ab2ee9ffSBen Skeggs
628ab2ee9ffSBen Skeggs int
gp100_vmm_new(struct nvkm_mmu * mmu,bool managed,u64 addr,u64 size,void * argv,u32 argc,struct lock_class_key * key,const char * name,struct nvkm_vmm ** pvmm)6292606f291SBen Skeggs gp100_vmm_new(struct nvkm_mmu *mmu, bool managed, u64 addr, u64 size,
6302606f291SBen Skeggs void *argv, u32 argc, struct lock_class_key *key,
6312606f291SBen Skeggs const char *name, struct nvkm_vmm **pvmm)
6328e39abffSBen Skeggs {
633ab2ee9ffSBen Skeggs return gp100_vmm_new_(&gp100_vmm, mmu, managed, addr, size,
6348e39abffSBen Skeggs argv, argc, key, name, pvmm);
6358e39abffSBen Skeggs }
636