nouveau: interface changes for nv5x 3d

main
Ben Skeggs 2008-06-25 04:39:32 +10:00 committed by Maarten Maathuis
parent a9089c4557
commit 4872ac9c62
4 changed files with 87 additions and 9 deletions

View File

@ -25,7 +25,7 @@
#ifndef __NOUVEAU_DRM_H__ #ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 10 #define NOUVEAU_DRM_HEADER_PATCHLEVEL 11
struct drm_nouveau_channel_alloc { struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle; uint32_t fb_ctxdma_handle;
@ -85,10 +85,12 @@ struct drm_nouveau_gpuobj_free {
#define NOUVEAU_MEM_PINNED 0x00000040 #define NOUVEAU_MEM_PINNED 0x00000040
#define NOUVEAU_MEM_USER_BACKED 0x00000080 #define NOUVEAU_MEM_USER_BACKED 0x00000080
#define NOUVEAU_MEM_MAPPED 0x00000100 #define NOUVEAU_MEM_MAPPED 0x00000100
#define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ #define NOUVEAU_MEM_TILE 0x00000200
#define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ #define NOUVEAU_MEM_TILE_ZETA 0x00000400
#define NOUVEAU_MEM_NOVM 0x00000800 /* internal */ #define NOUVEAU_MEM_INSTANCE 0x01000000 /* internal */
#define NOUVEAU_MEM_USER 0x00001000 /* internal */ #define NOUVEAU_MEM_NOTIFIER 0x02000000 /* internal */
#define NOUVEAU_MEM_NOVM 0x04000000 /* internal */
#define NOUVEAU_MEM_USER 0x08000000 /* internal */
#define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ #define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \
NOUVEAU_MEM_NOTIFIER | \ NOUVEAU_MEM_NOTIFIER | \
NOUVEAU_MEM_NOVM | \ NOUVEAU_MEM_NOVM | \
@ -107,6 +109,13 @@ struct drm_nouveau_mem_free {
int flags; int flags;
}; };
struct drm_nouveau_mem_tile {
uint64_t offset;
uint64_t delta;
uint64_t size;
int flags;
};
/* FIXME : maybe unify {GET,SET}PARAMs */ /* FIXME : maybe unify {GET,SET}PARAMs */
#define NOUVEAU_GETPARAM_PCI_VENDOR 3 #define NOUVEAU_GETPARAM_PCI_VENDOR 3
#define NOUVEAU_GETPARAM_PCI_DEVICE 4 #define NOUVEAU_GETPARAM_PCI_DEVICE 4
@ -168,5 +177,6 @@ struct drm_nouveau_sarea {
#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 #define DRM_NOUVEAU_GPUOBJ_FREE 0x07
#define DRM_NOUVEAU_MEM_ALLOC 0x08 #define DRM_NOUVEAU_MEM_ALLOC 0x08
#define DRM_NOUVEAU_MEM_FREE 0x09 #define DRM_NOUVEAU_MEM_FREE 0x09
#define DRM_NOUVEAU_MEM_TILE 0x0a
#endif /* __NOUVEAU_DRM_H__ */ #endif /* __NOUVEAU_DRM_H__ */

View File

@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0 #define DRIVER_MAJOR 0
#define DRIVER_MINOR 0 #define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 10 #define DRIVER_PATCHLEVEL 11
#define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000 #define NOUVEAU_FLAGS 0xFFFF0000
@ -385,6 +385,8 @@ extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data,
struct drm_file *); struct drm_file *);
extern int nouveau_ioctl_mem_free(struct drm_device *, void *data, extern int nouveau_ioctl_mem_free(struct drm_device *, void *data,
struct drm_file *); struct drm_file *);
extern int nouveau_ioctl_mem_tile(struct drm_device *, void *data,
struct drm_file *);
extern struct mem_block* nouveau_mem_alloc(struct drm_device *, extern struct mem_block* nouveau_mem_alloc(struct drm_device *,
int alignment, uint64_t size, int alignment, uint64_t size,
int flags, struct drm_file *); int flags, struct drm_file *);

View File

@ -593,6 +593,7 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_TILE, nouveau_ioctl_mem_tile, DRM_AUTH),
}; };
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);

View File

@ -606,8 +606,11 @@ nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size,
/* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB
* page size in the GPU VM. * page size in the GPU VM.
*/ */
if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) {
size = (size + (64 * 1024)) & ~((64 * 1024) - 1); size = (size + 65535) & ~65535;
if (alignment < 16)
alignment = 16;
}
/* /*
* Warn about 0 sized allocations, but let it go through. It'll return 1 page * Warn about 0 sized allocations, but let it go through. It'll return 1 page
@ -669,6 +672,7 @@ alloc_ok:
struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
unsigned offset = block->start; unsigned offset = block->start;
unsigned count = block->size / 65536; unsigned count = block->size / 65536;
unsigned tile = 0;
if (!pt) { if (!pt) {
DRM_ERROR("vm alloc without vm pt\n"); DRM_ERROR("vm alloc without vm pt\n");
@ -676,11 +680,22 @@ alloc_ok:
return NULL; return NULL;
} }
/* The tiling stuff is *not* what NVIDIA does - but both the
* 2D and 3D engines seem happy with this simpler method.
* Should look into why NVIDIA do what they do at some point.
*/
if (flags & NOUVEAU_MEM_TILE) {
if (flags & NOUVEAU_MEM_TILE_ZETA)
tile = 0x00002800;
else
tile = 0x00007000;
}
while (count--) { while (count--) {
unsigned pte = offset / 65536; unsigned pte = offset / 65536;
INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000); INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
offset += 65536; offset += 65536;
} }
} else { } else {
@ -833,3 +848,53 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *
nouveau_mem_free(dev, block); nouveau_mem_free(dev, block);
return 0; return 0;
} }
int
nouveau_ioctl_mem_tile(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_mem_tile *memtile = data;
struct mem_block *block = NULL;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
if (dev_priv->card_type < NV_50)
return -EINVAL;
if (memtile->flags & NOUVEAU_MEM_FB) {
memtile->offset -= 512*1024*1024;
block = find_block(dev_priv->fb_heap, memtile->offset);
}
if (!block)
return -EINVAL;
if (block->file_priv != file_priv)
return -EPERM;
{
struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
unsigned offset = block->start + memtile->delta;
unsigned count = memtile->size / 65536;
unsigned tile = 0;
if (memtile->flags & NOUVEAU_MEM_TILE) {
if (memtile->flags & NOUVEAU_MEM_TILE_ZETA)
tile = 0x00002800;
else
tile = 0x00007000;
}
while (count--) {
unsigned pte = offset / 65536;
INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
offset += 65536;
}
}
return 0;
}