2 * Copyright 2012 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>
27 #include <subdev/fb.h>
28 #include <subdev/instmem.h>
30 #include <nvif/class.h>
31 #include <nvif/unpack.h>
34 nvkm_dmaobj_bind(struct nvkm_dmaobj
*dmaobj
, struct nvkm_object
*parent
,
35 struct nvkm_gpuobj
**pgpuobj
)
37 const struct nvkm_dmaeng_impl
*impl
= (void *)
38 nv_oclass(nv_object(dmaobj
)->engine
);
41 if (nv_object(dmaobj
) == parent
) { /* ctor bind */
42 if (nv_mclass(parent
->parent
) == NV_DEVICE
) {
43 /* delayed, or no, binding */
46 ret
= impl
->bind(dmaobj
, parent
, pgpuobj
);
48 nvkm_object_ref(NULL
, &parent
);
52 return impl
->bind(dmaobj
, parent
, pgpuobj
);
56 nvkm_dmaobj_create_(struct nvkm_object
*parent
,
57 struct nvkm_object
*engine
,
58 struct nvkm_oclass
*oclass
, void **pdata
, u32
*psize
,
59 int length
, void **pobject
)
64 struct nvkm_instmem
*instmem
= nvkm_instmem(parent
);
65 struct nvkm_client
*client
= nvkm_client(parent
);
66 struct nvkm_device
*device
= nv_device(parent
);
67 struct nvkm_fb
*fb
= nvkm_fb(parent
);
68 struct nvkm_dmaobj
*dmaobj
;
73 ret
= nvkm_object_create_(parent
, engine
, oclass
, 0, length
, pobject
);
78 nv_ioctl(parent
, "create dma size %d\n", *psize
);
79 if (nvif_unpack(args
->v0
, 0, 0, true)) {
80 nv_ioctl(parent
, "create dma vers %d target %d access %d "
81 "start %016llx limit %016llx\n",
82 args
->v0
.version
, args
->v0
.target
, args
->v0
.access
,
83 args
->v0
.start
, args
->v0
.limit
);
84 dmaobj
->target
= args
->v0
.target
;
85 dmaobj
->access
= args
->v0
.access
;
86 dmaobj
->start
= args
->v0
.start
;
87 dmaobj
->limit
= args
->v0
.limit
;
94 if (dmaobj
->start
> dmaobj
->limit
)
97 switch (dmaobj
->target
) {
98 case NV_DMA_V0_TARGET_VM
:
99 dmaobj
->target
= NV_MEM_TARGET_VM
;
101 case NV_DMA_V0_TARGET_VRAM
:
102 if (!client
->super
) {
103 if (dmaobj
->limit
>= fb
->ram
->size
- instmem
->reserved
)
105 if (device
->card_type
>= NV_50
)
108 dmaobj
->target
= NV_MEM_TARGET_VRAM
;
110 case NV_DMA_V0_TARGET_PCI
:
113 dmaobj
->target
= NV_MEM_TARGET_PCI
;
115 case NV_DMA_V0_TARGET_PCI_US
:
116 case NV_DMA_V0_TARGET_AGP
:
119 dmaobj
->target
= NV_MEM_TARGET_PCI_NOSNOOP
;
125 switch (dmaobj
->access
) {
126 case NV_DMA_V0_ACCESS_VM
:
127 dmaobj
->access
= NV_MEM_ACCESS_VM
;
129 case NV_DMA_V0_ACCESS_RD
:
130 dmaobj
->access
= NV_MEM_ACCESS_RO
;
132 case NV_DMA_V0_ACCESS_WR
:
133 dmaobj
->access
= NV_MEM_ACCESS_WO
;
135 case NV_DMA_V0_ACCESS_RDWR
:
136 dmaobj
->access
= NV_MEM_ACCESS_RW
;
146 _nvkm_dmaeng_ctor(struct nvkm_object
*parent
, struct nvkm_object
*engine
,
147 struct nvkm_oclass
*oclass
, void *data
, u32 size
,
148 struct nvkm_object
**pobject
)
150 const struct nvkm_dmaeng_impl
*impl
= (void *)oclass
;
151 struct nvkm_dmaeng
*dmaeng
;
154 ret
= nvkm_engine_create(parent
, engine
, oclass
, true, "DMAOBJ",
156 *pobject
= nv_object(dmaeng
);
160 nv_engine(dmaeng
)->sclass
= impl
->sclass
;
161 dmaeng
->bind
= nvkm_dmaobj_bind
;