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.
25 #include <core/client.h>
27 #include <core/class.h>
28 #include <core/engctx.h>
29 #include <core/handle.h>
31 #include <subdev/fb.h>
32 #include <subdev/timer.h>
33 #include <subdev/instmem.h>
35 #include <engine/fifo.h>
36 #include <engine/mpeg.h>
37 #include <engine/graph/nv40.h>
39 struct nv31_mpeg_priv
{
40 struct nouveau_mpeg base
;
44 struct nv31_mpeg_chan
{
45 struct nouveau_object base
;
48 /*******************************************************************************
50 ******************************************************************************/
53 nv31_mpeg_object_ctor(struct nouveau_object
*parent
,
54 struct nouveau_object
*engine
,
55 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
56 struct nouveau_object
**pobject
)
58 struct nouveau_gpuobj
*obj
;
61 ret
= nouveau_gpuobj_create(parent
, engine
, oclass
, 0, parent
,
63 *pobject
= nv_object(obj
);
67 nv_wo32(obj
, 0x00, nv_mclass(obj
));
68 nv_wo32(obj
, 0x04, 0x00000000);
69 nv_wo32(obj
, 0x08, 0x00000000);
70 nv_wo32(obj
, 0x0c, 0x00000000);
75 nv31_mpeg_mthd_dma(struct nouveau_object
*object
, u32 mthd
, void *arg
, u32 len
)
77 struct nouveau_instmem
*imem
= nouveau_instmem(object
);
78 struct nv31_mpeg_priv
*priv
= (void *)object
->engine
;
79 u32 inst
= *(u32
*)arg
<< 4;
80 u32 dma0
= nv_ro32(imem
, inst
+ 0);
81 u32 dma1
= nv_ro32(imem
, inst
+ 4);
82 u32 dma2
= nv_ro32(imem
, inst
+ 8);
83 u32 base
= (dma2
& 0xfffff000) | (dma0
>> 20);
86 /* only allow linear DMA objects */
87 if (!(dma0
& 0x00002000))
92 nv_mask(priv
, 0x00b300, 0x00030000, (dma0
& 0x00030000));
93 nv_wr32(priv
, 0x00b334, base
);
94 nv_wr32(priv
, 0x00b324, size
);
98 nv_mask(priv
, 0x00b300, 0x000c0000, (dma0
& 0x00030000) << 2);
99 nv_wr32(priv
, 0x00b360, base
);
100 nv_wr32(priv
, 0x00b364, size
);
102 /* DMA_IMAGE, VRAM only */
103 if (dma0
& 0x000c0000)
106 nv_wr32(priv
, 0x00b370, base
);
107 nv_wr32(priv
, 0x00b374, size
);
113 static struct nouveau_ofuncs
115 .ctor
= nv31_mpeg_object_ctor
,
116 .dtor
= _nouveau_gpuobj_dtor
,
117 .init
= _nouveau_gpuobj_init
,
118 .fini
= _nouveau_gpuobj_fini
,
119 .rd32
= _nouveau_gpuobj_rd32
,
120 .wr32
= _nouveau_gpuobj_wr32
,
123 static struct nouveau_omthds
124 nv31_mpeg_omthds
[] = {
125 { 0x0190, 0x0190, nv31_mpeg_mthd_dma
},
126 { 0x01a0, 0x01a0, nv31_mpeg_mthd_dma
},
127 { 0x01b0, 0x01b0, nv31_mpeg_mthd_dma
},
131 struct nouveau_oclass
132 nv31_mpeg_sclass
[] = {
133 { 0x3174, &nv31_mpeg_ofuncs
, nv31_mpeg_omthds
},
137 /*******************************************************************************
139 ******************************************************************************/
142 nv31_mpeg_context_ctor(struct nouveau_object
*parent
,
143 struct nouveau_object
*engine
,
144 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
145 struct nouveau_object
**pobject
)
147 struct nv31_mpeg_priv
*priv
= (void *)engine
;
148 struct nv31_mpeg_chan
*chan
;
151 if (!atomic_add_unless(&priv
->refcount
, 1, 1))
154 ret
= nouveau_object_create(parent
, engine
, oclass
, 0, &chan
);
155 *pobject
= nv_object(chan
);
163 nv31_mpeg_context_dtor(struct nouveau_object
*object
)
165 struct nv31_mpeg_priv
*priv
= (void *)object
->engine
;
166 struct nv31_mpeg_chan
*chan
= (void *)object
;
167 atomic_dec(&priv
->refcount
);
168 nouveau_object_destroy(&chan
->base
);
171 static struct nouveau_oclass
173 .handle
= NV_ENGCTX(MPEG
, 0x31),
174 .ofuncs
= &(struct nouveau_ofuncs
) {
175 .ctor
= nv31_mpeg_context_ctor
,
176 .dtor
= nv31_mpeg_context_dtor
,
177 .init
= nouveau_object_init
,
178 .fini
= nouveau_object_fini
,
182 /*******************************************************************************
183 * PMPEG engine/subdev functions
184 ******************************************************************************/
187 nv31_mpeg_tile_prog(struct nouveau_engine
*engine
, int i
)
189 struct nouveau_fb_tile
*tile
= &nouveau_fb(engine
)->tile
.region
[i
];
190 struct nv31_mpeg_priv
*priv
= (void *)engine
;
192 nv_wr32(priv
, 0x00b008 + (i
* 0x10), tile
->pitch
);
193 nv_wr32(priv
, 0x00b004 + (i
* 0x10), tile
->limit
);
194 nv_wr32(priv
, 0x00b000 + (i
* 0x10), tile
->addr
);
198 nv31_mpeg_intr(struct nouveau_subdev
*subdev
)
200 struct nouveau_fifo
*pfifo
= nouveau_fifo(subdev
);
201 struct nouveau_engine
*engine
= nv_engine(subdev
);
202 struct nouveau_object
*engctx
;
203 struct nouveau_handle
*handle
;
204 struct nv31_mpeg_priv
*priv
= (void *)subdev
;
205 u32 inst
= nv_rd32(priv
, 0x00b318) & 0x000fffff;
206 u32 stat
= nv_rd32(priv
, 0x00b100);
207 u32 type
= nv_rd32(priv
, 0x00b230);
208 u32 mthd
= nv_rd32(priv
, 0x00b234);
209 u32 data
= nv_rd32(priv
, 0x00b238);
213 engctx
= nouveau_engctx_get(engine
, inst
);
214 chid
= pfifo
->chid(pfifo
, engctx
);
216 if (stat
& 0x01000000) {
217 /* happens on initial binding of the object */
218 if (type
== 0x00000020 && mthd
== 0x0000) {
219 nv_mask(priv
, 0x00b308, 0x00000000, 0x00000000);
223 if (type
== 0x00000010) {
224 handle
= nouveau_handle_get_class(engctx
, 0x3174);
225 if (handle
&& !nv_call(handle
->object
, mthd
, data
))
227 nouveau_handle_put(handle
);
231 nv_wr32(priv
, 0x00b100, stat
);
232 nv_wr32(priv
, 0x00b230, 0x00000001);
236 "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
237 chid
, inst
<< 4, nouveau_client_name(engctx
), stat
,
241 nouveau_engctx_put(engctx
);
245 nv31_mpeg_ctor(struct nouveau_object
*parent
, struct nouveau_object
*engine
,
246 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
247 struct nouveau_object
**pobject
)
249 struct nv31_mpeg_priv
*priv
;
252 ret
= nouveau_mpeg_create(parent
, engine
, oclass
, &priv
);
253 *pobject
= nv_object(priv
);
257 nv_subdev(priv
)->unit
= 0x00000002;
258 nv_subdev(priv
)->intr
= nv31_mpeg_intr
;
259 nv_engine(priv
)->cclass
= &nv31_mpeg_cclass
;
260 nv_engine(priv
)->sclass
= nv31_mpeg_sclass
;
261 nv_engine(priv
)->tile_prog
= nv31_mpeg_tile_prog
;
266 nv31_mpeg_init(struct nouveau_object
*object
)
268 struct nouveau_engine
*engine
= nv_engine(object
->engine
);
269 struct nv31_mpeg_priv
*priv
= (void *)engine
;
270 struct nouveau_fb
*pfb
= nouveau_fb(object
);
273 ret
= nouveau_mpeg_init(&priv
->base
);
278 nv_wr32(priv
, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
279 nv_wr32(priv
, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
281 for (i
= 0; i
< pfb
->tile
.regions
; i
++)
282 engine
->tile_prog(engine
, i
);
285 nv_wr32(priv
, 0x00b32c, 0x00000000);
286 nv_wr32(priv
, 0x00b314, 0x00000100);
287 nv_wr32(priv
, 0x00b220, nv44_graph_class(priv
) ? 0x00000044 : 0x00000031);
288 nv_wr32(priv
, 0x00b300, 0x02001ec1);
289 nv_mask(priv
, 0x00b32c, 0x00000001, 0x00000001);
291 nv_wr32(priv
, 0x00b100, 0xffffffff);
292 nv_wr32(priv
, 0x00b140, 0xffffffff);
294 if (!nv_wait(priv
, 0x00b200, 0x00000001, 0x00000000)) {
295 nv_error(priv
, "timeout 0x%08x\n", nv_rd32(priv
, 0x00b200));
302 struct nouveau_oclass
304 .handle
= NV_ENGINE(MPEG
, 0x31),
305 .ofuncs
= &(struct nouveau_ofuncs
) {
306 .ctor
= nv31_mpeg_ctor
,
307 .dtor
= _nouveau_mpeg_dtor
,
308 .init
= nv31_mpeg_init
,
309 .fini
= _nouveau_mpeg_fini
,
This page took 0.038888 seconds and 5 git commands to generate.