2 * Copyright 2005-2006 Stephane Marchesin
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
27 #include "nouveau_drv.h"
28 #include "nouveau_drm.h"
31 /* returns the number of hw fifos */
32 int nouveau_fifo_number(struct drm_device *dev)
34 struct drm_nouveau_private *dev_priv=dev->dev_private;
35 switch(dev_priv->card_type)
49 /* returns the size of fifo context */
50 int nouveau_fifo_ctx_size(struct drm_device *dev)
52 struct drm_nouveau_private *dev_priv=dev->dev_private;
54 if (dev_priv->card_type >= NV_40)
56 else if (dev_priv->card_type >= NV_17)
62 /***********************************
63 * functions doing the actual work
64 ***********************************/
66 /* voir nv_xaa.c : NVResetGraphics
67 * mémoire mappée par nv_driver.c : NVMapMem
68 * voir nv_driver.c : NVPreInit
71 static int nouveau_fifo_instmem_configure(struct drm_device *dev)
73 struct drm_nouveau_private *dev_priv = dev->dev_private;
75 NV_WRITE(NV03_PFIFO_RAMHT,
76 (0x03 << 24) /* search 128 */ |
77 ((dev_priv->ramht_bits - 9) << 16) |
78 (dev_priv->ramht_offset >> 8)
81 NV_WRITE(NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
83 switch(dev_priv->card_type)
87 NV_WRITE(NV40_PFIFO_RAMFC, 0x30002);
88 if((dev_priv->chipset == 0x49) || (dev_priv->chipset == 0x4b))
89 NV_WRITE(0x2230,0x00000001);
92 NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) |
98 NV_WRITE(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) |
99 (1 << 16) /* 64 Bytes entry*/);
100 /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */
106 NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8);
113 int nouveau_fifo_init(struct drm_device *dev)
115 struct drm_nouveau_private *dev_priv = dev->dev_private;
118 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
119 ~NV_PMC_ENABLE_PFIFO);
120 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
121 NV_PMC_ENABLE_PFIFO);
123 NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
125 ret = nouveau_fifo_instmem_configure(dev);
127 DRM_ERROR("Failed to configure instance memory\n");
131 /* FIXME remove all the stuff that's done in nouveau_fifo_alloc */
133 DRM_DEBUG("Setting defaults for remaining PFIFO regs\n");
135 /* All channels into PIO mode */
136 NV_WRITE(NV04_PFIFO_MODE, 0x00000000);
138 NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
139 NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
140 /* Channel 0 active, PIO mode */
141 NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00000000);
142 /* PUT and GET to 0 */
143 NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, 0x00000000);
144 NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, 0x00000000);
145 /* No cmdbuf object */
146 NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, 0x00000000);
147 NV_WRITE(NV03_PFIFO_CACHE0_PUSH0, 0x00000000);
148 NV_WRITE(NV03_PFIFO_CACHE0_PULL0, 0x00000000);
149 NV_WRITE(NV04_PFIFO_SIZE, 0x0000FFFF);
150 NV_WRITE(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF);
151 NV_WRITE(NV04_PFIFO_CACHE0_PULL1, 0x00000001);
152 NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, 0x00000000);
153 NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
154 NV_WRITE(NV04_PFIFO_CACHE1_ENGINE, 0x00000000);
156 NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES |
157 NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
158 NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 |
160 NV_PFIFO_CACHE1_BIG_ENDIAN |
164 NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001);
165 NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
166 NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
167 NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001);
170 if (dev_priv->card_type >= NV_10) {
171 NV_WRITE(NV10_PGRAPH_CTX_USER, 0x0);
172 NV_WRITE(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ );
173 if (dev_priv->card_type >= NV_40)
174 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x00002001);
176 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10110000);
178 NV_WRITE(NV04_PGRAPH_CTX_USER, 0x0);
179 NV_WRITE(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ );
180 NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10110000);
183 NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, 0x001fffff);
184 NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
189 nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
191 struct drm_nouveau_private *dev_priv = dev->dev_private;
192 struct nouveau_fifo *chan = dev_priv->fifos[channel];
193 struct nouveau_config *config = &dev_priv->config;
194 struct mem_block *cb;
195 int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE);
196 struct nouveau_gpuobj *pushbuf = NULL;
199 /* Defaults for unconfigured values */
200 if (!config->cmdbuf.location)
201 config->cmdbuf.location = NOUVEAU_MEM_FB;
202 if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size)
203 config->cmdbuf.size = cb_min_size;
205 cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
206 config->cmdbuf.location | NOUVEAU_MEM_MAPPED,
207 (struct drm_file *)-2);
209 DRM_ERROR("Couldn't allocate DMA command buffer.\n");
213 if (cb->flags & NOUVEAU_MEM_AGP) {
214 ret = nouveau_gpuobj_gart_dma_new(dev, channel,
218 &chan->pushbuf_base);
220 if (cb->flags & NOUVEAU_MEM_PCI) {
221 ret = nouveau_gpuobj_dma_new(dev, channel,
222 NV_CLASS_DMA_IN_MEMORY,
225 NV_DMA_TARGET_PCI_NONLINEAR,
227 chan->pushbuf_base = 0;
228 } else if (dev_priv->card_type != NV_04) {
229 ret = nouveau_gpuobj_dma_new
230 (dev, channel, NV_CLASS_DMA_IN_MEMORY,
232 cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM,
234 chan->pushbuf_base = 0;
236 /* NV04 cmdbuf hack, from original ddx.. not sure of it's
237 * exact reason for existing :) PCI access to cmdbuf in
240 ret = nouveau_gpuobj_dma_new
241 (dev, channel, NV_CLASS_DMA_IN_MEMORY,
242 cb->start + drm_get_resource_start(dev, 1),
243 cb->size, NV_DMA_ACCESS_RO,
244 NV_DMA_TARGET_PCI, &pushbuf);
245 chan->pushbuf_base = 0;
249 nouveau_mem_free(dev, cb);
250 DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret);
254 if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf,
256 DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret);
257 if (pushbuf != dev_priv->gart_info.sg_ctxdma)
258 nouveau_gpuobj_del(dev, &pushbuf);
262 chan->pushbuf_mem = cb;
266 /* allocates and initializes a fifo for user space consumption */
267 int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
268 struct drm_file *file_priv,
269 uint32_t vram_handle, uint32_t tt_handle)
272 struct drm_nouveau_private *dev_priv = dev->dev_private;
273 struct nouveau_engine_func *engine = &dev_priv->Engine;
274 struct nouveau_fifo *chan;
278 * Alright, here is the full story
279 * Nvidia cards have multiple hw fifo contexts (praise them for that,
280 * no complicated crash-prone context switches)
281 * We allocate a new context for each app and let it write to it directly
282 * (woo, full userspace command submission !)
283 * When there are no more contexts, you lost
285 for(channel=0; channel<nouveau_fifo_number(dev); channel++) {
286 if ((dev_priv->card_type == NV_50) && (channel == 0))
288 if (dev_priv->fifos[channel] == NULL)
291 /* no more fifos. you lost. */
292 if (channel==nouveau_fifo_number(dev))
294 (*chan_ret) = channel;
296 dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo),
298 if (!dev_priv->fifos[channel])
300 dev_priv->fifo_alloc_count++;
301 chan = dev_priv->fifos[channel];
302 chan->file_priv = file_priv;
304 DRM_INFO("Allocating FIFO number %d\n", channel);
306 /* Setup channel's default objects */
307 ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle);
309 nouveau_fifo_free(dev, channel);
313 /* allocate a command buffer, and create a dma object for the gpu */
314 ret = nouveau_fifo_cmdbuf_alloc(dev, channel);
316 nouveau_fifo_free(dev, channel);
320 /* Allocate space for per-channel fixed notifier memory */
321 ret = nouveau_notifier_init_channel(dev, channel, file_priv);
323 nouveau_fifo_free(dev, channel);
327 nouveau_wait_for_idle(dev);
329 /* disable the fifo caches */
330 NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
331 NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1));
332 NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
333 NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
335 /* Create a graphics context for new channel */
336 ret = engine->graph.create_context(dev, channel);
338 nouveau_fifo_free(dev, channel);
342 /* Construct inital RAMFC for new channel */
343 ret = engine->fifo.create_context(dev, channel);
345 nouveau_fifo_free(dev, channel);
349 /* setup channel's default get/put values */
350 if (dev_priv->card_type < NV_50) {
351 NV_WRITE(NV03_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base);
352 NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base);
354 NV_WRITE(NV50_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base);
355 NV_WRITE(NV50_FIFO_REGS_DMAGET(channel), chan->pushbuf_base);
358 /* If this is the first channel, setup PFIFO ourselves. For any
359 * other case, the GPU will handle this when it switches contexts.
361 if (dev_priv->fifo_alloc_count == 1) {
362 ret = engine->fifo.load_context(dev, channel);
364 nouveau_fifo_free(dev, channel);
368 ret = engine->graph.load_context(dev, channel);
370 nouveau_fifo_free(dev, channel);
374 /* Temporary hack, to avoid breaking Xv on cards where the
375 * initial context value for 0x400710 doesn't have these bits
376 * set. Proper fix would be to find which object+method is
377 * responsible for modifying this state.
379 if (dev_priv->chipset >= 0x10 && dev_priv->chipset < 0x50) {
381 tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
382 NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
383 tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
384 NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
388 NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
389 NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
390 NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
391 NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
392 NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001);
394 /* reenable the fifo caches */
395 NV_WRITE(NV03_PFIFO_CACHES, 1);
397 DRM_INFO("%s: initialised FIFO %d\n", __func__, channel);
402 void nouveau_fifo_free(struct drm_device *dev, int channel)
404 struct drm_nouveau_private *dev_priv = dev->dev_private;
405 struct nouveau_engine_func *engine = &dev_priv->Engine;
406 struct nouveau_fifo *chan = dev_priv->fifos[channel];
409 DRM_ERROR("Freeing non-existant channel %d\n", channel);
413 DRM_INFO("%s: freeing fifo %d\n", __func__, channel);
415 /* disable the fifo caches */
416 NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
418 // FIXME XXX needs more code
420 engine->fifo.destroy_context(dev, channel);
422 /* Cleanup PGRAPH state */
423 engine->graph.destroy_context(dev, channel);
425 /* reenable the fifo caches */
426 NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
428 /* Deallocate push buffer */
429 nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
430 if (chan->pushbuf_mem) {
431 nouveau_mem_free(dev, chan->pushbuf_mem);
432 chan->pushbuf_mem = NULL;
435 nouveau_notifier_takedown_channel(dev, channel);
437 /* Destroy objects belonging to the channel */
438 nouveau_gpuobj_channel_takedown(dev, channel);
440 dev_priv->fifos[channel] = NULL;
441 dev_priv->fifo_alloc_count--;
442 drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER);
445 /* cleanups all the fifos from file_priv */
446 void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv)
449 struct drm_nouveau_private *dev_priv = dev->dev_private;
451 DRM_DEBUG("clearing FIFO enables from file_priv\n");
452 for(i=0;i<nouveau_fifo_number(dev);i++)
453 if (dev_priv->fifos[i] &&
454 dev_priv->fifos[i]->file_priv==file_priv)
455 nouveau_fifo_free(dev,i);
459 nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv,
462 struct drm_nouveau_private *dev_priv = dev->dev_private;
464 if (channel >= nouveau_fifo_number(dev))
466 if (dev_priv->fifos[channel] == NULL)
468 return (dev_priv->fifos[channel]->file_priv == file_priv);
471 /***********************************
472 * ioctls wrapping the functions
473 ***********************************/
475 static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS)
478 struct drm_nouveau_private *dev_priv = dev->dev_private;
479 struct drm_nouveau_fifo_alloc init;
480 struct drm_map_list *entry;
481 struct nouveau_fifo *chan;
484 DRM_COPY_FROM_USER_IOCTL(init,
485 (struct drm_nouveau_fifo_alloc __user *) data,
488 if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0)
491 res = nouveau_fifo_alloc(dev, &init.channel, file_priv,
492 init.fb_ctxdma_handle,
493 init.tt_ctxdma_handle);
496 chan = dev_priv->fifos[init.channel];
498 init.put_base = chan->pushbuf_base;
500 /* make the fifo available to user space */
501 /* first, the fifo control regs */
502 init.ctrl = dev_priv->mmio->offset;
503 if (dev_priv->card_type < NV_50) {
504 init.ctrl += NV03_FIFO_REGS(init.channel);
505 init.ctrl_size = NV03_FIFO_REGS_SIZE;
507 init.ctrl += NV50_FIFO_REGS(init.channel);
508 init.ctrl_size = NV50_FIFO_REGS_SIZE;
510 res = drm_addmap(dev, init.ctrl, init.ctrl_size, _DRM_REGISTERS,
515 entry = drm_find_matching_map(dev, chan->regs);
518 init.ctrl = entry->user_token;
520 /* pass back FIFO map info to the caller */
521 init.cmdbuf = chan->pushbuf_mem->map_handle;
522 init.cmdbuf_size = chan->pushbuf_mem->size;
524 /* and the notifier block */
525 init.notifier = chan->notifier_block->map_handle;
526 init.notifier_size = chan->notifier_block->size;
528 DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_fifo_alloc __user *)data,
533 /***********************************
534 * finally, the ioctl table
535 ***********************************/
537 struct drm_ioctl_desc nouveau_ioctls[] = {
538 [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH},
539 [DRM_IOCTL_NR(DRM_NOUVEAU_GROBJ_ALLOC)] = {nouveau_ioctl_grobj_alloc, DRM_AUTH},
540 [DRM_IOCTL_NR(DRM_NOUVEAU_NOTIFIER_ALLOC)] = {nouveau_ioctl_notifier_alloc, DRM_AUTH},
541 [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH},
542 [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_FREE)] = {nouveau_ioctl_mem_free, DRM_AUTH},
543 [DRM_IOCTL_NR(DRM_NOUVEAU_GETPARAM)] = {nouveau_ioctl_getparam, DRM_AUTH},
544 [DRM_IOCTL_NR(DRM_NOUVEAU_SETPARAM)] = {nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
547 int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);