2 * Copyright (C) 2006 Ben Skeggs.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 * Ben Skeggs <darktama@iinet.net.au>
35 #include "nouveau_drv.h"
36 #include "nouveau_drm.h"
38 /* NVidia uses context objects to drive drawing operations.
40 Context objects can be selected into 8 subchannels in the FIFO,
41 and then used via DMA command buffers.
43 A context object is referenced by a user defined handle (CARD32). The HW
44 looks up graphics objects in a hash table in the instance RAM.
46 An entry in the hash table consists of 2 CARD32. The first CARD32 contains
47 the handle, the second one a bitfield, that contains the address of the
48 object in instance RAM.
50 The format of the second CARD32 seems to be:
54 15: 0 instance_addr >> 4
55 17:16 engine (here uses 1 = graphics)
56 28:24 channel id (here uses 0)
61 15: 0 instance_addr >> 4 (maybe 19-0)
62 21:20 engine (here uses 1 = graphics)
63 I'm unsure about the other bits, but using 0 seems to work.
65 The key into the hash table depends on the object handle and channel id and
69 nouveau_ramht_hash_handle(struct drm_device
*dev
, int channel
, uint32_t handle
)
71 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
75 NV_DEBUG(dev
, "ch%d handle=0x%08x\n", channel
, handle
);
77 for (i
= 32; i
> 0; i
-= dev_priv
->ramht_bits
) {
78 hash
^= (handle
& ((1 << dev_priv
->ramht_bits
) - 1));
79 handle
>>= dev_priv
->ramht_bits
;
82 if (dev_priv
->card_type
< NV_50
)
83 hash
^= channel
<< (dev_priv
->ramht_bits
- 4);
86 NV_DEBUG(dev
, "hash=0x%08x\n", hash
);
91 nouveau_ramht_entry_valid(struct drm_device
*dev
, struct nouveau_gpuobj
*ramht
,
94 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
95 uint32_t ctx
= nv_ro32(dev
, ramht
, (offset
+ 4)/4);
97 if (dev_priv
->card_type
< NV_40
)
98 return ((ctx
& NV_RAMHT_CONTEXT_VALID
) != 0);
103 nouveau_ramht_insert(struct drm_device
*dev
, struct nouveau_gpuobj_ref
*ref
)
105 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
106 struct nouveau_instmem_engine
*instmem
= &dev_priv
->engine
.instmem
;
107 struct nouveau_channel
*chan
= ref
->channel
;
108 struct nouveau_gpuobj
*ramht
= chan
->ramht
? chan
->ramht
->gpuobj
: NULL
;
109 uint32_t ctx
, co
, ho
;
112 NV_ERROR(dev
, "No hash table!\n");
116 if (dev_priv
->card_type
< NV_40
) {
117 ctx
= NV_RAMHT_CONTEXT_VALID
| (ref
->instance
>> 4) |
118 (chan
->id
<< NV_RAMHT_CONTEXT_CHANNEL_SHIFT
) |
119 (ref
->gpuobj
->engine
<< NV_RAMHT_CONTEXT_ENGINE_SHIFT
);
121 if (dev_priv
->card_type
< NV_50
) {
122 ctx
= (ref
->instance
>> 4) |
123 (chan
->id
<< NV40_RAMHT_CONTEXT_CHANNEL_SHIFT
) |
124 (ref
->gpuobj
->engine
<< NV40_RAMHT_CONTEXT_ENGINE_SHIFT
);
126 if (ref
->gpuobj
->engine
== NVOBJ_ENGINE_DISPLAY
) {
127 ctx
= (ref
->instance
<< 10) | 2;
129 ctx
= (ref
->instance
>> 4) |
130 ((ref
->gpuobj
->engine
<<
131 NV40_RAMHT_CONTEXT_ENGINE_SHIFT
));
135 co
= ho
= nouveau_ramht_hash_handle(dev
, chan
->id
, ref
->handle
);
137 if (!nouveau_ramht_entry_valid(dev
, ramht
, co
)) {
139 "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
140 chan
->id
, co
, ref
->handle
, ctx
);
141 nv_wo32(dev
, ramht
, (co
+ 0)/4, ref
->handle
);
142 nv_wo32(dev
, ramht
, (co
+ 4)/4, ctx
);
144 list_add_tail(&ref
->list
, &chan
->ramht_refs
);
148 NV_DEBUG(dev
, "collision ch%d 0x%08x: h=0x%08x\n",
149 chan
->id
, co
, nv_ro32(dev
, ramht
, co
/4));
152 if (co
>= dev_priv
->ramht_size
)
156 NV_ERROR(dev
, "RAMHT space exhausted. ch=%d\n", chan
->id
);
161 nouveau_ramht_remove(struct drm_device
*dev
, struct nouveau_gpuobj_ref
*ref
)
163 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
164 struct nouveau_instmem_engine
*instmem
= &dev_priv
->engine
.instmem
;
165 struct nouveau_channel
*chan
= ref
->channel
;
166 struct nouveau_gpuobj
*ramht
= chan
->ramht
? chan
->ramht
->gpuobj
: NULL
;
170 NV_ERROR(dev
, "No hash table!\n");
174 co
= ho
= nouveau_ramht_hash_handle(dev
, chan
->id
, ref
->handle
);
176 if (nouveau_ramht_entry_valid(dev
, ramht
, co
) &&
177 (ref
->handle
== nv_ro32(dev
, ramht
, (co
/4)))) {
179 "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
180 chan
->id
, co
, ref
->handle
,
181 nv_ro32(dev
, ramht
, (co
+ 4)));
182 nv_wo32(dev
, ramht
, (co
+ 0)/4, 0x00000000);
183 nv_wo32(dev
, ramht
, (co
+ 4)/4, 0x00000000);
185 list_del(&ref
->list
);
191 if (co
>= dev_priv
->ramht_size
)
194 list_del(&ref
->list
);
196 NV_ERROR(dev
, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
197 chan
->id
, ref
->handle
);
201 nouveau_gpuobj_new(struct drm_device
*dev
, struct nouveau_channel
*chan
,
202 uint32_t size
, int align
, uint32_t flags
,
203 struct nouveau_gpuobj
**gpuobj_ret
)
205 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
206 struct nouveau_engine
*engine
= &dev_priv
->engine
;
207 struct nouveau_gpuobj
*gpuobj
;
208 struct drm_mm
*pramin
= NULL
;
211 NV_DEBUG(dev
, "ch%d size=%u align=%d flags=0x%08x\n",
212 chan
? chan
->id
: -1, size
, align
, flags
);
214 if (!dev_priv
|| !gpuobj_ret
|| *gpuobj_ret
!= NULL
)
217 gpuobj
= kzalloc(sizeof(*gpuobj
), GFP_KERNEL
);
220 NV_DEBUG(dev
, "gpuobj %p\n", gpuobj
);
221 gpuobj
->flags
= flags
;
222 gpuobj
->im_channel
= chan
;
224 list_add_tail(&gpuobj
->list
, &dev_priv
->gpuobj_list
);
226 /* Choose between global instmem heap, and per-channel private
227 * instmem heap. On <NV50 allow requests for private instmem
228 * to be satisfied from global heap if no per-channel area
232 NV_DEBUG(dev
, "channel heap\n");
233 pramin
= &chan
->ramin_heap
;
235 NV_DEBUG(dev
, "global heap\n");
236 pramin
= &dev_priv
->ramin_heap
;
238 ret
= engine
->instmem
.populate(dev
, gpuobj
, &size
);
240 nouveau_gpuobj_del(dev
, &gpuobj
);
245 /* Allocate a chunk of the PRAMIN aperture */
246 gpuobj
->im_pramin
= drm_mm_search_free(pramin
, size
, align
, 0);
247 if (gpuobj
->im_pramin
)
248 gpuobj
->im_pramin
= drm_mm_get_block(gpuobj
->im_pramin
, size
, align
);
250 if (!gpuobj
->im_pramin
) {
251 nouveau_gpuobj_del(dev
, &gpuobj
);
256 ret
= engine
->instmem
.bind(dev
, gpuobj
);
258 nouveau_gpuobj_del(dev
, &gpuobj
);
263 if (gpuobj
->flags
& NVOBJ_FLAG_ZERO_ALLOC
) {
266 for (i
= 0; i
< gpuobj
->im_pramin
->size
; i
+= 4)
267 nv_wo32(dev
, gpuobj
, i
/4, 0);
268 engine
->instmem
.flush(dev
);
271 *gpuobj_ret
= gpuobj
;
276 nouveau_gpuobj_early_init(struct drm_device
*dev
)
278 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
282 INIT_LIST_HEAD(&dev_priv
->gpuobj_list
);
288 nouveau_gpuobj_init(struct drm_device
*dev
)
290 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
295 if (dev_priv
->card_type
< NV_50
) {
296 ret
= nouveau_gpuobj_new_fake(dev
,
297 dev_priv
->ramht_offset
, ~0, dev_priv
->ramht_size
,
298 NVOBJ_FLAG_ZERO_ALLOC
| NVOBJ_FLAG_ALLOW_NO_REFS
,
299 &dev_priv
->ramht
, NULL
);
308 nouveau_gpuobj_takedown(struct drm_device
*dev
)
310 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
314 nouveau_gpuobj_del(dev
, &dev_priv
->ramht
);
318 nouveau_gpuobj_late_takedown(struct drm_device
*dev
)
320 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
321 struct nouveau_gpuobj
*gpuobj
= NULL
;
322 struct list_head
*entry
, *tmp
;
326 list_for_each_safe(entry
, tmp
, &dev_priv
->gpuobj_list
) {
327 gpuobj
= list_entry(entry
, struct nouveau_gpuobj
, list
);
329 NV_ERROR(dev
, "gpuobj %p still exists at takedown, refs=%d\n",
330 gpuobj
, gpuobj
->refcount
);
331 gpuobj
->refcount
= 0;
332 nouveau_gpuobj_del(dev
, &gpuobj
);
337 nouveau_gpuobj_del(struct drm_device
*dev
, struct nouveau_gpuobj
**pgpuobj
)
339 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
340 struct nouveau_engine
*engine
= &dev_priv
->engine
;
341 struct nouveau_gpuobj
*gpuobj
;
344 NV_DEBUG(dev
, "gpuobj %p\n", pgpuobj
? *pgpuobj
: NULL
);
346 if (!dev_priv
|| !pgpuobj
|| !(*pgpuobj
))
350 if (gpuobj
->refcount
!= 0) {
351 NV_ERROR(dev
, "gpuobj refcount is %d\n", gpuobj
->refcount
);
355 if (gpuobj
->im_pramin
&& (gpuobj
->flags
& NVOBJ_FLAG_ZERO_FREE
)) {
356 for (i
= 0; i
< gpuobj
->im_pramin
->size
; i
+= 4)
357 nv_wo32(dev
, gpuobj
, i
/4, 0);
358 engine
->instmem
.flush(dev
);
362 gpuobj
->dtor(dev
, gpuobj
);
364 if (gpuobj
->im_backing
&& !(gpuobj
->flags
& NVOBJ_FLAG_FAKE
))
365 engine
->instmem
.clear(dev
, gpuobj
);
367 if (gpuobj
->im_pramin
) {
368 if (gpuobj
->flags
& NVOBJ_FLAG_FAKE
)
369 kfree(gpuobj
->im_pramin
);
371 drm_mm_put_block(gpuobj
->im_pramin
);
374 list_del(&gpuobj
->list
);
382 nouveau_gpuobj_instance_get(struct drm_device
*dev
,
383 struct nouveau_channel
*chan
,
384 struct nouveau_gpuobj
*gpuobj
, uint32_t *inst
)
386 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
387 struct nouveau_gpuobj
*cpramin
;
389 /* <NV50 use PRAMIN address everywhere */
390 if (dev_priv
->card_type
< NV_50
) {
391 *inst
= gpuobj
->im_pramin
->start
;
395 if (chan
&& gpuobj
->im_channel
!= chan
) {
396 NV_ERROR(dev
, "Channel mismatch: obj %d, ref %d\n",
397 gpuobj
->im_channel
->id
, chan
->id
);
401 /* NV50 channel-local instance */
403 cpramin
= chan
->ramin
->gpuobj
;
404 *inst
= gpuobj
->im_pramin
->start
- cpramin
->im_pramin
->start
;
408 /* NV50 global (VRAM) instance */
409 if (!gpuobj
->im_channel
) {
410 /* ...from global heap */
411 if (!gpuobj
->im_backing
) {
412 NV_ERROR(dev
, "AII, no VRAM backing gpuobj\n");
415 *inst
= gpuobj
->im_backing_start
;
418 /* ...from local heap */
419 cpramin
= gpuobj
->im_channel
->ramin
->gpuobj
;
420 *inst
= cpramin
->im_backing_start
+
421 (gpuobj
->im_pramin
->start
- cpramin
->im_pramin
->start
);
429 nouveau_gpuobj_ref_add(struct drm_device
*dev
, struct nouveau_channel
*chan
,
430 uint32_t handle
, struct nouveau_gpuobj
*gpuobj
,
431 struct nouveau_gpuobj_ref
**ref_ret
)
433 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
434 struct nouveau_gpuobj_ref
*ref
;
438 NV_DEBUG(dev
, "ch%d h=0x%08x gpuobj=%p\n",
439 chan
? chan
->id
: -1, handle
, gpuobj
);
441 if (!dev_priv
|| !gpuobj
|| (ref_ret
&& *ref_ret
!= NULL
))
444 if (!chan
&& !ref_ret
)
447 if (gpuobj
->engine
== NVOBJ_ENGINE_SW
&& !gpuobj
->im_pramin
) {
451 ret
= nouveau_gpuobj_instance_get(dev
, chan
, gpuobj
, &instance
);
456 ref
= kzalloc(sizeof(*ref
), GFP_KERNEL
);
459 INIT_LIST_HEAD(&ref
->list
);
460 ref
->gpuobj
= gpuobj
;
462 ref
->instance
= instance
;
465 ref
->handle
= handle
;
467 ret
= nouveau_ramht_insert(dev
, ref
);
477 ref
->gpuobj
->refcount
++;
481 int nouveau_gpuobj_ref_del(struct drm_device
*dev
, struct nouveau_gpuobj_ref
**pref
)
483 struct nouveau_gpuobj_ref
*ref
;
485 NV_DEBUG(dev
, "ref %p\n", pref
? *pref
: NULL
);
487 if (!dev
|| !pref
|| *pref
== NULL
)
491 if (ref
->handle
!= ~0)
492 nouveau_ramht_remove(dev
, ref
);
495 ref
->gpuobj
->refcount
--;
497 if (ref
->gpuobj
->refcount
== 0) {
498 if (!(ref
->gpuobj
->flags
& NVOBJ_FLAG_ALLOW_NO_REFS
))
499 nouveau_gpuobj_del(dev
, &ref
->gpuobj
);
509 nouveau_gpuobj_new_ref(struct drm_device
*dev
,
510 struct nouveau_channel
*oc
, struct nouveau_channel
*rc
,
511 uint32_t handle
, uint32_t size
, int align
,
512 uint32_t flags
, struct nouveau_gpuobj_ref
**ref
)
514 struct nouveau_gpuobj
*gpuobj
= NULL
;
517 ret
= nouveau_gpuobj_new(dev
, oc
, size
, align
, flags
, &gpuobj
);
521 ret
= nouveau_gpuobj_ref_add(dev
, rc
, handle
, gpuobj
, ref
);
523 nouveau_gpuobj_del(dev
, &gpuobj
);
531 nouveau_gpuobj_ref_find(struct nouveau_channel
*chan
, uint32_t handle
,
532 struct nouveau_gpuobj_ref
**ref_ret
)
534 struct nouveau_gpuobj_ref
*ref
;
535 struct list_head
*entry
, *tmp
;
537 list_for_each_safe(entry
, tmp
, &chan
->ramht_refs
) {
538 ref
= list_entry(entry
, struct nouveau_gpuobj_ref
, list
);
540 if (ref
->handle
== handle
) {
551 nouveau_gpuobj_new_fake(struct drm_device
*dev
, uint32_t p_offset
,
552 uint32_t b_offset
, uint32_t size
,
553 uint32_t flags
, struct nouveau_gpuobj
**pgpuobj
,
554 struct nouveau_gpuobj_ref
**pref
)
556 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
557 struct nouveau_gpuobj
*gpuobj
= NULL
;
561 "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n",
562 p_offset
, b_offset
, size
, flags
);
564 gpuobj
= kzalloc(sizeof(*gpuobj
), GFP_KERNEL
);
567 NV_DEBUG(dev
, "gpuobj %p\n", gpuobj
);
568 gpuobj
->im_channel
= NULL
;
569 gpuobj
->flags
= flags
| NVOBJ_FLAG_FAKE
;
571 list_add_tail(&gpuobj
->list
, &dev_priv
->gpuobj_list
);
573 if (p_offset
!= ~0) {
574 gpuobj
->im_pramin
= kzalloc(sizeof(struct drm_mm_node
),
576 if (!gpuobj
->im_pramin
) {
577 nouveau_gpuobj_del(dev
, &gpuobj
);
580 gpuobj
->im_pramin
->start
= p_offset
;
581 gpuobj
->im_pramin
->size
= size
;
584 if (b_offset
!= ~0) {
585 gpuobj
->im_backing
= (struct nouveau_bo
*)-1;
586 gpuobj
->im_backing_start
= b_offset
;
589 if (gpuobj
->flags
& NVOBJ_FLAG_ZERO_ALLOC
) {
590 for (i
= 0; i
< gpuobj
->im_pramin
->size
; i
+= 4)
591 nv_wo32(dev
, gpuobj
, i
/4, 0);
592 dev_priv
->engine
.instmem
.flush(dev
);
596 i
= nouveau_gpuobj_ref_add(dev
, NULL
, 0, gpuobj
, pref
);
598 nouveau_gpuobj_del(dev
, &gpuobj
);
610 nouveau_gpuobj_class_instmem_size(struct drm_device
*dev
, int class)
612 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
614 if (dev_priv
->card_type
>= NV_50
)
616 if (dev_priv
->card_type
>= NV_40
)
622 DMA objects are used to reference a piece of memory in the
623 framebuffer, PCI or AGP address space. Each object is 16 bytes big
624 and looks as follows:
627 11:0 class (seems like I can always use 0 here)
628 12 page table present?
629 13 page entry linear?
630 15:14 access: 0 rw, 1 ro, 2 wo
631 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
632 31:20 dma adjust (bits 0-11 of the address)
634 dma limit (size of transfer)
636 1 0 readonly, 1 readwrite
637 31:12 dma frame address of the page (bits 12-31 of the address)
639 page table terminator, same value as the first pte, as does nvidia
640 rivatv uses 0xffffffff
642 Non linear page tables need a list of frame addresses afterwards,
643 the rivatv project has some info on this.
645 The method below creates a DMA object in instance RAM and returns a handle
646 to it that can be used to set up context objects.
649 nouveau_gpuobj_dma_new(struct nouveau_channel
*chan
, int class,
650 uint64_t offset
, uint64_t size
, int access
,
651 int target
, struct nouveau_gpuobj
**gpuobj
)
653 struct drm_device
*dev
= chan
->dev
;
654 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
655 struct nouveau_instmem_engine
*instmem
= &dev_priv
->engine
.instmem
;
658 NV_DEBUG(dev
, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
659 chan
->id
, class, offset
, size
);
660 NV_DEBUG(dev
, "access=%d target=%d\n", access
, target
);
663 case NV_DMA_TARGET_AGP
:
664 offset
+= dev_priv
->gart_info
.aper_base
;
670 ret
= nouveau_gpuobj_new(dev
, chan
,
671 nouveau_gpuobj_class_instmem_size(dev
, class),
672 16, NVOBJ_FLAG_ZERO_ALLOC
|
673 NVOBJ_FLAG_ZERO_FREE
, gpuobj
);
675 NV_ERROR(dev
, "Error creating gpuobj: %d\n", ret
);
679 if (dev_priv
->card_type
< NV_50
) {
680 uint32_t frame
, adjust
, pte_flags
= 0;
682 if (access
!= NV_DMA_ACCESS_RO
)
684 adjust
= offset
& 0x00000fff;
685 frame
= offset
& ~0x00000fff;
687 nv_wo32(dev
, *gpuobj
, 0, ((1<<12) | (1<<13) |
692 nv_wo32(dev
, *gpuobj
, 1, size
- 1);
693 nv_wo32(dev
, *gpuobj
, 2, frame
| pte_flags
);
694 nv_wo32(dev
, *gpuobj
, 3, frame
| pte_flags
);
696 uint64_t limit
= offset
+ size
- 1;
697 uint32_t flags0
, flags5
;
699 if (target
== NV_DMA_TARGET_VIDMEM
) {
707 nv_wo32(dev
, *gpuobj
, 0, flags0
| class);
708 nv_wo32(dev
, *gpuobj
, 1, lower_32_bits(limit
));
709 nv_wo32(dev
, *gpuobj
, 2, lower_32_bits(offset
));
710 nv_wo32(dev
, *gpuobj
, 3, ((upper_32_bits(limit
) & 0xff) << 24) |
711 (upper_32_bits(offset
) & 0xff));
712 nv_wo32(dev
, *gpuobj
, 5, flags5
);
717 (*gpuobj
)->engine
= NVOBJ_ENGINE_SW
;
718 (*gpuobj
)->class = class;
723 nouveau_gpuobj_gart_dma_new(struct nouveau_channel
*chan
,
724 uint64_t offset
, uint64_t size
, int access
,
725 struct nouveau_gpuobj
**gpuobj
,
728 struct drm_device
*dev
= chan
->dev
;
729 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
732 if (dev_priv
->gart_info
.type
== NOUVEAU_GART_AGP
||
733 (dev_priv
->card_type
>= NV_50
&&
734 dev_priv
->gart_info
.type
== NOUVEAU_GART_SGDMA
)) {
735 ret
= nouveau_gpuobj_dma_new(chan
, NV_CLASS_DMA_IN_MEMORY
,
736 offset
+ dev_priv
->vm_gart_base
,
737 size
, access
, NV_DMA_TARGET_AGP
,
742 if (dev_priv
->gart_info
.type
== NOUVEAU_GART_SGDMA
) {
743 *gpuobj
= dev_priv
->gart_info
.sg_ctxdma
;
744 if (offset
& ~0xffffffffULL
) {
745 NV_ERROR(dev
, "obj offset exceeds 32-bits\n");
749 *o_ret
= (uint32_t)offset
;
750 ret
= (*gpuobj
!= NULL
) ? 0 : -EINVAL
;
752 NV_ERROR(dev
, "Invalid GART type %d\n", dev_priv
->gart_info
.type
);
759 /* Context objects in the instance RAM have the following structure.
760 * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.
770 scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
771 18 synchronize enable
772 19 endian: 1 big, 0 little
774 23 single step enable
775 24 patch status: 0 invalid, 1 valid
776 25 context_surface 0: 1 valid
777 26 context surface 1: 1 valid
778 27 context pattern: 1 valid
779 28 context rop: 1 valid
780 29,30 context beta, beta4
784 31:16 notify instance address
786 15:0 dma 0 instance address
787 31:16 dma 1 instance address
792 No idea what the exact format is. Here's what can be deducted:
795 11:0 class (maybe uses more bits here?)
798 25 patch status valid ?
800 15:0 DMA notifier (maybe 20:0)
802 15:0 DMA 0 instance (maybe 20:0)
805 15:0 DMA 1 instance (maybe 20:0)
811 nouveau_gpuobj_gr_new(struct nouveau_channel
*chan
, int class,
812 struct nouveau_gpuobj
**gpuobj
)
814 struct drm_device
*dev
= chan
->dev
;
815 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
818 NV_DEBUG(dev
, "ch%d class=0x%04x\n", chan
->id
, class);
820 ret
= nouveau_gpuobj_new(dev
, chan
,
821 nouveau_gpuobj_class_instmem_size(dev
, class),
823 NVOBJ_FLAG_ZERO_ALLOC
| NVOBJ_FLAG_ZERO_FREE
,
826 NV_ERROR(dev
, "Error creating gpuobj: %d\n", ret
);
830 if (dev_priv
->card_type
>= NV_50
) {
831 nv_wo32(dev
, *gpuobj
, 0, class);
832 nv_wo32(dev
, *gpuobj
, 5, 0x00010000);
836 nv_wo32(dev
, *gpuobj
, 0, 0x00001030);
837 nv_wo32(dev
, *gpuobj
, 1, 0xFFFFFFFF);
840 if (dev_priv
->card_type
>= NV_40
) {
841 nv_wo32(dev
, *gpuobj
, 0, class);
843 nv_wo32(dev
, *gpuobj
, 2, 0x01000000);
847 nv_wo32(dev
, *gpuobj
, 0, class | 0x00080000);
849 nv_wo32(dev
, *gpuobj
, 0, class);
854 dev_priv
->engine
.instmem
.flush(dev
);
856 (*gpuobj
)->engine
= NVOBJ_ENGINE_GR
;
857 (*gpuobj
)->class = class;
862 nouveau_gpuobj_sw_new(struct nouveau_channel
*chan
, int class,
863 struct nouveau_gpuobj
**gpuobj_ret
)
865 struct drm_nouveau_private
*dev_priv
;
866 struct nouveau_gpuobj
*gpuobj
;
868 if (!chan
|| !gpuobj_ret
|| *gpuobj_ret
!= NULL
)
870 dev_priv
= chan
->dev
->dev_private
;
872 gpuobj
= kzalloc(sizeof(*gpuobj
), GFP_KERNEL
);
875 gpuobj
->engine
= NVOBJ_ENGINE_SW
;
876 gpuobj
->class = class;
878 list_add_tail(&gpuobj
->list
, &dev_priv
->gpuobj_list
);
879 *gpuobj_ret
= gpuobj
;
884 nouveau_gpuobj_channel_init_pramin(struct nouveau_channel
*chan
)
886 struct drm_device
*dev
= chan
->dev
;
887 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
888 struct nouveau_gpuobj
*pramin
= NULL
;
893 NV_DEBUG(dev
, "ch%d\n", chan
->id
);
895 /* Base amount for object storage (4KiB enough?) */
900 size
+= dev_priv
->engine
.graph
.grctx_size
;
902 if (dev_priv
->card_type
== NV_50
) {
903 /* Various fixed table thingos */
904 size
+= 0x1400; /* mostly unknown stuff */
905 size
+= 0x4000; /* vm pd */
907 /* RAMHT, not sure about setting size yet, 32KiB to be safe */
913 ret
= nouveau_gpuobj_new_ref(dev
, NULL
, NULL
, 0, size
, 0x1000, 0,
916 NV_ERROR(dev
, "Error allocating channel PRAMIN: %d\n", ret
);
919 pramin
= chan
->ramin
->gpuobj
;
921 ret
= drm_mm_init(&chan
->ramin_heap
, pramin
->im_pramin
->start
+ base
, size
);
923 NV_ERROR(dev
, "Error creating PRAMIN heap: %d\n", ret
);
924 nouveau_gpuobj_ref_del(dev
, &chan
->ramin
);
932 nouveau_gpuobj_channel_init(struct nouveau_channel
*chan
,
933 uint32_t vram_h
, uint32_t tt_h
)
935 struct drm_device
*dev
= chan
->dev
;
936 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
937 struct nouveau_instmem_engine
*instmem
= &dev_priv
->engine
.instmem
;
938 struct nouveau_gpuobj
*vram
= NULL
, *tt
= NULL
;
941 INIT_LIST_HEAD(&chan
->ramht_refs
);
943 NV_DEBUG(dev
, "ch%d vram=0x%08x tt=0x%08x\n", chan
->id
, vram_h
, tt_h
);
945 /* Allocate a chunk of memory for per-channel object storage */
946 ret
= nouveau_gpuobj_channel_init_pramin(chan
);
948 NV_ERROR(dev
, "init pramin\n");
953 * - Allocate per-channel page-directory
954 * - Map GART and VRAM into the channel's address space at the
955 * locations determined during init.
957 if (dev_priv
->card_type
>= NV_50
) {
958 uint32_t vm_offset
, pde
;
960 vm_offset
= (dev_priv
->chipset
& 0xf0) == 0x50 ? 0x1400 : 0x200;
961 vm_offset
+= chan
->ramin
->gpuobj
->im_pramin
->start
;
963 ret
= nouveau_gpuobj_new_fake(dev
, vm_offset
, ~0, 0x4000,
964 0, &chan
->vm_pd
, NULL
);
967 for (i
= 0; i
< 0x4000; i
+= 8) {
968 nv_wo32(dev
, chan
->vm_pd
, (i
+0)/4, 0x00000000);
969 nv_wo32(dev
, chan
->vm_pd
, (i
+4)/4, 0xdeadcafe);
972 pde
= (dev_priv
->vm_gart_base
/ (512*1024*1024)) * 2;
973 ret
= nouveau_gpuobj_ref_add(dev
, NULL
, 0,
974 dev_priv
->gart_info
.sg_ctxdma
,
978 nv_wo32(dev
, chan
->vm_pd
, pde
++,
979 chan
->vm_gart_pt
->instance
| 0x03);
980 nv_wo32(dev
, chan
->vm_pd
, pde
++, 0x00000000);
982 pde
= (dev_priv
->vm_vram_base
/ (512*1024*1024)) * 2;
983 for (i
= 0; i
< dev_priv
->vm_vram_pt_nr
; i
++) {
984 ret
= nouveau_gpuobj_ref_add(dev
, NULL
, 0,
985 dev_priv
->vm_vram_pt
[i
],
986 &chan
->vm_vram_pt
[i
]);
990 nv_wo32(dev
, chan
->vm_pd
, pde
++,
991 chan
->vm_vram_pt
[i
]->instance
| 0x61);
992 nv_wo32(dev
, chan
->vm_pd
, pde
++, 0x00000000);
999 if (dev_priv
->card_type
< NV_50
) {
1000 ret
= nouveau_gpuobj_ref_add(dev
, NULL
, 0, dev_priv
->ramht
,
1005 ret
= nouveau_gpuobj_new_ref(dev
, chan
, chan
, 0,
1007 NVOBJ_FLAG_ZERO_ALLOC
,
1014 if (dev_priv
->card_type
>= NV_50
) {
1015 ret
= nouveau_gpuobj_dma_new(chan
, NV_CLASS_DMA_IN_MEMORY
,
1016 0, dev_priv
->vm_end
,
1018 NV_DMA_TARGET_AGP
, &vram
);
1020 NV_ERROR(dev
, "Error creating VRAM ctxdma: %d\n", ret
);
1024 ret
= nouveau_gpuobj_dma_new(chan
, NV_CLASS_DMA_IN_MEMORY
,
1025 0, dev_priv
->fb_available_size
,
1027 NV_DMA_TARGET_VIDMEM
, &vram
);
1029 NV_ERROR(dev
, "Error creating VRAM ctxdma: %d\n", ret
);
1034 ret
= nouveau_gpuobj_ref_add(dev
, chan
, vram_h
, vram
, NULL
);
1036 NV_ERROR(dev
, "Error referencing VRAM ctxdma: %d\n", ret
);
1040 /* TT memory ctxdma */
1041 if (dev_priv
->card_type
>= NV_50
) {
1044 if (dev_priv
->gart_info
.type
!= NOUVEAU_GART_NONE
) {
1045 ret
= nouveau_gpuobj_gart_dma_new(chan
, 0,
1046 dev_priv
->gart_info
.aper_size
,
1047 NV_DMA_ACCESS_RW
, &tt
, NULL
);
1049 NV_ERROR(dev
, "Invalid GART type %d\n", dev_priv
->gart_info
.type
);
1054 NV_ERROR(dev
, "Error creating TT ctxdma: %d\n", ret
);
1058 ret
= nouveau_gpuobj_ref_add(dev
, chan
, tt_h
, tt
, NULL
);
1060 NV_ERROR(dev
, "Error referencing TT ctxdma: %d\n", ret
);
1068 nouveau_gpuobj_channel_takedown(struct nouveau_channel
*chan
)
1070 struct drm_nouveau_private
*dev_priv
= chan
->dev
->dev_private
;
1071 struct drm_device
*dev
= chan
->dev
;
1072 struct list_head
*entry
, *tmp
;
1073 struct nouveau_gpuobj_ref
*ref
;
1076 NV_DEBUG(dev
, "ch%d\n", chan
->id
);
1078 if (!chan
->ramht_refs
.next
)
1081 list_for_each_safe(entry
, tmp
, &chan
->ramht_refs
) {
1082 ref
= list_entry(entry
, struct nouveau_gpuobj_ref
, list
);
1084 nouveau_gpuobj_ref_del(dev
, &ref
);
1087 nouveau_gpuobj_ref_del(dev
, &chan
->ramht
);
1089 nouveau_gpuobj_del(dev
, &chan
->vm_pd
);
1090 nouveau_gpuobj_ref_del(dev
, &chan
->vm_gart_pt
);
1091 for (i
= 0; i
< dev_priv
->vm_vram_pt_nr
; i
++)
1092 nouveau_gpuobj_ref_del(dev
, &chan
->vm_vram_pt
[i
]);
1094 if (chan
->ramin_heap
.free_stack
.next
)
1095 drm_mm_takedown(&chan
->ramin_heap
);
1097 nouveau_gpuobj_ref_del(dev
, &chan
->ramin
);
1102 nouveau_gpuobj_suspend(struct drm_device
*dev
)
1104 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1105 struct nouveau_gpuobj
*gpuobj
;
1108 if (dev_priv
->card_type
< NV_50
) {
1109 dev_priv
->susres
.ramin_copy
= vmalloc(dev_priv
->ramin_rsvd_vram
);
1110 if (!dev_priv
->susres
.ramin_copy
)
1113 for (i
= 0; i
< dev_priv
->ramin_rsvd_vram
; i
+= 4)
1114 dev_priv
->susres
.ramin_copy
[i
/4] = nv_ri32(dev
, i
);
1118 list_for_each_entry(gpuobj
, &dev_priv
->gpuobj_list
, list
) {
1119 if (!gpuobj
->im_backing
|| (gpuobj
->flags
& NVOBJ_FLAG_FAKE
))
1122 gpuobj
->im_backing_suspend
= vmalloc(gpuobj
->im_pramin
->size
);
1123 if (!gpuobj
->im_backing_suspend
) {
1124 nouveau_gpuobj_resume(dev
);
1128 for (i
= 0; i
< gpuobj
->im_pramin
->size
/ 4; i
++)
1129 gpuobj
->im_backing_suspend
[i
] = nv_ro32(dev
, gpuobj
, i
);
1136 nouveau_gpuobj_suspend_cleanup(struct drm_device
*dev
)
1138 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1139 struct nouveau_gpuobj
*gpuobj
;
1141 if (dev_priv
->card_type
< NV_50
) {
1142 vfree(dev_priv
->susres
.ramin_copy
);
1143 dev_priv
->susres
.ramin_copy
= NULL
;
1147 list_for_each_entry(gpuobj
, &dev_priv
->gpuobj_list
, list
) {
1148 if (!gpuobj
->im_backing_suspend
)
1151 vfree(gpuobj
->im_backing_suspend
);
1152 gpuobj
->im_backing_suspend
= NULL
;
1157 nouveau_gpuobj_resume(struct drm_device
*dev
)
1159 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1160 struct nouveau_gpuobj
*gpuobj
;
1163 if (dev_priv
->card_type
< NV_50
) {
1164 for (i
= 0; i
< dev_priv
->ramin_rsvd_vram
; i
+= 4)
1165 nv_wi32(dev
, i
, dev_priv
->susres
.ramin_copy
[i
/4]);
1166 nouveau_gpuobj_suspend_cleanup(dev
);
1170 list_for_each_entry(gpuobj
, &dev_priv
->gpuobj_list
, list
) {
1171 if (!gpuobj
->im_backing_suspend
)
1174 for (i
= 0; i
< gpuobj
->im_pramin
->size
/ 4; i
++)
1175 nv_wo32(dev
, gpuobj
, i
, gpuobj
->im_backing_suspend
[i
]);
1176 dev_priv
->engine
.instmem
.flush(dev
);
1179 nouveau_gpuobj_suspend_cleanup(dev
);
1182 int nouveau_ioctl_grobj_alloc(struct drm_device
*dev
, void *data
,
1183 struct drm_file
*file_priv
)
1185 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1186 struct drm_nouveau_grobj_alloc
*init
= data
;
1187 struct nouveau_pgraph_engine
*pgraph
= &dev_priv
->engine
.graph
;
1188 struct nouveau_pgraph_object_class
*grc
;
1189 struct nouveau_gpuobj
*gr
= NULL
;
1190 struct nouveau_channel
*chan
;
1193 NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init
->channel
, file_priv
, chan
);
1195 if (init
->handle
== ~0)
1198 grc
= pgraph
->grclass
;
1200 if (grc
->id
== init
->class)
1206 NV_ERROR(dev
, "Illegal object class: 0x%x\n", init
->class);
1210 if (nouveau_gpuobj_ref_find(chan
, init
->handle
, NULL
) == 0)
1214 ret
= nouveau_gpuobj_gr_new(chan
, grc
->id
, &gr
);
1216 ret
= nouveau_gpuobj_sw_new(chan
, grc
->id
, &gr
);
1219 NV_ERROR(dev
, "Error creating object: %d (%d/0x%08x)\n",
1220 ret
, init
->channel
, init
->handle
);
1224 ret
= nouveau_gpuobj_ref_add(dev
, chan
, init
->handle
, gr
, NULL
);
1226 NV_ERROR(dev
, "Error referencing object: %d (%d/0x%08x)\n",
1227 ret
, init
->channel
, init
->handle
);
1228 nouveau_gpuobj_del(dev
, &gr
);
1235 int nouveau_ioctl_gpuobj_free(struct drm_device
*dev
, void *data
,
1236 struct drm_file
*file_priv
)
1238 struct drm_nouveau_gpuobj_free
*objfree
= data
;
1239 struct nouveau_gpuobj_ref
*ref
;
1240 struct nouveau_channel
*chan
;
1243 NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree
->channel
, file_priv
, chan
);
1245 ret
= nouveau_gpuobj_ref_find(chan
, objfree
->handle
, &ref
);
1248 nouveau_gpuobj_ref_del(dev
, &ref
);