/[pkgs]/rpms/kernel/F-9/drm-nouveau.patch
ViewVC logotype

Contents of /rpms/kernel/F-9/drm-nouveau.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Mon Jan 12 19:54:17 2009 UTC (10 months, 1 week ago) by kyle
Branch: MAIN
CVS Tags: kernel-2_6_28-1_fc9, kernel-2_6_28-2_fc9, HEAD
File MIME type: text/x-patch
* Mon Jan 12 2009 Kyle McMartin <kyle@redhat.com>
- Rebase for Fedora 9.
- Turn off CONFIG_MAXSMP on x86_64.
1 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
2 index 649757f..014fa6f 100644
3 --- a/drivers/gpu/drm/Kconfig
4 +++ b/drivers/gpu/drm/Kconfig
5 @@ -113,3 +113,9 @@ config DRM_SAVAGE
6 help
7 Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
8 chipset. If M is selected the module will be called savage.
9 +
10 +config DRM_NOUVEAU
11 + tristate "Nouveau (nvidia) cards"
12 + depends on DRM
13 + help
14 + Choose for nvidia support
15 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
16 index 48567a9..e68042b 100644
17 --- a/drivers/gpu/drm/Makefile
18 +++ b/drivers/gpu/drm/Makefile
19 @@ -26,4 +26,5 @@ obj-$(CONFIG_DRM_I915) += i915/
20 obj-$(CONFIG_DRM_SIS) += sis/
21 obj-$(CONFIG_DRM_SAVAGE)+= savage/
22 obj-$(CONFIG_DRM_VIA) +=via/
23 +obj-$(CONFIG_DRM_NOUVEAU) += nouveau/
24
25 diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
26 index 112ba7a..6205d56 100644
27 --- a/drivers/gpu/drm/drm_bufs.c
28 +++ b/drivers/gpu/drm/drm_bufs.c
29 @@ -49,8 +49,8 @@ unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource
30
31 EXPORT_SYMBOL(drm_get_resource_len);
32
33 -static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
34 - drm_local_map_t *map)
35 +struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
36 + drm_local_map_t *map)
37 {
38 struct drm_map_list *entry;
39 list_for_each_entry(entry, &dev->maplist, head) {
40 @@ -63,6 +63,7 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
41
42 return NULL;
43 }
44 +EXPORT_SYMBOL(drm_find_matching_map);
45
46 static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
47 unsigned long user_token, int hashed_handle)
48 diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
49 new file mode 100644
50 index 0000000..f01f82a
51 --- /dev/null
52 +++ b/drivers/gpu/drm/nouveau/Makefile
53 @@ -0,0 +1,19 @@
54 +#
55 +# Makefile for the drm device driver. This driver provides support for the
56 +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
57 +
58 +ccflags-y := -Iinclude/drm
59 +nouveau-y := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
60 + nouveau_object.o nouveau_irq.o nouveau_notifier.o nouveau_swmthd.o \
61 + nouveau_sgdma.o nouveau_dma.o nouveau_bo.o nouveau_fence.o \
62 + nv04_timer.o \
63 + nv04_mc.o nv40_mc.o nv50_mc.o \
64 + nv04_fb.o nv10_fb.o nv40_fb.o \
65 + nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
66 + nv04_graph.o nv10_graph.o nv20_graph.o \
67 + nv40_graph.o nv50_graph.o \
68 + nv04_instmem.o nv50_instmem.o
69 +
70 +nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
71 +
72 +obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
73 diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
74 new file mode 100644
75 index 0000000..ab3b23a
76 --- /dev/null
77 +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
78 @@ -0,0 +1,296 @@
79 +/*
80 + * Copyright 2007 Dave Airlied
81 + * All Rights Reserved.
82 + *
83 + * Permission is hereby granted, free of charge, to any person obtaining a
84 + * copy of this software and associated documentation files (the "Software"),
85 + * to deal in the Software without restriction, including without limitation
86 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87 + * and/or sell copies of the Software, and to permit persons to whom the
88 + * Software is furnished to do so, subject to the following conditions:
89 + *
90 + * The above copyright notice and this permission notice (including the next
91 + * paragraph) shall be included in all copies or substantial portions of the
92 + * Software.
93 + *
94 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
95 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
96 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
97 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
98 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
99 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
100 + * OTHER DEALINGS IN THE SOFTWARE.
101 + */
102 +/*
103 + * Authors: Dave Airlied <airlied@linux.ie>
104 + * Ben Skeggs <darktama@iinet.net.au>
105 + * Jeremy Kolb <jkolb@brandeis.edu>
106 + */
107 +
108 +#include "drmP.h"
109 +#include "nouveau_drm.h"
110 +#include "nouveau_drv.h"
111 +#include "nouveau_dma.h"
112 +
113 +static struct drm_ttm_backend *
114 +nouveau_bo_create_ttm_backend_entry(struct drm_device * dev)
115 +{
116 + struct drm_nouveau_private *dev_priv = dev->dev_private;
117 +
118 + switch (dev_priv->gart_info.type) {
119 + case NOUVEAU_GART_AGP:
120 + return drm_agp_init_ttm(dev);
121 + case NOUVEAU_GART_SGDMA:
122 + return nouveau_sgdma_init_ttm(dev);
123 + default:
124 + DRM_ERROR("Unknown GART type %d\n", dev_priv->gart_info.type);
125 + break;
126 + }
127 +
128 + return NULL;
129 +}
130 +
131 +static int
132 +nouveau_bo_fence_type(struct drm_buffer_object *bo,
133 + uint32_t *fclass, uint32_t *type)
134 +{
135 + /* When we get called, *fclass is set to the requested fence class */
136 +
137 + if (bo->mem.proposed_flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
138 + *type = 3;
139 + else
140 + *type = 1;
141 + return 0;
142 +
143 +}
144 +
145 +static int
146 +nouveau_bo_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags)
147 +{
148 + /* We'll do this from user space. */
149 + return 0;
150 +}
151 +
152 +static int
153 +nouveau_bo_init_mem_type(struct drm_device *dev, uint32_t type,
154 + struct drm_mem_type_manager *man)
155 +{
156 + struct drm_nouveau_private *dev_priv = dev->dev_private;
157 +
158 + switch (type) {
159 + case DRM_BO_MEM_LOCAL:
160 + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
161 + _DRM_FLAG_MEMTYPE_CACHED;
162 + man->drm_bus_maptype = 0;
163 + break;
164 + case DRM_BO_MEM_VRAM:
165 + man->flags = _DRM_FLAG_MEMTYPE_FIXED |
166 + _DRM_FLAG_MEMTYPE_MAPPABLE |
167 + _DRM_FLAG_NEEDS_IOREMAP;
168 + man->io_addr = NULL;
169 + man->drm_bus_maptype = _DRM_FRAME_BUFFER;
170 + man->io_offset = drm_get_resource_start(dev, 1);
171 + man->io_size = drm_get_resource_len(dev, 1);
172 + if (man->io_size > nouveau_mem_fb_amount(dev))
173 + man->io_size = nouveau_mem_fb_amount(dev);
174 + break;
175 + case DRM_BO_MEM_PRIV0:
176 + /* Unmappable VRAM */
177 + man->flags = _DRM_FLAG_MEMTYPE_CMA;
178 + man->drm_bus_maptype = 0;
179 + break;
180 + case DRM_BO_MEM_TT:
181 + switch (dev_priv->gart_info.type) {
182 + case NOUVEAU_GART_AGP:
183 + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
184 + _DRM_FLAG_MEMTYPE_CSELECT |
185 + _DRM_FLAG_NEEDS_IOREMAP;
186 + man->drm_bus_maptype = _DRM_AGP;
187 + break;
188 + case NOUVEAU_GART_SGDMA:
189 + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
190 + _DRM_FLAG_MEMTYPE_CSELECT |
191 + _DRM_FLAG_MEMTYPE_CMA;
192 + man->drm_bus_maptype = _DRM_SCATTER_GATHER;
193 + break;
194 + default:
195 + DRM_ERROR("Unknown GART type: %d\n",
196 + dev_priv->gart_info.type);
197 + return -EINVAL;
198 + }
199 +
200 + man->io_offset = dev_priv->gart_info.aper_base;
201 + man->io_size = dev_priv->gart_info.aper_size;
202 + man->io_addr = NULL;
203 + break;
204 + default:
205 + DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
206 + return -EINVAL;
207 + }
208 + return 0;
209 +}
210 +
211 +static uint64_t
212 +nouveau_bo_evict_flags(struct drm_buffer_object *bo)
213 +{
214 + switch (bo->mem.mem_type) {
215 + case DRM_BO_MEM_LOCAL:
216 + case DRM_BO_MEM_TT:
217 + return DRM_BO_FLAG_MEM_LOCAL;
218 + default:
219 + return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
220 + }
221 + return 0;
222 +}
223 +
224 +
225 +/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access
226 + * DRM_BO_MEM_{VRAM,PRIV0,TT} directly.
227 + */
228 +static int
229 +nouveau_bo_move_m2mf(struct drm_buffer_object *bo, int evict, int no_wait,
230 + struct drm_bo_mem_reg *new_mem)
231 +{
232 + struct drm_device *dev = bo->dev;
233 + struct drm_nouveau_private *dev_priv = dev->dev_private;
234 + struct nouveau_drm_channel *dchan = &dev_priv->channel;
235 + struct drm_bo_mem_reg *old_mem = &bo->mem;
236 + uint32_t srch, dsth, page_count;
237 +
238 + /* Can happen during init/takedown */
239 + if (!dchan->chan)
240 + return -EINVAL;
241 +
242 + srch = old_mem->mem_type == DRM_BO_MEM_TT ? NvDmaTT : NvDmaFB;
243 + dsth = new_mem->mem_type == DRM_BO_MEM_TT ? NvDmaTT : NvDmaFB;
244 + if (srch != dchan->m2mf_dma_source || dsth != dchan->m2mf_dma_destin) {
245 + dchan->m2mf_dma_source = srch;
246 + dchan->m2mf_dma_destin = dsth;
247 +
248 + BEGIN_RING(NvSubM2MF,
249 + NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE, 2);
250 + OUT_RING (dchan->m2mf_dma_source);
251 + OUT_RING (dchan->m2mf_dma_destin);
252 + }
253 +
254 + page_count = new_mem->num_pages;
255 + while (page_count) {
256 + int line_count = (page_count > 2047) ? 2047 : page_count;
257 +
258 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
259 + OUT_RING (old_mem->mm_node->start << PAGE_SHIFT);
260 + OUT_RING (new_mem->mm_node->start << PAGE_SHIFT);
261 + OUT_RING (PAGE_SIZE); /* src_pitch */
262 + OUT_RING (PAGE_SIZE); /* dst_pitch */
263 + OUT_RING (PAGE_SIZE); /* line_length */
264 + OUT_RING (line_count);
265 + OUT_RING ((1<<8)|(1<<0));
266 + OUT_RING (0);
267 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
268 + OUT_RING (0);
269 +
270 + page_count -= line_count;
271 + }
272 +
273 + return drm_bo_move_accel_cleanup(bo, evict, no_wait, dchan->chan->id,
274 + DRM_FENCE_TYPE_EXE, 0, new_mem);
275 +}
276 +
277 +/* Flip pages into the GART and move if we can. */
278 +static int
279 +nouveau_bo_move_flipd(struct drm_buffer_object *bo, int evict, int no_wait,
280 + struct drm_bo_mem_reg *new_mem)
281 +{
282 + struct drm_device *dev = bo->dev;
283 + struct drm_bo_mem_reg tmp_mem;
284 + int ret;
285 +
286 + tmp_mem = *new_mem;
287 + tmp_mem.mm_node = NULL;
288 + tmp_mem.proposed_flags = (DRM_BO_FLAG_MEM_TT |
289 + DRM_BO_FLAG_CACHED |
290 + DRM_BO_FLAG_FORCE_CACHING);
291 +
292 + ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
293 + if (ret)
294 + return ret;
295 +
296 + ret = drm_ttm_bind(bo->ttm, &tmp_mem);
297 + if (ret)
298 + goto out_cleanup;
299 +
300 + ret = nouveau_bo_move_m2mf(bo, 1, no_wait, &tmp_mem);
301 + if (ret)
302 + goto out_cleanup;
303 +
304 + ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
305 +
306 +out_cleanup:
307 + if (tmp_mem.mm_node) {
308 + mutex_lock(&dev->struct_mutex);
309 + if (tmp_mem.mm_node != bo->pinned_node)
310 + drm_mm_put_block(tmp_mem.mm_node);
311 + tmp_mem.mm_node = NULL;
312 + mutex_unlock(&dev->struct_mutex);
313 + }
314 +
315 + return ret;
316 +}
317 +
318 +static int
319 +nouveau_bo_move(struct drm_buffer_object *bo, int evict, int no_wait,
320 + struct drm_bo_mem_reg *new_mem)
321 +{
322 + struct drm_bo_mem_reg *old_mem = &bo->mem;
323 +
324 + if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
325 + if (old_mem->mem_type == DRM_BO_MEM_LOCAL)
326 + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
327 + if (nouveau_bo_move_flipd(bo, evict, no_wait, new_mem))
328 + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
329 + }
330 + else
331 + if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
332 + if (1 /*nouveau_bo_move_flips(bo, evict, no_wait, new_mem)*/)
333 + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
334 + }
335 + else {
336 + if (nouveau_bo_move_m2mf(bo, evict, no_wait, new_mem))
337 + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
338 + }
339 +
340 + return 0;
341 +}
342 +
343 +static void
344 +nouveau_bo_flush_ttm(struct drm_ttm *ttm)
345 +{
346 +}
347 +
348 +static uint32_t nouveau_mem_prios[] = {
349 + DRM_BO_MEM_PRIV0,
350 + DRM_BO_MEM_VRAM,
351 + DRM_BO_MEM_TT,
352 + DRM_BO_MEM_LOCAL
353 +};
354 +static uint32_t nouveau_busy_prios[] = {
355 + DRM_BO_MEM_TT,
356 + DRM_BO_MEM_PRIV0,
357 + DRM_BO_MEM_VRAM,
358 + DRM_BO_MEM_LOCAL
359 +};
360 +
361 +struct drm_bo_driver nouveau_bo_driver = {
362 + .mem_type_prio = nouveau_mem_prios,
363 + .mem_busy_prio = nouveau_busy_prios,
364 + .num_mem_type_prio = sizeof(nouveau_mem_prios)/sizeof(uint32_t),
365 + .num_mem_busy_prio = sizeof(nouveau_busy_prios)/sizeof(uint32_t),
366 + .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
367 + .fence_type = nouveau_bo_fence_type,
368 + .invalidate_caches = nouveau_bo_invalidate_caches,
369 + .init_mem_type = nouveau_bo_init_mem_type,
370 + .evict_flags = nouveau_bo_evict_flags,
371 + .move = nouveau_bo_move,
372 + .ttm_cache_flush= nouveau_bo_flush_ttm,
373 + .command_stream_barrier = NULL
374 +};
375 diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
376 new file mode 100644
377 index 0000000..e519dc4
378 --- /dev/null
379 +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
380 @@ -0,0 +1,172 @@
381 +/*
382 + * Copyright (C) 2007 Ben Skeggs.
383 + * All Rights Reserved.
384 + *
385 + * Permission is hereby granted, free of charge, to any person obtaining
386 + * a copy of this software and associated documentation files (the
387 + * "Software"), to deal in the Software without restriction, including
388 + * without limitation the rights to use, copy, modify, merge, publish,
389 + * distribute, sublicense, and/or sell copies of the Software, and to
390 + * permit persons to whom the Software is furnished to do so, subject to
391 + * the following conditions:
392 + *
393 + * The above copyright notice and this permission notice (including the
394 + * next paragraph) shall be included in all copies or substantial
395 + * portions of the Software.
396 + *
397 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
398 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
399 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
400 + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
401 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
402 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
403 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
404 + *
405 + */
406 +
407 +#include "drmP.h"
408 +#include "drm.h"
409 +#include "nouveau_drv.h"
410 +#include "nouveau_dma.h"
411 +
412 +int
413 +nouveau_dma_channel_init(struct drm_device *dev)
414 +{
415 + struct drm_nouveau_private *dev_priv = dev->dev_private;
416 + struct nouveau_drm_channel *dchan = &dev_priv->channel;
417 + struct nouveau_gpuobj *gpuobj = NULL;
418 + struct mem_block *pushbuf;
419 + int grclass, ret, i;
420 +
421 + DRM_DEBUG("\n");
422 +
423 + pushbuf = nouveau_mem_alloc(dev, 0, 0x8000,
424 + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
425 + (struct drm_file *)-2);
426 + if (!pushbuf) {
427 + DRM_ERROR("Failed to allocate DMA push buffer\n");
428 + return -ENOMEM;
429 + }
430 +
431 + /* Allocate channel */
432 + ret = nouveau_fifo_alloc(dev, &dchan->chan, (struct drm_file *)-2,
433 + pushbuf, NvDmaFB, NvDmaTT);
434 + if (ret) {
435 + DRM_ERROR("Error allocating GPU channel: %d\n", ret);
436 + return ret;
437 + }
438 + DRM_DEBUG("Using FIFO channel %d\n", dchan->chan->id);
439 +
440 + /* Map push buffer */
441 + drm_core_ioremap(dchan->chan->pushbuf_mem->map, dev);
442 + if (!dchan->chan->pushbuf_mem->map->handle) {
443 + DRM_ERROR("Failed to ioremap push buffer\n");
444 + return -EINVAL;
445 + }
446 + dchan->pushbuf = (void*)dchan->chan->pushbuf_mem->map->handle;
447 +
448 + /* Initialise DMA vars */
449 + dchan->max = (dchan->chan->pushbuf_mem->size >> 2) - 2;
450 + dchan->put = dchan->chan->pushbuf_base >> 2;
451 + dchan->cur = dchan->put;
452 + dchan->free = dchan->max - dchan->cur;
453 +
454 + /* Insert NOPS for NOUVEAU_DMA_SKIPS */
455 + dchan->free -= NOUVEAU_DMA_SKIPS;
456 + dchan->push_free = NOUVEAU_DMA_SKIPS;
457 + for (i=0; i < NOUVEAU_DMA_SKIPS; i++)
458 + OUT_RING(0);
459 +
460 + /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier */
461 + if ((ret = nouveau_notifier_alloc(dchan->chan, NvNotify0, 1,
462 + &dchan->notify0_offset))) {
463 + DRM_ERROR("Error allocating NvNotify0: %d\n", ret);
464 + return ret;
465 + }
466 +
467 + /* We use NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
468 + if (dev_priv->card_type < NV_50) grclass = NV_MEMORY_TO_MEMORY_FORMAT;
469 + else grclass = NV50_MEMORY_TO_MEMORY_FORMAT;
470 + if ((ret = nouveau_gpuobj_gr_new(dchan->chan, grclass, &gpuobj))) {
471 + DRM_ERROR("Error creating NvM2MF: %d\n", ret);
472 + return ret;
473 + }
474 +
475 + if ((ret = nouveau_gpuobj_ref_add(dev, dchan->chan, NvM2MF,
476 + gpuobj, NULL))) {
477 + DRM_ERROR("Error referencing NvM2MF: %d\n", ret);
478 + return ret;
479 + }
480 + dchan->m2mf_dma_source = NvDmaFB;
481 + dchan->m2mf_dma_destin = NvDmaFB;
482 +
483 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
484 + OUT_RING (NvM2MF);
485 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY, 1);
486 + OUT_RING (NvNotify0);
487 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE, 2);
488 + OUT_RING (dchan->m2mf_dma_source);
489 + OUT_RING (dchan->m2mf_dma_destin);
490 + FIRE_RING();
491 +
492 + return 0;
493 +}
494 +
495 +void
496 +nouveau_dma_channel_takedown(struct drm_device *dev)
497 +{
498 + struct drm_nouveau_private *dev_priv = dev->dev_private;
499 + struct nouveau_drm_channel *dchan = &dev_priv->channel;
500 +
501 + DRM_DEBUG("\n");
502 +
503 + if (dchan->chan) {
504 + nouveau_fifo_free(dchan->chan);
505 + dchan->chan = NULL;
506 + }
507 +}
508 +
509 +#define READ_GET() ((NV_READ(dchan->chan->get) - \
510 + dchan->chan->pushbuf_base) >> 2)
511 +#define WRITE_PUT(val) do { \
512 + NV_WRITE(dchan->chan->put, \
513 + ((val) << 2) + dchan->chan->pushbuf_base); \
514 +} while(0)
515 +
516 +int
517 +nouveau_dma_wait(struct drm_device *dev, int size)
518 +{
519 + struct drm_nouveau_private *dev_priv = dev->dev_private;
520 + struct nouveau_drm_channel *dchan = &dev_priv->channel;
521 + uint32_t get;
522 +
523 + while (dchan->free < size) {
524 + get = READ_GET();
525 +
526 + if (dchan->put >= get) {
527 + dchan->free = dchan->max - dchan->cur;
528 +
529 + if (dchan->free < size) {
530 + dchan->push_free = 1;
531 + OUT_RING(0x20000000|dchan->chan->pushbuf_base);
532 + if (get <= NOUVEAU_DMA_SKIPS) {
533 + /*corner case - will be idle*/
534 + if (dchan->put <= NOUVEAU_DMA_SKIPS)
535 + WRITE_PUT(NOUVEAU_DMA_SKIPS + 1);
536 +
537 + do {
538 + get = READ_GET();
539 + } while (get <= NOUVEAU_DMA_SKIPS);
540 + }
541 +
542 + WRITE_PUT(NOUVEAU_DMA_SKIPS);
543 + dchan->cur = dchan->put = NOUVEAU_DMA_SKIPS;
544 + dchan->free = get - (NOUVEAU_DMA_SKIPS + 1);
545 + }
546 + } else {
547 + dchan->free = get - dchan->cur - 1;
548 + }
549 + }
550 +
551 + return 0;
552 +}
553 diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
554 new file mode 100644
555 index 0000000..ce3c58c
556 --- /dev/null
557 +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
558 @@ -0,0 +1,96 @@
559 +/*
560 + * Copyright (C) 2007 Ben Skeggs.
561 + * All Rights Reserved.
562 + *
563 + * Permission is hereby granted, free of charge, to any person obtaining
564 + * a copy of this software and associated documentation files (the
565 + * "Software"), to deal in the Software without restriction, including
566 + * without limitation the rights to use, copy, modify, merge, publish,
567 + * distribute, sublicense, and/or sell copies of the Software, and to
568 + * permit persons to whom the Software is furnished to do so, subject to
569 + * the following conditions:
570 + *
571 + * The above copyright notice and this permission notice (including the
572 + * next paragraph) shall be included in all copies or substantial
573 + * portions of the Software.
574 + *
575 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
576 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
577 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
578 + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
579 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
580 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
581 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
582 + *
583 + */
584 +
585 +#ifndef __NOUVEAU_DMA_H__
586 +#define __NOUVEAU_DMA_H__
587 +
588 +typedef enum {
589 + NvSubM2MF = 0,
590 +} nouveau_subchannel_id_t;
591 +
592 +typedef enum {
593 + NvM2MF = 0x80039001,
594 + NvDmaFB = 0x8003d001,
595 + NvDmaTT = 0x8003d002,
596 + NvNotify0 = 0x8003d003
597 +} nouveau_object_handle_t;
598 +
599 +#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039
600 +#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000
601 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050
602 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100
603 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
604 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000
605 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001
606 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY 0x00000180
607 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE 0x00000184
608 +#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
609 +
610 +#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039
611 +#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200
612 +#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c
613 +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238
614 +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c
615 +
616 +#define BEGIN_RING(subc, mthd, cnt) do { \
617 + int push_size = (cnt) + 1; \
618 + if (dchan->push_free) { \
619 + DRM_ERROR("prior packet incomplete: %d\n", dchan->push_free); \
620 + break; \
621 + } \
622 + if (dchan->free < push_size) { \
623 + if (nouveau_dma_wait(dev, push_size)) { \
624 + DRM_ERROR("FIFO timeout\n"); \
625 + break; \
626 + } \
627 + } \
628 + dchan->free -= push_size; \
629 + dchan->push_free = push_size; \
630 + OUT_RING(((cnt)<<18) | ((subc)<<15) | mthd); \
631 +} while(0)
632 +
633 +#define OUT_RING(data) do { \
634 + if (dchan->push_free == 0) { \
635 + DRM_ERROR("no space left in packet\n"); \
636 + break; \
637 + } \
638 + dchan->pushbuf[dchan->cur++] = (data); \
639 + dchan->push_free--; \
640 +} while(0)
641 +
642 +#define FIRE_RING() do { \
643 + if (dchan->push_free) { \
644 + DRM_ERROR("packet incomplete: %d\n", dchan->push_free); \
645 + break; \
646 + } \
647 + if (dchan->cur != dchan->put) { \
648 + DRM_MEMORYBARRIER(); \
649 + dchan->put = dchan->cur; \
650 + NV_WRITE(dchan->chan->put, dchan->put << 2); \
651 + } \
652 +} while(0)
653 +
654 +#endif
655 diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
656 new file mode 100644
657 index 0000000..4a4277f
658 --- /dev/null
659 +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
660 @@ -0,0 +1,112 @@
661 +/*
662 + * Copyright 2005 Stephane Marchesin.
663 + * All Rights Reserved.
664 + *
665 + * Permission is hereby granted, free of charge, to any person obtaining a
666 + * copy of this software and associated documentation files (the "Software"),
667 + * to deal in the Software without restriction, including without limitation
668 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
669 + * and/or sell copies of the Software, and to permit persons to whom the
670 + * Software is furnished to do so, subject to the following conditions:
671 + *
672 + * The above copyright notice and this permission notice (including the next
673 + * paragraph) shall be included in all copies or substantial portions of the
674 + * Software.
675 + *
676 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
677 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
678 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
679 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
680 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
681 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
682 + * OTHER DEALINGS IN THE SOFTWARE.
683 + */
684 +
685 +#include "drmP.h"
686 +#include "drm.h"
687 +#include "nouveau_drv.h"
688 +
689 +#include "drm_pciids.h"
690 +
691 +static struct pci_device_id pciidlist[] = {
692 + {
693 + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
694 + .class = PCI_BASE_CLASS_DISPLAY << 16,
695 + .class_mask = 0xff << 16,
696 + },
697 + {
698 + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
699 + .class = PCI_BASE_CLASS_DISPLAY << 16,
700 + .class_mask = 0xff << 16,
701 + }
702 +};
703 +
704 +extern struct drm_ioctl_desc nouveau_ioctls[];
705 +extern int nouveau_max_ioctl;
706 +
707 +static struct drm_driver driver = {
708 + .driver_features =
709 + DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
710 + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
711 + .load = nouveau_load,
712 + .firstopen = nouveau_firstopen,
713 + .lastclose = nouveau_lastclose,
714 + .unload = nouveau_unload,
715 + .preclose = nouveau_preclose,
716 + .irq_preinstall = nouveau_irq_preinstall,
717 + .irq_postinstall = nouveau_irq_postinstall,
718 + .irq_uninstall = nouveau_irq_uninstall,
719 + .irq_handler = nouveau_irq_handler,
720 + .reclaim_buffers = drm_core_reclaim_buffers,
721 + .get_map_ofs = drm_core_get_map_ofs,
722 + .get_reg_ofs = drm_core_get_reg_ofs,
723 + .ioctls = nouveau_ioctls,
724 + .fops = {
725 + .owner = THIS_MODULE,
726 + .open = drm_open,
727 + .release = drm_release,
728 + .ioctl = drm_ioctl,
729 + .mmap = drm_mmap,
730 + .poll = drm_poll,
731 + .fasync = drm_fasync,
732 +#if defined(CONFIG_COMPAT)
733 + .compat_ioctl = nouveau_compat_ioctl,
734 +#endif
735 + },
736 + .pci_driver = {
737 + .name = DRIVER_NAME,
738 + .id_table = pciidlist,
739 + },
740 +
741 + .bo_driver = &nouveau_bo_driver,
742 + .fence_driver = &nouveau_fence_driver,
743 +
744 + .name = DRIVER_NAME,
745 + .desc = DRIVER_DESC,
746 +#ifdef GIT_REVISION
747 + .date = GIT_REVISION,
748 +#else
749 + .date = DRIVER_DATE,
750 +#endif
751 + .major = DRIVER_MAJOR,
752 + .minor = DRIVER_MINOR,
753 + .patchlevel = DRIVER_PATCHLEVEL,
754 +};
755 +
756 +static int __init nouveau_init(void)
757 +{
758 + driver.num_ioctls = nouveau_max_ioctl;
759 + return drm_init(&driver);
760 +}
761 +
762 +static void __exit nouveau_exit(void)
763 +{
764 + drm_exit(&driver);
765 +}
766 +
767 +module_init(nouveau_init);
768 +module_exit(nouveau_exit);
769 +
770 +MODULE_AUTHOR(DRIVER_AUTHOR);
771 +MODULE_DESCRIPTION(DRIVER_DESC);
772 +MODULE_LICENSE("GPL and additional rights");
773 diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
774 new file mode 100644
775 index 0000000..a97e3e9
776 --- /dev/null
777 +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
778 @@ -0,0 +1,621 @@
779 +/*
780 + * Copyright 2005 Stephane Marchesin.
781 + * All Rights Reserved.
782 + *
783 + * Permission is hereby granted, free of charge, to any person obtaining a
784 + * copy of this software and associated documentation files (the "Software"),
785 + * to deal in the Software without restriction, including without limitation
786 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
787 + * and/or sell copies of the Software, and to permit persons to whom the
788 + * Software is furnished to do so, subject to the following conditions:
789 + *
790 + * The above copyright notice and this permission notice (including the next
791 + * paragraph) shall be included in all copies or substantial portions of the
792 + * Software.
793 + *
794 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
795 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
796 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
797 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
798 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
799 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
800 + * OTHER DEALINGS IN THE SOFTWARE.
801 + */
802 +
803 +#ifndef __NOUVEAU_DRV_H__
804 +#define __NOUVEAU_DRV_H__
805 +
806 +#define DRIVER_AUTHOR "Stephane Marchesin"
807 +#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net"
808 +
809 +#define DRIVER_NAME "nouveau"
810 +#define DRIVER_DESC "nVidia Riva/TNT/GeForce"
811 +#define DRIVER_DATE "20060213"
812 +
813 +#define DRIVER_MAJOR 0
814 +#define DRIVER_MINOR 0
815 +#define DRIVER_PATCHLEVEL 11
816 +
817 +#define NOUVEAU_FAMILY 0x0000FFFF
818 +#define NOUVEAU_FLAGS 0xFFFF0000
819 +
820 +#include "nouveau_drm.h"
821 +#include "nouveau_reg.h"
822 +
823 +struct mem_block {
824 + struct mem_block *next;
825 + struct mem_block *prev;
826 + uint64_t start;
827 + uint64_t size;
828 + struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
829 + int flags;
830 + drm_local_map_t *map;
831 + drm_handle_t map_handle;
832 +};
833 +
834 +enum nouveau_flags {
835 + NV_NFORCE =0x10000000,
836 + NV_NFORCE2 =0x20000000
837 +};
838 +
839 +#define NVOBJ_ENGINE_SW 0
840 +#define NVOBJ_ENGINE_GR 1
841 +#define NVOBJ_ENGINE_INT 0xdeadbeef
842 +
843 +#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0)
844 +#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
845 +#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
846 +#define NVOBJ_FLAG_FAKE (1 << 3)
847 +struct nouveau_gpuobj {
848 + struct list_head list;
849 +
850 + int im_channel;
851 + struct mem_block *im_pramin;
852 + struct mem_block *im_backing;
853 + int im_bound;
854 +
855 + uint32_t flags;
856 + int refcount;
857 +
858 + uint32_t engine;
859 + uint32_t class;
860 +
861 + void (*dtor)(struct drm_device *, struct nouveau_gpuobj *);
862 + void *priv;
863 +};
864 +
865 +struct nouveau_gpuobj_ref {
866 + struct list_head list;
867 +
868 + struct nouveau_gpuobj *gpuobj;
869 + uint32_t instance;
870 +
871 + int channel;
872 + int handle;
873 +};
874 +
875 +struct nouveau_channel
876 +{
877 + struct drm_device *dev;
878 + int id;
879 +
880 + /* owner of this fifo */
881 + struct drm_file *file_priv;
882 + /* mapping of the fifo itself */
883 + drm_local_map_t *map;
884 + /* mapping of the regs controling the fifo */
885 + drm_local_map_t *regs;
886 +
887 + /* Fencing */
888 + uint32_t next_sequence;
889 +
890 + /* DMA push buffer */
891 + struct nouveau_gpuobj_ref *pushbuf;
892 + struct mem_block *pushbuf_mem;
893 + uint32_t pushbuf_base;
894 +
895 + /* FIFO user control regs */
896 + uint32_t user, user_size;
897 + uint32_t put;
898 + uint32_t get;
899 + uint32_t ref_cnt;
900 +
901 + /* Notifier memory */
902 + struct mem_block *notifier_block;
903 + struct mem_block *notifier_heap;
904 + drm_local_map_t *notifier_map;
905 +
906 + /* PFIFO context */
907 + struct nouveau_gpuobj_ref *ramfc;
908 +
909 + /* PGRAPH context */
910 + /* XXX may be merge 2 pointers as private data ??? */
911 + struct nouveau_gpuobj_ref *ramin_grctx;
912 + void *pgraph_ctx;
913 +
914 + /* NV50 VM */
915 + struct nouveau_gpuobj *vm_pd;
916 + struct nouveau_gpuobj_ref *vm_gart_pt;
917 + struct nouveau_gpuobj_ref *vm_vram_pt;
918 +
919 + /* Objects */
920 + struct nouveau_gpuobj_ref *ramin; /* Private instmem */
921 + struct mem_block *ramin_heap; /* Private PRAMIN heap */
922 + struct nouveau_gpuobj_ref *ramht; /* Hash table */
923 + struct list_head ramht_refs; /* Objects referenced by RAMHT */
924 +};
925 +
926 +struct nouveau_drm_channel {
927 + struct nouveau_channel *chan;
928 +
929 + /* DMA state */
930 + int max, put, cur, free;
931 + int push_free;
932 + volatile uint32_t *pushbuf;
933 +
934 + /* Notifiers */
935 + uint32_t notify0_offset;
936 +
937 + /* Buffer moves */
938 + uint32_t m2mf_dma_source;
939 + uint32_t m2mf_dma_destin;
940 +};
941 +
942 +struct nouveau_config {
943 + struct {
944 + int location;
945 + int size;
946 + } cmdbuf;
947 +};
948 +
949 +struct nouveau_instmem_engine {
950 + void *priv;
951 +
952 + int (*init)(struct drm_device *dev);
953 + void (*takedown)(struct drm_device *dev);
954 +
955 + int (*populate)(struct drm_device *, struct nouveau_gpuobj *,
956 + uint32_t *size);
957 + void (*clear)(struct drm_device *, struct nouveau_gpuobj *);
958 + int (*bind)(struct drm_device *, struct nouveau_gpuobj *);
959 + int (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
960 +};
961 +
962 +struct nouveau_mc_engine {
963 + int (*init)(struct drm_device *dev);
964 + void (*takedown)(struct drm_device *dev);
965 +};
966 +
967 +struct nouveau_timer_engine {
968 + int (*init)(struct drm_device *dev);
969 + void (*takedown)(struct drm_device *dev);
970 + uint64_t (*read)(struct drm_device *dev);
971 +};
972 +
973 +struct nouveau_fb_engine {
974 + int (*init)(struct drm_device *dev);
975 + void (*takedown)(struct drm_device *dev);
976 +};
977 +
978 +struct nouveau_fifo_engine {
979 + void *priv;
980 +
981 + int channels;
982 +
983 + int (*init)(struct drm_device *);
984 + void (*takedown)(struct drm_device *);
985 +
986 + int (*channel_id)(struct drm_device *);
987 +
988 + int (*create_context)(struct nouveau_channel *);
989 + void (*destroy_context)(struct nouveau_channel *);
990 + int (*load_context)(struct nouveau_channel *);
991 + int (*save_context)(struct nouveau_channel *);
992 +};
993 +
994 +struct nouveau_pgraph_engine {
995 + int (*init)(struct drm_device *);
996 + void (*takedown)(struct drm_device *);
997 +
998 + int (*create_context)(struct nouveau_channel *);
999 + void (*destroy_context)(struct nouveau_channel *);
1000 + int (*load_context)(struct nouveau_channel *);
1001 + int (*save_context)(struct nouveau_channel *);
1002 +};
1003 +
1004 +struct nouveau_engine {
1005 + struct nouveau_instmem_engine instmem;
1006 + struct nouveau_mc_engine mc;
1007 + struct nouveau_timer_engine timer;
1008 + struct nouveau_fb_engine fb;
1009 + struct nouveau_pgraph_engine graph;
1010 + struct nouveau_fifo_engine fifo;
1011 +};
1012 +
1013 +#define NOUVEAU_MAX_CHANNEL_NR 128
1014 +struct drm_nouveau_private {
1015 + enum {
1016 + NOUVEAU_CARD_INIT_DOWN,
1017 + NOUVEAU_CARD_INIT_DONE,
1018 + NOUVEAU_CARD_INIT_FAILED
1019 + } init_state;
1020 +
1021 + int ttm;
1022 +
1023 + /* the card type, takes NV_* as values */
1024 + int card_type;
1025 + /* exact chipset, derived from NV_PMC_BOOT_0 */
1026 + int chipset;
1027 + int flags;
1028 +
1029 + drm_local_map_t *mmio;
1030 + drm_local_map_t *fb;
1031 + drm_local_map_t *ramin; /* NV40 onwards */
1032 +
1033 + int fifo_alloc_count;
1034 + struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
1035 +
1036 + struct nouveau_engine Engine;
1037 + struct nouveau_drm_channel channel;
1038 +
1039 + /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
1040 + struct nouveau_gpuobj *ramht;
1041 + uint32_t ramin_rsvd_vram;
1042 + uint32_t ramht_offset;
1043 + uint32_t ramht_size;
1044 + uint32_t ramht_bits;
1045 + uint32_t ramfc_offset;
1046 + uint32_t ramfc_size;
1047 + uint32_t ramro_offset;
1048 + uint32_t ramro_size;
1049 +
1050 + /* base physical adresses */
1051 + uint64_t fb_phys;
1052 + uint64_t fb_available_size;
1053 +
1054 + struct {
1055 + enum {
1056 + NOUVEAU_GART_NONE = 0,
1057 + NOUVEAU_GART_AGP,
1058 + NOUVEAU_GART_SGDMA
1059 + } type;
1060 + uint64_t aper_base;
1061 + uint64_t aper_size;
1062 +
1063 + struct nouveau_gpuobj *sg_ctxdma;
1064 + struct page *sg_dummy_page;
1065 + dma_addr_t sg_dummy_bus;
1066 +
1067 + /* nottm hack */
1068 + struct drm_ttm_backend *sg_be;
1069 + unsigned long sg_handle;
1070 + } gart_info;
1071 +
1072 + /* G8x global VRAM page table */
1073 + struct nouveau_gpuobj *vm_vram_pt;
1074 +
1075 + /* the mtrr covering the FB */
1076 + int fb_mtrr;
1077 +
1078 + struct mem_block *agp_heap;
1079 + struct mem_block *fb_heap;
1080 + struct mem_block *fb_nomap_heap;
1081 + struct mem_block *ramin_heap;
1082 + struct mem_block *pci_heap;
1083 +
1084 + /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
1085 + uint32_t ctx_table_size;
1086 + struct nouveau_gpuobj_ref *ctx_table;
1087 +
1088 + struct nouveau_config config;
1089 +
1090 + struct list_head gpuobj_list;
1091 +
1092 + struct nouveau_suspend_resume {
1093 + uint32_t fifo_mode;
1094 + uint32_t graph_ctx_control;
1095 + uint32_t graph_state;
1096 + uint32_t *ramin_copy;
1097 + uint64_t ramin_size;
1098 + } susres;
1099 +};
1100 +
1101 +#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \
1102 + struct drm_nouveau_private *nv = dev->dev_private; \
1103 + if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \
1104 + DRM_ERROR("called without init\n"); \
1105 + return -EINVAL; \
1106 + } \
1107 +} while(0)
1108 +
1109 +#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \
1110 + struct drm_nouveau_private *nv = dev->dev_private; \
1111 + if (!nouveau_fifo_owner(dev, (cl), (id))) { \
1112 + DRM_ERROR("pid %d doesn't own channel %d\n", \
1113 + DRM_CURRENTPID, (id)); \
1114 + return -EPERM; \
1115 + } \
1116 + (ch) = nv->fifos[(id)]; \
1117 +} while(0)
1118 +
1119 +/* nouveau_state.c */
1120 +extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
1121 +extern int nouveau_load(struct drm_device *, unsigned long flags);
1122 +extern int nouveau_firstopen(struct drm_device *);
1123 +extern void nouveau_lastclose(struct drm_device *);
1124 +extern int nouveau_unload(struct drm_device *);
1125 +extern int nouveau_ioctl_getparam(struct drm_device *, void *data,
1126 + struct drm_file *);
1127 +extern int nouveau_ioctl_setparam(struct drm_device *, void *data,
1128 + struct drm_file *);
1129 +extern void nouveau_wait_for_idle(struct drm_device *);
1130 +extern int nouveau_card_init(struct drm_device *);
1131 +extern int nouveau_ioctl_card_init(struct drm_device *, void *data,
1132 + struct drm_file *);
1133 +extern int nouveau_ioctl_suspend(struct drm_device *, void *data,
1134 + struct drm_file *);
1135 +extern int nouveau_ioctl_resume(struct drm_device *, void *data,
1136 + struct drm_file *);
1137 +
1138 +/* nouveau_mem.c */
1139 +extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start,
1140 + uint64_t size);
1141 +extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
1142 + uint64_t size, int align2,
1143 + struct drm_file *, int tail);
1144 +extern void nouveau_mem_takedown(struct mem_block **heap);
1145 +extern void nouveau_mem_free_block(struct mem_block *);
1146 +extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
1147 +extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
1148 +extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data,
1149 + struct drm_file *);
1150 +extern int nouveau_ioctl_mem_free(struct drm_device *, void *data,
1151 + struct drm_file *);
1152 +extern int nouveau_ioctl_mem_tile(struct drm_device *, void *data,
1153 + struct drm_file *);
1154 +extern struct mem_block* nouveau_mem_alloc(struct drm_device *,
1155 + int alignment, uint64_t size,
1156 + int flags, struct drm_file *);
1157 +extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*);
1158 +extern int nouveau_mem_init(struct drm_device *);
1159 +extern int nouveau_mem_init_ttm(struct drm_device *);
1160 +extern void nouveau_mem_close(struct drm_device *);
1161 +
1162 +/* nouveau_notifier.c */
1163 +extern int nouveau_notifier_init_channel(struct nouveau_channel *);
1164 +extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
1165 +extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
1166 + int cout, uint32_t *offset);
1167 +extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data,
1168 + struct drm_file *);
1169 +extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data,
1170 + struct drm_file *);
1171 +
1172 +/* nouveau_fifo.c */
1173 +extern int nouveau_fifo_init(struct drm_device *);
1174 +extern int nouveau_fifo_ctx_size(struct drm_device *);
1175 +extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *);
1176 +extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *,
1177 + int channel);
1178 +extern int nouveau_fifo_alloc(struct drm_device *dev,
1179 + struct nouveau_channel **chan,
1180 + struct drm_file *file_priv,
1181 + struct mem_block *pushbuf,
1182 + uint32_t fb_ctxdma, uint32_t tt_ctxdma);
1183 +extern void nouveau_fifo_free(struct nouveau_channel *);
1184 +extern int nouveau_channel_idle(struct nouveau_channel *chan);
1185 +
1186 +/* nouveau_object.c */
1187 +extern int nouveau_gpuobj_early_init(struct drm_device *);
1188 +extern int nouveau_gpuobj_init(struct drm_device *);
1189 +extern void nouveau_gpuobj_takedown(struct drm_device *);
1190 +extern void nouveau_gpuobj_late_takedown(struct drm_device *);
1191 +extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
1192 + uint32_t vram_h, uint32_t tt_h);
1193 +extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
1194 +extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *,
1195 + int size, int align, uint32_t flags,
1196 + struct nouveau_gpuobj **);
1197 +extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **);
1198 +extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *,
1199 + uint32_t handle, struct nouveau_gpuobj *,
1200 + struct nouveau_gpuobj_ref **);
1201 +extern int nouveau_gpuobj_ref_del(struct drm_device *,
1202 + struct nouveau_gpuobj_ref **);
1203 +extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle,
1204 + struct nouveau_gpuobj_ref **ref_ret);
1205 +extern int nouveau_gpuobj_new_ref(struct drm_device *,
1206 + struct nouveau_channel *alloc_chan,
1207 + struct nouveau_channel *ref_chan,
1208 + uint32_t handle, int size, int align,
1209 + uint32_t flags, struct nouveau_gpuobj_ref **);
1210 +extern int nouveau_gpuobj_new_fake(struct drm_device *,
1211 + uint32_t p_offset, uint32_t b_offset,
1212 + uint32_t size, uint32_t flags,
1213 + struct nouveau_gpuobj **,
1214 + struct nouveau_gpuobj_ref**);
1215 +extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class,
1216 + uint64_t offset, uint64_t size, int access,
1217 + int target, struct nouveau_gpuobj **);
1218 +extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
1219 + uint64_t offset, uint64_t size,
1220 + int access, struct nouveau_gpuobj **,
1221 + uint32_t *o_ret);
1222 +extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
1223 + struct nouveau_gpuobj **);
1224 +extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
1225 + struct drm_file *);
1226 +extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
1227 + struct drm_file *);
1228 +
1229 +/* nouveau_irq.c */
1230 +extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
1231 +extern void nouveau_irq_preinstall(struct drm_device *);
1232 +extern int nouveau_irq_postinstall(struct drm_device *);
1233 +extern void nouveau_irq_uninstall(struct drm_device *);
1234 +
1235 +/* nouveau_sgdma.c */
1236 +extern int nouveau_sgdma_init(struct drm_device *);
1237 +extern void nouveau_sgdma_takedown(struct drm_device *);
1238 +extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
1239 + uint32_t *page);
1240 +extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
1241 +extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
1242 +extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
1243 +
1244 +/* nouveau_dma.c */
1245 +extern int nouveau_dma_channel_init(struct drm_device *);
1246 +extern void nouveau_dma_channel_takedown(struct drm_device *);
1247 +extern int nouveau_dma_wait(struct drm_device *, int size);
1248 +
1249 +/* nv04_fb.c */
1250 +extern int nv04_fb_init(struct drm_device *);
1251 +extern void nv04_fb_takedown(struct drm_device *);
1252 +
1253 +/* nv10_fb.c */
1254 +extern int nv10_fb_init(struct drm_device *);
1255 +extern void nv10_fb_takedown(struct drm_device *);
1256 +
1257 +/* nv40_fb.c */
1258 +extern int nv40_fb_init(struct drm_device *);
1259 +extern void nv40_fb_takedown(struct drm_device *);
1260 +
1261 +/* nv04_fifo.c */
1262 +extern int nv04_fifo_channel_id(struct drm_device *);
1263 +extern int nv04_fifo_create_context(struct nouveau_channel *);
1264 +extern void nv04_fifo_destroy_context(struct nouveau_channel *);
1265 +extern int nv04_fifo_load_context(struct nouveau_channel *);
1266 +extern int nv04_fifo_save_context(struct nouveau_channel *);
1267 +
1268 +/* nv10_fifo.c */
1269 +extern int nv10_fifo_channel_id(struct drm_device *);
1270 +extern int nv10_fifo_create_context(struct nouveau_channel *);
1271 +extern void nv10_fifo_destroy_context(struct nouveau_channel *);
1272 +extern int nv10_fifo_load_context(struct nouveau_channel *);
1273 +extern int nv10_fifo_save_context(struct nouveau_channel *);
1274 +
1275 +/* nv40_fifo.c */
1276 +extern int nv40_fifo_init(struct drm_device *);
1277 +extern int nv40_fifo_create_context(struct nouveau_channel *);
1278 +extern void nv40_fifo_destroy_context(struct nouveau_channel *);
1279 +extern int nv40_fifo_load_context(struct nouveau_channel *);
1280 +extern int nv40_fifo_save_context(struct nouveau_channel *);
1281 +
1282 +/* nv50_fifo.c */
1283 +extern int nv50_fifo_init(struct drm_device *);
1284 +extern void nv50_fifo_takedown(struct drm_device *);
1285 +extern int nv50_fifo_channel_id(struct drm_device *);
1286 +extern int nv50_fifo_create_context(struct nouveau_channel *);
1287 +extern void nv50_fifo_destroy_context(struct nouveau_channel *);
1288 +extern int nv50_fifo_load_context(struct nouveau_channel *);
1289 +extern int nv50_fifo_save_context(struct nouveau_channel *);
1290 +
1291 +/* nv04_graph.c */
1292 +extern void nouveau_nv04_context_switch(struct drm_device *);
1293 +extern int nv04_graph_init(struct drm_device *);
1294 +extern void nv04_graph_takedown(struct drm_device *);
1295 +extern int nv04_graph_create_context(struct nouveau_channel *);
1296 +extern void nv04_graph_destroy_context(struct nouveau_channel *);
1297 +extern int nv04_graph_load_context(struct nouveau_channel *);
1298 +extern int nv04_graph_save_context(struct nouveau_channel *);
1299 +
1300 +/* nv10_graph.c */
1301 +extern void nouveau_nv10_context_switch(struct drm_device *);
1302 +extern int nv10_graph_init(struct drm_device *);
1303 +extern void nv10_graph_takedown(struct drm_device *);
1304 +extern int nv10_graph_create_context(struct nouveau_channel *);
1305 +extern void nv10_graph_destroy_context(struct nouveau_channel *);
1306 +extern int nv10_graph_load_context(struct nouveau_channel *);
1307 +extern int nv10_graph_save_context(struct nouveau_channel *);
1308 +
1309 +/* nv20_graph.c */
1310 +extern int nv20_graph_create_context(struct nouveau_channel *);
1311 +extern void nv20_graph_destroy_context(struct nouveau_channel *);
1312 +extern int nv20_graph_load_context(struct nouveau_channel *);
1313 +extern int nv20_graph_save_context(struct nouveau_channel *);
1314 +extern int nv20_graph_init(struct drm_device *);
1315 +extern void nv20_graph_takedown(struct drm_device *);
1316 +extern int nv30_graph_init(struct drm_device *);
1317 +
1318 +/* nv40_graph.c */
1319 +extern int nv40_graph_init(struct drm_device *);
1320 +extern void nv40_graph_takedown(struct drm_device *);
1321 +extern int nv40_graph_create_context(struct nouveau_channel *);
1322 +extern void nv40_graph_destroy_context(struct nouveau_channel *);
1323 +extern int nv40_graph_load_context(struct nouveau_channel *);
1324 +extern int nv40_graph_save_context(struct nouveau_channel *);
1325 +
1326 +/* nv50_graph.c */
1327 +extern int nv50_graph_init(struct drm_device *);
1328 +extern void nv50_graph_takedown(struct drm_device *);
1329 +extern int nv50_graph_create_context(struct nouveau_channel *);
1330 +extern void nv50_graph_destroy_context(struct nouveau_channel *);
1331 +extern int nv50_graph_load_context(struct nouveau_channel *);
1332 +extern int nv50_graph_save_context(struct nouveau_channel *);
1333 +
1334 +/* nv04_instmem.c */
1335 +extern int nv04_instmem_init(struct drm_device *);
1336 +extern void nv04_instmem_takedown(struct drm_device *);
1337 +extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
1338 + uint32_t *size);
1339 +extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
1340 +extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
1341 +extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
1342 +
1343 +/* nv50_instmem.c */
1344 +extern int nv50_instmem_init(struct drm_device *);
1345 +extern void nv50_instmem_takedown(struct drm_device *);
1346 +extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
1347 + uint32_t *size);
1348 +extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
1349 +extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
1350 +extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
1351 +
1352 +/* nv04_mc.c */
1353 +extern int nv04_mc_init(struct drm_device *);
1354 +extern void nv04_mc_takedown(struct drm_device *);
1355 +
1356 +/* nv40_mc.c */
1357 +extern int nv40_mc_init(struct drm_device *);
1358 +extern void nv40_mc_takedown(struct drm_device *);
1359 +
1360 +/* nv50_mc.c */
1361 +extern int nv50_mc_init(struct drm_device *);
1362 +extern void nv50_mc_takedown(struct drm_device *);
1363 +
1364 +/* nv04_timer.c */
1365 +extern int nv04_timer_init(struct drm_device *);
1366 +extern uint64_t nv04_timer_read(struct drm_device *);
1367 +extern void nv04_timer_takedown(struct drm_device *);
1368 +
1369 +extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
1370 + unsigned long arg);
1371 +
1372 +/* nouveau_buffer.c */
1373 +extern struct drm_bo_driver nouveau_bo_driver;
1374 +
1375 +/* nouveau_fence.c */
1376 +extern struct drm_fence_driver nouveau_fence_driver;
1377 +extern void nouveau_fence_handler(struct drm_device *dev, int channel);
1378 +
1379 +#if defined(__powerpc__)
1380 +#define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) )
1381 +#define NV_WRITE(reg,val) out_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) , (val) )
1382 +#else
1383 +#define NV_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
1384 +#define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
1385 +#endif
1386 +
1387 +/* PRAMIN access */
1388 +#if defined(__powerpc__)
1389 +#define NV_RI32(o) in_be32((void __iomem *)(dev_priv->ramin)->handle+(o))
1390 +#define NV_WI32(o,v) out_be32((void __iomem*)(dev_priv->ramin)->handle+(o), (v))
1391 +#else
1392 +#define NV_RI32(o) DRM_READ32(dev_priv->ramin, (o))
1393 +#define NV_WI32(o,v) DRM_WRITE32(dev_priv->ramin, (o), (v))
1394 +#endif
1395 +
1396 +#define INSTANCE_RD(o,i) NV_RI32((o)->im_pramin->start + ((i)<<2))
1397 +#define INSTANCE_WR(o,i,v) NV_WI32((o)->im_pramin->start + ((i)<<2), (v))
1398 +
1399 +#endif /* __NOUVEAU_DRV_H__ */
1400 diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
1401 new file mode 100644
1402 index 0000000..4ad51ae
1403 --- /dev/null
1404 +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
1405 @@ -0,0 +1,119 @@
1406 +/*
1407 + * Copyright (C) 2007 Ben Skeggs.
1408 + * All Rights Reserved.
1409 + *
1410 + * Permission is hereby granted, free of charge, to any person obtaining
1411 + * a copy of this software and associated documentation files (the
1412 + * "Software"), to deal in the Software without restriction, including
1413 + * without limitation the rights to use, copy, modify, merge, publish,
1414 + * distribute, sublicense, and/or sell copies of the Software, and to
1415 + * permit persons to whom the Software is furnished to do so, subject to
1416 + * the following conditions:
1417 + *
1418 + * The above copyright notice and this permission notice (including the
1419 + * next paragraph) shall be included in all copies or substantial
1420 + * portions of the Software.
1421 + *
1422 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1423 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1424 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1425 + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
1426 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
1427 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1428 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1429 + *
1430 + */
1431 +
1432 +#include "drmP.h"
1433 +#include "drm.h"
1434 +#include "nouveau_drv.h"
1435 +#include "nouveau_dma.h"
1436 +
1437 +static int
1438 +nouveau_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags)
1439 +{
1440 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1441 +
1442 + DRM_DEBUG("class=%d, flags=0x%08x\n", class, flags);
1443 +
1444 + /* DRM's channel always uses IRQs to signal fences */
1445 + if (class == dev_priv->channel.chan->id)
1446 + return 1;
1447 +
1448 + /* Other channels don't use IRQs at all yet */
1449 + return 0;
1450 +}
1451 +
1452 +static int
1453 +nouveau_fence_emit(struct drm_device *dev, uint32_t class, uint32_t flags,
1454 + uint32_t *breadcrumb, uint32_t *native_type)
1455 +{
1456 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1457 + struct nouveau_channel *chan = dev_priv->fifos[class];
1458 + struct nouveau_drm_channel *dchan = &dev_priv->channel;
1459 +
1460 + DRM_DEBUG("class=%d, flags=0x%08x\n", class, flags);
1461 +
1462 + /* We can't emit fences on client channels, update sequence number
1463 + * and userspace will emit the fence
1464 + */
1465 + *breadcrumb = ++chan->next_sequence;
1466 + *native_type = DRM_FENCE_TYPE_EXE;
1467 + if (chan != dchan->chan) {
1468 + DRM_DEBUG("user fence 0x%08x\n", *breadcrumb);
1469 + return 0;
1470 + }
1471 +
1472 + DRM_DEBUG("emit 0x%08x\n", *breadcrumb);
1473 + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_REF, 1);
1474 + OUT_RING (*breadcrumb);
1475 + BEGIN_RING(NvSubM2MF, 0x0150, 1);
1476 + OUT_RING (0);
1477 + FIRE_RING ();
1478 +
1479 + return 0;
1480 +}
1481 +
1482 +static void
1483 +nouveau_fence_poll(struct drm_device *dev, uint32_t class, uint32_t waiting_types)
1484 +{
1485 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1486 + struct drm_fence_class_manager *fc = &dev->fm.fence_class[class];
1487 + struct nouveau_channel *chan = dev_priv->fifos[class];
1488 +
1489 + DRM_DEBUG("class=%d\n", class);
1490 + DRM_DEBUG("pending: 0x%08x 0x%08x\n", waiting_types, fc->waiting_types);
1491 +
1492 + if (waiting_types & DRM_FENCE_TYPE_EXE) {
1493 + uint32_t sequence = NV_READ(chan->ref_cnt);
1494 +
1495 + DRM_DEBUG("got 0x%08x\n", sequence);
1496 + drm_fence_handler(dev, class, sequence, waiting_types, 0);
1497 + }
1498 +}
1499 +
1500 +void
1501 +nouveau_fence_handler(struct drm_device *dev, int channel)
1502 +{
1503 + struct drm_fence_manager *fm = &dev->fm;
1504 + struct drm_fence_class_manager *fc = &fm->fence_class[channel];
1505 +
1506 + DRM_DEBUG("class=%d\n", channel);
1507 +
1508 + write_lock(&fm->lock);
1509 + nouveau_fence_poll(dev, channel, fc->waiting_types);
1510 + write_unlock(&fm->lock);
1511 +}
1512 +
1513 +struct drm_fence_driver nouveau_fence_driver = {
1514 + .num_classes = 8,
1515 + .wrap_diff = (1 << 30),
1516 + .flush_diff = (1 << 29),
1517 + .sequence_mask = 0xffffffffU,
1518 + .has_irq = nouveau_fence_has_irq,
1519 + .emit = nouveau_fence_emit,
1520 + .flush = NULL,
1521 + .poll = nouveau_fence_poll,
1522 + .needed_flush = NULL,
1523 + .wait = NULL
1524 +};
1525 diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.c b/drivers/gpu/drm/nouveau/nouveau_fifo.c
1526 new file mode 100644
1527 index 0000000..92ea8fc
1528 --- /dev/null
1529 +++ b/drivers/gpu/drm/nouveau/nouveau_fifo.c
1530 @@ -0,0 +1,601 @@
1531 +/*
1532 + * Copyright 2005-2006 Stephane Marchesin
1533 + * All Rights Reserved.
1534 + *
1535 + * Permission is hereby granted, free of charge, to any person obtaining a
1536 + * copy of this software and associated documentation files (the "Software"),
1537 + * to deal in the Software without restriction, including without limitation
1538 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1539 + * and/or sell copies of the Software, and to permit persons to whom the
1540 + * Software is furnished to do so, subject to the following conditions:
1541 + *
1542 + * The above copyright notice and this permission notice (including the next
1543 + * paragraph) shall be included in all copies or substantial portions of the
1544 + * Software.
1545 + *
1546 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1547 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1548 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1549 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1550 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1551 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1552 + * DEALINGS IN THE SOFTWARE.
1553 + */
1554 +
1555 +#include "drmP.h"
1556 +#include "drm.h"
1557 +#include "nouveau_drv.h"
1558 +#include "nouveau_drm.h"
1559 +
1560 +
1561 +/* returns the size of fifo context */
1562 +int nouveau_fifo_ctx_size(struct drm_device *dev)
1563 +{
1564 + struct drm_nouveau_private *dev_priv=dev->dev_private;
1565 +
1566 + if (dev_priv->card_type >= NV_40)
1567 + return 128;
1568 + else if (dev_priv->card_type >= NV_17)
1569 + return 64;
1570 + else
1571 + return 32;
1572 +}
1573 +
1574 +/***********************************
1575 + * functions doing the actual work
1576 + ***********************************/
1577 +
1578 +static int nouveau_fifo_instmem_configure(struct drm_device *dev)
1579 +{
1580 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1581 +
1582 + NV_WRITE(NV03_PFIFO_RAMHT,
1583 + (0x03 << 24) /* search 128 */ |
1584 + ((dev_priv->ramht_bits - 9) << 16) |
1585 + (dev_priv->ramht_offset >> 8)
1586 + );
1587 +
1588 + NV_WRITE(NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
1589 +
1590 + switch(dev_priv->card_type)
1591 + {
1592 + case NV_40:
1593 + switch (dev_priv->chipset) {
1594 + case 0x47:
1595 + case 0x49:
1596 + case 0x4b:
1597 + NV_WRITE(0x2230, 1);
1598 + break;
1599 + default:
1600 + break;
1601 + }
1602 + NV_WRITE(NV40_PFIFO_RAMFC, 0x30002);
1603 + break;
1604 + case NV_44:
1605 + NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) |
1606 + (2 << 16));
1607 + break;
1608 + case NV_30:
1609 + case NV_20:
1610 + case NV_17:
1611 + NV_WRITE(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) |
1612 + (1 << 16) /* 64 Bytes entry*/);
1613 + /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */
1614 + break;
1615 + case NV_11:
1616 + case NV_10:
1617 + case NV_04:
1618 + NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8);
1619 + break;
1620 + }
1621 +
1622 + return 0;
1623 +}
1624 +
1625 +int nouveau_fifo_init(struct drm_device *dev)
1626 +{
1627 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1628 + int ret;
1629 +
1630 + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
1631 + ~NV_PMC_ENABLE_PFIFO);
1632 + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
1633 + NV_PMC_ENABLE_PFIFO);
1634 +
1635 + /* Enable PFIFO error reporting */
1636 + NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
1637 + NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
1638 +
1639 + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
1640 +
1641 + ret = nouveau_fifo_instmem_configure(dev);
1642 + if (ret) {
1643 + DRM_ERROR("Failed to configure instance memory\n");
1644 + return ret;
1645 + }
1646 +
1647 + /* FIXME remove all the stuff that's done in nouveau_fifo_alloc */
1648 +
1649 + DRM_DEBUG("Setting defaults for remaining PFIFO regs\n");
1650 +
1651 + /* All channels into PIO mode */
1652 + NV_WRITE(NV04_PFIFO_MODE, 0x00000000);
1653 +
1654 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
1655 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
1656 + /* Channel 0 active, PIO mode */
1657 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00000000);
1658 + /* PUT and GET to 0 */
1659 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, 0x00000000);
1660 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, 0x00000000);
1661 + /* No cmdbuf object */
1662 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, 0x00000000);
1663 + NV_WRITE(NV03_PFIFO_CACHE0_PUSH0, 0x00000000);
1664 + NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x00000000);
1665 + NV_WRITE(NV04_PFIFO_SIZE, 0x0000FFFF);
1666 + NV_WRITE(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF);
1667 + NV_WRITE(NV04_PFIFO_CACHE0_PULL1, 0x00000001);
1668 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, 0x00000000);
1669 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
1670 + NV_WRITE(NV04_PFIFO_CACHE1_ENGINE, 0x00000000);
1671 +
1672 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES |
1673 + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
1674 + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 |
1675 +#ifdef __BIG_ENDIAN
1676 + NV_PFIFO_CACHE1_BIG_ENDIAN |
1677 +#endif
1678 + 0x00000000);
1679 +
1680 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001);
1681 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
1682 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
1683 + NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001);
1684 +
1685 + /* FIXME on NV04 */
1686 + if (dev_priv->card_type >= NV_10) {
1687 + NV_WRITE(NV10_PGRAPH_CTX_USER, 0x0);
1688 + NV_WRITE(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ );
1689 + if (dev_priv->card_type >= NV_40)
1690 + NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x00002001);
1691 + else
1692 + NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10110000);
1693 + } else {
1694 + NV_WRITE(NV04_PGRAPH_CTX_USER, 0x0);
1695 + NV_WRITE(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ );
1696 + NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10110000);
1697 + }
1698 +
1699 + NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, 0x001fffff);
1700 + NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
1701 + return 0;
1702 +}
1703 +
1704 +static int
1705 +nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan)
1706 +{
1707 + struct drm_device *dev = chan->dev;
1708 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1709 + struct mem_block *pb = chan->pushbuf_mem;
1710 + struct nouveau_gpuobj *pushbuf = NULL;
1711 + int ret;
1712 +
1713 + if (pb->flags & NOUVEAU_MEM_AGP) {
1714 + ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size,
1715 + NV_DMA_ACCESS_RO,
1716 + &pushbuf,
1717 + &chan->pushbuf_base);
1718 + } else
1719 + if (pb->flags & NOUVEAU_MEM_PCI) {
1720 + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
1721 + pb->start, pb->size,
1722 + NV_DMA_ACCESS_RO,
1723 + NV_DMA_TARGET_PCI_NONLINEAR,
1724 + &pushbuf);
1725 + chan->pushbuf_base = 0;
1726 + } else if (dev_priv->card_type != NV_04) {
1727 + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
1728 + pb->start, pb->size,
1729 + NV_DMA_ACCESS_RO,
1730 + NV_DMA_TARGET_VIDMEM, &pushbuf);
1731 + chan->pushbuf_base = 0;
1732 + } else {
1733 + /* NV04 cmdbuf hack, from original ddx.. not sure of it's
1734 + * exact reason for existing :) PCI access to cmdbuf in
1735 + * VRAM.
1736 + */
1737 + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
1738 + pb->start +
1739 + drm_get_resource_start(dev, 1),
1740 + pb->size, NV_DMA_ACCESS_RO,
1741 + NV_DMA_TARGET_PCI, &pushbuf);
1742 + chan->pushbuf_base = 0;
1743 + }
1744 +
1745 + if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf,
1746 + &chan->pushbuf))) {
1747 + DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret);
1748 + if (pushbuf != dev_priv->gart_info.sg_ctxdma)
1749 + nouveau_gpuobj_del(dev, &pushbuf);
1750 + return ret;
1751 + }
1752 +
1753 + return 0;
1754 +}
1755 +
1756 +static struct mem_block *
1757 +nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev)
1758 +{
1759 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1760 + struct nouveau_config *config = &dev_priv->config;
1761 + struct mem_block *pb;
1762 + int pb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE);
1763 +
1764 + /* Defaults for unconfigured values */
1765 + if (!config->cmdbuf.location)
1766 + config->cmdbuf.location = NOUVEAU_MEM_FB;
1767 + if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size)
1768 + config->cmdbuf.size = pb_min_size;
1769 +
1770 + pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
1771 + config->cmdbuf.location | NOUVEAU_MEM_MAPPED,
1772 + (struct drm_file *)-2);
1773 + if (!pb)
1774 + DRM_ERROR("Couldn't allocate DMA push buffer.\n");
1775 +
1776 + return pb;
1777 +}
1778 +
1779 +/* allocates and initializes a fifo for user space consumption */
1780 +int
1781 +nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
1782 + struct drm_file *file_priv, struct mem_block *pushbuf,
1783 + uint32_t vram_handle, uint32_t tt_handle)
1784 +{
1785 + int ret;
1786 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1787 + struct nouveau_engine *engine = &dev_priv->Engine;
1788 + struct nouveau_channel *chan;
1789 + int channel;
1790 +
1791 + /*
1792 + * Alright, here is the full story
1793 + * Nvidia cards have multiple hw fifo contexts (praise them for that,
1794 + * no complicated crash-prone context switches)
1795 + * We allocate a new context for each app and let it write to it directly
1796 + * (woo, full userspace command submission !)
1797 + * When there are no more contexts, you lost
1798 + */
1799 + for (channel = 0; channel < engine->fifo.channels; channel++) {
1800 + if (dev_priv->fifos[channel] == NULL)
1801 + break;
1802 + }
1803 +
1804 + /* no more fifos. you lost. */
1805 + if (channel == engine->fifo.channels)
1806 + return -EINVAL;
1807 +
1808 + dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel),
1809 + DRM_MEM_DRIVER);
1810 + if (!dev_priv->fifos[channel])
1811 + return -ENOMEM;
1812 + dev_priv->fifo_alloc_count++;
1813 + chan = dev_priv->fifos[channel];
1814 + chan->dev = dev;
1815 + chan->id = channel;
1816 + chan->file_priv = file_priv;
1817 + chan->pushbuf_mem = pushbuf;
1818 +
1819 + DRM_INFO("Allocating FIFO number %d\n", channel);
1820 +
1821 + /* Locate channel's user control regs */
1822 + if (dev_priv->card_type < NV_40) {
1823 + chan->user = NV03_USER(channel);
1824 + chan->user_size = NV03_USER_SIZE;
1825 + chan->put = NV03_USER_DMA_PUT(channel);
1826 + chan->get = NV03_USER_DMA_GET(channel);
1827 + chan->ref_cnt = NV03_USER_REF_CNT(channel);
1828 + } else
1829 + if (dev_priv->card_type < NV_50) {
1830 + chan->user = NV40_USER(channel);
1831 + chan->user_size = NV40_USER_SIZE;
1832 + chan->put = NV40_USER_DMA_PUT(channel);
1833 + chan->get = NV40_USER_DMA_GET(channel);
1834 + chan->ref_cnt = NV40_USER_REF_CNT(channel);
1835 + } else {
1836 + chan->user = NV50_USER(channel);
1837 + chan->user_size = NV50_USER_SIZE;
1838 + chan->put = NV50_USER_DMA_PUT(channel);
1839 + chan->get = NV50_USER_DMA_GET(channel);
1840 + chan->ref_cnt = NV50_USER_REF_CNT(channel);
1841 + }
1842 +
1843 + /* Allocate space for per-channel fixed notifier memory */
1844 + ret = nouveau_notifier_init_channel(chan);
1845 + if (ret) {
1846 + nouveau_fifo_free(chan);
1847 + return ret;
1848 + }
1849 +
1850 + /* Setup channel's default objects */
1851 + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle);
1852 + if (ret) {
1853 + nouveau_fifo_free(chan);
1854 + return ret;
1855 + }
1856 +
1857 + /* Create a dma object for the push buffer */
1858 + ret = nouveau_fifo_pushbuf_ctxdma_init(chan);
1859 + if (ret) {
1860 + nouveau_fifo_free(chan);
1861 + return ret;
1862 + }
1863 +
1864 + nouveau_wait_for_idle(dev);
1865 +
1866 + /* disable the fifo caches */
1867 + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
1868 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1));
1869 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
1870 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
1871 +
1872 + /* Create a graphics context for new channel */
1873 + ret = engine->graph.create_context(chan);
1874 + if (ret) {
1875 + nouveau_fifo_free(chan);
1876 + return ret;
1877 + }
1878 +
1879 + /* Construct inital RAMFC for new channel */
1880 + ret = engine->fifo.create_context(chan);
1881 + if (ret) {
1882 + nouveau_fifo_free(chan);
1883 + return ret;
1884 + }
1885 +
1886 + /* setup channel's default get/put values
1887 + * XXX: quite possibly extremely pointless..
1888 + */
1889 + NV_WRITE(chan->get, chan->pushbuf_base);
1890 + NV_WRITE(chan->put, chan->pushbuf_base);
1891 +
1892 + /* If this is the first channel, setup PFIFO ourselves. For any
1893 + * other case, the GPU will handle this when it switches contexts.
1894 + */
1895 + if (dev_priv->fifo_alloc_count == 1) {
1896 + ret = engine->fifo.load_context(chan);
1897 + if (ret) {
1898 + nouveau_fifo_free(chan);
1899 + return ret;
1900 + }
1901 +
1902 + ret = engine->graph.load_context(chan);
1903 + if (ret) {
1904 + nouveau_fifo_free(chan);
1905 + return ret;
1906 + }
1907 + }
1908 +
1909 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
1910 + NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
1911 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
1912 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
1913 + NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001);
1914 +
1915 + /* reenable the fifo caches */
1916 + NV_WRITE(NV03_PFIFO_CACHES, 1);
1917 +
1918 + DRM_INFO("%s: initialised FIFO %d\n", __func__, channel);
1919 + *chan_ret = chan;
1920 + return 0;
1921 +}
1922 +
1923 +int
1924 +nouveau_channel_idle(struct nouveau_channel *chan)
1925 +{
1926 + struct drm_device *dev = chan->dev;
1927 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1928 + struct nouveau_engine *engine = &dev_priv->Engine;
1929 + uint32_t caches;
1930 + int idle;
1931 +
1932 + caches = NV_READ(NV03_PFIFO_CACHES);
1933 + NV_WRITE(NV03_PFIFO_CACHES, caches & ~1);
1934 +
1935 + if (engine->fifo.channel_id(dev) != chan->id) {
1936 + struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj;
1937 +
1938 + if (INSTANCE_RD(ramfc, 0) != INSTANCE_RD(ramfc, 1))
1939 + idle = 0;
1940 + else
1941 + idle = 1;
1942 + } else {
1943 + idle = (NV_READ(NV04_PFIFO_CACHE1_DMA_GET) ==
1944 + NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
1945 + }
1946 +
1947 + NV_WRITE(NV03_PFIFO_CACHES, caches);
1948 + return idle;
1949 +}
1950 +
1951 +/* stops a fifo */
1952 +void nouveau_fifo_free(struct nouveau_channel *chan)
1953 +{
1954 + struct drm_device *dev = chan->dev;
1955 + struct drm_nouveau_private *dev_priv = dev->dev_private;
1956 + struct nouveau_engine *engine = &dev_priv->Engine;
1957 + uint64_t t_start;
1958 +
1959 + DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id);
1960 +
1961 + /* Give the channel a chance to idle, wait 2s (hopefully) */
1962 + t_start = engine->timer.read(dev);
1963 + while (!nouveau_channel_idle(chan)) {
1964 + if (engine->timer.read(dev) - t_start > 2000000000ULL) {
1965 + DRM_ERROR("Failed to idle channel %d before destroy."
1966 + "Prepare for strangeness..\n", chan->id);
1967 + break;
1968 + }
1969 + }
1970 +
1971 + /*XXX: Maybe should wait for PGRAPH to finish with the stuff it fetched
1972 + * from CACHE1 too?
1973 + */
1974 +
1975 + /* disable the fifo caches */
1976 + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
1977 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1));
1978 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
1979 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
1980 +
1981 + // FIXME XXX needs more code
1982 +
1983 + engine->fifo.destroy_context(chan);
1984 +
1985 + /* Cleanup PGRAPH state */
1986 + engine->graph.destroy_context(chan);
1987 +
1988 + /* reenable the fifo caches */
1989 + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
1990 + NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
1991 + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
1992 + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
1993 + NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
1994 +
1995 + /* Deallocate push buffer */
1996 + nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
1997 + if (chan->pushbuf_mem) {
1998 + nouveau_mem_free(dev, chan->pushbuf_mem);
1999 + chan->pushbuf_mem = NULL;
2000 + }
2001 +
2002 + /* Destroy objects belonging to the channel */
2003 + nouveau_gpuobj_channel_takedown(chan);
2004 +
2005 + nouveau_notifier_takedown_channel(chan);
2006 +
2007 + dev_priv->fifos[chan->id] = NULL;
2008 + dev_priv->fifo_alloc_count--;
2009 + drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER);
2010 +}
2011 +
2012 +/* cleanups all the fifos from file_priv */
2013 +void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv)
2014 +{
2015