2 * Copyright 2017 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <core/client.h>
28 #include <nvif/if0008.h>
29 #include <nvif/unpack.h>
32 nvkm_ummu_sclass(struct nvkm_object
*object
, int index
,
33 struct nvkm_oclass
*oclass
)
35 struct nvkm_mmu
*mmu
= nvkm_ummu(object
)->mmu
;
37 if (mmu
->func
->mem
.user
.oclass
&& oclass
->client
->super
) {
39 oclass
->base
= mmu
->func
->mem
.user
;
40 oclass
->ctor
= nvkm_umem_new
;
45 if (mmu
->func
->vmm
.user
.oclass
) {
47 oclass
->base
= mmu
->func
->vmm
.user
;
48 oclass
->ctor
= nvkm_uvmm_new
;
57 nvkm_ummu_heap(struct nvkm_ummu
*ummu
, void *argv
, u32 argc
)
59 struct nvkm_mmu
*mmu
= ummu
->mmu
;
61 struct nvif_mmu_heap_v0 v0
;
66 if (!(ret
= nvif_unpack(ret
, &argv
, &argc
, args
->v0
, 0, 0, false))) {
67 if ((index
= args
->v0
.index
) >= mmu
->heap_nr
)
69 args
->v0
.size
= mmu
->heap
[index
].size
;
77 nvkm_ummu_type(struct nvkm_ummu
*ummu
, void *argv
, u32 argc
)
79 struct nvkm_mmu
*mmu
= ummu
->mmu
;
81 struct nvif_mmu_type_v0 v0
;
86 if (!(ret
= nvif_unpack(ret
, &argv
, &argc
, args
->v0
, 0, 0, false))) {
87 if ((index
= args
->v0
.index
) >= mmu
->type_nr
)
89 type
= mmu
->type
[index
].type
;
90 args
->v0
.heap
= mmu
->type
[index
].heap
;
91 args
->v0
.vram
= !!(type
& NVKM_MEM_VRAM
);
92 args
->v0
.host
= !!(type
& NVKM_MEM_HOST
);
93 args
->v0
.comp
= !!(type
& NVKM_MEM_COMP
);
94 args
->v0
.disp
= !!(type
& NVKM_MEM_DISP
);
95 args
->v0
.kind
= !!(type
& NVKM_MEM_KIND
);
96 args
->v0
.mappable
= !!(type
& NVKM_MEM_MAPPABLE
);
97 args
->v0
.coherent
= !!(type
& NVKM_MEM_COHERENT
);
98 args
->v0
.uncached
= !!(type
& NVKM_MEM_UNCACHED
);
106 nvkm_ummu_kind(struct nvkm_ummu
*ummu
, void *argv
, u32 argc
)
108 struct nvkm_mmu
*mmu
= ummu
->mmu
;
110 struct nvif_mmu_kind_v0 v0
;
112 const u8
*kind
= NULL
;
113 int ret
= -ENOSYS
, count
= 0;
117 kind
= mmu
->func
->kind(mmu
, &count
, &kind_inv
);
119 if (!(ret
= nvif_unpack(ret
, &argv
, &argc
, args
->v0
, 0, 0, true))) {
120 if (argc
!= args
->v0
.count
* sizeof(*args
->v0
.data
))
122 if (args
->v0
.count
> count
)
124 args
->v0
.kind_inv
= kind_inv
;
125 memcpy(args
->v0
.data
, kind
, args
->v0
.count
);
133 nvkm_ummu_mthd(struct nvkm_object
*object
, u32 mthd
, void *argv
, u32 argc
)
135 struct nvkm_ummu
*ummu
= nvkm_ummu(object
);
137 case NVIF_MMU_V0_HEAP
: return nvkm_ummu_heap(ummu
, argv
, argc
);
138 case NVIF_MMU_V0_TYPE
: return nvkm_ummu_type(ummu
, argv
, argc
);
139 case NVIF_MMU_V0_KIND
: return nvkm_ummu_kind(ummu
, argv
, argc
);
146 static const struct nvkm_object_func
148 .mthd
= nvkm_ummu_mthd
,
149 .sclass
= nvkm_ummu_sclass
,
153 nvkm_ummu_new(struct nvkm_device
*device
, const struct nvkm_oclass
*oclass
,
154 void *argv
, u32 argc
, struct nvkm_object
**pobject
)
157 struct nvif_mmu_v0 v0
;
159 struct nvkm_mmu
*mmu
= device
->mmu
;
160 struct nvkm_ummu
*ummu
;
161 int ret
= -ENOSYS
, kinds
= 0;
165 mmu
->func
->kind(mmu
, &kinds
, &unused
);
167 if (!(ret
= nvif_unpack(ret
, &argv
, &argc
, args
->v0
, 0, 0, false))) {
168 args
->v0
.dmabits
= mmu
->dma_bits
;
169 args
->v0
.heap_nr
= mmu
->heap_nr
;
170 args
->v0
.type_nr
= mmu
->type_nr
;
171 args
->v0
.kind_nr
= kinds
;
175 if (!(ummu
= kzalloc(sizeof(*ummu
), GFP_KERNEL
)))
177 nvkm_object_ctor(&nvkm_ummu
, oclass
, &ummu
->object
);
179 *pobject
= &ummu
->object
;