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/class.h>
27 #include <core/engctx.h>
28 #include <core/event.h>
30 #include <subdev/bar.h>
32 #include <engine/software.h>
33 #include <engine/disp.h>
37 /*******************************************************************************
38 * software object classes
39 ******************************************************************************/
42 nvc0_software_mthd_vblsem_offset(struct nouveau_object
*object
, u32 mthd
,
45 struct nv50_software_chan
*chan
= (void *)nv_engctx(object
->parent
);
46 u64 data
= *(u32
*)args
;
48 chan
->vblank
.offset
&= 0x00ffffffffULL
;
49 chan
->vblank
.offset
|= data
<< 32;
51 chan
->vblank
.offset
&= 0xff00000000ULL
;
52 chan
->vblank
.offset
|= data
;
58 nvc0_software_mthd_vblsem_value(struct nouveau_object
*object
, u32 mthd
,
61 struct nv50_software_chan
*chan
= (void *)nv_engctx(object
->parent
);
62 chan
->vblank
.value
= *(u32
*)args
;
67 nvc0_software_mthd_vblsem_release(struct nouveau_object
*object
, u32 mthd
,
70 struct nv50_software_chan
*chan
= (void *)nv_engctx(object
->parent
);
71 struct nouveau_disp
*disp
= nouveau_disp(object
);
72 u32 crtc
= *(u32
*)args
;
74 if ((nv_device(object
)->card_type
< NV_E0
&& crtc
> 1) || crtc
> 3)
77 nouveau_event_get(disp
->vblank
, crtc
, &chan
->vblank
.event
);
82 nvc0_software_mthd_flip(struct nouveau_object
*object
, u32 mthd
,
85 struct nv50_software_chan
*chan
= (void *)nv_engctx(object
->parent
);
87 return chan
->base
.flip(chan
->base
.flip_data
);
92 nvc0_software_mthd_mp_control(struct nouveau_object
*object
, u32 mthd
,
95 struct nv50_software_chan
*chan
= (void *)nv_engctx(object
->parent
);
96 struct nv50_software_priv
*priv
= (void *)nv_object(chan
)->engine
;
97 u32 data
= *(u32
*)args
;
101 nv_wr32(priv
, 0x419e00, data
); /* MP.PM_UNK000 */
104 if (data
& ~0x1ffffe)
106 nv_wr32(priv
, 0x419e44, data
); /* MP.TRAP_WARP_ERROR_EN */
109 nv_wr32(priv
, 0x419eac, data
); /* MP.PM_UNK0AC */
117 static struct nouveau_omthds
118 nvc0_software_omthds
[] = {
119 { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset
},
120 { 0x0404, 0x0404, nvc0_software_mthd_vblsem_offset
},
121 { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value
},
122 { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release
},
123 { 0x0500, 0x0500, nvc0_software_mthd_flip
},
124 { 0x0600, 0x0600, nvc0_software_mthd_mp_control
},
125 { 0x0644, 0x0644, nvc0_software_mthd_mp_control
},
126 { 0x06ac, 0x06ac, nvc0_software_mthd_mp_control
},
130 static struct nouveau_oclass
131 nvc0_software_sclass
[] = {
132 { 0x906e, &nouveau_object_ofuncs
, nvc0_software_omthds
},
136 /*******************************************************************************
138 ******************************************************************************/
141 nvc0_software_vblsem_release(struct nouveau_eventh
*event
, int head
)
143 struct nv50_software_chan
*chan
=
144 container_of(event
, typeof(*chan
), vblank
.event
);
145 struct nv50_software_priv
*priv
= (void *)nv_object(chan
)->engine
;
146 struct nouveau_bar
*bar
= nouveau_bar(priv
);
148 nv_wr32(priv
, 0x001718, 0x80000000 | chan
->vblank
.channel
);
150 nv_wr32(priv
, 0x06000c, upper_32_bits(chan
->vblank
.offset
));
151 nv_wr32(priv
, 0x060010, lower_32_bits(chan
->vblank
.offset
));
152 nv_wr32(priv
, 0x060014, chan
->vblank
.value
);
154 return NVKM_EVENT_DROP
;
158 nvc0_software_context_ctor(struct nouveau_object
*parent
,
159 struct nouveau_object
*engine
,
160 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
161 struct nouveau_object
**pobject
)
163 struct nv50_software_chan
*chan
;
166 ret
= nouveau_software_context_create(parent
, engine
, oclass
, &chan
);
167 *pobject
= nv_object(chan
);
171 chan
->vblank
.channel
= nv_gpuobj(parent
->parent
)->addr
>> 12;
172 chan
->vblank
.event
.func
= nvc0_software_vblsem_release
;
176 static struct nouveau_oclass
177 nvc0_software_cclass
= {
178 .handle
= NV_ENGCTX(SW
, 0xc0),
179 .ofuncs
= &(struct nouveau_ofuncs
) {
180 .ctor
= nvc0_software_context_ctor
,
181 .dtor
= _nouveau_software_context_dtor
,
182 .init
= _nouveau_software_context_init
,
183 .fini
= _nouveau_software_context_fini
,
187 /*******************************************************************************
188 * software engine/subdev functions
189 ******************************************************************************/
192 nvc0_software_ctor(struct nouveau_object
*parent
, struct nouveau_object
*engine
,
193 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
194 struct nouveau_object
**pobject
)
196 struct nv50_software_priv
*priv
;
199 ret
= nouveau_software_create(parent
, engine
, oclass
, &priv
);
200 *pobject
= nv_object(priv
);
204 nv_engine(priv
)->cclass
= &nvc0_software_cclass
;
205 nv_engine(priv
)->sclass
= nvc0_software_sclass
;
206 nv_subdev(priv
)->intr
= nv04_software_intr
;
210 struct nouveau_oclass
*
211 nvc0_software_oclass
= &(struct nv50_software_oclass
) {
212 .base
.handle
= NV_ENGINE(SW
, 0xc0),
213 .base
.ofuncs
= &(struct nouveau_ofuncs
) {
214 .ctor
= nvc0_software_ctor
,
215 .dtor
= _nouveau_software_dtor
,
216 .init
= _nouveau_software_init
,
217 .fini
= _nouveau_software_fini
,