2 * Copyright (C) 2007 Ben Skeggs.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include "nouveau_drv.h"
31 struct nv50_fifo_priv
{
32 struct nouveau_gpuobj_ref
*thingo
[2];
36 #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
39 nv50_fifo_init_thingo(struct drm_device
*dev
)
41 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
42 struct nv50_fifo_priv
*priv
= dev_priv
->Engine
.fifo
.priv
;
43 struct nouveau_gpuobj_ref
*cur
;
48 cur
= priv
->thingo
[priv
->cur_thingo
];
49 priv
->cur_thingo
= !priv
->cur_thingo
;
51 /* We never schedule channel 0 or 127 */
52 for (i
= 1, nr
= 0; i
< 127; i
++) {
53 if (dev_priv
->fifos
[i
]) {
54 INSTANCE_WR(cur
->gpuobj
, nr
++, i
);
57 NV_WRITE(0x32f4, cur
->instance
>> 12);
59 NV_WRITE(0x2500, 0x101);
63 nv50_fifo_channel_enable(struct drm_device
*dev
, int channel
, int nt
)
65 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
66 struct nouveau_channel
*chan
= dev_priv
->fifos
[channel
];
69 DRM_DEBUG("ch%d\n", channel
);
74 if (IS_G80
) inst
= chan
->ramfc
->instance
>> 12;
75 else inst
= chan
->ramfc
->instance
>> 8;
76 NV_WRITE(NV50_PFIFO_CTX_TABLE(channel
),
77 inst
| NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED
);
79 if (!nt
) nv50_fifo_init_thingo(dev
);
84 nv50_fifo_channel_disable(struct drm_device
*dev
, int channel
, int nt
)
86 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
89 DRM_DEBUG("ch%d, nt=%d\n", channel
, nt
);
91 if (IS_G80
) inst
= NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80
;
92 else inst
= NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84
;
93 NV_WRITE(NV50_PFIFO_CTX_TABLE(channel
), inst
);
95 if (!nt
) nv50_fifo_init_thingo(dev
);
99 nv50_fifo_init_reset(struct drm_device
*dev
)
101 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
102 uint32_t pmc_e
= NV_PMC_ENABLE_PFIFO
;
106 NV_WRITE(NV03_PMC_ENABLE
, NV_READ(NV03_PMC_ENABLE
) & ~pmc_e
);
107 NV_WRITE(NV03_PMC_ENABLE
, NV_READ(NV03_PMC_ENABLE
) | pmc_e
);
111 nv50_fifo_init_intr(struct drm_device
*dev
)
113 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
117 NV_WRITE(NV03_PFIFO_INTR_0
, 0xFFFFFFFF);
118 NV_WRITE(NV03_PFIFO_INTR_EN_0
, 0xFFFFFFFF);
122 nv50_fifo_init_context_table(struct drm_device
*dev
)
128 for (i
= 0; i
< NV50_PFIFO_CTX_TABLE__SIZE
; i
++)
129 nv50_fifo_channel_disable(dev
, i
, 1);
130 nv50_fifo_init_thingo(dev
);
134 nv50_fifo_init_regs__nv(struct drm_device
*dev
)
136 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
140 NV_WRITE(0x250c, 0x6f3cfc34);
144 nv50_fifo_init_regs(struct drm_device
*dev
)
146 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
157 /* Enable dummy channels setup by nv50_instmem.c */
158 nv50_fifo_channel_enable(dev
, 0, 1);
159 nv50_fifo_channel_enable(dev
, 127, 1);
163 nv50_fifo_init(struct drm_device
*dev
)
165 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
166 struct nv50_fifo_priv
*priv
;
171 priv
= drm_calloc(1, sizeof(*priv
), DRM_MEM_DRIVER
);
174 dev_priv
->Engine
.fifo
.priv
= priv
;
176 nv50_fifo_init_reset(dev
);
177 nv50_fifo_init_intr(dev
);
179 ret
= nouveau_gpuobj_new_ref(dev
, NULL
, NULL
, 0, 128*4, 0x1000,
180 NVOBJ_FLAG_ZERO_ALLOC
, &priv
->thingo
[0]);
182 DRM_ERROR("error creating thingo0: %d\n", ret
);
186 ret
= nouveau_gpuobj_new_ref(dev
, NULL
, NULL
, 0, 128*4, 0x1000,
187 NVOBJ_FLAG_ZERO_ALLOC
, &priv
->thingo
[1]);
189 DRM_ERROR("error creating thingo1: %d\n", ret
);
193 nv50_fifo_init_context_table(dev
);
194 nv50_fifo_init_regs__nv(dev
);
195 nv50_fifo_init_regs(dev
);
201 nv50_fifo_takedown(struct drm_device
*dev
)
203 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
204 struct nv50_fifo_priv
*priv
= dev_priv
->Engine
.fifo
.priv
;
211 nouveau_gpuobj_ref_del(dev
, &priv
->thingo
[0]);
212 nouveau_gpuobj_ref_del(dev
, &priv
->thingo
[1]);
214 dev_priv
->Engine
.fifo
.priv
= NULL
;
215 drm_free(priv
, sizeof(*priv
), DRM_MEM_DRIVER
);
219 nv50_fifo_channel_id(struct drm_device
*dev
)
221 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
223 return (NV_READ(NV03_PFIFO_CACHE1_PUSH1
) &
224 NV50_PFIFO_CACHE1_PUSH1_CHID_MASK
);
228 nv50_fifo_create_context(struct nouveau_channel
*chan
)
230 struct drm_device
*dev
= chan
->dev
;
231 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
232 struct nouveau_gpuobj
*ramfc
= NULL
;
235 DRM_DEBUG("ch%d\n", chan
->id
);
238 uint32_t ramfc_offset
= chan
->ramin
->gpuobj
->im_pramin
->start
;
239 uint32_t vram_offset
= chan
->ramin
->gpuobj
->im_backing
->start
;
240 ret
= nouveau_gpuobj_new_fake(dev
, ramfc_offset
, vram_offset
,
241 0x100, NVOBJ_FLAG_ZERO_ALLOC
|
242 NVOBJ_FLAG_ZERO_FREE
, &ramfc
,
247 ret
= nouveau_gpuobj_new_ref(dev
, chan
, NULL
, 0, 0x100, 256,
248 NVOBJ_FLAG_ZERO_ALLOC
|
249 NVOBJ_FLAG_ZERO_FREE
,
253 ramfc
= chan
->ramfc
->gpuobj
;
256 INSTANCE_WR(ramfc
, 0x48/4, chan
->pushbuf
->instance
>> 4);
257 INSTANCE_WR(ramfc
, 0x80/4, (0xc << 24) | (chan
->ramht
->instance
>> 4));
258 INSTANCE_WR(ramfc
, 0x3c/4, 0x000f0078); /* fetch? */
259 INSTANCE_WR(ramfc
, 0x44/4, 0x2101ffff);
260 INSTANCE_WR(ramfc
, 0x60/4, 0x7fffffff);
261 INSTANCE_WR(ramfc
, 0x10/4, 0x00000000);
262 INSTANCE_WR(ramfc
, 0x08/4, 0x00000000);
263 INSTANCE_WR(ramfc
, 0x40/4, 0x00000000);
264 INSTANCE_WR(ramfc
, 0x50/4, 0x2039b2e0);
265 INSTANCE_WR(ramfc
, 0x54/4, 0x000f0000);
266 INSTANCE_WR(ramfc
, 0x7c/4, 0x30000001);
267 INSTANCE_WR(ramfc
, 0x78/4, 0x00000000);
268 INSTANCE_WR(ramfc
, 0x4c/4, chan
->pushbuf_mem
->size
- 1);
271 INSTANCE_WR(chan
->ramin
->gpuobj
, 0, chan
->id
);
272 INSTANCE_WR(chan
->ramin
->gpuobj
, 1, chan
->ramfc
->instance
>> 8);
274 INSTANCE_WR(ramfc
, 0x88/4, 0x3d520); /* some vram addy >> 10 */
275 INSTANCE_WR(ramfc
, 0x98/4, chan
->ramin
->instance
>> 12);
278 ret
= nv50_fifo_channel_enable(dev
, chan
->id
, 0);
280 DRM_ERROR("error enabling ch%d: %d\n", chan
->id
, ret
);
281 nouveau_gpuobj_ref_del(dev
, &chan
->ramfc
);
289 nv50_fifo_destroy_context(struct nouveau_channel
*chan
)
291 struct drm_device
*dev
= chan
->dev
;
292 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
294 DRM_DEBUG("ch%d\n", chan
->id
);
296 nv50_fifo_channel_disable(dev
, chan
->id
, 0);
298 /* Dummy channel, also used on ch 127 */
300 nv50_fifo_channel_disable(dev
, 127, 0);
302 if ((NV_READ(NV03_PFIFO_CACHE1_PUSH1
) & 0xffff) == chan
->id
)
303 NV_WRITE(NV03_PFIFO_CACHE1_PUSH1
, 127);
305 nouveau_gpuobj_ref_del(dev
, &chan
->ramfc
);
309 nv50_fifo_load_context(struct nouveau_channel
*chan
)
311 struct drm_device
*dev
= chan
->dev
;
312 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
313 struct nouveau_gpuobj
*ramfc
= chan
->ramfc
->gpuobj
;
315 DRM_DEBUG("ch%d\n", chan
->id
);
317 /*XXX: incomplete, only touches the regs that NV does */
322 NV_WRITE(0x3224, INSTANCE_RD(ramfc
, 0x3c/4));
323 NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE
, INSTANCE_RD(ramfc
, 0x48/4));
324 NV_WRITE(0x3234, INSTANCE_RD(ramfc
, 0x4c/4));
326 NV_WRITE(NV03_PFIFO_RAMHT
, INSTANCE_RD(ramfc
, 0x80/4));
329 NV_WRITE(0x340c, INSTANCE_RD(ramfc
, 0x88/4));
330 NV_WRITE(0x3410, INSTANCE_RD(ramfc
, 0x98/4));
333 NV_WRITE(NV03_PFIFO_CACHE1_PUSH1
, chan
->id
| (1<<16));
338 nv50_fifo_save_context(struct nouveau_channel
*chan
)
340 DRM_DEBUG("ch%d\n", chan
->id
);
341 DRM_ERROR("stub!\n");