diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c | 106 |
1 files changed, 23 insertions, 83 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c index 57f6eca078ef..1a377201949c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "priv.h" | 24 | #include "priv.h" |
25 | 25 | ||
26 | #include <core/client.h> | 26 | #include <core/client.h> |
27 | #include <engine/fifo.h> | ||
27 | 28 | ||
28 | #include <nvif/class.h> | 29 | #include <nvif/class.h> |
29 | 30 | ||
@@ -88,11 +89,19 @@ nvkm_dma_oclass_base = { | |||
88 | .ctor = nvkm_dma_oclass_new, | 89 | .ctor = nvkm_dma_oclass_new, |
89 | }; | 90 | }; |
90 | 91 | ||
92 | static int | ||
93 | nvkm_dma_oclass_fifo_new(const struct nvkm_oclass *oclass, void *data, u32 size, | ||
94 | struct nvkm_object **pobject) | ||
95 | { | ||
96 | return nvkm_dma_oclass_new(oclass->engine->subdev.device, | ||
97 | oclass, data, size, pobject); | ||
98 | } | ||
99 | |||
91 | static const struct nvkm_sclass | 100 | static const struct nvkm_sclass |
92 | nvkm_dma_sclass[] = { | 101 | nvkm_dma_sclass[] = { |
93 | { 0, 0, NV_DMA_FROM_MEMORY }, | 102 | { 0, 0, NV_DMA_FROM_MEMORY, NULL, nvkm_dma_oclass_fifo_new }, |
94 | { 0, 0, NV_DMA_TO_MEMORY }, | 103 | { 0, 0, NV_DMA_TO_MEMORY, NULL, nvkm_dma_oclass_fifo_new }, |
95 | { 0, 0, NV_DMA_IN_MEMORY }, | 104 | { 0, 0, NV_DMA_IN_MEMORY, NULL, nvkm_dma_oclass_fifo_new }, |
96 | }; | 105 | }; |
97 | 106 | ||
98 | static int | 107 | static int |
@@ -110,89 +119,21 @@ nvkm_dma_oclass_base_get(struct nvkm_oclass *sclass, int index, | |||
110 | return count; | 119 | return count; |
111 | } | 120 | } |
112 | 121 | ||
113 | static const struct nvkm_engine_func | ||
114 | nvkm_dma = { | ||
115 | .base.sclass = nvkm_dma_oclass_base_get, | ||
116 | }; | ||
117 | |||
118 | #include <core/gpuobj.h> | ||
119 | |||
120 | static struct nvkm_oclass empty = { | ||
121 | .ofuncs = &(struct nvkm_ofuncs) { | ||
122 | .dtor = nvkm_object_destroy, | ||
123 | .init = _nvkm_object_init, | ||
124 | .fini = _nvkm_object_fini, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static int | 122 | static int |
129 | nvkm_dmaobj_compat_ctor(struct nvkm_object *parent, struct nvkm_object *engine, | 123 | nvkm_dma_oclass_fifo_get(struct nvkm_oclass *oclass, int index) |
130 | struct nvkm_oclass *oclass, void *data, u32 size, | ||
131 | struct nvkm_object **pobject) | ||
132 | { | ||
133 | struct nvkm_oclass hack = { | ||
134 | .base.oclass = oclass->handle, | ||
135 | .client = nvkm_client(parent), | ||
136 | .parent = parent, | ||
137 | .engine = nv_engine(engine), | ||
138 | }; | ||
139 | struct nvkm_dma *dma = (void *)engine; | ||
140 | struct nvkm_dma_impl *impl = (void *)dma->engine.subdev.object.oclass; | ||
141 | struct nvkm_dmaobj *dmaobj = NULL; | ||
142 | struct nvkm_gpuobj *gpuobj; | ||
143 | int ret; | ||
144 | |||
145 | ret = impl->class_new(dma, &hack, data, size, &dmaobj); | ||
146 | if (dmaobj) | ||
147 | *pobject = &dmaobj->object; | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | gpuobj = (void *)nv_pclass(parent, NV_GPUOBJ_CLASS); | ||
152 | |||
153 | ret = dmaobj->func->bind(dmaobj, gpuobj, 16, &gpuobj); | ||
154 | nvkm_object_ref(NULL, pobject); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | ret = nvkm_object_create(parent, engine, &empty, 0, pobject); | ||
159 | if (ret) | ||
160 | return ret; | ||
161 | |||
162 | gpuobj->object.parent = *pobject; | ||
163 | gpuobj->object.engine = &dma->engine; | ||
164 | gpuobj->object.oclass = oclass; | ||
165 | gpuobj->object.pclass = NV_GPUOBJ_CLASS; | ||
166 | #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA | ||
167 | gpuobj->object._magic = NVKM_OBJECT_MAGIC; | ||
168 | #endif | ||
169 | *pobject = &gpuobj->object; | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static void | ||
174 | nvkm_dmaobj_compat_dtor(struct nvkm_object *object) | ||
175 | { | 124 | { |
176 | struct nvkm_object *parent = object->parent; | 125 | const int count = ARRAY_SIZE(nvkm_dma_sclass); |
177 | struct nvkm_gpuobj *gpuobj = (void *)object; | 126 | if (index < count) { |
178 | nvkm_gpuobj_del(&gpuobj); | 127 | oclass->base = nvkm_dma_sclass[index]; |
179 | nvkm_object_ref(NULL, &parent); | 128 | return index; |
129 | } | ||
130 | return count; | ||
180 | } | 131 | } |
181 | 132 | ||
182 | static struct nvkm_ofuncs | 133 | static const struct nvkm_engine_func |
183 | nvkm_dmaobj_compat_ofuncs = { | 134 | nvkm_dma = { |
184 | .ctor = nvkm_dmaobj_compat_ctor, | 135 | .base.sclass = nvkm_dma_oclass_base_get, |
185 | .dtor = nvkm_dmaobj_compat_dtor, | 136 | .fifo.sclass = nvkm_dma_oclass_fifo_get, |
186 | .init = _nvkm_object_init, | ||
187 | .fini = _nvkm_object_fini, | ||
188 | }; | ||
189 | |||
190 | static struct nvkm_oclass | ||
191 | nvkm_dma_compat_sclass[] = { | ||
192 | { NV_DMA_FROM_MEMORY, &nvkm_dmaobj_compat_ofuncs }, | ||
193 | { NV_DMA_TO_MEMORY, &nvkm_dmaobj_compat_ofuncs }, | ||
194 | { NV_DMA_IN_MEMORY, &nvkm_dmaobj_compat_ofuncs }, | ||
195 | {} | ||
196 | }; | 137 | }; |
197 | 138 | ||
198 | int | 139 | int |
@@ -209,7 +150,6 @@ _nvkm_dma_ctor(struct nvkm_object *parent, struct nvkm_object *engine, | |||
209 | if (ret) | 150 | if (ret) |
210 | return ret; | 151 | return ret; |
211 | 152 | ||
212 | dmaeng->engine.sclass = nvkm_dma_compat_sclass; | ||
213 | dmaeng->engine.func = &nvkm_dma; | 153 | dmaeng->engine.func = &nvkm_dma; |
214 | return 0; | 154 | return 0; |
215 | } | 155 | } |